import std.container;
import std.algorithm;
import std.range;
import std.array;
import std.stdio;
import std.utf;
import std.math;
import std.typecons;

alias type = single;
struct TestCase
{
  mixin prettyPrinting;

  string str;

  void solve(long tc = -1)
  {
    auto fromab = str.find("AB");
    if (fromab.empty)
      return writeln("NO");
    if (fromab[2 .. $].canFind("BA"))
      return writeln("YES");
    auto fromba = str.find("BA");
    if (fromba.empty)
      return writeln("NO");
    if (fromba[2 .. $].canFind("AB"))
      return writeln("YES");
    return writeln("NO");
  }
}

struct Interval
{
  long l, h;

  bool empty()
  {
    return l > h;
  }
}

Interval intersect(Interval a, Interval b)
{
  return Interval(max(a.l, b.l), min(a.h, b.h));
}

struct If
{
  string condition;
}
enum ignore = If("false");
struct Dim
{
  string dimensions;
  int levels;
  this(string dimensions)
  {
    this.dimensions = dimensions;
    levels = cast(int)dimensions.count(",") + 1;
  }
}

template getArrayLevel(W)
{
  static if (isDynamicArray!W && !is(W == string))
    enum getArrayLevel = 1 + getArrayLevel!(removeArray!(W, 1));
  else
    enum getArrayLevel = 0;
}

static foreach(fieldName; 'a' .. cast(char)('z' + 1))
  {
    static if (fieldName != 'o')
      mixin("enum d", fieldName, " = Dim(\"", fieldName, "\");");
  }

mixin template prettyPrinting()
{
  string toString()
  {
    alias structType = typeof(this);
    auto res = appender!(string)();
    res.put(structType.stringof);
    res.put("(");
    static foreach(fieldName; FieldNameTuple!structType)
      {
        res.put(text(" ", fieldName, ": ", mixin(fieldName)));
      }
    res.put(" )");
    res.put("\n");
    return res[];
  }
}

struct Graph(N)
{
  size_t size;
  this(S)(S size)
  {
    adjacencyList.length = cast(size_t) size;
    this.size = cast(size_t) size;
    this.visited = makeSlice!bool(size);
  }
  N[][] adjacencyList;
  alias ne = neighbours;
  N[] neighbours(N n)
  {
    return adjacencyList.at(n);
  }
  alias bcon = biconnect;
  void biconnect(N a, N b)
  {
    adjacencyList.at(a) ~= b;
    adjacencyList.at(b) ~= a;
  }
  alias con = connect;
  void connect(N a, N b)
  {
    adjacencyList.at(a) ~= b;
  }
  void connect(R)(R edges)
  {
    foreach(ref edge; edges)
      {
        connect(edge[0], edge[1]);
      }
  }
  void biconnect(R)(R edges)
  {
    foreach(ref edge; edges)
      {
        biconnect(edge[0], edge[1]);
      }
  }
  alias deg = degree!long;
  auto degree(T)(N a)
  {
    return cast(T) adjacencyList.at(a).length;
  }

  auto visited = new bool[0];
  void dfs(Visitor)(long startNode)
  {
    auto visitor = Visitor.init;
    void internalDfs(long node)
    {
      visited.set(node, true);
      static if (is(typeof({visitor.n = node;})))
        visitor.n = node;
      static if (is(typeof({visitor.pre;})))
        visitor.pre;
      foreach(w; ne(node))
        if (!visited.at(w))
          {
            static if (is(typeof({visitor.w = w;})))
              visitor.w = w;
            static if (is(typeof(visitor.pren)))
              visitor.pren;
            internalDfs(w);
            static if (is(typeof(visitor.postn)))
              visitor.postn;
          }
      static if (is(typeof(visitor.post)))
        visitor.post;
    }
    internalDfs(startNode);
  }
  void dfs(long startNode)
  {
    struct DefVisitor {}
    dfs!DefVisitor(startNode);
  }
}

DList!string _words;

template removeArray(W, int times)
{
  static if (times == 0)
    alias removeArray = W;
  else static if (times == 1)
    alias removeArray = typeof(function(){W w; return w[0];}());
  else
    {
      static assert(isDynamicArray!W);
      alias removeArray = removeArray!(removeArray!(W, 1), times - 1);
    }
}

template baseType(W)
{
  static if (isDynamicArray!W && !is(W == string))
    alias baseType = baseType!(typeof((delegate() {W w; return w[0];})()));
  else
    alias baseType = W;
}

auto makeSlice(E, W, T...)(W size, T otherSizes)
{
  static if (T.length == 0)
    {
      E[] res;
      res.length = cast(size_t) size;
      return res;
    }
  else
    {
      typeof(makeSlice!E(otherSizes))[] res;
      res.length = cast(size_t) size;
      foreach(ref row; res)
        row = makeSlice!E(otherSizes);
      return res;
    }
}

void read(T...)(ref T t)
{
  void basicTypeRead(W)(ref W w)
  {
    import std.stdio: readln;
    while(_words.empty)
      {
        import std.array: split;
        foreach(word; readln.split)
          {
            _words.insertBack(word);
          }
      }
    import std.conv: to;
    string word = _words.front;
    _words.removeFront;
    w = to!W(word);
  }
  void iterableRead(W)(ref W w)
  {
    foreach(ref element; w)
      read(element);
  }
  void tupleRead(W)(ref W w)
  {
    static foreach(j; 0 .. W.length)
      read(w[j]);
  }
  void structRead(W)(ref W readStruct)
  {
    static foreach(fieldName; FieldNameTuple!W)
      {
        with(readStruct)
          {
            alias fieldSymbol = mixin(W.stringof, ".", fieldName);
            alias typeOfField = typeof(mixin(fieldName));
            static if (hasUDA!(fieldSymbol, If))
              enum condition = getUDAs!(fieldSymbol, If)[0].condition;
            else
              enum condition = "true";

            if (mixin(condition))
              {
                static if (hasUDA!(fieldSymbol, Dim))
                  {
                    static assert(isDynamicArray!(typeOfField)
                                  , text(W.stringof, ".", fieldName, " has Dim UDA but isn't a Dynamic Array."));
                    enum uda = getUDAs!(fieldSymbol, Dim)[0];
                    static assert(getArrayLevel!(typeOfField) == uda.levels,
                                  text(W.stringof, ".", fieldName, " has a Dim UDA with different number of dimensions than it's type."));
                    mixin(fieldName) = mixin(q{makeSlice!(baseType!typeOfField)(}, uda.dimensions, q{)});
                  }
                else static if (isDynamicArray!typeOfField && !is(typeOfField == string))
                  {
                    pragma(msg, "Warning: You probably want to add dimension to input ", W.stringof, ".", fieldName);
                  }
                read(mixin(fieldName));
              }
          }
      }
  }
  static foreach(i; 0 .. T.length)
    {
      static if (isBasicType!(T[i]) || is(T[i] == string))
        basicTypeRead(t[i]);
      else static if (is(typeof({foreach(ref e; t[i]){}})))
        iterableRead(t[i]);
      else static if (isTuple!(T[i]))
        tupleRead(t[i]);
      else static if (isAggregateType!(T[i]))
        structRead(t[i]);
    }
}

auto next(T)()
{
  T t;
  read(t);
  return t;
}

size_t ind(T)(T t)
{
  return cast(size_t)t;
}

ref auto at(R, I)(ref R r, I i)
{
  return r[cast(size_t)i];
}

void set(R, I, V)(ref R r, I i, V v)
{
  r[cast(size_t)i] = v;
}

import std.conv;
import std.traits;
import std.meta;
int _loglevel = -1;
void _log(string functionName, argSeq...)()
{
  foreach(i; 0 .. _loglevel * 4)
    write(' ');
  write(functionName);
  static foreach(arg; argSeq)
    {
      write(" ", arg.stringof, " = ", arg);
    }
  writeln;
}
enum logCall =
  q{
    debug
    {
     {
     _loglevel++;
     alias _parameterTuple = ParameterIdentifierTuple!(mixin(split(__FUNCTION__, ".").back));
     static if (_parameterTuple.length > 0)
       mixin(`_log!(__FUNCTION__, `, [_parameterTuple].joiner(", ").array, `);`);
     else
       _log!(__FUNCTION__);
      }
     foreach(i; 0 .. _loglevel * 4) write(' ');
     writeln('{');
     scope(exit)
       {
         foreach(i; 0 .. _loglevel * 4) write(' ');
         writeln('}');
         _loglevel--;
       }
    }
};

void logSym(S...)(int line = __LINE__, string file = __FUNCTION__)
{
  debug
    {
      foreach(i; 0 .. _loglevel * 4) write(' ');
      write(file, "(", line, "):");
      static foreach(s; S)
        write(" ", s.stringof, " = ", s);
      writeln;

    }
}

Array!E makeArray(E, S)(S size, lazy E value)
{
  auto a = Array!E();
  a.length = cast(size_t) size;
  foreach(ref ai; a)
    ai = value();
  return a;
}
Array!E makeArray(E, S)(S size)
{
  auto a = Array!E();
  a.length = cast(size_t) size;
  return a;
}

template mem(alias F)
{
  ReturnType!F[Tuple!(Parameters!F)] table;
  ReturnType!F mem(Parameters!F args)
  {
    return table.require(tuple(args), F(args));
  }
}

string input(string names, string type = "long")
{
  return text(type, " ", names, "; read(", names, ");");
}

auto pmod(T, W)(T t, W w)
{
  return (t%w + w) % w;
}

void rep(S, F)(F f, S times)
{
  static if (is(typeof(f(i))))
    foreach(i; 0 .. times)
      f(i);
  else
    foreach(i; 0 .. times)
      f();
}

void multi()
{
  foreach(tc; 0 .. next!long)
    next!TestCase.solve(tc);
}

void single()
{
  auto tc = next!TestCase;
  tc.solve;
}

void main()
{
  type;
}

import std.stdio;
import std.string;

bool find(const(char)[] s,
          immutable(char)[] pat1,
          immutable(char)[] pat2) {
  uint p1 = cast(uint)s.indexOf(pat1);
  if (p1 == -1) {
    return false;
  }
  auto t = s[p1+pat1.length..$];
  uint p2 = cast(uint)t.indexOf(pat2);
  if (p2 == -1) {
    return false;
  }
  return true;
}

void main() {
  string s = readln();
  writeln(find(s, "AB", "BA") || find(s, "BA", "AB") ? "YES" : "NO");
}

import std.stdio;
import std.string;

bool find(const(char)[] s,
          immutable(char)[] pat1,
          immutable(char)[] pat2) {
  auto p1 = s.indexOf(pat1);
  if (p1 == -1) {
    return false;
  }
  auto t = s[p1+pat1.length..$];
  auto p2 = t.indexOf(pat2);
  if (p2 == -1) {
    return false;
  }
  return true;
}

void main() {
  string s = readln();
  writeln(find(s, "AB", "BA") || find(s, "BA", "AB") ? "YES" : "NO");
}

version (all) {
import std.math,
       std.conv,
       std.stdio,
       std.ascii,
       std.range,
       std.array,
       std.regex,
       std.format,
       std.bigint,
       std.traits,
       std.random,
       std.string,
       std.numeric,
       std.variant,
       std.typecons,
       std.container,
       std.algorithm,
       std.typetuple,
       std.exception,
       core.checkedint;
}

void main() {

	string s = readln;

	int idx = s.indexOf("AB");
	if (idx != -1) {
		if (s[idx + 2 .. $].indexOf("BA") != -1) {
			writeln("YES");
			return;
		}
	}

	int jdx = s.indexOf("BA");
	if (jdx != -1) {
		if (s[jdx + 2 .. $].indexOf("AB") != -1) {
			writeln("YES");
			return;
		}
	}

	writeln("NO");
}

import std.stdio : writeln, readln;
import std.string : chomp;

void main() {
  string s = readln.chomp;

  bool ab = false;
  bool ba = false;
  bool optional = false;

  char last = s[0];
  foreach (char i; s) {
    if (last == 'A' && i == 'B' && !ab) {
      ab = true;
      last = 'x';
    } else if (last == 'B' && i == 'A' && !ba) {
      ba = true;
      last = 'y';
    } else {
      if (last == 'x' && i == 'A') {
        optional = true;
        ab = false;
      } else if (last == 'y' && i == 'B') {
        optional = true;
        ba = false;
      } else
        last = i;
    }
    if ((ab || ba) && optional || ba && ab) {
      writeln("YES");
      return;
    }
  }
  writeln("NO");
}

import std.stdio : writeln, readln;
import std.string : chomp;

void main() {
  string s = readln.chomp;

  bool ab = false;
  bool ba = false;
  bool optional = false;

  char last = s[0];
  foreach (char i; s[1 .. $]) {
    if (last == 'A' && i == 'B' && !ab) {
      ab = true;
      last = 'x';
    } else if (last == 'B' && i == 'A' && !ba) {
      ba = true;
      last = 'y';
    } else {
      if (last == 'x' && i == 'A') {
        optional = true;
        ab = false;
      } else if (last == 'y' && i == 'B') {
        optional = true;
        ba = false;
      } else
        last = i;
    }
    if ((ab || ba) && optional || ba && ab) {
      writeln("YES");
      return;
    }
  }
  writeln("NO");
}

