// Cheese-Cracker: cheese-cracker.github.io

void solve(){
    auto n = scan;
    auto arr = scanArray;
    long summ = 0;
    for(int i = 0; i < n; ++i){
        summ += arr[i];
    }
    long asum = 2*summ;
    if(asum % n != 0 || asum % (n + 1) != 0){
        writeln("NO");
        return;
    }
    asum /= n;
    asum /= (n+1);
    long[] res;
    for(int i = 0; i < n; ++i){
        int previ = (i - 1 + n.to!int) % n.to!int;
        long diff = arr[i] - arr[previ];
        long nai = asum - diff;
        if(nai % n != 0 || nai <= 0){
            writeln("NO");
            return;
        }
        long ai = nai / n.to!long;
        res ~= ai;
    }
    writeln("YES");
    assert(res.length == n);
    res.each!(a => write(a, " "));
    writeln;
}

void main(){
    long tests = scan;        // Toggle!
    while(tests--) solve;
}

/**************    *****    That's All Folks!    *****    **************/
import std.stdio, std.range, std.conv, std.typecons, std.algorithm, std.container, std.math, std.numeric;
string[] tk; T scan(T=long)(){while(!tk.length)tk = readln.split; string a=tk.front; tk.popFront; return a.to!T;}
T[] scanArray(T=long)(){ auto r = readln.split.to!(T[]); return r; }
void show(A...)(A a){ debug{ foreach(t; a){stderr.write(t, "| ");} stderr.writeln; } }
alias ll = long, tup = Tuple!(long, "x",  long, "y");

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

T read(T)() { return readln.chomp.to!T; }
T[] readarray(T)() { return readln.chomp.split(" ").map!(to!T).array; }

void main() {
    int T = read!int;
    foreach (t; 0 .. T) solve();
}

void solve() {
    int N = read!int;
    auto B = readarray!long;

    auto A = new long[N];
    bool f() {
        auto sB = B.reduce!"a + b";
        long Z = N * (N + 1L) / 2L;
        if (sB % Z > 0) {
            return false;
        }
        long sA = sB / Z;
        for (int k = 0; k < N; k++) {
            int pk = (k + N - 1) % N;
            long na = (sA - B[k] + B[pk]);
            if (na % N > 0) return false;
            if (na <= 0) return false;
            A[k] = na / N;
        }
        return true;
    }
    auto pos = f();
    writeln(pos ? "YES" : "NO");
    if (pos) {
        writefln("%(%s %)", A);
    }
}

immutable multi = true;

void solve(int tc)
{
  auto n = readInt!int;
  auto b = ma(n, readInt!long);
  if (n == 1) { writeln("YES"); writeln(b[0]); return; }
  auto dlt = new long[](n);
  dlt[0] = b[0] - b[n-1];
  foreach(i; 1 .. n)
    dlt[i] = b[i] - b[i-1];
  debug writeln("dlt ", dlt);
  long[] aDlt = new long[](n);
  foreach(i; 0 .. n)
    {
      aDlt[i] = -dlt[i] + dlt[0];
      if (aDlt[i]%n != 0) return writeln("NO");
      aDlt[i] /= n;
    }
  debug writeln("aDlt ", aDlt);
  long wsum = 0;
  foreach(i; 0 .. n)
    {
      long fact = n - i + 1;
      wsum += fact * aDlt[i];
    }
  long rhs = b[0] - wsum;
  long lhsFact = cast(long)n * (cast(long)n + 1) / 2L;
  if (rhs <= 0) return writeln("NO");
  if (rhs % lhsFact != 0) return writeln("NO");
  rhs /= lhsFact;

  aDlt[] += rhs;
  if (aDlt.fold!min <= 0) return writeln("NO");

  writeln("YES");
  foreach(d; aDlt)
    {
      write(d, " ");
    }
  writeln;
}

// main {{{
void main()
{
	auto t = multi? readInt!int : 1;
	foreach(tc; 0 .. t) solve(tc);
}
// }}}
// input {{{
int currChar;
static this()
{
	currChar = ' ';
}

char topChar()
{
	return cast(char) currChar;
}

void popChar()
{
	import core.stdc.stdio;
	currChar = getchar();
}

auto readInt(T)()
{
	T num = 0;
	int sgn = 0;
	while (topChar.isWhite)
		popChar;
	while (topChar == '-' || topChar == '+')
	{
		sgn ^= (topChar == '-');
		popChar;
	}
	while (topChar.isDigit)
	{
		num *= 10;
		num += (topChar - '0');
		popChar;
	}
	if (sgn)
		return -num;
	return num;
}

string readString()
{
	string res = "";
	while (topChar.isWhite)
		popChar;
	while (!topChar.isWhite)
	{
		res ~= topChar;
		popChar;
	}
	return res;
}
void writes(T...)(T t)
{
	static foreach(i, ti; t)
	{
		static if (isIterable!(T[i]))
		{
			foreach(e; ti)
			{
				write(e, " ");
			}
		}
	}
}
auto ra(V)()
{
	int n = readInt!int;
	return ma(n, readInt!V);
}
auto rt(V)()
{
	int n = readInt!int;
	int m = readInt!int;
	return ma(n, ma(m, readInt!V));
}
auto rbg()
{
	int n = readInt!int;
	int m = readInt!int;
	auto adj = new int[][](n);
	foreach(i; 0 .. m)
	{
		auto u = readInt!int - 1;
		auto v = readInt!int - 1;
		adj[u] ~= v;
		adj[v] ~= u;
	}
	return adj;
}
auto ma(V)(size_t n, lazy V v)
{
	auto arr = new V[](n);
	foreach(ref ai; arr) ai = v;
	return arr;
}
// }}}
// imports {{{
import std.stdio;
import std.algorithm;
import std.typecons;
import std.math;
import std.numeric;
import std.container;
import std.range;
import std.array;
import std.ascii;
// }}}

// Cheese-Cracker: cheese-cracker.github.io

void solve(){
    auto n = scan;
    auto arr = scanArray;
    long summ = 0;
    for(int i = 0; i < n; ++i){
        summ += arr[i];
    }
    long asum = 2*summ;
    asum /= n;
    asum /= (n+1);
    long[] res;
    for(int i = 0; i < n; ++i){
        int previ = (i - 1 + n.to!int) % n.to!int;
        long diff = arr[i] - arr[previ];
        long nai = asum - diff;
        if(nai % n != 0 || nai <= 0){
            writeln("NO");
            return;
        }
        long ai = nai / n.to!long;
        res ~= ai;
    }
    writeln("YES");
    assert(res.length == n);
    res.each!(a => write(a, " "));
    writeln;
}

void main(){
    long tests = scan;        // Toggle!
    while(tests--) solve;
}

/**************    *****    That's All Folks!    *****    **************/
import std.stdio, std.range, std.conv, std.typecons, std.algorithm, std.container, std.math, std.numeric;
string[] tk; T scan(T=long)(){while(!tk.length)tk = readln.split; string a=tk.front; tk.popFront; return a.to!T;}
T[] scanArray(T=long)(){ auto r = readln.split.to!(T[]); return r; }
void show(A...)(A a){ debug{ foreach(t; a){stderr.write(t, "| ");} stderr.writeln; } }
alias ll = long, tup = Tuple!(long, "x",  long, "y");

// Cheese-Cracker: cheese-cracker.github.io

void solve(){
    auto n = scan!int;
    auto arr = scanArray;
    long summ = arr.sum;
    long asum = 2*summ;
    asum /= n.to!long;
    asum /= (n+1).to!long;
    long[] res;
    for(int i = 0; i < n; ++i){
        long diff = arr[i] - arr[(i - 1 + n) % n];
        long nai = asum - diff;
        if(nai % n != 0 || nai < n){
            writeln("NO");
            return;
        }
        long ai = nai / n.to!long;
        assert(ai <= 1_000_000_000);
        res ~= ai;
    }
    assert(asum == res.sum);
    if(asum != res.sum){
        writeln("NO");
        return;
    }
    writeln("YES");
    res.each!(a => write(a, " "));
    writeln;
}

void main(){
    long tests = scan;        // Toggle!
    while(tests--) solve;
}

/**************    *****    That's All Folks!    *****    **************/
import std.stdio, std.range, std.conv, std.typecons, std.algorithm, std.container, std.math, std.numeric;
string[] tk; T scan(T=long)(){while(!tk.length)tk = readln.split; string a=tk.front; tk.popFront; return a.to!T;}
T[] scanArray(T=long)(){ auto r = readln.split.to!(T[]); return r; }
void show(A...)(A a){ debug{ foreach(t; a){stderr.write(t, "| ");} stderr.writeln; } }
alias ll = long, tup = Tuple!(long, "x",  long, "y");

// Cheese-Cracker: cheese-cracker.github.io

void solve(){
    auto n = scan!int;
    auto arr = scanArray;
    long summ = arr.sum;
    long asum = 2*summ;
    asum /= n;
    asum /= (n+1);
    long[] res;
    for(int i = 0; i < n; ++i){
        long diff = arr[i] - arr[(i - 1 + n) % n];
        long nai = asum - diff;
        if(nai % n != 0 || nai < n){
            writeln("NO");
            return;
        }
        res ~= nai / n;
    }
    writeln("YES");
    res.each!(a => write(a, " "));
    writeln;
}

void main(){
    long tests = scan;        // Toggle!
    while(tests--) solve;
}

/**************    *****    That's All Folks!    *****    **************/
import std.stdio, std.range, std.conv, std.typecons, std.algorithm, std.container, std.math, std.numeric;
string[] tk; T scan(T=long)(){while(!tk.length)tk = readln.split; string a=tk.front; tk.popFront; return a.to!T;}
T[] scanArray(T=long)(){ auto r = readln.split.to!(T[]); return r; }
void show(A...)(A a){ debug{ foreach(t; a){stderr.write(t, "| ");} stderr.writeln; } }
alias ll = long, tup = Tuple!(long, "x",  long, "y");

// Cheese-Cracker: cheese-cracker.github.io

void solve(){
    auto n = scan!int;
    auto arr = scanArray;
    long summ = arr.sum;
    long asum = (2*summ) /(n * (n + 1));
    long[] res;
    for(int i = 0; i < n; ++i){
        long diff = arr[i] - arr[(i - 1 + n) % n];
        long nai = asum - diff;
        if(nai % n != 0 || nai < n){
            writeln("NO");
            return;
        }
        res ~= nai / n;
    }
    writeln("YES");
    res.each!(a => write(a, " "));
    writeln;
}

void main(){
    long tests = scan;        // Toggle!
    while(tests--) solve;
}

/**************    *****    That's All Folks!    *****    **************/
import std.stdio, std.range, std.conv, std.typecons, std.algorithm, std.container, std.math, std.numeric;
string[] tk; T scan(T=long)(){while(!tk.length)tk = readln.split; string a=tk.front; tk.popFront; return a.to!T;}
T[] scanArray(T=long)(){ auto r = readln.split.to!(T[]); return r; }
void show(A...)(A a){ debug{ foreach(t; a){stderr.write(t, "| ");} stderr.writeln; } }
alias ll = long, tup = Tuple!(long, "x",  long, "y");


import std.stdio, std.conv, std.algorithm, std.range, std.math, std.string;

void main() {
	string number = stdin.readln().stripRight;
	auto n = to!int(number[max(2, $)-2..$]) % 4;
	writeln(sum(iota(1, 5).map!(i => i ^^ n)) % 5);
}

import core.thread;
import std.conv, std.stdio, std.string;
import std.algorithm, std.array, std.bigint, std.container, std.math, std.range, std.regex;

//	Input
class EOFException : Throwable { this() { super("EOF"); } }
string[] tokens;
string readToken() { for (; tokens.empty; ) { tokens = readln.split; if (stdin.eof) throw new EOFException; } auto token = tokens[0]; tokens.popFront; return token; }
int readInt() { return to!int(readToken); }
long readLong() { return to!long(readToken); }
real readReal() { return to!real(readToken); }

//	chmin/chmax
void chmin(T)(ref T t, in T f) { if (t > f) t = f; }
void chmax(T)(ref T t, in T f) { if (t < f) t = f; }

//	Pair
struct Pair(S, T) {
	S x; T y;
	int opCmp(    const Pair p) const { return (x < p.x) ? -1 : (x > p.x) ? +1 : (y < p.y) ? -1 : (y > p.y) ? +1 : 0; }
	int opCmp(ref const Pair p) const { return (x < p.x) ? -1 : (x > p.x) ? +1 : (y < p.y) ? -1 : (y > p.y) ? +1 : 0; }
	string toString() const { return "(" ~ to!string(x) ~ ", " ~ to!string(y) ~ ")"; }
}
auto pair(S, T)(inout(S) x, inout(T) y) { return Pair!(S, T)(x, y); }

