#include<iostream>
#include<string>
#include<queue>
#include<math.h>
using namespace std;
const int maxsize=512;
char MAP[maxsize][maxsize];
struct quadtree
{
quadtree *q[4];
string value;
bool operator == (quadtree temp)
{
return temp.value==value;
}
quadtree()
{
for(int i=0;i<4;i++)
q[i]=NULL;
}
};
string levelorder(quadtree *&root)
{
queue<quadtree > que;
quadtree temp;
int i;
string str;
que.push(*root);
while(!que.empty())
{
temp=que.front();
que.pop();
str+=temp.value;
for(i=0;i<4;++i)
if(temp.q[i])
que.push(*temp.q[i]);
}
return str;
}
int turn(const string str)
{
int i,sum=0;
for(i=0;i<str.size();++i)
{
if(str[str.size()-i-1]=='1')
sum+=pow(2.0,i);
}
return sum;
}
quadtree *DFS(int r,int c,int s)//行号列号间隔
{
int i;
bool f=true;
quadtree *temp=new quadtree;
if(s==1)//最小格就赋值
{
temp->value='0';
temp->value+=MAP[r][c];
return temp;
}
s/=2;
temp->q[0]=DFS(r,c,s);//跳格继续递归
temp->q[1]=DFS(r,c+s,s);
temp->q[2]=DFS(r+s,c,s);
temp->q[3]=DFS(r+s,c+s,s);
for(i=1;i<4;++i)//检测是否需要合并
{
if(!(*temp->q[0]==*temp->q[i])||temp->q[0]->value=="1")//不用合并
{
f=false;
break;
}
}
if(f)//需要
{
temp->value=temp->q[0]->value;
for(i=0;i<4;++i)
{
delete temp->q[i];
temp->q[i]=NULL;//防止野指针
}
}
else
temp->value="1";
return temp;
}
void deltree(quadtree *&node)//回收内存
{
if(node)
{
for(int i=0;i<4;++i)
{
deltree(node->q[i]);
}
delete node;
}
}
int main()
{
int icase,i,j,N;
quadtree *order;
cin>>icase;
while(icase--)
{
cin>>N;
for(i=0;i<N;++i)
for(j=0;j<N;++j)
cin>>MAP[i][j];
order=DFS(0,0,N);
cout.setf(ios_base::hex,ios_base::basefield);//十六进制显示
cout.setf(ios::uppercase);//大写显示
cout<<turn(levelorder(order))<<endl;
deltree(order);
}
return 0;
}