//ahmat
import core.stdc.stdio:scanf,printf,puts;
import core.bitop;
import std.stdio;
import std.string;
import std.algorithm;
import std.functional;
import std.array;
import std.container;
import std.conv;
import std.container;
import std.typecons;
import std.math;
import std.numeric;
pragma(inline,true);

void main(){
    string s=readln.strip;
    if(s.length<4){
        writeln("NO");
        return;
    }
    long i=s.indexOf("AB");
    long j=s[cast(uint)i+2..$].indexOf("BA");
    if(i>=0 && j>=0){
        writeln("YES");
        return;
    }
    i=s.indexOf("BA");
    j=s[cast(uint)i+2..$].indexOf("AB");
    if(i>=0 && j>=0)
        writeln("YES");
    else writeln("NO");
}

import std.container;
import std.algorithm;
import std.range;
import std.array;
import std.stdio;
import std.utf;
import std.math;
import std.typecons;

alias type = single;
struct TestCase
{
  mixin prettyPrinting;

  string str;

  void solve(long tc = -1)
  {
    if (str.canFind("AB") && str.canFind("BA")
        && (str.find("AB")[2 .. $].canFind("BA")
            || str.find("BA")[2 .. $].canFind("AB")))
      return writeln("YES");
    writeln("NO");
  }
}

struct Interval
{
  long l, h;

  bool empty()
  {
    return l > h;
  }
}

Interval intersect(Interval a, Interval b)
{
  return Interval(max(a.l, b.l), min(a.h, b.h));
}

struct If
{
  string condition;
}
enum ignore = If("false");
struct Dim
{
  string dimensions;
  int levels;
  this(string dimensions)
  {
    this.dimensions = dimensions;
    levels = cast(int)dimensions.count(",") + 1;
  }
}

template getArrayLevel(W)
{
  static if (isDynamicArray!W && !is(W == string))
    enum getArrayLevel = 1 + getArrayLevel!(removeArray!(W, 1));
  else
    enum getArrayLevel = 0;
}

static foreach(fieldName; 'a' .. cast(char)('z' + 1))
  {
    static if (fieldName != 'o')
      mixin("enum d", fieldName, " = Dim(\"", fieldName, "\");");
  }

mixin template prettyPrinting()
{
  string toString()
  {
    alias structType = typeof(this);
    auto res = appender!(string)();
    res.put(structType.stringof);
    res.put("(");
    static foreach(fieldName; FieldNameTuple!structType)
      {
        res.put(text(" ", fieldName, ": ", mixin(fieldName)));
      }
    res.put(" )");
    res.put("\n");
    return res[];
  }
}

struct Graph(N)
{
  size_t size;
  this(S)(S size)
  {
    adjacencyList.length = cast(size_t) size;
    this.size = cast(size_t) size;
    this.visited = makeSlice!bool(size);
  }
  N[][] adjacencyList;
  alias ne = neighbours;
  N[] neighbours(N n)
  {
    return adjacencyList.at(n);
  }
  alias bcon = biconnect;
  void biconnect(N a, N b)
  {
    adjacencyList.at(a) ~= b;
    adjacencyList.at(b) ~= a;
  }
  alias con = connect;
  void connect(N a, N b)
  {
    adjacencyList.at(a) ~= b;
  }
  void connect(R)(R edges)
  {
    foreach(ref edge; edges)
      {
        connect(edge[0], edge[1]);
      }
  }
  void biconnect(R)(R edges)
  {
    foreach(ref edge; edges)
      {
        biconnect(edge[0], edge[1]);
      }
  }
  alias deg = degree!long;
  auto degree(T)(N a)
  {
    return cast(T) adjacencyList.at(a).length;
  }

  auto visited = new bool[0];
  void dfs(Visitor)(long startNode)
  {
    auto visitor = Visitor.init;
    void internalDfs(long node)
    {
      visited.set(node, true);
      static if (is(typeof({visitor.n = node;})))
        visitor.n = node;
      static if (is(typeof({visitor.pre;})))
        visitor.pre;
      foreach(w; ne(node))
        if (!visited.at(w))
          {
            static if (is(typeof({visitor.w = w;})))
              visitor.w = w;
            static if (is(typeof(visitor.pren)))
              visitor.pren;
            internalDfs(w);
            static if (is(typeof(visitor.postn)))
              visitor.postn;
          }
      static if (is(typeof(visitor.post)))
        visitor.post;
    }
    internalDfs(startNode);
  }
  void dfs(long startNode)
  {
    struct DefVisitor {}
    dfs!DefVisitor(startNode);
  }
}

DList!string _words;

template removeArray(W, int times)
{
  static if (times == 0)
    alias removeArray = W;
  else static if (times == 1)
    alias removeArray = typeof(function(){W w; return w[0];}());
  else
    {
      static assert(isDynamicArray!W);
      alias removeArray = removeArray!(removeArray!(W, 1), times - 1);
    }
}

template baseType(W)
{
  static if (isDynamicArray!W && !is(W == string))
    alias baseType = baseType!(typeof((delegate() {W w; return w[0];})()));
  else
    alias baseType = W;
}

auto makeSlice(E, W, T...)(W size, T otherSizes)
{
  static if (T.length == 0)
    {
      E[] res;
      res.length = cast(size_t) size;
      return res;
    }
  else
    {
      typeof(makeSlice!E(otherSizes))[] res;
      res.length = cast(size_t) size;
      foreach(ref row; res)
        row = makeSlice!E(otherSizes);
      return res;
    }
}

void read(T...)(ref T t)
{
  void basicTypeRead(W)(ref W w)
  {
    import std.stdio: readln;
    while(_words.empty)
      {
        import std.array: split;
        foreach(word; readln.split)
          {
            _words.insertBack(word);
          }
      }
    import std.conv: to;
    string word = _words.front;
    _words.removeFront;
    w = to!W(word);
  }
  void iterableRead(W)(ref W w)
  {
    foreach(ref element; w)
      read(element);
  }
  void tupleRead(W)(ref W w)
  {
    static foreach(j; 0 .. W.length)
      read(w[j]);
  }
  void structRead(W)(ref W readStruct)
  {
    static foreach(fieldName; FieldNameTuple!W)
      {
        with(readStruct)
          {
            alias fieldSymbol = mixin(W.stringof, ".", fieldName);
            alias typeOfField = typeof(mixin(fieldName));
            static if (hasUDA!(fieldSymbol, If))
              enum condition = getUDAs!(fieldSymbol, If)[0].condition;
            else
              enum condition = "true";

            if (mixin(condition))
              {
                static if (hasUDA!(fieldSymbol, Dim))
                  {
                    static assert(isDynamicArray!(typeOfField)
                                  , text(W.stringof, ".", fieldName, " has Dim UDA but isn't a Dynamic Array."));
                    enum uda = getUDAs!(fieldSymbol, Dim)[0];
                    static assert(getArrayLevel!(typeOfField) == uda.levels,
                                  text(W.stringof, ".", fieldName, " has a Dim UDA with different number of dimensions than it's type."));
                    mixin(fieldName) = mixin(q{makeSlice!(baseType!typeOfField)(}, uda.dimensions, q{)});
                  }
                else static if (isDynamicArray!typeOfField && !is(typeOfField == string))
                  {
                    pragma(msg, "Warning: You probably want to add dimension to input ", W.stringof, ".", fieldName);
                  }
                read(mixin(fieldName));
              }
          }
      }
  }
  static foreach(i; 0 .. T.length)
    {
      static if (isBasicType!(T[i]) || is(T[i] == string))
        basicTypeRead(t[i]);
      else static if (is(typeof({foreach(ref e; t[i]){}})))
        iterableRead(t[i]);
      else static if (isTuple!(T[i]))
        tupleRead(t[i]);
      else static if (isAggregateType!(T[i]))
        structRead(t[i]);
    }
}

auto next(T)()
{
  T t;
  read(t);
  return t;
}

size_t ind(T)(T t)
{
  return cast(size_t)t;
}

ref auto at(R, I)(ref R r, I i)
{
  return r[cast(size_t)i];
}

void set(R, I, V)(ref R r, I i, V v)
{
  r[cast(size_t)i] = v;
}

import std.conv;
import std.traits;
import std.meta;
int _loglevel = -1;
void _log(string functionName, argSeq...)()
{
  foreach(i; 0 .. _loglevel * 4)
    write(' ');
  write(functionName);
  static foreach(arg; argSeq)
    {
      write(" ", arg.stringof, " = ", arg);
    }
  writeln;
}
enum logCall =
  q{
    debug
    {
     {
     _loglevel++;
     alias _parameterTuple = ParameterIdentifierTuple!(mixin(split(__FUNCTION__, ".").back));
     static if (_parameterTuple.length > 0)
       mixin(`_log!(__FUNCTION__, `, [_parameterTuple].joiner(", ").array, `);`);
     else
       _log!(__FUNCTION__);
      }
     foreach(i; 0 .. _loglevel * 4) write(' ');
     writeln('{');
     scope(exit)
       {
         foreach(i; 0 .. _loglevel * 4) write(' ');
         writeln('}');
         _loglevel--;
       }
    }
};

void logSym(S...)(int line = __LINE__, string file = __FUNCTION__)
{
  debug
    {
      foreach(i; 0 .. _loglevel * 4) write(' ');
      write(file, "(", line, "):");
      static foreach(s; S)
        write(" ", s.stringof, " = ", s);
      writeln;

    }
}

Array!E makeArray(E, S)(S size, lazy E value)
{
  auto a = Array!E();
  a.length = cast(size_t) size;
  foreach(ref ai; a)
    ai = value();
  return a;
}
Array!E makeArray(E, S)(S size)
{
  auto a = Array!E();
  a.length = cast(size_t) size;
  return a;
}

template mem(alias F)
{
  ReturnType!F[Tuple!(Parameters!F)] table;
  ReturnType!F mem(Parameters!F args)
  {
    return table.require(tuple(args), F(args));
  }
}

string input(string names, string type = "long")
{
  return text(type, " ", names, "; read(", names, ");");
}

auto pmod(T, W)(T t, W w)
{
  return (t%w + w) % w;
}

void rep(S, F)(F f, S times)
{
  static if (is(typeof(f(i))))
    foreach(i; 0 .. times)
      f(i);
  else
    foreach(i; 0 .. times)
      f();
}

void multi()
{
  foreach(tc; 0 .. next!long)
    next!TestCase.solve(tc);
}

void single()
{
  auto tc = next!TestCase;
  tc.solve;
}

void main()
{
  type;
}

import std.stdio : writeln, readln;
import std.string : chomp;

void main() {
  string s = readln.chomp;

  bool first = true;

  char last = s[0];
  foreach (char i; s[1 .. $]) {
    if ((last == 'A' && i == 'B') || (last == 'B' && i == 'A')) {
      if (first) {
        first = false;
        last = 'x';
      } else {
        writeln("YES");
        return;
      }
    } else
      last = i;
  }
  writeln("NO");
}

import std.stdio : writeln, readln;
import std.string : chomp;

void main() {
  string s = readln.chomp;

  bool first = true;

  char last = s[0];
  foreach (char i; s[1 .. $]) {
    if ((last == 'A' && i == 'B') || (last == 'B' && i == 'A')) {
      if (first) {
        first = false;
        last = 'x';
      } else {
        writeln("YES");
        return;
      }
    }
  }
  writeln("NO");
}

import std.stdio : writeln, readln;
import std.string : chomp;

void main() {
  string s = readln.chomp;

  bool ab = false;
  bool ba = false;
  bool optional = false;

  char last = s[0];
  foreach (char i; s[1 .. $]) {
    if (last == 'A' && i == 'B' && !ab) {
      ab = true;
      last = 'x';
    } else if (last == 'B' && i == 'A' && !ba) {
      ba = true;
      last = 'y';
    } else {
      if (last == 'x' && i == 'A') {
        optional = true;
        ab = false;
      } else if (last == 'y' && i == 'B') {
        optional = true;
        ba = false;
      }
      last = i;
    }
    if ((ab || ba) && optional) {
      writeln("YES");
      return;
    }
  }
  writeln("NO");
}

import std.stdio : writeln, readln;
import std.string : chomp;

void main() {
  string s = readln.chomp;

  bool ab = false;
  bool ba = false;

  char last = s[0];
  foreach (char i; s[1 .. $]) {
    if (last == 'A' && i == 'B' && !ab) {
      ab = true;
      last = 'x';
    } else if (last == 'B' && i == 'A' && !ba) {
      ba = true;
      last = 'x';
    } else {
      last = i;
    }
    if (ab && ba) {
      writeln("YES");
      return;
    }
  }
  writeln("NO");
}

import std.stdio : writeln, readln;
import std.string : chomp;

void main() {
  string s = readln.chomp;

  bool ab = false;
  bool ba = false;
  bool optional = false;

  char last = s[0];
  foreach (char i; s[1 .. $]) {
    if (last == 'A' && i == 'B' && !ab) {
      ab = true;
      last = 'x';
    } else if (last == 'B' && i == 'A' && !ba) {
      ba = true;
      last = 'y';
    } else {
      if (last == 'x' && i == 'A') {
        optional = true;
        ab = false;
      } else if (last == 'y' && i == 'B') {
        optional = true;
        ba = false;
      } else
        last = i;
    }
    if ((ab || ba) && optional) {
      writeln("YES");
      return;
    }
  }
  writeln("NO");
}