//	Array
int binarySearch(T)(in T[] as, in bool delegate(T) test) { int low = -1, upp = as.length; for (; low + 1 < upp; ) { int mid = (low + upp) >> 1; (test(as[mid]) ? low : upp) = mid; } return upp; }
int lowerBound(T)(in T[] as, in T val) { return as.binarySearch((T a) { return (a <  val); }); }
int upperBound(T)(in T[] as, in T val) { return as.binarySearch((T a) { return (a <= val); }); }
T[] unique(T)(in T[] as) { T[] bs; foreach (a; as) if (bs.empty || bs[$ - 1] != a) bs ~= a; return bs; }

string S;

void main(string[] args) {
	try {
	for (; ; ) {
		S = readToken;

		const n = S[max(cast(int)($) - 2, 0) .. $].to!int % 4;
		int ans;
		foreach (a; 1 .. 5) {
			int tmp = 1;
			foreach (_; 0 .. n) {
				tmp *= a;
			}
			ans += tmp;
		}
		ans %= 5;
		writeln(ans);

	}
	} catch (EOFException) {}
}

static immutable MOD = 4;
static immutable MOD_OVERAL = 5;
static immutable MODS = [
	[1, 1, 1, 1],
	[1, 2, 4, 3],
	[1, 3, 4, 2],
	[1, 4, 1, 4]
];

uint solve(const string n) {
	uint sum = 0;
	foreach (ch; n) {
		if (ch < '0' || ch > '9') {break;}
		sum = ( (sum * 10) + (ch - '0') ) % MOD;
	}

	sum %= MOD;
	uint res = 0;
	foreach (curMod; MODS) {
		res += curMod[sum];
	}

	return res % MOD_OVERAL;
}

unittest {
	assert(4 == solve("4"));
	assert(0 == solve("124356983594583453458888889"));
	assert(4 == solve("0"));
	assert(0 == solve("5"));
	assert(0 == solve("6"));
	assert(0 == solve("7"));
	assert(4 == solve("8"));
}

int main(string[] argv) {
	import std.stdio;
	writeln(solve(readln));
    return 0;
}


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

void main()
{
    auto t = to!long(readln().chomp);
    OUTER: foreach(_; 0..t)
    {
        auto n = readln().chomp.to!int;

        auto tasks = readln().chomp;
        bool[] count = new bool[26];
        int i = 0;

        while(i < tasks.length)
        {
            if(count[tasks[i]-'A'])
            {
                writeln("NO");
                continue OUTER;
            }

            char cur = tasks[i];
            count[tasks[i]-'A'] = true;
            while(i < tasks.length -1 && tasks[i+1] == cur) i++;
            i++;
        }

        writeln("YES");
    }
}

// Vicfred
// https://codeforces.com/contest/1520/problem/A
// implementation, greedy
import std.stdio;

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

while(t--) {
    int n;
    readf("%s\n", &n);
    string s;
    readf("%s\n", &s);
    char[] u;
    char last = 'a';
    foreach(ch; s) {
        if(ch != last) {
            last = ch;
            u ~= ch;
        }
    }
    bool suspicious = false;
    int[] seen = new int[27];
    foreach(ch; u) {
        if(seen[ch - 65] == 1) {
            suspicious = true;
            break;
        }
        seen[ch - 65] = 1;
    }
    if(suspicious)
        "NO".writeln;
    else
        "YES".writeln;
}
}

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)); }
double[] rotate(double[] vec, double rad) { return [cos(rad) * vec[0] - sin(rad) * vec[1], sin(rad) * vec[0] + cos(rad) * vec[1]]; }

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 bool[](t);
	foreach (ti; 0..t)
	{
		auto n = RD!int;
		auto s = RD!string;

		string s2 = [s[0]];
		foreach (i; 1..n)
		{
			if (s[i] == s[i-1]) continue;
			s2 ~= s[i];
		}

		bool ok = true;
		bool[char] used;
		foreach (c; s2)
		{
			if (used.get(c, false))
			{
				ok = false;
				break;
			}
			used[c] = true;
		}
		ans[ti] = ok;
	}

	foreach (e; ans)
		writeln(e ? "YES" : "NO");
	stdout.flush;
	debug readln;
}


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

void main ()
{
	auto tests = readln.strip.to !(int);
multitest_loop:
	foreach (test; 0..tests)
	{
		long l, r, m;
		readf !(" %s %s %s") (l, r, m);
		auto d = r - l;
		foreach (a; l..r + 1)
		{
			auto start = max (m - d, 1);
			start = (start + a - 1) / a * a;
			for (auto s = start; s <= m + d; s += a)
			{
				auto n = s / a;
				long b, c;
				if (s < m)
				{
					b = r;
					c = b + s - m;
				}
				else
				{
					b = l;
					c = b + s - m;
				}
				writeln (a, " ", b, " ", c);
				continue multitest_loop;
			}
		}
	}
}

import std.container: DList;
import std.algorithm: all, map, count, filter;
import std.range: iota;
import std.array: array;
import std.stdio;
import std.utf;

DList!string _words;
void read(T)(out T t)
{
  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;
  t = to!T(word);
}

void main()
{
  size_t t;
  read(t);
 testCase:foreach(tc; 0 .. t)
    {
      long l, r, m;
      read(l), read(r), read(m);
      foreach(ca; l .. r + 1)
        {
          long a = cast(long) ca;
          long b, c;
          long nm = m % a < (a - m % a)? (m - m % a) : (m - m % a + a);
          if (nm == 0)
            nm = a;
          long rem = m - nm;
          if (rem > r - l || rem < l - r) continue;
          long n = nm / a;
          if (rem >= 0)
            c = l;
          else
            c = r;
          b = c + rem;
          assert(a * n + b - c == m);
          assert(l <= a && a <= r && l <= b && b <= r && l <= c && c <= r);
          writeln(a, " ", b, " ", c);
          continue testCase;
        }
    }
}

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

void main ()
{
	auto tests = readln.strip.to !(int);
multitest_loop:
	foreach (test; 0..tests)
	{
		long l, r, m;
		readf !(" %s %s %s") (l, r, m);
		auto d = r - l;
		foreach (a; l..r + 1)
		{
			auto start = max (m - d, 1);
			start = (start + a - 1) / a * a;
			for (auto s = start; s <= m + d; s += a)
			{
				auto n = s / a;
				long b, c;
				if (s < 0)
				{
					c = r;
					b = c + s - m;
				}
				else
				{
					b = l;
					c = b + s - m;
				}
				writeln (a, " ", b, " ", c);
				continue multitest_loop;
			}
		}
	}
}

import std.container: DList;
import std.algorithm: all, map, count, filter;
import std.range: iota;
import std.array: array;
import std.stdio;
import std.utf;

DList!string _words;
void read(T)(out T t)
{
  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;
  t = to!T(word);
}

void main()
{
  size_t t;
  read(t);
 testCase:foreach(tc; 0 .. t)
    {
      long l, r, m;
      read(l), read(r), read(m);
      if (m <= r)
        {
          if (l <= m)
            {
              long a = m;
              long b = l;
              long c = l;
              assert(a * 1 + b - c == m);
              assert(l <= a && a <= r && l <= b && b <= r && l <= c && c <= r);
              writeln(a, " ", b, " ", c);
              continue testCase;
            }
          long a = l;
          long c = r;
          long b = m - a + c;
          assert(a * 1 + b - c == m);
          assert(l <= a && a <= r && l <= b && b <= r && l <= c && c <= r);
          writeln(a, " ", b, " ", c);
          continue testCase;
        }
      long a = r;
      long n = m / a;
      long bmc = m - a * n;
      assert(bmc <= r - l);
      long c = l;
      long b = c + bmc;
      assert(a * n + b - c == m);
      assert(l <= a && a <= r && l <= b && b <= r && l <= c && c <= r);
      writeln(a, " ", b, " ", c);
    }
}

import std.container: DList;
import std.algorithm: all, map, count, filter;
import std.range: iota;
import std.array: array;
import std.stdio;
import std.utf;

DList!string _words;
void read(T)(out T t)
{
  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;
  t = to!T(word);
}

void main()
{
  size_t t;
  read(t);
 testCase:foreach(tc; 0 .. t)
    {
      long l, r, m;
      read(l), read(r), read(m);
      foreach(ca; l .. r + 1)
        {
          long a = cast(long) ca;
          long b, c;
          long nm = m % a < (a - m % a)? (m - m % a) : (m - m % a + a);
          long rem = m - nm;
          if (rem > r - l || rem < l - r) continue;
          long n = nm / a;
          if (rem >= 0)
            c = l;
          else
            c = r;
          b = c + rem;
          assert(a * n + b - c == m);
          assert(l <= a && a <= r && l <= b && b <= r && l <= c && c <= r);
          writeln(a, " ", b, " ", c);
          continue testCase;
        }
    }
}


import std.stdio;
import std.string;
import std.conv;

int main() {
    debug stdin = File("in.txt", "r");

    char[12][200000] buf;
    bool[const(char)[12]] set;
    int n;
    readf(" %s\n", &n);
    char[] pbuf;
    foreach(i; 0 .. n) {
        readln(pbuf);
        buf[i][0 .. pbuf.length] = pbuf[];
    }

    foreach_reverse(i; 0 .. n) {
        if (cast(const)buf[i] !in set) {
            foreach (c; buf[i]) {
                if (c == 255) break;
                write(c);
            }
            set[cast(const)buf[i]] = true;
        }
    }

    return 0;
}

import std.stdio;

struct Deque(T) {
private:
    size_t size = 0, capacity = 1;
    int frontmark = 0, backmark = 0;
    T[] store = [T.init];
    void resize() {
        store.length *= 3;
        foreach(i; 0 .. capacity) {
            advance(frontmark);
            store[i + capacity] = store[frontmark];
        }
        frontmark = capacity - 1;
        backmark = 2 * capacity;
        capacity *= 3;
    }
    void advance(ref int mark) {
        ++mark;
        if (mark >= capacity) mark = 0;
    }
    void retreat(ref int mark) {
        --mark;
        if (mark < 0) mark = capacity - 1;
    }
public:
    string toString() {
        import std.conv : to;
        string result = "[ " ~ to!string(store[0]);
        foreach(i; 1 .. capacity) {
            result ~= ", ";
            result ~= to!string(store[i]);
        }
        result ~= " ]";
        return result;
    }
    @property bool empty() {
        return (size == 0);
    }
    @property T back() {
        if (empty()) return T.init;
        retreat(backmark);
        immutable savedmark = backmark;
        advance(backmark);
        return store[savedmark];
    }
    void popBack() {
        if (!empty()) {
            retreat(backmark);
            --size;
        }
    }
    void pushBack(T item) {
        if (size == capacity) resize();
        store[backmark] = item;
        advance(backmark);
        ++size;
    }
    @property T front() {
        if (empty()) return T.init;
        advance(frontmark);
        immutable savedmark = frontmark;
        retreat(frontmark);
        return store[savedmark];
    }
    void popFront() {
        if (!empty()) {
            advance(frontmark);
            --size;
        }
    }
    void pushFront(T item) {
        if (size == capacity) resize();
        store[frontmark] = item;
        retreat(frontmark);
        ++size;
    }
}

int main() {
    debug stdin = File("in.txt", "r");

    Deque!(string) stack;
    bool[string] set;
    char[15][200000] buf = void;
    int n;
    readf(" %s\n", &n);
    foreach(i; 0 .. n) {
        char[] pbuf = buf[i];
        readln(pbuf);
        stack.pushBack(cast(string)pbuf);
    }
    while (!stack.empty) {
        string str = stack.back;
        stack.popBack();
        if (!(str in set)) {
            write(str);
            set[str] = true;
        }
    }

    return 0;
}

import std.stdio;
import std.string;
import std.conv;

int main() {
    debug stdin = File("in.txt", "r");

    char[12][200000] buf;
    bool[string] set;
    int n;
    readf(" %s\n", &n);
    char[] pbuf;
    foreach(i; 0 .. n) {
        readln(pbuf);
        buf[i][0 .. pbuf.length] = pbuf[];
    }
    foreach_reverse(i; 0 .. n) {
        string str = to!string(buf[i]);
        while (str[$ - 1] == 255) str.length -= 1;
        if (str !in set) {
            write(str);
            set[str] = true;
        }
    }

    return 0;
}

import std.stdio;

struct Deque(T) {
private:
    size_t size = 0, capacity = 1;
    int frontmark = 0, backmark = 0;
    T[] store = [T.init];
    void resize() {
        store.length *= 3;
        foreach(i; 0 .. capacity) {
            advance(frontmark);
            store[i + capacity] = store[frontmark];
        }
        frontmark = capacity - 1;
        backmark = 2 * capacity;
        capacity *= 3;
    }
    void advance(ref int mark) {
        ++mark;
        if (mark >= capacity) mark = 0;
    }
    void retreat(ref int mark) {
        --mark;
        if (mark < 0) mark = capacity - 1;
    }
public:
    string toString() {
        import std.conv : to;
        string result = "[ " ~ to!string(store[0]);
        foreach(i; 1 .. capacity) {
            result ~= ", ";
            result ~= to!string(store[i]);
        }
        result ~= " ]";
        return result;
    }
    @property bool empty() {
        return (size == 0);
    }
    @property T back() {
        if (empty()) return T.init;
        retreat(backmark);
        immutable savedmark = backmark;
        advance(backmark);
        return store[savedmark];
    }
    void popBack() {
        if (!empty()) {
            retreat(backmark);
            --size;
        }
    }
    void pushBack(T item) {
        if (size == capacity) resize();
        store[backmark] = item;
        advance(backmark);
        ++size;
    }
    @property T front() {
        if (empty()) return T.init;
        advance(frontmark);
        immutable savedmark = frontmark;
        retreat(frontmark);
        return store[savedmark];
    }
    void popFront() {
        if (!empty()) {
            advance(frontmark);
            --size;
        }
    }
    void pushFront(T item) {
        if (size == capacity) resize();
        store[frontmark] = item;
        retreat(frontmark);
        ++size;
    }
}

int main() {
    debug stdin = File("in.txt", "r");

    Deque!string stack;
    bool[string] set;
    int n;
    readf(" %s", &n);
    foreach(i; 0 .. n) {
        string str;
        readf(" %s\n", &str);
        stack.pushBack(str);
    }
    while (!stack.empty()) {
        string str = stack.back;
        stack.popBack();
        if (!(str in set)) {
            writeln(str);
            set[str] = true;
        }
    }

    return 0;
}

import std.stdio;
import std.algorithm.sorting;
import std.range.primitives;

int main() {
    debug stdin = File("in.txt", "r");

    string[] stack;
    bool[string] set;
    int n;
    readf(" %s", &n);
    foreach(i; 0 .. n) {
        string str;
        readf(" %s\n", &str);
        stack ~= str;
    }
    while (!stack.empty) {
        string str = stack.back;
        stack.popBack();
        if (str !in set) {
            writeln(str);
            set[str] = true;
        }
    }

    return 0;
}

import std.stdio;
import std.string;
import std.conv;

int main() {
    debug stdin = File("in.txt", "r");

    char[15][200000] buf = void;
    bool[string] set;
    int n;
    readf(" %s\n", &n);
    foreach(i; 0 .. n) {
        char[] pbuf;
        readln(pbuf);
        buf[i][0 .. pbuf.length] = pbuf[];
    }
    foreach_reverse(i; 0 .. n) {
        string str = to!string(buf[i]);
        while (str[$ - 1] == 0) str.length -= 1;
        if (str !in set) {
            write(str);
            set[str] = true;
        }
    }

    return 0;
}

import std.stdio;
import std.string;
import std.conv;

int main() {
    debug stdin = File("in.txt", "r");

    char[15][200000] buf = void;
    bool[string] set;
    int n;
    readf(" %s\n", &n);
    foreach(i; 0 .. n) {
        char[] pbuf = buf[i];
        readln(pbuf);
    }
    foreach_reverse(i; 0 .. n) {
        string str = cast(string)buf[i];
        while (str[$ - 1] == 0) str.length -= 1;
        if (str !in set) {
            write(str);
            set[str] = true;
        }
    }

    return 0;
}

import std.stdio;
import std.string;

int main() {
    debug stdin = File("in.txt", "r");

    char[15][200000] buf = void;
    bool[string] set;
    int n;
    readf(" %s\n", &n);
    foreach(i; 0 .. n) {
        char[] pbuf = buf[i];
        readln(pbuf);
    }
    foreach_reverse(i; 0 .. n) {
        string str = cast(string)fromStringz(cast(char*)buf[i]);
        if (str !in set) {
            write(str);
            set[str] = true;
        }
    }

    return 0;
}

import std.stdio;
import std.string;
import std.conv;

int main() {
    debug stdin = File("in.txt", "r");

    char[15][200000] buf = void;
    bool[string] set;
    int n;
    readf(" %s\n", &n);
    foreach(i; 0 .. n) {
        char[] pbuf;
        readln(pbuf);
        buf[i][0 .. pbuf.length] = pbuf[];
    }
    foreach_reverse(i; 0 .. n) {
        string str = cast(string)buf[i];
        while (str[$ - 1] == 0) str.length -= 1;
        if (str !in set) {
            write(str);
            set[str] = true;
        }
    }

    return 0;
}


import std.conv, std.functional, std.range, std.stdio, std.string;
import std.algorithm, std.array, std.bigint, std.bitmanip, std.complex, std.container, std.math, std.mathspecial, std.numeric, std.regex, std.typecons;
import core.bitop;

class EOFException : Throwable { this() { super("EOF"); } }
string[] tokens;
string readToken() { for (; tokens.empty; ) { if (stdin.eof) { throw new EOFException; } tokens = readln.split; } auto token = tokens.front; tokens.popFront; return token; }
int readInt() { return readToken.to!int; }
long readLong() { return readToken.to!long; }
real readReal() { return readToken.to!real; }

bool chmin(T)(ref T t, in T f) { if (t > f) { t = f; return true; } else { return false; } }
bool chmax(T)(ref T t, in T f) { if (t < f) { t = f; return true; } else { return false; } }

int binarySearch(alias pred, T)(in T[] as) { int lo = -1, hi = cast(int)(as.length); for (; lo + 1 < hi; ) { const mid = (lo + hi) >> 1; (unaryFun!pred(as[mid]) ? hi : lo) = mid; } return hi; }
int lowerBound(T)(in T[] as, T val) { return as.binarySearch!(a => (a >= val)); }
int upperBound(T)(in T[] as, T val) { return as.binarySearch!(a => (a > val)); }

void main() {
  try {
    for (; ; ) {
      const numCases = readInt;
      foreach (caseId; 0 .. numCases) {
        const N = readInt;
        auto A = new int[N];
        foreach (i; 0 .. N) {
          A[i] = readInt;
        }

        int ans;
        foreach (i; 0 .. N) {
          ans += (A[i] - 1);
        }
        writeln((ans % 2 != 0) ? "errorgorn" : "maomao90");
      }
    }
  } catch (EOFException e) {
  }
}

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

void main ()
{
	auto tests = readln.strip.to !(int);
	foreach (test; 0..tests)
	{
		auto n = readln.strip.to !(int);
		auto a = readln.splitter.map !(to !(int)).array;
		writeln (["maomao90", "errorgorn"][(a.sum - n) % 2]);
	}
}


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

string FMT_F = "%.10f";

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; }
string RDR()() { return readln.chomp; }
T[] ARR(T = long)(in string str, T fix = 0) { auto r = str.split.to!(T[]); r[] += fix; return r; }
T[] RDA(T = long)(T fix = 0) { auto r = readln.chomp.split.to!(T[]); r[] += fix; return r; }
T[][] RDA2(T = long)(size_t n, T[] fix = []) { auto r = new T[][](n); foreach (i; 0..n) { r[i] = readln.chomp.split.to!(T[]); foreach (j, e; fix) r[i][j] += e; } return r; }
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; }