import std.stdio : writeln, readln;
import std.string : chomp;

void main() {
  string s = readln.chomp;

  bool ab = false;
  bool ba = false;
  bool optional_ab = false;
  bool optional_ba = false;

  char last = s[0];
  foreach (char i; s[1 .. $]) {
    if (last == 'A' && i == 'B' && !ab) {
      ab = true;
      last = 'x';
    } else if (last == 'B' && i == 'A' && !ba) {
      ba = true;
      last = 'y';
    } else {
      if (last == 'x' && i == 'A')
        optional_ba = true;
      else if (last == 'y' && i == 'B')
        optional_ab = true;
      last = i;
    }
    if ((ab || optional_ab) && (ba || optional_ba)) {
      writeln("YES");
      return;
    }
  }
  writeln("NO");
}

import std.stdio : writeln, readln;
import std.string : chomp;

void main()
{
  string s = readln.chomp;

  bool ab = false;
  bool ba = false;

  char last = s[0];
  foreach (char i; s[1 .. $])
  {
    if (last == 'A' && i == 'B')
    {
      ab = true;
      last = 'x';
    }
    else if (last == 'B' && i == 'A')
    {
      ba = true;
      last = 'x';
    }
    else
    {
      last = i;
    }
    if (ab && ba)
    {
      writeln("YES");
      return;
    }
  }
  writeln("NO");
}

//ahmat
import core.stdc.stdio:scanf,printf,puts;
import core.bitop;
import std.stdio;
import std.string;
import std.algorithm;
import std.functional;
import std.array;
import std.container;
import std.conv;
import std.container;
import std.typecons;
import std.math;
import std.numeric;
pragma(inline,true);

void main(){
    string s=readln.strip;
    long i=s.indexOf("AB"),j=s.indexOf("BA");
    if(i>=0 && j>=0 && abs(i-j)>=2)
        writeln("YES");
    else
        writeln("NO");
}

import std.container;
import std.algorithm;
import std.range;
import std.array;
import std.stdio;
import std.utf;
import std.math;
import std.typecons;

alias type = single;
struct TestCase
{
  mixin prettyPrinting;

  string str;

  void solve(long tc = -1)
  {
    bool hasleft, hasright;
    foreach(i; 0 .. str.length)
      {
        if (str[i] == 'B')
          {
            if (i >= 1 && str[i - 1] == 'A')
              {
                if (hasright)
                  {
                    writeln("YES");
                    return;
                  }
              }
            if (i + 1 < str.length && str[i + 1] == 'A')
              {
                if (hasleft)
                  {
                    writeln("YES");
                    return;
                  }
              }
            if (i >= 1 && str[i - 1] == 'A')
              hasleft = true;
            if (i + 1 < str.length && str[i + 1] == 'A')
              hasright = true;
          }
      }
    writeln("NO");
  }
}

struct Interval
{
  long l, h;

  bool empty()
  {
    return l > h;
  }
}

Interval intersect(Interval a, Interval b)
{
  return Interval(max(a.l, b.l), min(a.h, b.h));
}

struct If
{
  string condition;
}
enum ignore = If("false");
struct Dim
{
  string dimensions;
  int levels;
  this(string dimensions)
  {
    this.dimensions = dimensions;
    levels = cast(int)dimensions.count(",") + 1;
  }
}

template getArrayLevel(W)
{
  static if (isDynamicArray!W && !is(W == string))
    enum getArrayLevel = 1 + getArrayLevel!(removeArray!(W, 1));
  else
    enum getArrayLevel = 0;
}

static foreach(fieldName; 'a' .. cast(char)('z' + 1))
  {
    static if (fieldName != 'o')
      mixin("enum d", fieldName, " = Dim(\"", fieldName, "\");");
  }

mixin template prettyPrinting()
{
  string toString()
  {
    alias structType = typeof(this);
    auto res = appender!(string)();
    res.put(structType.stringof);
    res.put("(");
    static foreach(fieldName; FieldNameTuple!structType)
      {
        res.put(text(" ", fieldName, ": ", mixin(fieldName)));
      }
    res.put(" )");
    res.put("\n");
    return res[];
  }
}

struct Graph(N)
{
  size_t size;
  this(S)(S size)
  {
    adjacencyList.length = cast(size_t) size;
    this.size = cast(size_t) size;
    this.visited = makeSlice!bool(size);
  }
  N[][] adjacencyList;
  alias ne = neighbours;
  N[] neighbours(N n)
  {
    return adjacencyList.at(n);
  }
  alias bcon = biconnect;
  void biconnect(N a, N b)
  {
    adjacencyList.at(a) ~= b;
    adjacencyList.at(b) ~= a;
  }
  alias con = connect;
  void connect(N a, N b)
  {
    adjacencyList.at(a) ~= b;
  }
  void connect(R)(R edges)
  {
    foreach(ref edge; edges)
      {
        connect(edge[0], edge[1]);
      }
  }
  void biconnect(R)(R edges)
  {
    foreach(ref edge; edges)
      {
        biconnect(edge[0], edge[1]);
      }
  }
  alias deg = degree!long;
  auto degree(T)(N a)
  {
    return cast(T) adjacencyList.at(a).length;
  }

  auto visited = new bool[0];
  void dfs(Visitor)(long startNode)
  {
    auto visitor = Visitor.init;
    void internalDfs(long node)
    {
      visited.set(node, true);
      static if (is(typeof({visitor.n = node;})))
        visitor.n = node;
      static if (is(typeof({visitor.pre;})))
        visitor.pre;
      foreach(w; ne(node))
        if (!visited.at(w))
          {
            static if (is(typeof({visitor.w = w;})))
              visitor.w = w;
            static if (is(typeof(visitor.pren)))
              visitor.pren;
            internalDfs(w);
            static if (is(typeof(visitor.postn)))
              visitor.postn;
          }
      static if (is(typeof(visitor.post)))
        visitor.post;
    }
    internalDfs(startNode);
  }
  void dfs(long startNode)
  {
    struct DefVisitor {}
    dfs!DefVisitor(startNode);
  }
}

DList!string _words;

template removeArray(W, int times)
{
  static if (times == 0)
    alias removeArray = W;
  else static if (times == 1)
    alias removeArray = typeof(function(){W w; return w[0];}());
  else
    {
      static assert(isDynamicArray!W);
      alias removeArray = removeArray!(removeArray!(W, 1), times - 1);
    }
}

template baseType(W)
{
  static if (isDynamicArray!W && !is(W == string))
    alias baseType = baseType!(typeof((delegate() {W w; return w[0];})()));
  else
    alias baseType = W;
}

auto makeSlice(E, W, T...)(W size, T otherSizes)
{
  static if (T.length == 0)
    {
      E[] res;
      res.length = cast(size_t) size;
      return res;
    }
  else
    {
      typeof(makeSlice!E(otherSizes))[] res;
      res.length = cast(size_t) size;
      foreach(ref row; res)
        row = makeSlice!E(otherSizes);
      return res;
    }
}

void read(T...)(ref T t)
{
  void basicTypeRead(W)(ref W w)
  {
    import std.stdio: readln;
    while(_words.empty)
      {
        import std.array: split;
        foreach(word; readln.split)
          {
            _words.insertBack(word);
          }
      }
    import std.conv: to;
    string word = _words.front;
    _words.removeFront;
    w = to!W(word);
  }
  void iterableRead(W)(ref W w)
  {
    foreach(ref element; w)
      read(element);
  }
  void tupleRead(W)(ref W w)
  {
    static foreach(j; 0 .. W.length)
      read(w[j]);
  }
  void structRead(W)(ref W readStruct)
  {
    static foreach(fieldName; FieldNameTuple!W)
      {
        with(readStruct)
          {
            alias fieldSymbol = mixin(W.stringof, ".", fieldName);
            alias typeOfField = typeof(mixin(fieldName));
            static if (hasUDA!(fieldSymbol, If))
              enum condition = getUDAs!(fieldSymbol, If)[0].condition;
            else
              enum condition = "true";

            if (mixin(condition))
              {
                static if (hasUDA!(fieldSymbol, Dim))
                  {
                    static assert(isDynamicArray!(typeOfField)
                                  , text(W.stringof, ".", fieldName, " has Dim UDA but isn't a Dynamic Array."));
                    enum uda = getUDAs!(fieldSymbol, Dim)[0];
                    static assert(getArrayLevel!(typeOfField) == uda.levels,
                                  text(W.stringof, ".", fieldName, " has a Dim UDA with different number of dimensions than it's type."));
                    mixin(fieldName) = mixin(q{makeSlice!(baseType!typeOfField)(}, uda.dimensions, q{)});
                  }
                else static if (isDynamicArray!typeOfField && !is(typeOfField == string))
                  {
                    pragma(msg, "Warning: You probably want to add dimension to input ", W.stringof, ".", fieldName);
                  }
                read(mixin(fieldName));
              }
          }
      }
  }
  static foreach(i; 0 .. T.length)
    {
      static if (isBasicType!(T[i]) || is(T[i] == string))
        basicTypeRead(t[i]);
      else static if (is(typeof({foreach(ref e; t[i]){}})))
        iterableRead(t[i]);
      else static if (isTuple!(T[i]))
        tupleRead(t[i]);
      else static if (isAggregateType!(T[i]))
        structRead(t[i]);
    }
}

auto next(T)()
{
  T t;
  read(t);
  return t;
}

size_t ind(T)(T t)
{
  return cast(size_t)t;
}

ref auto at(R, I)(ref R r, I i)
{
  return r[cast(size_t)i];
}

void set(R, I, V)(ref R r, I i, V v)
{
  r[cast(size_t)i] = v;
}

import std.conv;
import std.traits;
import std.meta;
int _loglevel = -1;
void _log(string functionName, argSeq...)()
{
  foreach(i; 0 .. _loglevel * 4)
    write(' ');
  write(functionName);
  static foreach(arg; argSeq)
    {
      write(" ", arg.stringof, " = ", arg);
    }
  writeln;
}
enum logCall =
  q{
    debug
    {
     {
     _loglevel++;
     alias _parameterTuple = ParameterIdentifierTuple!(mixin(split(__FUNCTION__, ".").back));
     static if (_parameterTuple.length > 0)
       mixin(`_log!(__FUNCTION__, `, [_parameterTuple].joiner(", ").array, `);`);
     else
       _log!(__FUNCTION__);
      }
     foreach(i; 0 .. _loglevel * 4) write(' ');
     writeln('{');
     scope(exit)
       {
         foreach(i; 0 .. _loglevel * 4) write(' ');
         writeln('}');
         _loglevel--;
       }
    }
};

void logSym(S...)(int line = __LINE__, string file = __FUNCTION__)
{
  debug
    {
      foreach(i; 0 .. _loglevel * 4) write(' ');
      write(file, "(", line, "):");
      static foreach(s; S)
        write(" ", s.stringof, " = ", s);
      writeln;

    }
}

Array!E makeArray(E, S)(S size, lazy E value)
{
  auto a = Array!E();
  a.length = cast(size_t) size;
  foreach(ref ai; a)
    ai = value();
  return a;
}
Array!E makeArray(E, S)(S size)
{
  auto a = Array!E();
  a.length = cast(size_t) size;
  return a;
}

template mem(alias F)
{
  ReturnType!F[Tuple!(Parameters!F)] table;
  ReturnType!F mem(Parameters!F args)
  {
    return table.require(tuple(args), F(args));
  }
}

string input(string names, string type = "long")
{
  return text(type, " ", names, "; read(", names, ");");
}

auto pmod(T, W)(T t, W w)
{
  return (t%w + w) % w;
}

void rep(S, F)(F f, S times)
{
  static if (is(typeof(f(i))))
    foreach(i; 0 .. times)
      f(i);
  else
    foreach(i; 0 .. times)
      f();
}

void multi()
{
  foreach(tc; 0 .. next!long)
    next!TestCase.solve(tc);
}

void single()
{
  auto tc = next!TestCase;
  tc.solve;
}

void main()
{
  type;
}

import std.container;
import std.algorithm;
import std.range;
import std.array;
import std.stdio;
import std.utf;
import std.math;
import std.typecons;

alias type = single;
struct TestCase
{
  mixin prettyPrinting;

  string str;

  void solve(long tc = -1)
  {
    auto cntaba = str.count("ABA");
    auto cntab = str.count("AB");
    cntab -= cntaba;
    auto cntba = str.count("BA");
    cntba -= cntaba;
    if (cntaba >= 2)
      {
        writeln("YES");
        return;
      }
    if (cntaba == 0)
      {
        if (cntba > 0 && cntab > 0)
          writeln("YES");
        else
          writeln("NO");
      }
    else
      {
        if (cntba > 0 || cntab > 0)
          writeln("YES");
        else
          writeln("NO");
      }
  }
}

struct Interval
{
  long l, h;

  bool empty()
  {
    return l > h;
  }
}

Interval intersect(Interval a, Interval b)
{
  return Interval(max(a.l, b.l), min(a.h, b.h));
}

struct If
{
  string condition;
}
enum ignore = If("false");
struct Dim
{
  string dimensions;
  int levels;
  this(string dimensions)
  {
    this.dimensions = dimensions;
    levels = cast(int)dimensions.count(",") + 1;
  }
}

template getArrayLevel(W)
{
  static if (isDynamicArray!W && !is(W == string))
    enum getArrayLevel = 1 + getArrayLevel!(removeArray!(W, 1));
  else
    enum getArrayLevel = 0;
}

static foreach(fieldName; 'a' .. cast(char)('z' + 1))
  {
    static if (fieldName != 'o')
      mixin("enum d", fieldName, " = Dim(\"", fieldName, "\");");
  }

mixin template prettyPrinting()
{
  string toString()
  {
    alias structType = typeof(this);
    auto res = appender!(string)();
    res.put(structType.stringof);
    res.put("(");
    static foreach(fieldName; FieldNameTuple!structType)
      {
        res.put(text(" ", fieldName, ": ", mixin(fieldName)));
      }
    res.put(" )");
    res.put("\n");
    return res[];
  }
}

struct Graph(N)
{
  size_t size;
  this(S)(S size)
  {
    adjacencyList.length = cast(size_t) size;
    this.size = cast(size_t) size;
    this.visited = makeSlice!bool(size);
  }
  N[][] adjacencyList;
  alias ne = neighbours;
  N[] neighbours(N n)
  {
    return adjacencyList.at(n);
  }
  alias bcon = biconnect;
  void biconnect(N a, N b)
  {
    adjacencyList.at(a) ~= b;
    adjacencyList.at(b) ~= a;
  }
  alias con = connect;
  void connect(N a, N b)
  {
    adjacencyList.at(a) ~= b;
  }
  void connect(R)(R edges)
  {
    foreach(ref edge; edges)
      {
        connect(edge[0], edge[1]);
      }
  }
  void biconnect(R)(R edges)
  {
    foreach(ref edge; edges)
      {
        biconnect(edge[0], edge[1]);
      }
  }
  alias deg = degree!long;
  auto degree(T)(N a)
  {
    return cast(T) adjacencyList.at(a).length;
  }

  auto visited = new bool[0];
  void dfs(Visitor)(long startNode)
  {
    auto visitor = Visitor.init;
    void internalDfs(long node)
    {
      visited.set(node, true);
      static if (is(typeof({visitor.n = node;})))
        visitor.n = node;
      static if (is(typeof({visitor.pre;})))
        visitor.pre;
      foreach(w; ne(node))
        if (!visited.at(w))
          {
            static if (is(typeof({visitor.w = w;})))
              visitor.w = w;
            static if (is(typeof(visitor.pren)))
              visitor.pren;
            internalDfs(w);
            static if (is(typeof(visitor.postn)))
              visitor.postn;
          }
      static if (is(typeof(visitor.post)))
        visitor.post;
    }
    internalDfs(startNode);
  }
  void dfs(long startNode)
  {
    struct DefVisitor {}
    dfs!DefVisitor(startNode);
  }
}

DList!string _words;

template removeArray(W, int times)
{
  static if (times == 0)
    alias removeArray = W;
  else static if (times == 1)
    alias removeArray = typeof(function(){W w; return w[0];}());
  else
    {
      static assert(isDynamicArray!W);
      alias removeArray = removeArray!(removeArray!(W, 1), times - 1);
    }
}

template baseType(W)
{
  static if (isDynamicArray!W && !is(W == string))
    alias baseType = baseType!(typeof((delegate() {W w; return w[0];})()));
  else
    alias baseType = W;
}

auto makeSlice(E, W, T...)(W size, T otherSizes)
{
  static if (T.length == 0)
    {
      E[] res;
      res.length = cast(size_t) size;
      return res;
    }
  else
    {
      typeof(makeSlice!E(otherSizes))[] res;
      res.length = cast(size_t) size;
      foreach(ref row; res)
        row = makeSlice!E(otherSizes);
      return res;
    }
}

void read(T...)(ref T t)
{
  void basicTypeRead(W)(ref W w)
  {
    import std.stdio: readln;
    while(_words.empty)
      {
        import std.array: split;
        foreach(word; readln.split)
          {
            _words.insertBack(word);
          }
      }
    import std.conv: to;
    string word = _words.front;
    _words.removeFront;
    w = to!W(word);
  }
  void iterableRead(W)(ref W w)
  {
    foreach(ref element; w)
      read(element);
  }
  void tupleRead(W)(ref W w)
  {
    static foreach(j; 0 .. W.length)
      read(w[j]);
  }
  void structRead(W)(ref W readStruct)
  {
    static foreach(fieldName; FieldNameTuple!W)
      {
        with(readStruct)
          {
            alias fieldSymbol = mixin(W.stringof, ".", fieldName);
            alias typeOfField = typeof(mixin(fieldName));
            static if (hasUDA!(fieldSymbol, If))
              enum condition = getUDAs!(fieldSymbol, If)[0].condition;
            else
              enum condition = "true";

            if (mixin(condition))
              {
                static if (hasUDA!(fieldSymbol, Dim))
                  {
                    static assert(isDynamicArray!(typeOfField)
                                  , text(W.stringof, ".", fieldName, " has Dim UDA but isn't a Dynamic Array."));
                    enum uda = getUDAs!(fieldSymbol, Dim)[0];
                    static assert(getArrayLevel!(typeOfField) == uda.levels,
                                  text(W.stringof, ".", fieldName, " has a Dim UDA with different number of dimensions than it's type."));
                    mixin(fieldName) = mixin(q{makeSlice!(baseType!typeOfField)(}, uda.dimensions, q{)});
                  }
                else static if (isDynamicArray!typeOfField && !is(typeOfField == string))
                  {
                    pragma(msg, "Warning: You probably want to add dimension to input ", W.stringof, ".", fieldName);
                  }
                read(mixin(fieldName));
              }
          }
      }
  }
  static foreach(i; 0 .. T.length)
    {
      static if (isBasicType!(T[i]) || is(T[i] == string))
        basicTypeRead(t[i]);
      else static if (is(typeof({foreach(ref e; t[i]){}})))
        iterableRead(t[i]);
      else static if (isTuple!(T[i]))
        tupleRead(t[i]);
      else static if (isAggregateType!(T[i]))
        structRead(t[i]);
    }
}

auto next(T)()
{
  T t;
  read(t);
  return t;
}

size_t ind(T)(T t)
{
  return cast(size_t)t;
}

ref auto at(R, I)(ref R r, I i)
{
  return r[cast(size_t)i];
}

void set(R, I, V)(ref R r, I i, V v)
{
  r[cast(size_t)i] = v;
}

import std.conv;
import std.traits;
import std.meta;
int _loglevel = -1;
void _log(string functionName, argSeq...)()
{
  foreach(i; 0 .. _loglevel * 4)
    write(' ');
  write(functionName);
  static foreach(arg; argSeq)
    {
      write(" ", arg.stringof, " = ", arg);
    }
  writeln;
}
enum logCall =
  q{
    debug
    {
     {
     _loglevel++;
     alias _parameterTuple = ParameterIdentifierTuple!(mixin(split(__FUNCTION__, ".").back));
     static if (_parameterTuple.length > 0)
       mixin(`_log!(__FUNCTION__, `, [_parameterTuple].joiner(", ").array, `);`);
     else
       _log!(__FUNCTION__);
      }
     foreach(i; 0 .. _loglevel * 4) write(' ');
     writeln('{');
     scope(exit)
       {
         foreach(i; 0 .. _loglevel * 4) write(' ');
         writeln('}');
         _loglevel--;
       }
    }
};

void logSym(S...)(int line = __LINE__, string file = __FUNCTION__)
{
  debug
    {
      foreach(i; 0 .. _loglevel * 4) write(' ');
      write(file, "(", line, "):");
      static foreach(s; S)
        write(" ", s.stringof, " = ", s);
      writeln;

    }
}

Array!E makeArray(E, S)(S size, lazy E value)
{
  auto a = Array!E();
  a.length = cast(size_t) size;
  foreach(ref ai; a)
    ai = value();
  return a;
}
Array!E makeArray(E, S)(S size)
{
  auto a = Array!E();
  a.length = cast(size_t) size;
  return a;
}

template mem(alias F)
{
  ReturnType!F[Tuple!(Parameters!F)] table;
  ReturnType!F mem(Parameters!F args)
  {
    return table.require(tuple(args), F(args));
  }
}

string input(string names, string type = "long")
{
  return text(type, " ", names, "; read(", names, ");");
}

auto pmod(T, W)(T t, W w)
{
  return (t%w + w) % w;
}

void rep(S, F)(F f, S times)
{
  static if (is(typeof(f(i))))
    foreach(i; 0 .. times)
      f(i);
  else
    foreach(i; 0 .. times)
      f();
}

void multi()
{
  foreach(tc; 0 .. next!long)
    next!TestCase.solve(tc);
}

void single()
{
  auto tc = next!TestCase;
  tc.solve;
}

void main()
{
  type;
}

import std.container;
import std.algorithm;
import std.range;
import std.array;
import std.stdio;
import std.utf;
import std.math;
import std.typecons;

alias type = single;
struct TestCase
{
  mixin prettyPrinting;

  string str;

  void solve(long tc = -1)
  {
    bool hasleft, hasright;
    bool answer = false;
  loop1:foreach(i; 0 .. str.length)
      {
        if (str[i] == 'B')
          {
            if (i >= 1 && str[i - 1] == 'A')
              {
                if (hasright)
                  {
                    answer = true;
                    break loop1;
                  }
              }
            if (i + 1 < str.length && str[i + 1] == 'A')
              {
                if (hasleft)
                  {
                    answer = true;
                    break loop1;
                  }
              }
            if (i >= 1 && str[i - 1] == 'A')
              hasleft = true;
            if (i + 1 < str.length && str[i + 1] == 'A')
              hasright = true;
          }
      }
    hasleft = false; hasright = false;
    bool answer2;
  loop2:foreach(i; 0 .. str.length)
      {
        if (str[i] == 'A')
          {
            if (i >= 1 && str[i - 1] == 'B')
              {
                if (hasright)
                  {
                    answer2 = true;
                    break loop2;
                  }
              }
            if (i + 1 < str.length && str[i + 1] == 'B')
              {
                if (hasleft)
                  {
                    answer2 = true;
                    break loop2;
                  }
              }
            if (i >= 1 && str[i - 1] == 'B')
              hasleft = true;
            if (i + 1 < str.length && str[i + 1] == 'B')
              hasright = true;
          }
      }
    if (answer && answer2)
      writeln("YES");
    else
      writeln("NO");
  }
}

struct Interval
{
  long l, h;

  bool empty()
  {
    return l > h;
  }
}

Interval intersect(Interval a, Interval b)
{
  return Interval(max(a.l, b.l), min(a.h, b.h));
}

struct If
{
  string condition;
}
enum ignore = If("false");
struct Dim
{
  string dimensions;
  int levels;
  this(string dimensions)
  {
    this.dimensions = dimensions;
    levels = cast(int)dimensions.count(",") + 1;
  }
}

template getArrayLevel(W)
{
  static if (isDynamicArray!W && !is(W == string))
    enum getArrayLevel = 1 + getArrayLevel!(removeArray!(W, 1));
  else
    enum getArrayLevel = 0;
}

static foreach(fieldName; 'a' .. cast(char)('z' + 1))
  {
    static if (fieldName != 'o')
      mixin("enum d", fieldName, " = Dim(\"", fieldName, "\");");
  }

mixin template prettyPrinting()
{
  string toString()
  {
    alias structType = typeof(this);
    auto res = appender!(string)();
    res.put(structType.stringof);
    res.put("(");
    static foreach(fieldName; FieldNameTuple!structType)
      {
        res.put(text(" ", fieldName, ": ", mixin(fieldName)));
      }
    res.put(" )");
    res.put("\n");
    return res[];
  }
}

struct Graph(N)
{
  size_t size;
  this(S)(S size)
  {
    adjacencyList.length = cast(size_t) size;
    this.size = cast(size_t) size;
    this.visited = makeSlice!bool(size);
  }
  N[][] adjacencyList;
  alias ne = neighbours;
  N[] neighbours(N n)
  {
    return adjacencyList.at(n);
  }
  alias bcon = biconnect;
  void biconnect(N a, N b)
  {
    adjacencyList.at(a) ~= b;
    adjacencyList.at(b) ~= a;
  }
  alias con = connect;
  void connect(N a, N b)
  {
    adjacencyList.at(a) ~= b;
  }
  void connect(R)(R edges)
  {
    foreach(ref edge; edges)
      {
        connect(edge[0], edge[1]);
      }
  }
  void biconnect(R)(R edges)
  {
    foreach(ref edge; edges)
      {
        biconnect(edge[0], edge[1]);
      }
  }
  alias deg = degree!long;
  auto degree(T)(N a)
  {
    return cast(T) adjacencyList.at(a).length;
  }