bool inside(T)(T x, T b, T e) { return x >= b && x < e; }
long lcm(long x, long 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 main()
{
	auto t = RD!int;
	auto ans = new long[](t);
	foreach (i; 0..t)
	{
		auto n = RD!int;
		auto s = RD!string;
		long cnt1, cnt2;
		foreach (j; 0..n)
		{
			if (s[j] == '1')
				break;
			++cnt1;
		}
		foreach_reverse (j; 0..n)
		{
			if (s[j] == '1')
				break;
			++cnt2;
		}
		if (cnt1 == n)
			ans[i] = n;
		else
			ans[i] = n*2 - min(cnt1, cnt2)*2;
	}

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

import std.algorithm;
import std.range;
import std.stdio;
import std.typecons;
import std.traits;
import std.array;
void read(T...)(ref T args)
{
  import std.traits;
  static foreach(i; 0 .. T.length)
    static if(isArray!(T[i]) && !is(T[i] == string))
      foreach(ref e; args[i])
    	read(e);
    else static if(isTuple!(T[i]))
      {
	static foreach(n; 0 .. T[i].Types.length)
	  {
	    read(args[i][n]);
	  }
      }
    else
      readf!" %s "(args[i]);
}
auto brange(alias low, alias high, alias pred, bool value)()
{
  return iota(low, high + 1).map!((a) => cast(int) pred(a)).assumeSorted.equalRange(value);
}
auto ftrue(alias low, alias high, alias pred)()
{
  return brange!(low, high, pred, false).length + low;
}
auto itup(alias k, alias F)()
{
  alias T = Parameters!F;
  foreach(i; 0 .. k)
    {
      T t;
      get(t);
      F(t);
    }
}
alias get = read;
alias w = writeln;
alias ln = long;

ln maxsum(string str)
{
  size_t i = 0;
  ln res = 0;
  while(i < str.length && str[i] == '0')
    {
      i++;
      res++;
    }
  if (i >= str.length)
    {
      return res;
    }
  assert(str[i] == '1');
  res += 2;
  res += max(i, maxsum(str[i + 1 .. $]));
  return res;
}

int main()
{
  ln t; readf!" %s "(t);
  while(t--)
    {
      import std.conv;
      string strn = readln();
      strn = strn[0 .. $ - 1];
      ln n = to!ln(strn);
      string str = readln();
      str = str[0 .. $ - 1];
      ln maxi = -1;
      ln lowi = n + 1;
      foreach(i, c; str)
	{
	  if ( c == '1' )
	    {
	      maxi = i;
	      lowi = min(lowi, i);
	    }
	}

      import std.algorithm: reverse;
      w(max(maxsum(str), maxsum(reverse(dup(str))), 2 * (maxi + 1), 2 * (n - lowi)));
    }
  return 0;
}

import std.algorithm;
import std.range;
import std.stdio;
import std.typecons;
import std.traits;
import std.array;
void read(T...)(ref T args)
{
  import std.traits;
  static foreach(i; 0 .. T.length)
    static if(isArray!(T[i]) && !is(T[i] == string))
      foreach(ref e; args[i])
    	read(e);
    else static if(isTuple!(T[i]))
      {
	static foreach(n; 0 .. T[i].Types.length)
	  {
	    read(args[i][n]);
	  }
      }
    else
      readf!" %s "(args[i]);
}
auto brange(alias low, alias high, alias pred, bool value)()
{
  return iota(low, high + 1).map!((a) => cast(int) pred(a)).assumeSorted.equalRange(value);
}
auto ftrue(alias low, alias high, alias pred)()
{
  return brange!(low, high, pred, false).length + low;
}
auto itup(alias k, alias F)()
{
  alias T = Parameters!F;
  foreach(i; 0 .. k)
    {
      T t;
      get(t);
      F(t);
    }
}
alias get = read;
alias w = writeln;
alias ln = long;

ln maxsum(string str)
{
  size_t i = 0;
  ln res = 0;
  while(i < str.length && str[i] == '0')
    {
      i++;
      res++;
    }
  if (i >= str.length)
    {
      return res;
    }
  assert(str[i] == '1');
  res += 2;
  res += max(i, maxsum(str[i + 1 .. $]));
  return res;
}

int main()
{
  ln t; readf!" %s "(t);
  while(t--)
    {
      import std.conv;
      string strn = readln();
      strn = strn[0 .. $ - 1];
      ln n = to!ln(strn);
      string str = readln();
      str = str[0 .. $ - 1];
      w(maxsum(str));
    }
  return 0;
}


/+ dub.sdl:
    name "E"
    dependency "dunkelheit" version="1.0.1"
+/

import std.stdio, std.algorithm, std.range, std.conv, std.string;
// import dkh.foundation, dkh.scanner, dkh.container.deque;

int main() {
    Scanner sc = new Scanner(stdin);
    scope(exit) assert(!sc.hasNext);

    string s;
    sc.read(s);

    string l, r;
    while (s.length) {
        if (s.length == 1) {
            l ~= s;
            break;
        }
        if (s.front == s.back) {
            l ~= s.front;
            r ~= s.back;
            s = s[1..$-1];
            continue;
        }
        if (s[1] == s.back) {
            s = s[1..$];
            continue;
        }
        if (s.front == s[$-1]) {
            s = s[0..$-1];
            continue;
        }
        s = s[1..$-1];
        continue;
    }
    writeln(l ~ r.dup.reverse);
    return 0;
}
/* IMPORT /home/yosupo/Programs/dunkelheit/source/dkh/foundation.d */

// module dkh.foundation;

static if (__VERSION__ <= 2070) {
    /*
    Copied by https://github.com/dlang/phobos/blob/master/std/algorithm/iteration.d
    Copyright: Andrei Alexandrescu 2008-.
    License: $(HTTP boost.org/LICENSE_1_0.txt, Boost License 1.0).
    */
    template fold(fun...) if (fun.length >= 1) {
        auto fold(R, S...)(R r, S seed) {
            import std.algorithm : reduce;
            static if (S.length < 2) {
                return reduce!fun(seed, r);
            } else {
                import std.typecons : tuple;
                return reduce!fun(tuple(seed), r);
            }
        }
    }

}
/* IMPORT /home/yosupo/Programs/dunkelheit/source/dkh/container/deque.d */
// module dkh.container.deque;

struct DequePayload(T) {
    import core.exception : RangeError;

    private T* _data;
    private uint start, len, cap;

    @property bool empty() const { return len == 0; }
    @property size_t length() const { return len; }
    alias opDollar = length;

    ref inout(T) opIndex(size_t i) inout {
        version(assert) if (len <= i) throw new RangeError();
        if (start + i < cap) return _data[start + i];
        else return _data[start + i - cap];
    }
    ref inout(T) front() inout { return this[0]; }
    ref inout(T) back() inout { return this[$-1]; }

    void reserve(size_t newCap) {
        import core.memory : GC;
        import std.algorithm : max;
        import std.conv : to;
        if (newCap <= cap) return;
        T* newData = cast(T*)GC.malloc(newCap * T.sizeof);
        foreach (i; 0..length) {
            newData[i] = this[i];
        }
        _data = newData; start = 0; cap = newCap.to!uint;
    }
    void clear() {
        start = len = 0;
    }
    import std.algorithm : max;
    void insertFront(T item) {
        if (len == cap) reserve(max(cap * 2, 4));
        if (start == 0) start += cap;
        start--; len++;
        this[0] = item;
    }
    void insertBack(T item) {
        if (len == cap) reserve(max(cap * 2, 4));
        len++;
        this[len-1] = item;
    }
    void removeFront() {
        assert(!empty, "Deque.removeFront: Deque is empty");
        start++; len--;
        if (start == cap) start = 0;
    }
    void removeBack() {
        assert(!empty, "Deque.removeBack: Deque is empty");
        len--;
    }
}

struct Deque(T, bool mayNull = true) {
    import core.exception : RangeError;
    import std.range : ElementType, isInputRange;
    import std.traits : isImplicitlyConvertible;

    alias Payload = DequePayload!T;
    Payload* _p;

    static if (!mayNull) @disable this();

    this(U)(U[] values...) if (isImplicitlyConvertible!(U, T)) {
        _p = new Payload();
        foreach (v; values) {
            insertBack(v);
        }
    }

    this(Range)(Range r)
    if (isInputRange!Range &&
    isImplicitlyConvertible!(ElementType!Range, T) &&
    !is(Range == T[])) {
        _p = new Payload();
        foreach (v; r) {
            insertBack(v);
        }
    }
    private this(Payload* p) { _p = p; }
    static Deque make() { return Deque(new Payload()); }

    private bool havePayload() const { return (!mayNull || _p); }
    @property bool empty() const { return (!havePayload || _p.empty); }
    @property size_t length() const { return (havePayload ? _p.length : 0); }
    alias opDollar = length;

    ref inout(T) opIndex(size_t i) inout {
        assert(!empty, "Deque.opIndex: Deque is empty");
        return (*_p)[i];
    }
    ref inout(T) front() inout { return this[0]; }
    ref inout(T) back() inout { return this[$-1]; }

    void clear() { if (_p) _p.clear(); }

    void insertFront(T item) {
        if (mayNull && !_p) _p = new Payload();
        _p.insertFront(item);
    }
    void insertBack(T item) {
        if (mayNull && !_p) _p = new Payload();
        _p.insertBack(item);
    }
    alias opOpAssign(string op : "~") = insertBack;
    alias stableInsertBack = insertBack;

    void removeFront() {
        assert(!mayNull || _p, "Deque.removeFront: Deque is empty");
        _p.removeFront();
    }
    void removeBack() {
        assert(!mayNull || _p, "Deque.removeBack: Deque is empty");
        _p.removeBack();
    }
    alias stableRemoveBack = removeBack;

    alias Range = RangeT!(DequePayload!T);
    alias ConstRange = RangeT!(const DequePayload!T);
    alias ImmutableRange = RangeT!(immutable DequePayload!T);

    size_t[2] opSlice(size_t dim : 0)(size_t start, size_t end) const {
        assert(start <= end && end <= length);
        return [start, end];
    }
    Range opIndex(size_t[2] rng) { return Range(_p, rng[0], rng[1]); }
    ConstRange opIndex(size_t[2] rng) const { return ConstRange(_p, rng[0], rng[1]); }
    ImmutableRange opIndex(size_t[2] rng) immutable { return ImmutableRange(_p, rng[0], rng[1]); }
    auto opIndex() inout { return this[0..$]; }

    static struct RangeT(QualifiedPayload) {
        alias A = QualifiedPayload;
        import std.traits : CopyTypeQualifiers;
        alias E = CopyTypeQualifiers!(A, T);
        A *p;
        size_t l, r;

        @property bool empty() const { return r <= l; }
        @property size_t length() const { return r - l; }
        alias opDollar = length;

        @property auto save() { return this; }

        ref inout(E) opIndex(size_t i) inout {
            version(assert) if (empty) throw new RangeError();
            return (*p)[l+i];
        }
        @property ref inout(E) front() inout { return this[0]; }
        @property ref inout(E) back() inout { return this[$-1]; }

        void popFront() {
            version(assert) if (empty) throw new RangeError();
            l++;
        }
        void popBack() {
            version(assert) if (empty) throw new RangeError();
            r--;
        }

        size_t[2] opSlice(size_t dim : 0)(size_t start, size_t end) const {
            assert(start <= end && end <= length);
            return [start, end];
        }
        auto opIndex(size_t[2] rng) { return RangeT(p, l+rng[0], l+rng[1]); }
        auto opIndex(size_t[2] rng) const { return RangeT!(const A)(p, l+rng[0], l+rng[1]); }
        auto opIndex(size_t[2] rng) immutable { return RangeT!(immutable A)(p, l+rng[0], l+rng[1]); }
        auto opIndex() inout { return this[0..$]; }
    }
}

/* IMPORT /home/yosupo/Programs/dunkelheit/source/dkh/container/stackpayload.d */
// module dkh.container.stackpayload;

struct StackPayload(T, size_t MINCAP = 4) if (MINCAP >= 1) {
    import core.exception : RangeError;

    private T* _data;
    private uint len, cap;

    @property bool empty() const { return len == 0; }
    @property size_t length() const { return len; }
    alias opDollar = length;

    inout(T)[] data() inout { return (_data) ? _data[0..len] : null; }

    ref inout(T) opIndex(size_t i) inout {
        version(assert) if (len <= i) throw new RangeError();
        return _data[i];
    }
    ref inout(T) front() inout { return this[0]; }
    ref inout(T) back() inout { return this[$-1]; }

    void reserve(size_t newCap) {
        import core.memory : GC;
        import core.stdc.string : memcpy;
        import std.conv : to;
        if (newCap <= cap) return;
        void* newData = GC.malloc(newCap * T.sizeof);
        cap = newCap.to!uint;
        if (len) memcpy(newData, _data, len * T.sizeof);
        _data = cast(T*)(newData);
    }
    void free() {
        import core.memory : GC;
        GC.free(_data);
    }

    void clear() {
        len = 0;
    }

    void insertBack(T item) {
        import std.algorithm : max;
        if (len == cap) reserve(max(cap * 2, MINCAP));
        _data[len++] = item;
    }
    alias opOpAssign(string op : "~") = insertBack;
    void removeBack() {
        assert(!empty, "StackPayload.removeBack: Stack is empty");
        len--;
    }
}

/* IMPORT /home/yosupo/Programs/dunkelheit/source/dkh/scanner.d */
// module dkh.scanner;

// import dkh.container.stackpayload;

class Scanner {
    import std.stdio : File;
    import std.conv : to;
    import std.range : front, popFront, array, ElementType;
    import std.array : split;
    import std.traits : isSomeChar, isStaticArray, isArray;
    import std.algorithm : map;
    private File f;

    this(File f) {
        this.f = f;
    }
    private char[512] lineBuf;
    private char[] line;
    private bool succW() {
        import std.range.primitives : empty, front, popFront;
        import std.ascii : isWhite;
        while (!line.empty && line.front.isWhite) {
            line.popFront;
        }
        return !line.empty;
    }
    private bool succ() {
        import std.range.primitives : empty, front, popFront;
        import std.ascii : isWhite;
        while (true) {
            while (!line.empty && line.front.isWhite) {
                line.popFront;
            }
            if (!line.empty) break;
            line = lineBuf[];
            f.readln(line);
            if (!line.length) return false;
        }
        return true;
    }

    private bool readSingle(T)(ref T x) {
        import std.algorithm : findSplitBefore;
        import std.string : strip;
        import std.conv : parse;
        if (!succ()) return false;
        static if (isArray!T) {
            alias E = ElementType!T;
            static if (isSomeChar!E) {

                auto r = line.findSplitBefore(" ");
                x = r[0].strip.dup;
                line = r[1];
            } else static if (isStaticArray!T) {
                foreach (i; 0..T.length) {
                    assert(succW());
                    x[i] = line.parse!E;
                }
            } else {
                StackPayload!E buf;
                while (succW()) {
                    buf ~= line.parse!E;
                }
                x = buf.data;
            }
        } else {
            x = line.parse!T;
        }
        return true;
    }

    int unsafeRead(T, Args...)(ref T x, auto ref Args args) {
        if (!readSingle(x)) return 0;
        static if (args.length == 0) {
            return 1;
        } else {
            return 1 + read(args);
        }
    }

    void read(Args...)(auto ref Args args) {
        import std.exception : enforce;
        static if (args.length != 0) {
            enforce(readSingle(args[0]));
            read(args[1..$]);
        }
    }

    bool hasNext() {
        return succ();
    }
}

/*
This source code generated by dunkelheit and include dunkelheit's source code.
dunkelheit's Copyright: Copyright (c) 2016- Kohei Morita. (https://github.com/yosupo06/dunkelheit)
dunkelheit's License: MIT License(https://github.com/yosupo06/dunkelheit/blob/master/LICENSE.txt)
*/

import core.bitop, std.bitmanip;
import core.checkedint;
import std.algorithm, std.functional;
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.typecons;

void main()
{
    auto s = readln.chomp;
    if (s.length < 4) {
        writeln(s[0]);
        return;
    }

    dchar[] ans;
    foreach (i; (s.length/2 - 1).iota.stride(2)) {
        dchar c = 'a';
        while ((s[i] != c && s[i+1] != c)
               || (s[s.length - 1 - i] != c && s[s.length - 1 - i - 1] != c)) {
            c += 1;
        }
        ans ~= c;
    }

    auto tail = ans.dup;
    tail.reverse();

    if (s.length % 4 != 0) { ans ~= s[s.length/2]; }

    ans = ans.chain(tail).array;

    ans.writeln;
}

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

class EOFException : Throwable { this() { super("EOF"); } }
string[] tokens;
string readToken() { for (; tokens.empty; ) { if (stdin.eof) { throw new EOFException; } tokens = readln.split; } auto token = tokens.front; tokens.popFront; return token; }
int readInt() { return readToken.to!int; }
long readLong() { return readToken.to!long; }
real readReal() { return readToken.to!real; }

bool chmin(T)(ref T t, in T f) { if (t > f) { t = f; return true; } else { return false; } }
bool chmax(T)(ref T t, in T f) { if (t < f) { t = f; return true; } else { return false; } }

int binarySearch(alias pred, T)(in T[] as) { int lo = -1, hi = cast(int)(as.length); for (; lo + 1 < hi; ) { const mid = (lo + hi) >> 1; (unaryFun!pred(as[mid]) ? hi : lo) = mid; } return hi; }
int lowerBound(T)(in T[] as, T val) { return as.binarySearch!(a => (a >= val)); }
int upperBound(T)(in T[] as, T val) { return as.binarySearch!(a => (a > val)); }

string S;
int N;

void main() {
  try {
    for (; ; ) {
      S = readToken();
      N = cast(int)(S.length);

      char[] ansL, ansM;
      for (int l = 0, r = N; l < r; ) {
        if (l + 4 <= r) {
          bool found;
          foreach (d; "abc") {
            if ((S[l] == d || S[l + 1] == d) && (S[r - 2] == d || S[r - 1] == d)) {
              found = true;
              ansL ~= d;
              break;
            }
          }
          assert(found);
          l += 2;
          r -= 2;
        } else {
          ansM ~= S[l];
          break;
        }
      }
      write(ansL.to!string);
      write(ansM.to!string);
      ansL.reverse;
      write(ansL.to!string);
      writeln();
    }
  } catch (EOFException e) {
  }
}

/+ dub.sdl:
    name "E"
    dependency "dunkelheit" version="1.0.1"
+/

import std.stdio, std.algorithm, std.range, std.conv, std.string;
// import dkh.foundation, dkh.scanner, dkh.container.deque;

int main() {
    Scanner sc = new Scanner(stdin);
    scope(exit) assert(!sc.hasNext);

    string s;
    sc.read(s);

    string l, r;
    while (s.length) {
        if (s.length == 1) {
            l ~= s;
            break;
        }
        if (s.front == s.back) {
            l ~= s.front;
            r ~= s.back;
            s = s[1..$-1];
            continue;
        }
        if (s[1] == s.back) {
            s = s[1..$];
            continue;
        }
        if (s.front == s[$-1]) {
            s = s[0..$-1];
            continue;
        }
        s = s[1..$-1];
        continue;
    }
    r.dup.reverse;
    writeln(l ~ r);
    return 0;
}
/* IMPORT /home/yosupo/Programs/dunkelheit/source/dkh/foundation.d */

// module dkh.foundation;

static if (__VERSION__ <= 2070) {
    /*
    Copied by https://github.com/dlang/phobos/blob/master/std/algorithm/iteration.d
    Copyright: Andrei Alexandrescu 2008-.
    License: $(HTTP boost.org/LICENSE_1_0.txt, Boost License 1.0).
    */
    template fold(fun...) if (fun.length >= 1) {
        auto fold(R, S...)(R r, S seed) {
            import std.algorithm : reduce;
            static if (S.length < 2) {
                return reduce!fun(seed, r);
            } else {
                import std.typecons : tuple;
                return reduce!fun(tuple(seed), r);
            }
        }
    }

}
/* IMPORT /home/yosupo/Programs/dunkelheit/source/dkh/container/deque.d */
// module dkh.container.deque;

struct DequePayload(T) {
    import core.exception : RangeError;

    private T* _data;
    private uint start, len, cap;

    @property bool empty() const { return len == 0; }
    @property size_t length() const { return len; }
    alias opDollar = length;

    ref inout(T) opIndex(size_t i) inout {
        version(assert) if (len <= i) throw new RangeError();
        if (start + i < cap) return _data[start + i];
        else return _data[start + i - cap];
    }
    ref inout(T) front() inout { return this[0]; }
    ref inout(T) back() inout { return this[$-1]; }

    void reserve(size_t newCap) {
        import core.memory : GC;
        import std.algorithm : max;
        import std.conv : to;
        if (newCap <= cap) return;
        T* newData = cast(T*)GC.malloc(newCap * T.sizeof);
        foreach (i; 0..length) {
            newData[i] = this[i];
        }
        _data = newData; start = 0; cap = newCap.to!uint;
    }
    void clear() {
        start = len = 0;
    }
    import std.algorithm : max;
    void insertFront(T item) {
        if (len == cap) reserve(max(cap * 2, 4));
        if (start == 0) start += cap;
        start--; len++;
        this[0] = item;
    }
    void insertBack(T item) {
        if (len == cap) reserve(max(cap * 2, 4));
        len++;
        this[len-1] = item;
    }
    void removeFront() {
        assert(!empty, "Deque.removeFront: Deque is empty");
        start++; len--;
        if (start == cap) start = 0;
    }
    void removeBack() {
        assert(!empty, "Deque.removeBack: Deque is empty");
        len--;
    }
}

struct Deque(T, bool mayNull = true) {
    import core.exception : RangeError;
    import std.range : ElementType, isInputRange;
    import std.traits : isImplicitlyConvertible;

    alias Payload = DequePayload!T;
    Payload* _p;

    static if (!mayNull) @disable this();

    this(U)(U[] values...) if (isImplicitlyConvertible!(U, T)) {
        _p = new Payload();
        foreach (v; values) {
            insertBack(v);
        }
    }

    this(Range)(Range r)
    if (isInputRange!Range &&
    isImplicitlyConvertible!(ElementType!Range, T) &&
    !is(Range == T[])) {
        _p = new Payload();
        foreach (v; r) {
            insertBack(v);
        }
    }
    private this(Payload* p) { _p = p; }
    static Deque make() { return Deque(new Payload()); }

    private bool havePayload() const { return (!mayNull || _p); }
    @property bool empty() const { return (!havePayload || _p.empty); }
    @property size_t length() const { return (havePayload ? _p.length : 0); }
    alias opDollar = length;

    ref inout(T) opIndex(size_t i) inout {
        assert(!empty, "Deque.opIndex: Deque is empty");
        return (*_p)[i];
    }
    ref inout(T) front() inout { return this[0]; }
    ref inout(T) back() inout { return this[$-1]; }

    void clear() { if (_p) _p.clear(); }

    void insertFront(T item) {
        if (mayNull && !_p) _p = new Payload();
        _p.insertFront(item);
    }
    void insertBack(T item) {
        if (mayNull && !_p) _p = new Payload();
        _p.insertBack(item);
    }
    alias opOpAssign(string op : "~") = insertBack;
    alias stableInsertBack = insertBack;

    void removeFront() {
        assert(!mayNull || _p, "Deque.removeFront: Deque is empty");
        _p.removeFront();
    }
    void removeBack() {
        assert(!mayNull || _p, "Deque.removeBack: Deque is empty");
        _p.removeBack();
    }
    alias stableRemoveBack = removeBack;

    alias Range = RangeT!(DequePayload!T);
    alias ConstRange = RangeT!(const DequePayload!T);
    alias ImmutableRange = RangeT!(immutable DequePayload!T);

    size_t[2] opSlice(size_t dim : 0)(size_t start, size_t end) const {
        assert(start <= end && end <= length);
        return [start, end];
    }
    Range opIndex(size_t[2] rng) { return Range(_p, rng[0], rng[1]); }
    ConstRange opIndex(size_t[2] rng) const { return ConstRange(_p, rng[0], rng[1]); }
    ImmutableRange opIndex(size_t[2] rng) immutable { return ImmutableRange(_p, rng[0], rng[1]); }
    auto opIndex() inout { return this[0..$]; }

    static struct RangeT(QualifiedPayload) {
        alias A = QualifiedPayload;
        import std.traits : CopyTypeQualifiers;
        alias E = CopyTypeQualifiers!(A, T);
        A *p;
        size_t l, r;

        @property bool empty() const { return r <= l; }
        @property size_t length() const { return r - l; }
        alias opDollar = length;

        @property auto save() { return this; }

        ref inout(E) opIndex(size_t i) inout {
            version(assert) if (empty) throw new RangeError();
            return (*p)[l+i];
        }
        @property ref inout(E) front() inout { return this[0]; }
        @property ref inout(E) back() inout { return this[$-1]; }

        void popFront() {
            version(assert) if (empty) throw new RangeError();
            l++;
        }
        void popBack() {
            version(assert) if (empty) throw new RangeError();
            r--;
        }

        size_t[2] opSlice(size_t dim : 0)(size_t start, size_t end) const {
            assert(start <= end && end <= length);
            return [start, end];
        }
        auto opIndex(size_t[2] rng) { return RangeT(p, l+rng[0], l+rng[1]); }
        auto opIndex(size_t[2] rng) const { return RangeT!(const A)(p, l+rng[0], l+rng[1]); }
        auto opIndex(size_t[2] rng) immutable { return RangeT!(immutable A)(p, l+rng[0], l+rng[1]); }
        auto opIndex() inout { return this[0..$]; }
    }
}

/* IMPORT /home/yosupo/Programs/dunkelheit/source/dkh/container/stackpayload.d */
// module dkh.container.stackpayload;

struct StackPayload(T, size_t MINCAP = 4) if (MINCAP >= 1) {
    import core.exception : RangeError;

    private T* _data;
    private uint len, cap;

    @property bool empty() const { return len == 0; }
    @property size_t length() const { return len; }
    alias opDollar = length;

    inout(T)[] data() inout { return (_data) ? _data[0..len] : null; }

    ref inout(T) opIndex(size_t i) inout {
        version(assert) if (len <= i) throw new RangeError();
        return _data[i];
    }
    ref inout(T) front() inout { return this[0]; }
    ref inout(T) back() inout { return this[$-1]; }

    void reserve(size_t newCap) {
        import core.memory : GC;
        import core.stdc.string : memcpy;
        import std.conv : to;
        if (newCap <= cap) return;
        void* newData = GC.malloc(newCap * T.sizeof);
        cap = newCap.to!uint;
        if (len) memcpy(newData, _data, len * T.sizeof);
        _data = cast(T*)(newData);
    }
    void free() {
        import core.memory : GC;
        GC.free(_data);
    }

    void clear() {
        len = 0;
    }

    void insertBack(T item) {
        import std.algorithm : max;
        if (len == cap) reserve(max(cap * 2, MINCAP));
        _data[len++] = item;
    }
    alias opOpAssign(string op : "~") = insertBack;
    void removeBack() {
        assert(!empty, "StackPayload.removeBack: Stack is empty");
        len--;
    }
}

/* IMPORT /home/yosupo/Programs/dunkelheit/source/dkh/scanner.d */
// module dkh.scanner;

// import dkh.container.stackpayload;

class Scanner {
    import std.stdio : File;
    import std.conv : to;
    import std.range : front, popFront, array, ElementType;
    import std.array : split;
    import std.traits : isSomeChar, isStaticArray, isArray;
    import std.algorithm : map;
    private File f;

    this(File f) {
        this.f = f;
    }
    private char[512] lineBuf;
    private char[] line;
    private bool succW() {
        import std.range.primitives : empty, front, popFront;
        import std.ascii : isWhite;
        while (!line.empty && line.front.isWhite) {
            line.popFront;
        }
        return !line.empty;
    }
    private bool succ() {
        import std.range.primitives : empty, front, popFront;
        import std.ascii : isWhite;
        while (true) {
            while (!line.empty && line.front.isWhite) {
                line.popFront;
            }
            if (!line.empty) break;
            line = lineBuf[];
            f.readln(line);
            if (!line.length) return false;
        }
        return true;
    }

    private bool readSingle(T)(ref T x) {
        import std.algorithm : findSplitBefore;
        import std.string : strip;
        import std.conv : parse;
        if (!succ()) return false;
        static if (isArray!T) {
            alias E = ElementType!T;
            static if (isSomeChar!E) {

                auto r = line.findSplitBefore(" ");
                x = r[0].strip.dup;
                line = r[1];
            } else static if (isStaticArray!T) {
                foreach (i; 0..T.length) {
                    assert(succW());
                    x[i] = line.parse!E;
                }
            } else {
                StackPayload!E buf;
                while (succW()) {
                    buf ~= line.parse!E;
                }
                x = buf.data;
            }
        } else {
            x = line.parse!T;
        }
        return true;
    }

    int unsafeRead(T, Args...)(ref T x, auto ref Args args) {
        if (!readSingle(x)) return 0;
        static if (args.length == 0) {
            return 1;
        } else {
            return 1 + read(args);
        }
    }

    void read(Args...)(auto ref Args args) {
        import std.exception : enforce;
        static if (args.length != 0) {
            enforce(readSingle(args[0]));
            read(args[1..$]);
        }
    }

    bool hasNext() {
        return succ();
    }
}

/*
This source code generated by dunkelheit and include dunkelheit's source code.
dunkelheit's Copyright: Copyright (c) 2016- Kohei Morita. (https://github.com/yosupo06/dunkelheit)
dunkelheit's License: MIT License(https://github.com/yosupo06/dunkelheit/blob/master/LICENSE.txt)
*/

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

class EOFException : Throwable { this() { super("EOF"); } }
string[] tokens;
string readToken() { for (; tokens.empty; ) { if (stdin.eof) { throw new EOFException; } tokens = readln.split; } auto token = tokens.front; tokens.popFront; return token; }
int readInt() { return readToken.to!int; }
long readLong() { return readToken.to!long; }
real readReal() { return readToken.to!real; }

bool chmin(T)(ref T t, in T f) { if (t > f) { t = f; return true; } else { return false; } }
bool chmax(T)(ref T t, in T f) { if (t < f) { t = f; return true; } else { return false; } }

int binarySearch(alias pred, T)(in T[] as) { int lo = -1, hi = cast(int)(as.length); for (; lo + 1 < hi; ) { const mid = (lo + hi) >> 1; (unaryFun!pred(as[mid]) ? hi : lo) = mid; } return hi; }
int lowerBound(T)(in T[] as, T val) { return as.binarySearch!(a => (a >= val)); }
int upperBound(T)(in T[] as, T val) { return as.binarySearch!(a => (a > val)); }

string S;
int N;

void main() {
  try {
    for (; ; ) {
      S = readToken();
      N = cast(int)(S.length);

      string ans;
      foreach (d; "abc") {
        string t;
        foreach (e; S) {
          if (e != d) {
            t ~= e;
          }
        }
        t = t.uniq.array.to!string;
        if (!t.empty) {
          if (t.length % 2 == 0) {
            t = t[0 .. $ - 1];
          }
          if (ans.length < t.length) {
            ans = t;
          }
        }
      }
      writeln(ans);
    }
  } catch (EOFException e) {
  }
}

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

class EOFException : Throwable { this() { super("EOF"); } }
string[] tokens;
string readToken() { for (; tokens.empty; ) { if (stdin.eof) { throw new EOFException; } tokens = readln.split; } auto token = tokens.front; tokens.popFront; return token; }
int readInt() { return readToken.to!int; }
long readLong() { return readToken.to!long; }
real readReal() { return readToken.to!real; }

bool chmin(T)(ref T t, in T f) { if (t > f) { t = f; return true; } else { return false; } }
bool chmax(T)(ref T t, in T f) { if (t < f) { t = f; return true; } else { return false; } }

int binarySearch(alias pred, T)(in T[] as) { int lo = -1, hi = cast(int)(as.length); for (; lo + 1 < hi; ) { const mid = (lo + hi) >> 1; (unaryFun!pred(as[mid]) ? hi : lo) = mid; } return hi; }
int lowerBound(T)(in T[] as, T val) { return as.binarySearch!(a => (a >= val)); }
int upperBound(T)(in T[] as, T val) { return as.binarySearch!(a => (a > val)); }

string S;
int N;

void main() {
  try {
    for (; ; ) {
      S = readToken();
      N = cast(int)(S.length);

      char[] ansL, ansM;
      for (int l = 0, r = N; l <= r; ) {
        if (l + 4 <= r) {
          bool found;
          foreach (d; "abc") {
            if ((S[l] == d || S[l + 1] == d) && (S[r - 2] == d || S[r - 1] == d)) {
              found = true;
              ansL ~= d;
              break;
            }
          }
if(!found)writeln(l," ",r);
          assert(found);
          l += 2;
          r -= 2;
        } else {
          ansM ~= S[l];
          break;
        }
      }
      write(ansL.to!string);
      write(ansM.to!string);
      ansL.reverse;
      write(ansL.to!string);
      writeln();
    }
  } catch (EOFException e) {
  }
}


import std.stdio;
import std.uni;
import std.conv;
import std.container;
import std.functional;
import std.algorithm;
import std.array;
import std.typecons;

const KB = 1024;
const MB = 1024 * 1024;

void main(string[] args)
{
  inputFile = stdin;
  debug inputFile = File(args[1]);
  auto nt = next!int;
  foreach(t; 0 .. nt)
    {
      auto n = next!int;
      auto ss = next!string(n);
      int[char] cnt;
      foreach(s; ss)
        foreach(c; s)
          cnt.require(c, 0)++;
      if (cnt.byValue.all!(c => c % n == 0))
        writeln("YES");
      else
        writeln("NO");
    }
}

// INPUT

enum InputStyle
  {
    byChunk, byLine
  };
enum inputStyle = InputStyle.byChunk;

File inputFile;
string popWord();
static if (inputStyle == InputStyle.byChunk)
  {
    const chunkSize = MB;
    const wordSize = 4096;
    char[chunkSize] chunkBuff;
    char[] currChunk;
    void renewChunk()
    {
      if (inputFile.eof)
        currChunk = null;
      else
        currChunk = inputFile.rawRead(chunkBuff);
    }
    char[wordSize] wordBuff;
    char[] word;
    string popWord()
    {
      if (currChunk.length == 0)
        renewChunk;
      assert(currChunk.length > 0);
      while (currChunk[0].isWhite)
        {

          currChunk = currChunk[1 .. $];
          if (currChunk.length == 0)
            renewChunk;
        }
      word = wordBuff[0 .. 0];
      while (!currChunk[0].isWhite)
        {
          word.length++;
          word[$ - 1] = currChunk[0];
          currChunk = currChunk[1 .. $];
          if (currChunk.length == 0)
            {
              renewChunk;
              if (currChunk.length == 0)
                return cast(string) word;
            }
        }
      return cast(string) word;
    }
  }
 else
   {
     DList!string _words;
     string popWord()
     {
       while (_words.empty)
         {
           foreach(w; inputFile.readln.split)
             {
               _words.insertBack(w);
             }
         }
       auto word = _words.front;
       _words.removeFront;
       return word;
     }
   }
T next(T)()
{
  return to!T(popWord);
}
auto next(T, S...)(S s)
{
  static if (S.length == 0)
    {
      return to!T(popWord);
    }
  else
    {
      auto res = new typeof(next!T(s[1 .. $]))[](s[0]);
      foreach(ref elem; res)
        elem = next!T(s[1 .. $]);
      return res;
    }
}

import std.stdio;
import std.string;

T read(T)()
{
    T t;
    readf(" %s", &t);
    return t;
}

int main(string[] args)
{
    int T = read!int;

    foreach (t; 0..T)
    {
	int n = read!int;
	readln;
	int[char] inc;
	//string[] arr;
	foreach (i; 0..n)
	{
	    auto s = readln.strip;
	    foreach (c; s)
	    {
		int *p = c in inc;
		if (p !is null)
		    inc[c]++;
		else
		    inc[c] = 1;
	    }
	}

	bool success = true;
	foreach (i, k; inc)
	{
	    if (k % n != 0)
	    {
		success = false;
		writeln("NO");
		break;
	    }
	}
	if (success)
	    writeln("YES");
	//writeln (inc);
    }

    return 0;
}

// Vicfred
// https://codeforces.com/contest/1397/problem/A
// simulation, math
import std.conv;
import std.stdio;
import std.string;

void main() {
    long t = readln.chomp.to!long;

    while(t--) {
        long[char] counter;

        long n = readln.chomp.to!long;
        string[] s;
        foreach(_; 0..n)
            s ~= readln.strip;
        foreach(str; s) {
            foreach(ch; str) {
                if(ch in counter)
                    counter[ch] += 1;
                else
                    counter[ch] = 1;
            }
        }

        string ans = "YES";
        foreach(value; counter.values) {
            if(value%n != 0) {
                ans = "NO";
                break;
            }
        }
        ans.writeln;
    }

}

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

void main ()
{
	auto tests = readln.strip.to !(int);
	foreach (test; 0..tests)
	{
		auto n = readln.strip.to !(int);
		int [char] d;
		foreach (i; 0..n)
		{
			foreach (char c; readln.strip)
			{
				d[c] += 1;
			}
		}
		writeln (d.byValue.all !(x => x % n == 0) ? "YES" : "NO");
	}
}

import std.stdio;
import std.uni;
import std.conv;
import std.container;
import std.functional;
import std.algorithm;
import std.array;
import std.typecons;

void main(string[] args)
{
  inputFile = stdin;
  debug inputFile = File(args[1]);
  auto nt = next!int;
  foreach(t; 0 .. nt)
    {
      auto n = next!int;
      auto ss = next!string(n);
      int[char] cnt;
      foreach(s; ss)
        foreach(c; s)
          cnt.require(c, 0)++;
      if (cnt.byValue.all!(c => c % n == 0))
        writeln("YES");
      else
        writeln("NO");
    }
}

// INPUT

enum InputStyle
  {
    byChunk, byLine
  };
enum inputStyle = InputStyle.byChunk;

File inputFile;
string popWord();
static if (inputStyle == InputStyle.byChunk)
  {
    const chunkSize = 4096;
    const wordSize = 4096;
    char[chunkSize] chunkBuff;
    char[] currChunk;
    void renewChunk()
    {
      if (inputFile.eof)
        currChunk = null;
      else
        currChunk = inputFile.rawRead(chunkBuff);
    }
    char[wordSize] wordBuff;
    char[] word;
    string popWord()
    {
      if (currChunk.length == 0)
        renewChunk;
      assert(currChunk.length > 0);
      while (currChunk[0].isWhite)
        {

          currChunk = currChunk[1 .. $];
          if (currChunk.length == 0)
            renewChunk;
        }
      word = wordBuff[0 .. 0];
      while (!currChunk[0].isWhite)
        {
          word.length++;
          word[$ - 1] = currChunk[0];
          currChunk = currChunk[1 .. $];
          if (currChunk.length == 0)
            {
              renewChunk;
              if (currChunk.length == 0)
                return cast(string) word;
            }
        }
      return cast(string) word;
    }
  }
 else
   {
     DList!string _words;
     string popWord()
     {
       while (_words.empty)
         {
           foreach(w; inputFile.readln.split)
             {
               _words.insertBack(w);
             }
         }
       auto word = _words.front;
       _words.removeFront;
       return word;
     }
   }
T next(T)()
{
  return to!T(popWord);
}
auto next(T, S...)(S s)
{
  static if (S.length == 0)
    {
      return to!T(popWord);
    }
  else
    {
      auto res = new typeof(next!T(s[1 .. $]))[](s[0]);
      foreach(ref elem; res)
        elem = next!T(s[1 .. $]);
      return res;
    }
}

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(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 modd(T)(ref T x, T y) { y.modpow(mod - 2); x.modm(y); }

void main()
{
	auto t = RD!int;
	auto ans = new bool[](t);
	foreach (ti; 0..t)
	{
		auto n = RD!int;
		auto cnt = new long[](26);
		foreach (i; 0..n)
		{
			auto s = RD!string;
			foreach (c; s)
			{
				auto num = c - 'a';
				++cnt[num];
			}
		}

		ans[ti] = true;
		foreach (i; 0..26)
		{
			if (cnt[i] % n)
			{
				ans[ti] = false;
				break;
			}
		}
	}

	foreach (e; ans)
		writeln(e ? "YES" : "NO");
	stdout.flush;
	debug readln;
}


//prewritten code: https://github.com/antma/algo
import std.algorithm;
import std.array;
import std.conv;
import std.range;
import std.stdio;
import std.string;

int[] sieveArray (int n) {
  auto a = iota (0, n + 1).map! (i => (i & 1) ? i : 2).array;
  for (int p = 3; p * p <= n; p += 2) {
    if (a[p] == p) {
      foreach (o; iota (p * p, n + 1, 2 * p)) {
        if (a[o] == o) {
          a[o] = p;
        }
      }
    }
  }
  return a;
}

void main() {
  int n;
  readf (" %d", &n);
  auto s = sieveArray (n);
  int[int] h = [ 2 : 1 ];
  int idx = 1;
  foreach (i; iota (3, n + 1, 2)) {
    if (s[i] == i) {
      h[i] = ++idx;
    }
  }
  foreach (i; 2 .. n + 1) {
    s[i] = h[s[i]];
  }
  writefln ("%(%s %)", s[2 .. $]);
}

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, core.stdc.string;

immutable long MOD = 10^^9 + 7;
immutable long INF = 1L << 59;

void main() {
    auto N = readln.chomp.to!int;
    auto ans = new int[](N+1);

    int tmp = 1;
    foreach (i; 2..N+1) {
        if (ans[i] != 0) continue;
        for (int j = i; j <= N; j += i) {
            ans[j] = tmp;
        }
        tmp += 1;
    }

    ans[2..$].map!(to!string).join(" ").writeln;
}

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

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

    auto ans = new int[] (n+1);
    int cnt = 1;
    for (int i = 2; i <= n; ++i) {
        bool made = false;
        for (int j = i; j <= n; j += i) {
            if (ans[j] == 0) {
                ans[j] = cnt;
                made = true;
            }
        }

        if (made) { cnt += 1; }
    }

    ans[2 .. n+1].writefln!"%(%s %)";
}

//prewritten code: https://github.com/antma/algo
import std.algorithm;
import std.array;
import std.conv;
import std.math;
import std.range;
import std.stdio;
import std.string;
import std.traits;
import std.bitmanip;

class PrimeTable {
  private:
  BitArray a;
  size_t n;
  public:
  bool isPrime (size_t i) const pure nothrow @nogc {
    return (i & 1) ? !a[i>>>1] : (i == 2);
  }
  int[] primes () const pure {
    int[] p;
    if (n > 2) {
      p ~= 2;
      p ~= (~a).bitsSet.map! (i => (2 * i + 1).to!int).array;
    }
    return p;
  }
  this (size_t _n) pure {
    n = _n;
    auto m = n >> 1;
    a.length = max (1, m);
    a[0] = true;
    foreach (i; 1 .. ceil((sqrt (n.to!(double)) - 1.0)).to!(size_t)) {
      if (!a[i]) {
        immutable k = (i << 1) + 1;
        for (size_t j = 2 * i * (i + 1); j < m; j += k) {
          a[j] = true;
        }
      }
    }
  }
}

void main() {
  int n;
  readf (" %d", &n);
  auto pt = new PrimeTable (n + 16);
  auto a = new int[n+1];
  int[] q;
  foreach (i; 2 .. n + 1) {
    if (pt.isPrime(i)) {
      q ~= i;
      a[i] = q.length.to!int;
    } else {
      foreach (k, j; q) {
        if ((i % j) == 0) {
          a[i] = k.to!int + 1;
          break;
        }
      }
    }
  }
  writefln ("%(%s %)", a[2 .. $]);
}

import std.typecons;
import core.stdc.stdio;
import std.stdio;
import std.algorithm;
import std.range;

alias PII = Tuple!(int, int);
alias PLL = Tuple!(long, long);

void main()
{
    uint n;
    scanf("%d", &n);

    bool[] primes = new bool[n + 1];
    int[] ans = new int[n + 1];
    fill(primes, true);

    int c = 0;

    foreach (i; 2 .. n + 1)
        if (primes[i])
        {
            c++;
            ans[i] = c;
            for (auto j = i * i; j <= n; j += i)
            {
                primes[j] = false;
                ans[j] = c;
            }
        }

    writefln("%(%d%| %)", ans[2 .. n + 1]);
}

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

string FMT_F = "%.10f";

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; }
string RDR()() { return readln.chomp; }
T[] ARR(T = long)(in string str, T fix = 0) { auto r = str.split.to!(T[]); r[] += fix; return r; }
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; }