  auto visited = new bool[0];
  void dfs(Visitor)(long startNode)
  {
    auto visitor = Visitor.init;
    void internalDfs(long node)
    {
      visited.set(node, true);
      static if (is(typeof({visitor.n = node;})))
        visitor.n = node;
      static if (is(typeof({visitor.pre;})))
        visitor.pre;
      foreach(w; ne(node))
        if (!visited.at(w))
          {
            static if (is(typeof({visitor.w = w;})))
              visitor.w = w;
            static if (is(typeof(visitor.pren)))
              visitor.pren;
            internalDfs(w);
            static if (is(typeof(visitor.postn)))
              visitor.postn;
          }
      static if (is(typeof(visitor.post)))
        visitor.post;
    }
    internalDfs(startNode);
  }
  void dfs(long startNode)
  {
    struct DefVisitor {}
    dfs!DefVisitor(startNode);
  }
}

DList!string _words;

template removeArray(W, int times)
{
  static if (times == 0)
    alias removeArray = W;
  else static if (times == 1)
    alias removeArray = typeof(function(){W w; return w[0];}());
  else
    {
      static assert(isDynamicArray!W);
      alias removeArray = removeArray!(removeArray!(W, 1), times - 1);
    }
}

template baseType(W)
{
  static if (isDynamicArray!W && !is(W == string))
    alias baseType = baseType!(typeof((delegate() {W w; return w[0];})()));
  else
    alias baseType = W;
}

auto makeSlice(E, W, T...)(W size, T otherSizes)
{
  static if (T.length == 0)
    {
      E[] res;
      res.length = cast(size_t) size;
      return res;
    }
  else
    {
      typeof(makeSlice!E(otherSizes))[] res;
      res.length = cast(size_t) size;
      foreach(ref row; res)
        row = makeSlice!E(otherSizes);
      return res;
    }
}

void read(T...)(ref T t)
{
  void basicTypeRead(W)(ref W w)
  {
    import std.stdio: readln;
    while(_words.empty)
      {
        import std.array: split;
        foreach(word; readln.split)
          {
            _words.insertBack(word);
          }
      }
    import std.conv: to;
    string word = _words.front;
    _words.removeFront;
    w = to!W(word);
  }
  void iterableRead(W)(ref W w)
  {
    foreach(ref element; w)
      read(element);
  }
  void tupleRead(W)(ref W w)
  {
    static foreach(j; 0 .. W.length)
      read(w[j]);
  }
  void structRead(W)(ref W readStruct)
  {
    static foreach(fieldName; FieldNameTuple!W)
      {
        with(readStruct)
          {
            alias fieldSymbol = mixin(W.stringof, ".", fieldName);
            alias typeOfField = typeof(mixin(fieldName));
            static if (hasUDA!(fieldSymbol, If))
              enum condition = getUDAs!(fieldSymbol, If)[0].condition;
            else
              enum condition = "true";

            if (mixin(condition))
              {
                static if (hasUDA!(fieldSymbol, Dim))
                  {
                    static assert(isDynamicArray!(typeOfField)
                                  , text(W.stringof, ".", fieldName, " has Dim UDA but isn't a Dynamic Array."));
                    enum uda = getUDAs!(fieldSymbol, Dim)[0];
                    static assert(getArrayLevel!(typeOfField) == uda.levels,
                                  text(W.stringof, ".", fieldName, " has a Dim UDA with different number of dimensions than it's type."));
                    mixin(fieldName) = mixin(q{makeSlice!(baseType!typeOfField)(}, uda.dimensions, q{)});
                  }
                else static if (isDynamicArray!typeOfField && !is(typeOfField == string))
                  {
                    pragma(msg, "Warning: You probably want to add dimension to input ", W.stringof, ".", fieldName);
                  }
                read(mixin(fieldName));
              }
          }
      }
  }
  static foreach(i; 0 .. T.length)
    {
      static if (isBasicType!(T[i]) || is(T[i] == string))
        basicTypeRead(t[i]);
      else static if (is(typeof({foreach(ref e; t[i]){}})))
        iterableRead(t[i]);
      else static if (isTuple!(T[i]))
        tupleRead(t[i]);
      else static if (isAggregateType!(T[i]))
        structRead(t[i]);
    }
}

auto next(T)()
{
  T t;
  read(t);
  return t;
}

size_t ind(T)(T t)
{
  return cast(size_t)t;
}

ref auto at(R, I)(ref R r, I i)
{
  return r[cast(size_t)i];
}

void set(R, I, V)(ref R r, I i, V v)
{
  r[cast(size_t)i] = v;
}

import std.conv;
import std.traits;
import std.meta;
int _loglevel = -1;
void _log(string functionName, argSeq...)()
{
  foreach(i; 0 .. _loglevel * 4)
    write(' ');
  write(functionName);
  static foreach(arg; argSeq)
    {
      write(" ", arg.stringof, " = ", arg);
    }
  writeln;
}
enum logCall =
  q{
    debug
    {
     {
     _loglevel++;
     alias _parameterTuple = ParameterIdentifierTuple!(mixin(split(__FUNCTION__, ".").back));
     static if (_parameterTuple.length > 0)
       mixin(`_log!(__FUNCTION__, `, [_parameterTuple].joiner(", ").array, `);`);
     else
       _log!(__FUNCTION__);
      }
     foreach(i; 0 .. _loglevel * 4) write(' ');
     writeln('{');
     scope(exit)
       {
         foreach(i; 0 .. _loglevel * 4) write(' ');
         writeln('}');
         _loglevel--;
       }
    }
};

void logSym(S...)(int line = __LINE__, string file = __FUNCTION__)
{
  debug
    {
      foreach(i; 0 .. _loglevel * 4) write(' ');
      write(file, "(", line, "):");
      static foreach(s; S)
        write(" ", s.stringof, " = ", s);
      writeln;

    }
}

Array!E makeArray(E, S)(S size, lazy E value)
{
  auto a = Array!E();
  a.length = cast(size_t) size;
  foreach(ref ai; a)
    ai = value();
  return a;
}
Array!E makeArray(E, S)(S size)
{
  auto a = Array!E();
  a.length = cast(size_t) size;
  return a;
}

template mem(alias F)
{
  ReturnType!F[Tuple!(Parameters!F)] table;
  ReturnType!F mem(Parameters!F args)
  {
    return table.require(tuple(args), F(args));
  }
}

string input(string names, string type = "long")
{
  return text(type, " ", names, "; read(", names, ");");
}

auto pmod(T, W)(T t, W w)
{
  return (t%w + w) % w;
}

void rep(S, F)(F f, S times)
{
  static if (is(typeof(f(i))))
    foreach(i; 0 .. times)
      f(i);
  else
    foreach(i; 0 .. times)
      f();
}

void multi()
{
  foreach(tc; 0 .. next!long)
    next!TestCase.solve(tc);
}

void single()
{
  auto tc = next!TestCase;
  tc.solve;
}

void main()
{
  type;
}


import std.algorithm;
import std.array;
import std.container;
import std.conv;
import std.functional;
import std.numeric;
import std.range;
import std.stdio;
import std.typecons;

immutable int MAX_N = 100_005;
immutable int NA    = -1;

int [] [] a;
bool [] b;
int [] f;
int [] g;

void recur (int v, int p)
{
	if (b[v])
	{
		f[v] = max (f[v], 0);
	}

	foreach (u; a[v])
	{
		if (u == p)
		{
			continue;
		}
		recur (u, v);
		f[v] = max (f[v], f[u] + 1);
	}
}

void recur2 (int v, int p, int z)
{
	int max1 = int.min;
	int max2 = int.min;

	foreach (u; a[v])
	{
		if (u == p)
		{
			continue;
		}
		if (max1 < f[u])
		{
			max2 = max1;
			max1 = f[u];
		}
		else if (max2 < f[u])
		{
			max2 = f[u];
		}
	}

	foreach (u; a[v])
	{
		if (u == p)
		{
			continue;
		}
		int cur;
		if (max1 == f[u])
		{
			cur = max2 + 2;
		}
		else
		{
			cur = max1 + 2;
		}
		cur = max (cur, z + 1);
		f[u] = max (f[u], cur);
		recur2 (u, v, cur);
	}
}

void recur3 (int v, int p)
{
	if (b[v])
	{
		g[v] = max (g[v], 0);
	}

	foreach (u; a[v])
	{
		if (u == p)
		{
			continue;
		}
		g[u] = max (g[u], g[v] + 1);
		recur3 (u, v);
	}
}

void main ()
{
	int n, m, d;
	while (readf (" %s %s %s", &n, &m, &d) > 0)
	{
		b = new bool [n];
		foreach (i; 0..m)
		{
			int v;
			readf (" %s", &v);
			v--;
			b[v] = true;
		}
		a = new int [] [n];
		foreach (i; 0..n - 1)
		{
			int u, v;
			readf (" %s %s", &u, &v);
			u--;
			v--;
			a[u] ~= v;
			a[v] ~= u;
		}

		f = new int [n];
		f[] = int.min;
		recur (0, NA);
		debug {writeln (f);}
		recur2 (0, NA, int.min);
		debug {writeln (f);}
		g = new int [n];
		g[] = int.min;
		recur3 (0, NA);
		debug {writeln (g);}
		int res = 0;
		foreach (v; 0..n)
		{
			res += (f[v] <= d && g[v] <= d);
		}
		writeln (res);
	}
}

import std.stdio, std.getopt, std.random, std.range, std.string, std.conv;
import std.algorithm, std.container, std.datetime;

int n, m, d;
bool[] isE;
int[][] g;
int md, mv;
int[] dps;
void dfs(int v, int b, int dp) {
	if (isE[v] && md < dp) {
		md = dp;
		mv = v;
	}
	dps[v] = dp;
	foreach (u; g[v]) {
		if (u == b) continue;
		dfs(u, v, dp+1);
	}
}

void dfs2(int v, int b, int dp) {

}
int solve() {
	readf("%d %d %d\n", &n, &m, &d);
	auto p = readln().split().map!(s => to!int(s)-1).array;
	isE.length = n;
	foreach (u; p) {
		isE[u] = true;
	}
	g.length = n;
	foreach (i; 0..n-1) {
		int a, b;
		readf("%d %d\n", &a, &b); a--; b--;
		g[a] ~= b;
		g[b] ~= a;
	}
	dps.length = n;
	md = mv = -1;
	dfs(p[0], -1, 0);
	auto v = mv;
	md = mv = -1;
	dfs(v, -1, 0);
	auto dp1 = dps.dup;
	dfs(mv, -1, 0);
	auto dp2 = dps.dup;
	int res = 0;
	foreach (i; 0..n) {
		if (dp1[i] <= d && dp2[i] <= d) {
			res++;
		}
	}
//	if (md > d*2) return 0;
	return res;
}

int main() {
	writeln(solve());
    return 0;
}

import std.algorithm;
import std.array;
import std.container;
import std.conv;
import std.functional;
import std.numeric;
import std.range;
import std.stdio;
import std.typecons;

immutable int MAX_N = 100_005;
immutable int MAX_C = 0x3F3F3F3F;
immutable int NA    = -1;

int [] [] a;
bool [] b;
int [] f;
int [] g;

void recur (int v, int p)
{
	if (b[v])
	{
		f[v] = max (f[v], 0);
	}

	foreach (u; a[v])
	{
		if (u == p)
		{
			continue;
		}
		recur (u, v);
		f[v] = max (f[v], f[u] + 1);
	}
}

void recur2 (int v, int p)
{
	int max1 = int.min;
	int max2 = int.min;

	foreach (u; a[v])
	{
		if (u == p)
		{
			continue;
		}
		if (max1 < f[u])
		{
			max2 = max1;
			max1 = f[u];
		}
		else if (max2 < f[u])
		{
			max2 = f[u];
		}
	}

	foreach (u; a[v])
	{
		if (u == p)
		{
			continue;
		}
		if (max1 == f[u])
		{
			f[u] = max (f[u], max2 + 2);
		}
		else
		{
			f[u] = max (f[u], max1 + 2);
		}
		recur2 (u, v);
	}
}

void recur3 (int v, int p)
{
	if (b[v])
	{
		g[v] = max (g[v], 0);
	}

	foreach (u; a[v])
	{
		if (u == p)
		{
			continue;
		}
		g[u] = max (g[u], g[v] + 1);
		recur3 (u, v);
	}
}

void main ()
{
	int n, m, d;
	while (readf (" %s %s %s", &n, &m, &d) > 0)
	{
		b = new bool [n];
		foreach (i; 0..m)
		{
			int v;
			readf (" %s", &v);
			v--;
			b[v] = true;
		}
		a = new int [] [n];
		foreach (i; 0..n - 1)
		{
			int u, v;
			readf (" %s %s", &u, &v);
			u--;
			v--;
			a[u] ~= v;
			a[v] ~= u;
		}

		f = new int [n];
		f[] = -MAX_C;
		recur (0, NA);
		debug {writeln (f);}
		recur2 (0, NA);
		debug {writeln (f);}
		g = new int [n];
		g[] = -MAX_C;
		recur3 (0, NA);
		debug {writeln (g);}
		int res = 0;
		foreach (v; 0..n)
		{
			res += (f[v] <= d && g[v] <= d);
		}
		writeln (res);
	}
}


import std.stdio, std.algorithm, std.conv, std.array, std.string, std.math, std.typecons, std.numeric, std.container, std.range;

void get(Args...)(ref Args args)
{
    import std.traits, std.meta, std.typecons;

    static if (Args.length == 1) {
        alias Arg = Args[0];

        static if (isArray!Arg) {
          static if (isSomeChar!(ElementType!Arg)) {
            args[0] = readln.chomp.to!Arg;
          } else {
            args[0] = readln.split.to!Arg;
          }
        } else static if (isTuple!Arg) {
            auto input = readln.split;
            static foreach (i; 0..Fields!Arg.length) {
                args[0][i] = input[i].to!(Fields!Arg[i]);
            }
        } else {
            args[0] = readln.chomp.to!Arg;
        }
    } else {
        auto input = readln.split;
        assert(input.length == Args.length);

        static foreach (i; 0..Args.length) {
            args[i] = input[i].to!(Args[i]);
        }
    }
}

void get_lines(Args...)(size_t N, ref Args args)
{
    import std.traits, std.range;

    static foreach (i; 0..Args.length) {
        static assert(isArray!(Args[i]));
        args[i].length = N;
    }

    foreach (i; 0..N) {
        static if (Args.length == 1) {
            get(args[0][i]);
        } else {
            auto input = readln.split;
            static foreach (j; 0..Args.length) {
                args[j][i] = input[j].to!(ElementType!(Args[j]));
            }
        }
    }
}

void main()
{
    int T; get(T);
    while (T--) {
        char[] s; get(s);
        foreach (i; 0..s.length) {
            if (i%2 == 0) {
                if (s[i] == 'a') {
                    s[i] = 'b';
                } else {
                    s[i] = 'a';
                }
            } else {
                if (s[i] == 'z') {
                    s[i] = 'y';
                } else {
                    s[i] = 'z';
                }
            }
        }
        writeln(s);
    }
}

import std.stdio, std.conv, std.functional, std.string;
import std.algorithm, std.array, std.container, std.range, std.typecons;
import std.bigint, std.numeric, std.math, std.random;
import core.bitop;

string FMT_F = "%.10f";

static File _f;
void file_io(string fn) { _f = File(fn, "r"); }
static string[] s_rd;
T _RD(T = long)() { while(!s_rd.length) s_rd = readln.chomp.split; string res = s_rd[0]; s_rd.popFront; return res.to!T; }
T _RD(T = long)(File f) { while(!s_rd.length) s_rd = f.readln.chomp.split; string res = s_rd[0]; s_rd.popFront; return res.to!T; }
T[] _RDA(T = long)(T fix = 0) { auto r = readln.chomp.split.to!(T[]); r[] += fix; return r; }
T[] _RDA(T = long)(File f, T fix = 0) { auto r = f.readln.chomp.split.to!(T[]); r[] += fix; return r; }
T RD(T = long)() { if (_f.isOpen) return _RD!T(_f); else return _RD!T; }
T[] RDA(T = long)(T fix = 0) { if (_f.isOpen)  return _RDA!T(_f, fix); else return _RDA!T(fix); }

size_t[] MAKE_IDX(alias less = "a < b", Range)(Range range) { auto idx = new size_t[](range.length); makeIndex!(less)(range, idx); return idx;}
size_t MIN_POS(alias less = "a < b", Range)(Range range) { auto r = minPos!(less)(range); return range.length - r.length; }

void chmin(T)(ref T x, T y) { x = min(x, y); } void chmax(T)(ref T x, T y) { x = max(x, y); }
bool inside(T)(T x, T b, T e) { return x >= b && x < e; }
T lcm(T)(T x, T y) { return x * (y / gcd(x, y)); }

long mod = 10^^9 + 7;
//long mod = 998_244_353;
//long mod = 1_000_003;
void moda(ref long x, long y) { x = (x + y) % mod; }
void mods(ref long x, long y) { x = ((x + mod) - (y % mod)) % mod; }
void modm(ref long x, long y) { x = (x * y) % mod; }
void modpow(ref long x, long y) { if (!y) { x = 1; return; } auto t = x; x.modpow(y>>1); x.modm(x); if (y&1) x.modm(t); }
void modd(ref long x, long y) { y.modpow(mod - 2); x.modm(y); }

void main()
{
	auto t = RD!int;
	auto ans = new string[](t);
	foreach (ti; 0..t)
	{
		auto s = RD!string;

		foreach (i; 0..s.length)
		{
			if (i % 2 == 0)
			{
				if (s[i] == 'a')
					ans[ti] ~= 'b';
				else
					ans[ti] ~= 'a';
			}
			else
			{
				if (s[i] == 'z')
					ans[ti] ~= 'y';
				else
					ans[ti] ~= 'z';
			}
		}
	}

	foreach (e; ans)
		writeln(e);
	stdout.flush;
	debug readln;
}


import std.container;
import std.algorithm;
import std.range;
import std.array;
import std.stdio;
import std.utf;
import std.math;
import std.typecons;

DList!string _words;

void read(T...)(ref T t)
{
  void singleRead(W)(ref W w)
  {
    import std.stdio: readln;
    while(_words.empty)
      {
        import std.array: split;
        foreach(word; readln.split)
          {
            _words.insertBack(word);
          }
      }
    import std.conv: to;
    string word = _words.front;
    _words.removeFront;
    w = to!W(word);
  }
  static foreach(i; 0 .. T.length)
    {
      static if (is(typeof({foreach(ref e; t[i]){}})) && !is(T[i] == string))
        {
          foreach(ref element; t[i])
            read(element);
        }
      else
        {
          singleRead(t[i]);
        }
    }
}

auto next(T)()
{
  T t;
  read(t);
  return t;
}

size_t ind(T)(T t)
{
  return cast(size_t)t;
}

ref auto at(R, I)(ref R r, I i)
{
  return r[cast(size_t)i];
}

void set(R, I, V)(ref R r, I i, V v)
{
  r[cast(size_t)i] = v;
}

import std.conv;
import std.traits;
import std.meta;
int _loglevel = -1;
void _log(string functionName, argSeq...)()
{
  foreach(i; 0 .. _loglevel * 4)
    write(' ');
  write(functionName);
  static foreach(arg; argSeq)
    {
      write(" ", arg.stringof, " = ", arg);
    }
  writeln;
}
enum logCall =
  q{
    debug
    {
     {
     _loglevel++;
     alias _parameterTuple = ParameterIdentifierTuple!(mixin(split(__FUNCTION__, ".").back));
     static if (_parameterTuple.length > 0)
       mixin(`_log!(__FUNCTION__, `, [_parameterTuple].joiner(", ").array, `);`);
     else
       _log!(__FUNCTION__);
      }
     foreach(i; 0 .. _loglevel * 4) write(' ');
     writeln('{');
     scope(exit)
       {
         foreach(i; 0 .. _loglevel * 4) write(' ');
         writeln('}');
         _loglevel--;
       }
    }
};

void logSym(S...)(int line = __LINE__, string file = __FUNCTION__)
{
  debug
    {
      foreach(i; 0 .. _loglevel * 4) write(' ');
      write(file, "(", line, "):");
      static foreach(s; S)
        write(" ", s.stringof, " = ", s);
      writeln;

    }
}

Array!E makeArray(E, S)(S size, lazy E value)
{
  auto a = Array!E();
  a.length = cast(size_t) size;
  foreach(ref ai; a)
    ai = value();
  return a;
}
Array!E makeArray(E, S)(S size)
{
  auto a = Array!E();
  a.length = cast(size_t) size;
  return a;
}

E[] makeSlice(E, S)(S size, lazy E value)
{
  auto a = new E[size.ind];
  foreach(ref ai; a)
    ai = value();
  return a;
}

E[] makeSlice(E, S)(S size = 0)
{
  return new E[size.ind];
}

template mem(alias F)
{
  ReturnType!F[Tuple!(Parameters!F)] table;
  ReturnType!F mem(Parameters!F args)
  {
    return table.require(tuple(args), F(args));
  }
}

string input(string names, string type = "long")
{
  return text(type, " ", names, "; read(", names, ");");
}

auto pmod(T, W)(T t, W w)
{
  return (t%w + w) % w;
}

void main()
{
  auto t = next!int;
  foreach(tc; 0 .. t)
    {
      auto n = next!int;
      auto a = makeSlice(n, next!int);
      auto res = a.count(0);
      logSym!(a, res);
      a = a.map!(ai => ai == 0? 1 : ai).array;
      logSym!(a, res);
      if (a.sum == 0)
        res++;
      logSym!(a, res);
      writeln(res);
    }
}

import std.algorithm : max, maxElement;
import std.container : Array;
import std.stdio : stdin, write, writeln;
import std.typecons : Tuple, tuple;

struct IO {
    string readToken() {
        import std.range : empty, front, popFront, split;
        import std.stdio : readln;

        while (tokens.empty) {
            tokens = readln.split;
        }
        auto token = tokens.front;
        tokens.popFront;
        return token;
    }

    int readInt() {
        import std.conv : to;

        return readToken.to!int;
    }

    long readLong() {
        import std.conv : to;

        return readToken.to!long;
    }

    string[] tokens;
}

void main() {
    import std.algorithm : max, min;

    IO io;
    int T = io.readInt;
    while (T--) {
        int n = io.readInt;
        int[] a = new int[n];
        int result = 0, sum = 0;
        for (int i = 0; i < n; ++i) {
            a[i] = io.readInt;
            if (!a[i]) {
                a[i]++, result++;
            }
            sum += a[i];
        }
        if (!sum) {
            result++;
        }
        writeln(result);
    }
}

import std.stdio;
int main()
{
	int t=0;
	readf(" %d", &t);
	for (int i=0; i<t; i++)
	{
		int n=0;
		readf(" %d", &n);
		int[101] m;
		for (int j=0; j<n; j++)
		{
			readf(" %d", &m[j]);
		}
		int sum=0;
		int mul=1;
		int zsum=0;
		for (int j=0; j<n; j++)
		{
			sum=sum+m[j];
			mul=mul*m[j];
			if (m[j]==0)
			{
				zsum=zsum+1;
			}
		}
		if (sum!=0 && mul!=0)
		{
			writeln(0);
		}
		else
		{
			if (sum+zsum==0)
			{
				writeln(zsum+1);
			}
			else
			{
				writeln(zsum);
			}
		}
	}
	return 0;
}

import std.stdio, std.conv, std.functional, std.string;
import std.algorithm, std.array, std.container, std.range, std.typecons;
import std.bigint, std.numeric, std.math, std.random;
import core.bitop;

string FMT_F = "%.10f";

static File _f;
void file_io(string fn) { _f = File(fn, "r"); }
static string[] s_rd;
T _RD(T = long)() { while(!s_rd.length) s_rd = readln.chomp.split; string res = s_rd[0]; s_rd.popFront; return res.to!T; }
T _RD(T = long)(File f) { while(!s_rd.length) s_rd = f.readln.chomp.split; string res = s_rd[0]; s_rd.popFront; return res.to!T; }
T[] _RDA(T = long)(T fix = 0) { auto r = readln.chomp.split.to!(T[]); r[] += fix; return r; }
T[] _RDA(T = long)(File f, T fix = 0) { auto r = f.readln.chomp.split.to!(T[]); r[] += fix; return r; }
T RD(T = long)() { if (_f.isOpen) return _RD!T(_f); else return _RD!T; }
T[] RDA(T = long)(T fix = 0) { if (_f.isOpen)  return _RDA!T(_f, fix); else return _RDA!T(fix); }

size_t[] MAKE_IDX(alias less = "a < b", Range)(Range range) { auto idx = new size_t[](range.length); makeIndex!(less)(range, idx); return idx;}
size_t MIN_POS(alias less = "a < b", Range)(Range range) { auto r = minPos!(less)(range); return range.length - r.length; }

void chmin(T)(ref T x, T y) { x = min(x, y); } void chmax(T)(ref T x, T y) { x = max(x, y); }
bool inside(T)(T x, T b, T e) { return x >= b && x < e; }
T lcm(T)(T x, T y) { return x * (y / gcd(x, y)); }

long mod = 10^^9 + 7;
//long mod = 998244353;
//long mod = 1_000_003;
void moda(T)(ref T x, T y) { x = (x + y) % mod; }
void mods(T)(ref T x, T y) { x = ((x + mod) - (y % mod)) % mod; }
void modm(T)(ref T x, T y) { x = (x * y) % mod; }
void modpow(T)(ref T x, T y) { if (!y) { x = 1; return; } auto t = x; x.modpow(y>>1); x.modm(x); if (y&1) x.modm(t); }

void main()
{
	auto t = RD!int;
	auto ans = new int[](t);
	foreach (ti; 0..t)
	{
		auto n = RD!int;
		auto a = RDA;
		foreach (i; 0..n)
		{
			if (a[i] == 0)
			{
				++a[i];
				++ans[ti];
			}
		}

		auto s = a.sum;
		if (s == 0)
			++ans[ti];
	}

	foreach (e; ans)
		writeln(e);
	stdout.flush;
	debug readln;
}


import std.stdio;
import std.conv;
import std.string;
import std.typecons;
import std.algorithm;
import std.array;
import std.range;
import std.math;
import std.container;