bool inside(T)(T x, T b, T e) { return x >= b && x < e; }
long lcm(long x, long y) { return x * y / gcd(x, y); }

long mod = 10^^9 + 7;
//long mod = 998244353;
//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 main()
{
	auto N = RD!int;
	auto A = new long[](N-1);
	long num = 1;
	foreach (i; 2..N+1)
	{
		if (A[i-2] != 0) continue;

		for (int j = i; j <= N; j += i)
		{
			A[j-2] = num;
		}
		++num;
	}

	A.map!(to!string).join(" ").writeln;
	stdout.flush();
	debug readln();
}


import core.stdc.math;
import core.stdc.stdio;
import core.stdc.stdlib;
import std.algorithm;
int n,y=1;
int[200005] a;
void main()
{
	scanf("%d",&n);
	for (int i=1;i<=n;++i) scanf("%d",&a[i]);
	for (int i=2;i<=n;++i) y=max(y,abs(a[i]-a[i-1]));
	for (int i=2;i<=n;++i)
	{
		if (y!=1 && (a[i-1]+1==a[i] || a[i-1]-1==a[i]))
		{
			if ((a[i-1]-1)/y!=(a[i]-1)/y)
			{
				puts("NO");
				exit(0);
			}
		}
		else if (a[i-1]+y!=a[i] && a[i-1]-y!=a[i])
		{
			puts("NO");
			exit(0);
		}
	}
	printf("YES\n1000000000 %d\n",y);
}