void main()
{
	auto hw = readln.chomp.split.map!(to!int);
	auto field = new string[](hw[0]);
	foreach (i; 0..hw[0]) {
		field[i] = readln.chomp;
	}
	int cnt;
	foreach (y; 0..hw[0]-1) {
		foreach (x; 0..hw[1]-1) {
			bool f, a, c, e;
			foreach (i; 0..2) {
				foreach (j;0..2) {
					if (field[y+i][x+j] == 'f') f = 1;
					if (field[y+i][x+j] == 'a') a = 1;
					if (field[y+i][x+j] == 'c') c = 1;
					if (field[y+i][x+j] == 'e') e = 1;
				}
			}
			if (f + a + c + e == 4) cnt++;
		}
	}
	cnt.writeln;
}

import std.algorithm;
import std.range;
import std.stdio;
import std.string;

void main ()
{
	int n, m;
	while (readf (" %s %s ", &n, &m) > 0)
	{
		string [] s;
		foreach (i; 0..n)
		{
			s ~= readln.strip;
		}

		long res = 0;
		auto f = ['f': true, 'a': true, 'c': true, 'e': true];
		foreach (i; 0..n - 1)
		{
			foreach (j; 0..m - 1)
			{
				bool [char] b;
				foreach (p; 0..2)
				{
					foreach (q; 0..2)
					{
						b[s[i + p][j + q]] = true;
					}
				}
				res += b == f;
			}
		}

		writeln (res);
	}
}

import std.stdio;
import std.string;
import std.array;
import std.functional;
import std.algorithm;
import std.container;
import std.conv;
import std.random;

int n, m;
string data[100];

bool check(int x, int y, char c) {
	return data[x][y] == c || data[x + 1][y] == c || data[x][y + 1] == c || data[x + 1][y + 1] == c;
}

void main() {
	readf("%s %s", &n, &m);
	readln();
	for (int i = 0; i < n; ++i)
		data[i] = readln();
	int result = 0;
	for (int i = 0; i < n - 1; ++i)
		for (int j = 0; j < m - 1; ++j)
		{
			if (!check(i, j, 'f')) continue;
			if (!check(i, j, 'a')) continue;
			if (!check(i, j, 'c')) continue;
			if (!check(i, j, 'e')) continue;
			++result;
		}
	writeln(result);
}

module _template;
import std.stdio;
import std.string;
import std.algorithm;
import std.container;
import std.range;
import std.math;
import std.numeric;
import std.conv;
import std.typecons;
import std.format;

struct IO {
        string[] tk;
        string readString() {
                while (tk.empty)
                        tk = readln.split;
                auto tkt = tk.front;
                tk.popFront;
                return tkt;
        }
        int readInt() {
                return readString.to!int;
        }
        double readDouble() {
                return readString.to!double;
        }
}
int n, m;
int countFaces(ref char[][] mat, int i, int j) {
        int[4] count;
        for (int dy = 0; dy < 2; dy++) {
                for (int dx = 0; dx < 2; dx++) {
                        if (mat[i + dy][j + dx] == 'f') count[0]++;
                        if (mat[i + dy][j + dx] == 'a') count[1]++;
                        if (mat[i + dy][j + dx] == 'c') count[2]++;
                        if (mat[i + dy][j + dx] == 'e') count[3]++;
                }
        }
        return (count[0] == 1 && count[1] == 1 && count[2] == 1 && count[3] == 1);
}
void main() {
        IO cin;
        int t = 1;
        // t = cin.readInt;
        while (t--) {
                n = cin.readInt;
                m = cin.readInt;
                char[][] mat = new char[][](n, m);
                for (int i = 0; i < n; i++) {
                        mat[i] = cin.readString.dup;
                }
                if (n < 2 || m < 2) {
                        writeln(0);
                        return;
                }
                int count = 0;
                for (int i = 0; i <= n - 2; i++) {
                        for (int j = 0; j <= m - 2; j++) {
                                if (countFaces(mat, i, j)) count++;
                        }
                }
                writeln(count);
        }
}


import core.bitop, std.bitmanip;
import core.checkedint;
import std.algorithm, std.functional, std.meta;
import std.array, std.container;
import std.bigint;
import std.conv;
import std.math, std.numeric;
import std.range, std.range.interfaces;
import std.stdio, std.string;
import std.ascii, std.typecons;

void main()
{
    int t;
    readf("%s", &t);
    readln;

    while (t--) {
        auto s = readln.chomp;
        s = "2" ~ s;
        auto p = new int[] (s.length + 1);
        p[0] = 0;
        foreach (i; 1 .. s.length) {
            p[i] = s[i] == '0' ? p[i-1] + 1 : 0;
        }

        int ans = 0;
        foreach (i; 1 .. s.length) {
            foreach (len; 1 .. 19) {
                if (i.to!int - len + 1 < 1) { break; }
                if (s[i-len+1] != '1') { continue; }

                auto x = to!int(s[i-len+1 .. i+1], 2);

                debug { writeln(i, ' ', len, ' ', x); }

                if (p[i-len] + len >= x) { ++ans; }
            }
        }

        ans.writeln;
    }

}

import std.stdio, std.conv, std.string, std.array, std.range, std.algorithm, std.container;
import std.math, std.random, std.bigint, std.datetime, std.format;
void main(string[] args){ if(args.length > 1) if(args[1] == "-debug") DEBUG = 1; solve(); }
void log()(){ writeln(""); } void log(T, A ...)(T t, lazy A a){ if(DEBUG) write(t, " "), log(a); } bool DEBUG = 0;
string read(){ static string[] ss; while(!ss.length) ss = readln.chomp.split; string res = ss[0]; ss.popFront; return res; }
T rtype(T)(){ return read.to!T; } alias rint = rtype!int, rlong = rtype!long, rreal = rtype!real;
T[] rtypes(T)(int n){ return n.iota.map!(i => rtype!T()).array; } alias rint = rtypes!int, rlong = rtypes!long, rreal = rtype!real;

// ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- //
void solve(){
	int t = rint;
	foreach(_; 0 .. t){
		bool[ ] bs = read.to!(char[]).map!(c => c == '1').array;
		int n = bs.length.to!int;

		long ans;
		int j;
		foreach(i; 0 .. n){
			if(bs[i]){
				int m = 0;
				foreach(k; i .. n){
					int len = k - j + 1;
					m *= 2, m += (bs[k]? 1: 0);
					log("[", bs[i .. k + 1].map!(b => b ? "1": "0").array.join(), "]",  "j:", j, "i:", i, "k:", k, "len:", len, "m:", m);
					if(len >= m) ans += 1;
					else if(len < m) break;
					log("ans:", ans);
				}
				j = i + 1;
			}
		}
		ans.writeln;
	}
}
/*
1
011
00101
000110
0000111
000001001
0000001010
00000001011
000000001100

After 0's in a row, check if there is

*/


import std.bigint,std.container,std.array,std.algorithm,std.conv,
	std.functional,std.math,std.numeric,std.string,std.range,std.complex,
	std.typecons,std.regex,std.random,std.uni,std.traits,std.stdio,std.variant,
	core.stdc.stdio : freopen;
alias RedBlackTree Rbt;alias redBlackTree rbt;alias BigInt big;
alias pair(X,Y)=Tuple!(X,"fi",Y,"se");alias long lint;immutable int mod=1000000007;
alias pair!(int,int) pii;alias pair!(long,long) pll;alias BoyerMooreFinder strfind;
alias make_pair mp;alias binary_search bins;alias gcd=std.numeric.gcd;
pure nothrow
{
	T lcm (T)(auto ref T a,auto ref T b){return a/gcd(a,b)*b;}
	pair!(X,Y) make_pair(X,Y)(in X x_,in Y y_){return tuple!(X,"fi",Y,"se")(x_,y_);}
	big gcd(big a,big b){while(b){a%=b;swap(a,b);}return a;}
	@property X sqr(X)(in X a_) {return a_*a_;}
	@property X cub(X)(in X a_) {return a_*a_*a_;}
	int sz(T)(T a) if(hasLength!T){return cast(int)a.length;}
	size_t lowb(T,X)(in T a,auto ref X g)
	 if(isRandomAccessRange!T && hasLength!T && is(typeof(g<a[0])==bool))
	{
		size_t l=0,r=a.length;
		while(r-l>1)
		{
			auto m=(l+r)>>1;
			if(!(a[m]<g))r=m;
			else l=m;
		}
		return (!(a[l]<g))?l:r;
	}
	size_t upb(T,X)(in T a,auto ref X g)
	 if(isRandomAccessRange!T && hasLength!T && is(typeof(g<a[0])==bool))
	{
		auto pos=lowb(a,g);
		if(pos==a.length)return pos;
		else return a[pos]==g?pos+1:pos;
	}
	size_t binf(T,X)(in T a,auto ref X g)
	 if(isRandomAccessRange!T && hasLength!T && is(typeof(g<a[0])==bool))
	{
		auto pos=lowb(a,g);
		return (g==a[pos])?pos:a.length;
	}
	bool binary_search(T,X)(in T a,auto ref X g)
	 if(isRandomAccessRange!T && hasLength!T && is(typeof(g<a[0])==bool))
	{
		return binf(a,g)!=a.length;
	}
}
void putarr(X)(in X a,in char ch=' '){foreach(const ref i;a)write(i,ch);}
void putarr(X)(in X a,in size_t n=a.length,in size_t m=a.front.length)
{
	foreach(i;0..n)
	{
		foreach(j;0..m)write(a[i][j],' ');
		writeln;
	}
}
bool getarr(X)(X a,in size_t n)
{bool b=1; foreach(ref i;a[0..n])b=input(&i);return b;}
bool input(T...)(auto ref T ptrs) if (ptrs.length > 0)
{
	size_t s=0;
	foreach(ref e;ptrs)
	{
		if(isSomeChar!(Unqual!(typeof(e))))s+=readf(" %c",&e);
		else s+=readf(" %s",&e);
	}
	return s==ptrs.length;
}
bool read(T...)(auto ref T ptrs) if (ptrs.length > 0)
{
	size_t s=0;
	foreach(ref e;ptrs)
	{
		if(isSomeChar!(Unqual!(typeof(e))))s+=readf(" %c",&e);
		else s+=readf(" %s",&e);
	}
	readln;
	return s==ptrs.length;
}
nothrow auto inf(in char* name) {return freopen(name,"r",core.stdc.stdio.stdin);}
nothrow auto ouf(in char* name) {return freopen(name,"w",core.stdc.stdio.stdout);}
@property auto arread(T)(){return readln.splitter.map!(to!(T)).array;}
//foreach_reverse isAlpha isNumber isWhite isLower isUpper toLower toUpper mixin
//cumulativeFold return static heapify join filter foreach
//------------------------------------------program beginning--------------------------

void main()
{
	version(ONLINE_JUDGE){}
	else
	{
		assert(freopen("input.txt","r",core.stdc.stdio.stdin));
		assert(freopen("output.txt","w",core.stdc.stdio.stdout));
	}
	int n;
loop:while(read(n))
	{
		auto a=arread!lint;
		lint xx=0;
		foreach(i;a)xx=gcd(xx,i);
		if(xx!=1)
		{
			writeln("YES\n0");
		}
		else
		{
			int ans=0;
			foreach(i;0..n-1)
			{
				while(a[i]&1)
				{
					long x=a[i]+a[i+1],y=a[i]-a[i+1];
					a[i]=x;
					a[i+1]=y;
					ans++;
				}
			}
			while((a[n-1]&1) || (a[n-2]&1))
			{
				long x=a[n-2]+a[n-1],y=a[n-2]-a[n-1];
				a[n-2]=x;
				a[n-1]=y;
				ans++;
			}
			writeln("YES\n",ans);
		}
	}
}

import std.stdio, std.array, std.string, std.conv, std.algorithm;
import std.typecons, std.range, std.random, std.math, std.container;
import std.numeric, std.bigint, core.bitop;

void main() {
    auto N = readln.chomp.to!int;
    auto A = readln.split.map!(to!int).array;
    writeln("YES");

    if (A.reduce!gcd > 1) {
        writeln(0);
        return;
    }

    int ans = 0;
    foreach (i; 0..N) {
        if (A[i] % 2 == 0) continue;
        else if (i == N-1) ans += 2;
        else if (A[i+1] % 2 == 0) ans += 2;
        else {
            ans += 1;
            A[i+1] = 2;
        }
    }

    ans.writeln;
}


import std.stdio;
import std.typecons;
import core.stdc.stdio : scanf;
import std.conv;
import std.array;
import std.string;
import std.range;
import std.algorithm;
import std.container;

alias Tuple!(int, "to", long, "cost") Edge;
alias Tuple!(int, "v", long, "cost") State;

void main() {
    int N, M; scanf("%d %d\n", &N, &M);
    auto G = new Edge[][2*N];
    foreach (i; 0 .. N) {
        G[i] ~= Edge(N + i, 0);
    }
    foreach (i; 0 .. M) {
        int U, V, W; scanf("%d %d %d\n", &U, &V, &W);
        U--; V--;
        G[U] ~= Edge(V, W);
        G[N + V] ~= Edge(N + U, W);
    }
    auto PQ = heapify!"a.cost > b.cost"(new State[0], 0);
    auto D = new long[](2*N);
    D[] = long.max;
    PQ.insert(State(0, 0));
    D[0] = 0;
    while (! PQ.empty) {
        State cur = PQ.front; PQ.popFront;
        if (D[cur.v] != cur.cost) continue;
        foreach (e; G[cur.v]) {
            auto nextv = e.to;
            auto nexts = State(nextv, cur.cost + e.cost);
            if (D[nexts.v] > nexts.cost) {
                D[nexts.v] = nexts.cost;
                PQ.insert(nexts);
            }
        }
    }
    long[] buf;
    for (int p = 1; p < N; p++) {
        long ans = long.max;
        for (int b = 0; b < 2; b++) {
            ans = min(ans, D[p + N * b]);
        }
        buf ~= (ans == long.max ? -1 : ans);
    }
    writefln("%(%s %)", buf);
}

import std.stdio;
import std.typecons;
import core.stdc.stdio : scanf;
import std.conv;
import std.array;
import std.string;
import std.range;
import std.algorithm;
import std.container;

alias Tuple!(int, "to", long, "cost") Edge;
alias Tuple!(int, "v", long, "cost") State;

long[] dijkstra(in Edge[][] G, int N, int s) {
    auto PQ = heapify!"a.cost > b.cost"(new State[0], 0);
    auto D = new long[](N);
    D[] = long.max;
    PQ.insert(State(s, 0));
    D[s] = 0;
    while (! PQ.empty) {
        State cur = PQ.front; PQ.popFront;
        if (D[cur.v] != cur.cost) continue;
        foreach (e; G[cur.v]) {
            auto nextv = e.to;
            auto nexts = State(nextv, cur.cost + e.cost);
            if (D[nexts.v] > nexts.cost) {
                D[nexts.v] = nexts.cost;
                PQ.insert(nexts);
            }
        }
    }
    return D;
}

void main() {
    int N, M; scanf("%d %d\n", &N, &M);
    auto G = new Edge[][2*N];
    foreach (i; 0 .. N) {
        G[i] ~= Edge(N + i, 0);
    }
    foreach (i; 0 .. M) {
        int U, V, W; scanf("%d %d %d\n", &U, &V, &W);
        U--; V--;
        G[U] ~= Edge(V, W);
        G[N + V] ~= Edge(N + U, W);
    }
    auto D = dijkstra(G, 2*N, 0);
    long[] buf;
    for (int p = 1; p < N; p++) {
        long ans = long.max;
        for (int b = 0; b < 2; b++) {
            ans = min(ans, D[p + N * b]);
        }
        buf ~= (ans == long.max ? -1 : ans);
    }
    writefln("%(%s %)", buf);
}

import std.stdio;
import std.typecons;
import core.stdc.stdio : scanf;
import std.conv;
import std.array;
import std.string;
import std.range;
import std.algorithm;
import std.container;

alias Tuple!(int, "to", long, "cost") Edge;
alias Tuple!(int, "v", long, "cost") State;

long[] dijkstra(in Edge[][] G, int N, int s) {
    auto PQ = heapify!"a.cost > b.cost"(new State[0], 0);
    auto D = new long[](N);
    D[] = long.max;
    PQ.insert(State(0, 0));
    D[0] = 0;
    while (! PQ.empty) {
        State cur = PQ.front; PQ.popFront;
        if (D[cur.v] != cur.cost) continue;
        foreach (e; G[cur.v]) {
            auto nextv = e.to;
            auto nexts = State(nextv, cur.cost + e.cost);
            if (D[nexts.v] > nexts.cost) {
                D[nexts.v] = nexts.cost;
                PQ.insert(nexts);
            }
        }
    }
    return D;
}

void main() {
    int N, M; scanf("%d %d\n", &N, &M);
    auto G = new Edge[][2*N];
    foreach (i; 0 .. N) {
        G[i] ~= Edge(N + i, 0);
    }
    foreach (i; 0 .. M) {
        int U, V, W; scanf("%d %d %d\n", &U, &V, &W);
        U--; V--;
        G[U] ~= Edge(V, W);
        G[N + V] ~= Edge(N + U, W);
    }
    auto D = dijkstra(G, 2*N, 0);
    long[] buf;
    for (int p = 1; p < N; p++) {
        long ans = long.max;
        for (int b = 0; b < 2; b++) {
            ans = min(ans, D[p + N * b]);
        }
        buf ~= (ans == long.max ? -1 : ans);
    }
    writefln("%(%s %)", buf);
}

import std.stdio;
import std.typecons;
import core.stdc.stdio : scanf;
import std.conv;
import std.array;
import std.string;
import std.range;
import std.algorithm;
import std.container;

alias Tuple!(int, "from", int, "to", long, "cost") Edge;
alias Tuple!(int, "v", int, "b") ExtV;
alias Tuple!(ExtV, "v", long, "cost") State;

void main() {
    int N, M; readf("%d %d\n", &N, &M);
    auto G = new Edge[][N],
        rG = new Edge[][N];
    foreach (i; 0 .. M) {
        int U, V, W; readf("%d %d %d\n", &U, &V, &W);
        U--; V--;
        G[U] ~= Edge(U, V, W);
        rG[V] ~= Edge(V, U, W);
    }
    auto PQ = heapify!"a.cost > b.cost"(new State[0]);
    long[ExtV] D;
    PQ.insert(State(ExtV(0, 0), 0));
    while (! PQ.empty) {
        State cur = PQ.front; PQ.popFront;
        if (cur.v.b  == 0) {
            // can use original and reversed
            foreach (e; G[cur.v.v]) {
                auto nextv = e.to;
                auto nexts = State(ExtV(nextv, 0), cur.cost + e.cost);
                if (nexts.v !in D || D[nexts.v] > nexts.cost) {
                    D[nexts.v] = nexts.cost;
                    PQ.insert(nexts);
                }
            }
        }
        // can use reversed
        foreach (e; rG[cur.v.v]) {
            auto nextv = e.to;
            auto nexts = State(ExtV(nextv, 1), cur.cost + e.cost);
            if (nexts.v !in D || D[nexts.v] > nexts.cost) {
                D[nexts.v] = nexts.cost;
                PQ.insert(nexts);
            }
        }
    }
    long[] buf;
    for (int p = 1; p < N; p++) {
        long ans = int.max;
        for (int b = 0; b < 2; b++) {
            auto k = ExtV(p, b);
            if (k !in D) continue;
            ans = min(ans, D[k]);
        }
        buf ~= (ans == int.max ? -1 : ans);
    }
    writefln("%(%s %)", buf);
}


import std.container;
import std.algorithm;
import std.range;
import std.array;
import std.stdio;
import std.utf;
import std.math;
import std.typecons;

DList!string _words;

void read(T...)(ref T t)
{
  void singleRead(W)(ref W w)
  {
    import std.stdio: readln;
    while(_words.empty)
      {
        import std.array: split;
        foreach(word; readln.split)
          {
            _words.insertBack(word);
          }
      }
    import std.conv: to;
    string word = _words.front;
    _words.removeFront;
    w = to!W(word);
  }
  static foreach(i; 0 .. T.length)
    {
      static if (is(typeof({foreach(ref e; t[i]){}})) && !is(T[i] == string))
        {
          foreach(ref element; t[i])
            read(element);
        }
      else
        {
          singleRead(t[i]);
        }
    }
}

auto next(T)()
{
  T t;
  read(t);
  return t;
}

size_t ind(T)(T t)
{
  return cast(size_t)t;
}

ref auto at(R, I)(ref R r, I i)
{
  return r[cast(size_t)i];
}

void set(R, I, V)(ref R r, I i, V v)
{
  r[cast(size_t)i] = v;
}

import std.conv;
import std.traits;
import std.meta;
int _loglevel = -1;
void _log(string functionName, argSeq...)()
{
  foreach(i; 0 .. _loglevel * 4)
    write(' ');
  write(functionName);
  static foreach(arg; argSeq)
    {
      write(" ", arg.stringof, " = ", arg);
    }
  writeln;
}
enum logCall =
  q{
    debug
    {
     {
     _loglevel++;
     alias _parameterTuple = ParameterIdentifierTuple!(mixin(split(__FUNCTION__, ".").back));
     static if (_parameterTuple.length > 0)
       mixin(`_log!(__FUNCTION__, `, [_parameterTuple].joiner(", ").array, `);`);
     else
       _log!(__FUNCTION__);
      }
     foreach(i; 0 .. _loglevel * 4) write(' ');
     writeln('{');
     scope(exit)
       {
         foreach(i; 0 .. _loglevel * 4) write(' ');
         writeln('}');
         _loglevel--;
       }
    }
};

void logSym(S...)(int line = __LINE__, string file = __FUNCTION__)
{
  debug
    {
      foreach(i; 0 .. _loglevel * 4) write(' ');
      write(file, "(", line, "):");
      static foreach(s; S)
        write(" ", s.stringof, " = ", s);
      writeln;

    }
}

Array!E makeArray(E, S)(S size, lazy E value = E.init)
{
  auto a = Array!E();
  a.length = cast(size_t) size;
  foreach(ref ai; a)
    ai = value();
  return a;
}
Array!E makeArray(E, S)(S size)
{
  auto a = Array!E();
  a.length = cast(size_t) size;
  return a;
}

void main()
{
  int t;
  read(t);
  foreach(tc; 0 .. t)
    {
      int n = next!int;
      string s = next!string;
      auto res = s.filter!(c => to!int(c) % 2 != 0).array.take(2);
      if (res.length == 2)
        {
          foreach(r; res)
            write(r);
          writeln;
        }
      else
        {
          writeln(-1);
        }
    }
}

import std.algorithm : max, maxElement;
import std.container : Array;
import std.stdio : stdin, write, writeln;
import std.typecons : Tuple, tuple;

struct IO {
    string readToken() {
        import std.range : empty, front, popFront, split;
        import std.stdio : readln;

        while (tokens.empty) {
            tokens = readln.split;
        }
        auto token = tokens.front;
        tokens.popFront;
        return token;
    }

    int readInt() {
        import std.conv : to;

        return readToken.to!int;
    }

    long readLong() {
        import std.conv : to;

        return readToken.to!long;
    }

    string[] tokens;
}

void main() {
    IO io;
    int T = io.readInt;
    while (T--) {
        int n = io.readInt;
        string s = io.readToken;
        int i = 0;
        while (i < n && (s[i] - '0') % 2 == 0) {
            i++;
        }
        if (i == n) {
            writeln(-1);
        }
        else {
            int j = n - 1;
            while (j >= 0 && (s[j] - '0') % 2 == 0) {
                j--;
            }
            if (i == j) {
                writeln(-1);
            }
            else {
                writeln(s[i], s[j]);
            }
        }
    }
}

import std.stdio, std.conv, std.functional, std.string;
import std.algorithm, std.array, std.container, std.range, std.typecons;
import std.bigint, std.numeric, std.math, std.random;
import core.bitop;

string FMT_F = "%.10f";

static File _f;
void file_io(string fn) { _f = File(fn, "r"); }
static string[] s_rd;
T _RD(T = long)() { while(!s_rd.length) s_rd = readln.chomp.split; string res = s_rd[0]; s_rd.popFront; return res.to!T; }
T _RD(T = long)(File f) { while(!s_rd.length) s_rd = f.readln.chomp.split; string res = s_rd[0]; s_rd.popFront; return res.to!T; }
T[] _RDA(T = long)(T fix = 0) { auto r = readln.chomp.split.to!(T[]); r[] += fix; return r; }
T[] _RDA(T = long)(File f, T fix = 0) { auto r = f.readln.chomp.split.to!(T[]); r[] += fix; return r; }
T RD(T = long)() { if (_f.isOpen) return _RD!T(_f); else return _RD!T; }
T[] RDA(T = long)(T fix = 0) { if (_f.isOpen)  return _RDA!T(_f, fix); else return _RDA!T(fix); }

size_t[] MAKE_IDX(alias less = "a < b", Range)(Range range) { auto idx = new size_t[](range.length); makeIndex!(less)(range, idx); return idx;}
size_t MIN_POS(alias less = "a < b", Range)(Range range) { auto r = minPos!(less)(range); return range.length - r.length; }

void chmin(T)(ref T x, T y) { x = min(x, y); } void chmax(T)(ref T x, T y) { x = max(x, y); }
bool inside(T)(T x, T b, T e) { return x >= b && x < e; }
T lcm(T)(T x, T y) { return x * (y / gcd(x, y)); }

long mod = 10^^9 + 7;
//long mod = 998244353;
//long mod = 1_000_003;
void moda(T)(ref T x, T y) { x = (x + y) % mod; }
void mods(T)(ref T x, T y) { x = ((x + mod) - (y % mod)) % mod; }
void modm(T)(ref T x, T y) { x = (x * y) % mod; }
void modpow(T)(ref T x, T y) { if (!y) { x = 1; return; } auto t = x; x.modpow(y>>1); x.modm(x); if (y&1) x.modm(t); }

void main()
{
	auto t = RD!int;
	auto ans = new long[](t);
	foreach (ti; 0..t)
	{
		auto n = RD!int;
		auto s = RD!string;
		long cnt;
		string tmp;
		foreach (c; s)
		{
			auto num = [c].to!int;
			if (num % 2 == 1)
			{
				++cnt;
				tmp ~= c;
				if (cnt == 2) break;
			}
		}
		if (cnt != 2)
			ans[ti] = -1;
		else
			ans[ti] = tmp.to!long;
	}

	foreach (e; ans)
		writeln(e);
	stdout.flush;
	debug readln;
}