import core.bitop, std.algorithm, std.bigint, std.compiler, std.container,
	std.complex, std.bitmanip, std.conv, std.math;
import std.numeric : Fft, fft, gcd, inverseFft;
import std.random, std.range, std.regex, std.stdio, std.string, std.traits,
	std.typecons, std.uni;

alias pair(X, Y) = Tuple!(X, "fi", Y, "se");
alias mp = make_pair;
alias pii = pair!(int, int);
alias pll = pair!(long, long);
// alias gcd = std.numeric.gcd;
alias lint = long;
alias rbt = RedBlackTree;
///modulo
const int mod = 10 ^^ 9 + 7, mod2 = mod + 2;
public
{
	pure nothrow
	{
		///int length
		int sz(T)(ref const T a) if (hasLength!T)
		{
			return cast(int) a.length;
		}
		///make_pair
		pair!(X, Y) make_pair(X, Y)(in X x_, in Y y_)
		{
			return tuple!(X, "fi", Y, "se")(x_, y_);
		}
		///square
		@property X sqr(X)(in X a_)
		{
			return a_ * a_;
		}
		///cube
		@property X cub(X)(in X a_)
		{
			return a_ * a_ * a_;
		}
		///posicion lower bound
		size_t lowb(T, X)(T a, auto ref X g)
				if (isRandomAccessRange!T && hasLength!T && is(typeof(g < a[0]) == bool))
		{
			return assumeSorted(a).lowerBound(g).length;
		}
		///posicion upper bound
		size_t upb(T, X)(T a, auto ref X g)
				if (isRandomAccessRange!T && hasLength!T && is(typeof(g < a[0]) == bool))
		{
			return a.length - assumeSorted(a).upperBound(g).length;
		}
		///posicion binary search
		size_t binf(T, X)(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;
		}
		///binary search
		bool binary_search(T, X)(T a, auto ref X g)
				if (isRandomAccessRange!T && hasLength!T && is(typeof(g < a[0]) == bool))
		{
			return assumeSorted(a).contains(g);
		}
	}
	static if (version_minor >= 74)
	{
		///read without format
		bool input(T...)(auto ref T ptrs) if (ptrs.length > 0)
		{
			return readf!(replicate(" %s", ptrs.length))(ptrs) == ptrs.length;
		}
		///readln without format
		bool read(T...)(auto ref T ptrs) if (ptrs.length > 0)
		{
			const bool fl = readf!(replicate(" %s", ptrs.length))(ptrs) == ptrs.length;
			readln;
			return fl;
		}
	}
	else
	{
		///read without format
		bool input(T...)(ref T ptrs) if (ptrs.length > 0)
		{
			size_t s;
			foreach (ref e; ptrs)
			{
				if (isSomeChar!(Unqual!(typeof(e))))
					s += readf(" %c", &e);
				else
					s += readf(" %s", &e);
			}
			return s == ptrs.length;
		}
		///readln without format
		bool read(T...)(ref T ptrs) if (ptrs.length > 0)
		{
			size_t s;
			foreach (ref e; ptrs)
			{
				if (isSomeChar!(Unqual!(typeof(e))))
					s += readf(" %c", &e);
				else
					s += readf(" %s", &e);
			}
			readln;
			return s == ptrs.length;
		}
	}
	///opening file
	nothrow auto inf(in char* name)
	{
		return freopen(name, "r", core.stdc.stdio.stdin);
	}
	///closing file
	nothrow auto ouf(in char* name)
	{
		return freopen(name, "w", core.stdc.stdio.stdout);
	}
	///parsing array from line
	@property auto arread(T)()
	{
		return readln.splitter.map!(to!(T)).array;
	}
	///outbuffer
	void enter(T...)(T args)
	{
		writeln(args);
		stdout.flush;
	}
}
//foreach_reverse isAlpha isNumber isWhite isLower isUpper toLower toUpper mixin
//cumulativeFold return static heapify join filter foreach
//------------------------------------------program beginning--------------------------
void main()
{
	version (home)
	{
		assert(freopen("input.txt", "r", core.stdc.stdio.stdin));
	}
	int n;
	read(n);
	auto a = arread!int;
	if (n == 1)
	{
		return writefln("YES\n%d %d", 1, a[0]);
	}
	int d = abs(a[0] - a[1]);
	foreach (i; 1 .. n - 1)
	{
		if (d == 1)
			d = abs(a[i] - a[i + 1]);
		else if (abs(a[i] - a[i + 1]) != 1)
		{
			if (d != abs(a[i] - a[i + 1]))
				return writeln("NO");
		}
	}
	if (d == 0)
		return writeln("NO");
	if (d == 1)
		return writefln("YES\n%d %d", 10 ^^ 9, 10 ^^ 9);
	int y = d, x = 10 ^^ 9;
	int x0 = (a[0] + d - 1) / d, y0 = a[0] - d * (x0 - 1);
	foreach (i; 1 .. n)
	{
		auto t = a[i] - a[i - 1];
		if (abs(t) > 1)
		{
			x0 += (t < 0 ? -1 : 1);
		}
		else
		{
			y0 += (t < 0 ? -1 : 1);
		}
		if (x0 < 1 || x0 > x || y0 < 1 || y0 > y)
			return writeln("NO");
	}
	writefln("YES\n%d %d", x, y);
}

import
		std.math,
		std.conv,
		std.file,
		std.range,
		std.array,
		std.stdio,
		std.string,
		std.bitmanip,
		std.algorithm;

void main()
{
	readln;

	auto arr = readln.strip.splitter.map!(to!int).array;
	auto pairs = zip(arr, arr[1..$]);

	auto y = pairs.map!(a => abs(a[0] - a[1])).filter!(a => a && a != 1).chain([ 1 ]).front;

	foreach(u, v; pairs)
	{
		auto d = abs(u - v);

		if(d != y && (d != 1 || min(u, v) % y == 0))
		{
			`NO`.writeln;
			return;
		}
	}

	writefln("YES\n%u %u", 10 ^^ 9, y);
}

import
		std.math,
		std.conv,
		std.file,
		std.range,
		std.array,
		std.stdio,
		std.string,
		std.bitmanip,
		std.algorithm;

void main()
{
	readln;

	int x, p, m;

	foreach(i, n; readln.strip.splitter.map!(to!int).enumerate)
	{
		if(i)
		{
			auto d = abs(n - p);

			if(!d)
			{
				`NO`.writeln;
				return;
			}

			if(d > 1)
			{
				if(x)
				{
					if(d != x)
					{
						`NO`.writeln;
						return;
					}
				}
				else
				{
					x = d;
				}
			}
		}

		if(m < n)
		{
			m = n;
		}

		p = n;
	}

	if(!x)
	{
		x = m;
	}

	writefln("YES\n%u %u", 1 + m / x, x);
}

import
		std.math,
		std.conv,
		std.file,
		std.range,
		std.array,
		std.stdio,
		std.string,
		std.bitmanip,
		std.algorithm;

void main()
{
	readln;

	int x, p, m;

	foreach(i, n; readln.strip.splitter.map!(to!int).enumerate)
	{
		if(i)
		{
			auto d = abs(n - p);

			if(d > 1)
			{
				if(x)
				{
					if(d != x)
					{
						`NO`.writeln;
						return;
					}
				}
				else
				{
					x = d;
				}
			}
		}

		if(m < n)
		{
			m = n;
		}

		p = n;
	}

	writefln("YES\n%u %u", m / x, x);
}

import
		std.math,
		std.conv,
		std.file,
		std.range,
		std.array,
		std.stdio,
		std.string,
		std.bitmanip,
		std.algorithm;

void main()
{
	readln;

	auto arr = readln.strip.splitter.map!(to!int).array;
	auto pairs = zip(arr, arr[1..$]);

	auto y = pairs.map!(a => abs(a[0] - a[1])).filter!(a => a != 1).chain([ 1 ]).front;

	foreach(u, v; pairs)
	{
		auto d = abs(u - v);

		if(d != y || d != 1 || min(u, v) % y == 0)
		{
			`NO`.writeln;
			return;
		}
	}

	writefln("YES\n%u %u", 10 ^^ 9, y);
}

import core.bitop, std.algorithm, std.bigint, std.compiler, std.container,
	std.complex, std.bitmanip, std.conv, std.math;
import std.numeric : Fft, fft, gcd, inverseFft;
import std.random, std.range, std.regex, std.stdio, std.string, std.traits,
	std.typecons, std.uni;

alias pair(X, Y) = Tuple!(X, "fi", Y, "se");
alias mp = make_pair;
alias pii = pair!(int, int);
alias pll = pair!(long, long);
// alias gcd = std.numeric.gcd;
alias lint = long;
alias rbt = RedBlackTree;
///modulo
const int mod = 10 ^^ 9 + 7, mod2 = mod + 2;
public
{
	pure nothrow
	{
		///int length
		int sz(T)(ref const T a) if (hasLength!T)
		{
			return cast(int) a.length;
		}
		///make_pair
		pair!(X, Y) make_pair(X, Y)(in X x_, in Y y_)
		{
			return tuple!(X, "fi", Y, "se")(x_, y_);
		}
		///square
		@property X sqr(X)(in X a_)
		{
			return a_ * a_;
		}
		///cube
		@property X cub(X)(in X a_)
		{
			return a_ * a_ * a_;
		}
		///posicion lower bound
		size_t lowb(T, X)(T a, auto ref X g)
				if (isRandomAccessRange!T && hasLength!T && is(typeof(g < a[0]) == bool))
		{
			return assumeSorted(a).lowerBound(g).length;
		}
		///posicion upper bound
		size_t upb(T, X)(T a, auto ref X g)
				if (isRandomAccessRange!T && hasLength!T && is(typeof(g < a[0]) == bool))
		{
			return a.length - assumeSorted(a).upperBound(g).length;
		}
		///posicion binary search
		size_t binf(T, X)(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;
		}
		///binary search
		bool binary_search(T, X)(T a, auto ref X g)
				if (isRandomAccessRange!T && hasLength!T && is(typeof(g < a[0]) == bool))
		{
			return assumeSorted(a).contains(g);
		}
	}
	static if (version_minor >= 74)
	{
		///read without format
		bool input(T...)(auto ref T ptrs) if (ptrs.length > 0)
		{
			return readf!(replicate(" %s", ptrs.length))(ptrs) == ptrs.length;
		}
		///readln without format
		bool read(T...)(auto ref T ptrs) if (ptrs.length > 0)
		{
			const bool fl = readf!(replicate(" %s", ptrs.length))(ptrs) == ptrs.length;
			readln;
			return fl;
		}
	}
	else
	{
		///read without format
		bool input(T...)(ref T ptrs) if (ptrs.length > 0)
		{
			size_t s;
			foreach (ref e; ptrs)
			{
				if (isSomeChar!(Unqual!(typeof(e))))
					s += readf(" %c", &e);
				else
					s += readf(" %s", &e);
			}
			return s == ptrs.length;
		}
		///readln without format
		bool read(T...)(ref T ptrs) if (ptrs.length > 0)
		{
			size_t s;
			foreach (ref e; ptrs)
			{
				if (isSomeChar!(Unqual!(typeof(e))))
					s += readf(" %c", &e);
				else
					s += readf(" %s", &e);
			}
			readln;
			return s == ptrs.length;
		}
	}
	///opening file
	nothrow auto inf(in char* name)
	{
		return freopen(name, "r", core.stdc.stdio.stdin);
	}
	///closing file
	nothrow auto ouf(in char* name)
	{
		return freopen(name, "w", core.stdc.stdio.stdout);
	}
	///parsing array from line
	@property auto arread(T)()
	{
		return readln.splitter.map!(to!(T)).array;
	}
	///outbuffer
	void enter(T...)(T args)
	{
		writeln(args);
		stdout.flush;
	}
}
//foreach_reverse isAlpha isNumber isWhite isLower isUpper toLower toUpper mixin
//cumulativeFold return static heapify join filter foreach
//------------------------------------------program beginning--------------------------
void main()
{
	version (home)
	{
		assert(freopen("input.txt", "r", core.stdc.stdio.stdin));
	}
	int n;
	read(n);
	auto a = arread!int;
	if (n == 1)
	{
		return writefln("YES\n%d %d", 1, a[0]);
	}
	int d = abs(a[0] - a[1]);
	foreach (i; 1 .. n - 1)
	{
		if (d == 1)
			d = abs(a[i] - a[i + 1]);
		else if (abs(a[i] - a[i + 1]) != 1)
		{
			if (d != abs(a[i] - a[i + 1]))
				return writeln("NO");
		}
	}
	if (d == 0)
		return writeln("NO");
	if (d == 1)
		return writefln("YES\n%d %d", 10 ^^ 9, 10 ^^ 9);
	int y = d, x = 10 ^^ 9;
	int x0 = (a[0] + d - 1) / d, y0 = a[0] - d * (x0 - 1);
	foreach (i; 1 .. n)
	{
		auto t = a[i] - a[i - 1];
		if (abs(t) > 1)
		{
			x0 += (t < 0 ? -1 : 1);
		}
		else
		{
			y0 += (t < 0 ? -1 : 1);
		}
		if (x0 < 1 || x0 > x || y0 < 1 || y0 > y)
			return writeln("NO");
	}
	writefln("YES\n%d %d", y, x);
}

import core.bitop, std.algorithm, std.bigint, std.compiler, std.container,
	std.complex, std.bitmanip, std.conv, std.math;
import std.numeric : Fft, fft, gcd, inverseFft;
import std.random, std.range, std.regex, std.stdio, std.string, std.traits,
	std.typecons, std.uni;

alias pair(X, Y) = Tuple!(X, "fi", Y, "se");
alias mp = make_pair;
alias pii = pair!(int, int);
alias pll = pair!(long, long);
// alias gcd = std.numeric.gcd;
alias lint = long;
alias rbt = RedBlackTree;
///modulo
const int mod = 10 ^^ 9 + 7, mod2 = mod + 2;
public
{
	pure nothrow
	{
		///int length
		int sz(T)(ref const T a) if (hasLength!T)
		{
			return cast(int) a.length;
		}
		///make_pair
		pair!(X, Y) make_pair(X, Y)(in X x_, in Y y_)
		{
			return tuple!(X, "fi", Y, "se")(x_, y_);
		}
		///square
		@property X sqr(X)(in X a_)
		{
			return a_ * a_;
		}
		///cube
		@property X cub(X)(in X a_)
		{
			return a_ * a_ * a_;
		}
		///posicion lower bound
		size_t lowb(T, X)(T a, auto ref X g)
				if (isRandomAccessRange!T && hasLength!T && is(typeof(g < a[0]) == bool))
		{
			return assumeSorted(a).lowerBound(g).length;
		}
		///posicion upper bound
		size_t upb(T, X)(T a, auto ref X g)
				if (isRandomAccessRange!T && hasLength!T && is(typeof(g < a[0]) == bool))
		{
			return a.length - assumeSorted(a).upperBound(g).length;
		}
		///posicion binary search
		size_t binf(T, X)(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;
		}
		///binary search
		bool binary_search(T, X)(T a, auto ref X g)
				if (isRandomAccessRange!T && hasLength!T && is(typeof(g < a[0]) == bool))
		{
			return assumeSorted(a).contains(g);
		}
	}
	static if (version_minor >= 74)
	{
		///read without format
		bool input(T...)(auto ref T ptrs) if (ptrs.length > 0)
		{
			return readf!(replicate(" %s", ptrs.length))(ptrs) == ptrs.length;
		}
		///readln without format
		bool read(T...)(auto ref T ptrs) if (ptrs.length > 0)
		{
			const bool fl = readf!(replicate(" %s", ptrs.length))(ptrs) == ptrs.length;
			readln;
			return fl;
		}
	}
	else
	{
		///read without format
		bool input(T...)(ref T ptrs) if (ptrs.length > 0)
		{
			size_t s;
			foreach (ref e; ptrs)
			{
				if (isSomeChar!(Unqual!(typeof(e))))
					s += readf(" %c", &e);
				else
					s += readf(" %s", &e);
			}
			return s == ptrs.length;
		}
		///readln without format
		bool read(T...)(ref T ptrs) if (ptrs.length > 0)
		{
			size_t s;
			foreach (ref e; ptrs)
			{
				if (isSomeChar!(Unqual!(typeof(e))))
					s += readf(" %c", &e);
				else
					s += readf(" %s", &e);
			}
			readln;
			return s == ptrs.length;
		}
	}
	///opening file
	nothrow auto inf(in char* name)
	{
		return freopen(name, "r", core.stdc.stdio.stdin);
	}
	///closing file
	nothrow auto ouf(in char* name)
	{
		return freopen(name, "w", core.stdc.stdio.stdout);
	}
	///parsing array from line
	@property auto arread(T)()
	{
		return readln.splitter.map!(to!(T)).array;
	}
	///outbuffer
	void enter(T...)(T args)
	{
		writeln(args);
		stdout.flush;
	}
}
//foreach_reverse isAlpha isNumber isWhite isLower isUpper toLower toUpper mixin
//cumulativeFold return static heapify join filter foreach
//------------------------------------------program beginning--------------------------
void main()
{
	version (home)
	{
		assert(freopen("input.txt", "r", core.stdc.stdio.stdin));
	}
	int n;
	read(n);
	auto a = arread!int;
	if (n == 1)
	{
		return writefln("YES\n%d %d", 1, a[0]);
	}
	int d = abs(a[0] - a[1]);
	foreach (i; 1 .. n - 1)
	{
		if (d == 1)
			d = abs(a[i] - a[i + 1]);
		else if (abs(a[i] - a[i + 1]) != 1)
		{
			if (d != abs(a[i] - a[i + 1]))
				return writeln("NO");
		}
	}
	if (d == 0)
		return writeln("NO");
	if (d == 1)
		return writefln("YES\n%d %d", 10 ^^ 9, 10 ^^ 9);
	int x = d, y = 10 ^^ 9;
	int x0 = (a[0] + d - 1) / d, y0 = a[0] - d * (x0 - 1);
	foreach (i; 1 .. n)
	{
		auto t = a[i] - a[i - 1];
		if (abs(t) > 1)
		{
			y0 += (t < 0 ? -1 : 1);
		}
		else
		{
			x0 += (t < 0 ? -1 : 1);
		}
		if (x0 < 1 || x0 > x || y0 < 1 || y0 > y)
			return writeln("No");
	}
	writefln("YES\n%d %d", y, x);
}

import core.bitop, std.algorithm, std.bigint, std.compiler, std.container,
	std.complex, std.bitmanip, std.conv, std.math;
import std.numeric : Fft, fft, gcd, inverseFft;
import std.random, std.range, std.regex, std.stdio, std.string, std.traits,
	std.typecons, std.uni;

alias pair(X, Y) = Tuple!(X, "fi", Y, "se");
alias mp = make_pair;
alias pii = pair!(int, int);
alias pll = pair!(long, long);
// alias gcd = std.numeric.gcd;
alias lint = long;
alias rbt = RedBlackTree;
///modulo
const int mod = 10 ^^ 9 + 7, mod2 = mod + 2;
public
{
	pure nothrow
	{
		///int length
		int sz(T)(ref const T a) if (hasLength!T)
		{
			return cast(int) a.length;
		}
		///make_pair
		pair!(X, Y) make_pair(X, Y)(in X x_, in Y y_)
		{
			return tuple!(X, "fi", Y, "se")(x_, y_);
		}
		///square
		@property X sqr(X)(in X a_)
		{
			return a_ * a_;
		}
		///cube
		@property X cub(X)(in X a_)
		{
			return a_ * a_ * a_;
		}
		///posicion lower bound
		size_t lowb(T, X)(T a, auto ref X g)
				if (isRandomAccessRange!T && hasLength!T && is(typeof(g < a[0]) == bool))
		{
			return assumeSorted(a).lowerBound(g).length;
		}
		///posicion upper bound
		size_t upb(T, X)(T a, auto ref X g)
				if (isRandomAccessRange!T && hasLength!T && is(typeof(g < a[0]) == bool))
		{
			return a.length - assumeSorted(a).upperBound(g).length;
		}
		///posicion binary search
		size_t binf(T, X)(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;
		}
		///binary search
		bool binary_search(T, X)(T a, auto ref X g)
				if (isRandomAccessRange!T && hasLength!T && is(typeof(g < a[0]) == bool))
		{
			return assumeSorted(a).contains(g);
		}
	}
	static if (version_minor >= 74)
	{
		///read without format
		bool input(T...)(auto ref T ptrs) if (ptrs.length > 0)
		{
			return readf!(replicate(" %s", ptrs.length))(ptrs) == ptrs.length;
		}
		///readln without format
		bool read(T...)(auto ref T ptrs) if (ptrs.length > 0)
		{
			const bool fl = readf!(replicate(" %s", ptrs.length))(ptrs) == ptrs.length;
			readln;
			return fl;
		}
	}
	else
	{
		///read without format
		bool input(T...)(ref T ptrs) if (ptrs.length > 0)
		{
			size_t s;
			foreach (ref e; ptrs)
			{
				if (isSomeChar!(Unqual!(typeof(e))))
					s += readf(" %c", &e);
				else
					s += readf(" %s", &e);
			}
			return s == ptrs.length;
		}
		///readln without format
		bool read(T...)(ref T ptrs) if (ptrs.length > 0)
		{
			size_t s;
			foreach (ref e; ptrs)
			{
				if (isSomeChar!(Unqual!(typeof(e))))
					s += readf(" %c", &e);
				else
					s += readf(" %s", &e);
			}
			readln;
			return s == ptrs.length;
		}
	}
	///opening file
	nothrow auto inf(in char* name)
	{
		return freopen(name, "r", core.stdc.stdio.stdin);
	}
	///closing file
	nothrow auto ouf(in char* name)
	{
		return freopen(name, "w", core.stdc.stdio.stdout);
	}
	///parsing array from line
	@property auto arread(T)()
	{
		return readln.splitter.map!(to!(T)).array;
	}
	///outbuffer
	void enter(T...)(T args)
	{
		writeln(args);
		stdout.flush;
	}
}
//foreach_reverse isAlpha isNumber isWhite isLower isUpper toLower toUpper mixin
//cumulativeFold return static heapify join filter foreach
//------------------------------------------program beginning--------------------------
void main()
{
	version (home)
	{
		assert(freopen("input.txt", "r", core.stdc.stdio.stdin));
	}
	int n;
	read(n);
	auto a = arread!int;
	if (n == 1)
	{
		return writefln("YES\n%d %d", 1, a[0]);
	}
	int d = abs(a[0] - a[1]);
	foreach (i; 1 .. n - 1)
	{
		if (d == 1)
			d = abs(a[i] - a[i + 1]);
		else if (abs(a[i] - a[i + 1]) != 1)
		{
			if (d != abs(a[i] - a[i + 1]))
				return writeln("NO");
		}
	}
	if (d == 0)
		return writeln("NO");
	if (d == 1)
		return writefln("YES\n%d %d", 10 ^^ 9, 10 ^^ 9);
	int x = d, y = 10 ^^ 9;
	int x0 = (a[0] + d - 1) / d, y0 = a[0] - d * (x0 - 1);
	foreach (i; 1 .. n)
	{
		auto t = a[i] - a[i - 1];
		if (abs(t) > 1)
		{
			y0 += (t < 0 ? -1 : 1);
		}
		else
		{
			x0 += (t < 0 ? -1 : 1);
		}
		if (x0 < 1 || x0 > x || y0 < 1 || y0 > y)
			return writeln("NO");
	}
	writefln("YES\n%d %d", y, x);
}