#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
#define fi first
#define se second
const int N=2001;
// -------------------- Input Checker Start --------------------
long long readInt(long long l, long long r, char endd)
{
long long x = 0;
int cnt = 0, fi = -1;
bool is_neg = false;
while(true)
{
char g = getchar();
if(g == '-')
{
assert(fi == -1);
is_neg = true;
continue;
}
if('0' <= g && g <= '9')
{
x *= 10;
x += g - '0';
if(cnt == 0)
fi = g - '0';
cnt++;
assert(fi != 0 || cnt == 1);
assert(fi != 0 || is_neg == false);
assert(!(cnt > 19 || (cnt == 19 && fi > 1)));
}
else if(g == endd)
{
if(is_neg)
x = -x;
if(!(l <= x && x <= r))
{
cerr << l << ' ' << r << ' ' << x << '\n';
assert(false);
}
return x;
}
else
{
assert(false);
}
}
}
string readString(int l, int r, char endd)
{
string ret = "";
int cnt = 0;
while(true)
{
char g = getchar();
assert(g != -1);
if(g == endd)
break;
cnt++;
ret += g;
}
assert(l <= cnt && cnt <= r);
return ret;
}
long long readIntSp(long long l, long long r) { return readInt(l, r, ' '); }
long long readIntLn(long long l, long long r) { return readInt(l, r, '\n'); }
string readStringLn(int l, int r) { return readString(l, r, '\n'); }
string readStringSp(int l, int r) { return readString(l, r, ' '); }
void readEOF() { assert(getchar() == EOF); }
vector<int> readVectorInt(int n, long long l, long long r)
{
vector<int> a(n);
for(int i = 0; i < n - 1; i++)
a[i] = readIntSp(l, r);
a[n - 1] = readIntLn(l, r);
return a;
}
// -------------------- Input Checker End --------------------
int n;
int a[N],b[N],d[N];
pair<int,int>c[N];
void _kill(int id,int bit){
b[id]|=(1<<(bit+1))-1;
b[id]^=(1<<bit);
}
int god[N];
int lg[N];
int e[N][N];
void add(int x,int y){
e[x][y]=e[y][x]=1;
}
void out(){
for(int i=1; i<=n ;i++){
for(int j=1; j<=n ;j++){
cout << e[i][j];
}
cout << '\n';
}
}
bool check(){
int x=0;
for(int i=1; i<=n ;i++) x^=b[i];
return (x==0);
}
void treesolve(stack<int>&st, int star){
for(int i=star; i>=1 ;i--){
int x=st.top();
while(d[x]==b[x]){
st.pop();x=st.top();
}
d[x]++;d[c[i].se]++;
add(x,c[i].se);
st.push(c[i].se);
}
}
int tot=1e7;
void solve(){
n=readInt(1,2000,'\n');
tot-=n*n;
assert(tot>=0);
for(int i=1; i<=n ;i++){
for(int j=1; j<=n ;j++){
e[i][j]=0;
}
d[i]=b[i]=0;
}
int funny=0;
int ss=0;
int c1=0;
for(int i=1; i<=n ;i++){
if(i==n) a[i]=readInt(1,n,'\n');
else a[i]=readInt(1,n-1,' ');
c[i]={a[i],i};
funny^=a[i];
ss+=a[i];
c1+=(a[i]==1);
}
if(ss<2*n-2 || n==3){//not enough edges
cout << "NO\n";
return;
}
if(c1>=n-1){
if(n==2) cout << "YES\n01\n10\n";
else cout << "NO\n";
return;
}
sort(c+1,c+n+1);
if(c[1].fi>=2 && n%2==0){
cout << "YES\n";
for(int i=1; i<n ;i++) add(i,i+1);
add(1,n);
out();return;
}
if(c[n-1].fi*2>n && c[n].fi*2>n+1 && n%4!=1){
if(n%2==0){
cout << "YES\n";
for(int i=1; i<=n/2-1 ;i++) add(c[i].se,c[n-1].se);
for(int i=n/2; i<=n-2 ;i++) add(c[i].se,c[n].se);
add(c[n-1].se,c[n].se);
out();return;
}
if(n%8==3){
if(c[n-2].fi==1){
cout << "NO\n";return;
}
cout << "YES\n";
for(int i=1; i<=n/2 ;i++) add(c[i].se,c[n].se);
for(int i=n/2+1; i<=n-3 ;i++) add(c[i].se,c[n-1].se);
add(c[n-2].se,c[n-1].se);add(c[n-2].se,c[n].se);add(c[n-1].se,c[n].se);
out();return;
}
if(c[n-3].fi!=1){
for(int i=1; i<=n-4 ;i++) b[c[i].se]=1;
b[c[n-3].se]=b[c[n-2].se]=2;
b[c[n-1].se]=n/2-1;b[c[n].se]=n/2;
stack<int>st;st.push(c[n].se);
treesolve(st,n-1);
cout << "YES\n";
out();return;
}
for(int i=2; i<=c[n-2].fi ;i++){
for(int j=2; j<=c[n-1].fi ;j++){
{
int k=2*n-2-i-j-(n-3);
if(k>1 && k<=c[n].fi && (i^j^k)==0){
for(int i=1; i<=n-3 ;i++) b[c[i].se]=1;
b[c[n-2].se]=i;b[c[n-1].se]=j;b[c[n].se]=k;
stack<int>st;st.push(c[n].se);
treesolve(st,n-1);
cout << "YES\n";
out();return;
}
}
{
int k=2*n-i-j-(n-3);
if(k>1 && k<=c[n].fi && (i^j^k)==0){
for(int i=1; i<=n-3 ;i++) b[c[i].se]=1;
b[c[n-2].se]=i;b[c[n-1].se]=j;b[c[n].se]=k;
stack<int>st;
d[c[n].se]+=2;d[c[n-1].se]+=2;d[c[n-2].se]+=2;
add(c[n].se,c[n-1].se);add(c[n].se,c[n-2].se);add(c[n-1].se,c[n-2].se);
st.push(c[n].se);st.push(c[n-1].se);st.push(c[n-2].se);
treesolve(st,n-3);
cout << "YES\n";
out();return;
}
}
}
}
cout << "NO\n";
return;
//n%4==1 doesnt exhibit this bad behavior
}
if(funny==0){
for(int i=1; i<=n ;i++) b[i]=a[i];
}
else{
bool ok=false;
if(funny==1){
for(int i=1; i<=n ;i++){
if(a[i]%2==1 && a[i]>=3){
for(int j=1; j<=n ;j++) b[j]=a[j];
b[i]--;
ok=true;
break;//s is guarenteed to be >=2*n-2, and sum b is maximized
}
}
}
if(!ok){//now carrying must happen
int en=1;
for(int i=10; i>=en ;i--){
vector<pair<pair<int,int>,int> >v;
int mk=(1<<(i+1))-1;
for(int j=1; j<=n ;j++){
int cur=a[j]&mk;
if((cur>>i)&1) v.push_back({{cur,-a[j]},j});
}
if(v.empty()) continue;//nothing to carry, cannot try
sort(v.begin(),v.end());
for(int j=1; j<=n ;j++) b[j]=a[j];
int spc=v[0].se;
if(v.size()%2==1){//1 or 3 carrying happens
en=i;//carrying must happen
bool fucked=true;
for(int j=1; j<=n ;j++) fucked&=(a[j]==(1<<i)) || (a[j]==1);//i hope correct :P
if(fucked && funny%2==0){//last resort is to use 3, if still fail then die
_kill(v[0].se,i);_kill(v[1].se,i);_kill(v[2].se,i);
}
else{
_kill(v[0].se,i);//remove i-th bit from v[0]
}
}
else{//two carrying happens (4 cant help impossible->possible)
_kill(v[0].se,i);_kill(v[1].se,i);
}/*
for(int j=1; j<=n ;j++) cout << b[j] << ' ';
cout << endl;*/
//i~10th bit works now
//greedy to maximize sum b
//spc stores some 2^k-1
for(int k=i-1; k>=1 ;k--){//fix 1~i-1 bit
int cnt=0;
int mn=spc;
for(int j=1; j<=n ;j++){
if((b[j]>>k)&1){
cnt++;
int cv=b[j]&((1<<k)-1);
int mv=b[mn]&((1<<k)-1);
if(cv<mv) mn=j;
}
}
if(cnt%2==1){//odd number of k-th bit, sacrifice min dude
_kill(mn,k);
}
}
{///fix last bit
int orz=0;
for(int j=1; j<=n ;j++) orz^=b[j];
if(orz%2==1){
bool done=false;
for(int j=1; j<=n ;j++){
if(b[j]%2==1 && b[j]>=3){
b[j]--;done=true;break;
}
}
if(!done) continue;
}
}
int sum=0;
for(int j=1; j<=n ;j++) sum+=b[j];
if(sum>=2*n-2){
ok=true;break;
}
}
if(!ok){
cout << "NO\n";
return;
}
}
}
//current: b xor to 0, 1<=b[i]<=a[i], sum b>=2n-2
//aim: sum b<=2n
/*
for(int i=1; i<=n ;i++) cout << b[i] << ' ';
cout << endl;*/
for(int i=0; i<=10 ;i++) god[i]=0;
int sum=0;
stack<int>s;
if(!check()) while(true);
for(int i=1; i<=n ;i++){
sum+=b[i];
s.push(i);
}
while(!s.empty() && sum>2*n){
int x=s.top();s.pop();
if(b[x]==1) continue;
int y=b[x]&-b[x];
int z=lg[y];
if(god[z]!=0){
int w=god[z];
int frog=min((sum-(2*n-2))/2,1<<z);
if(b[w]==(1<<z) || b[x]==(1<<z)) frog=min(frog,(1<<z)-1);
b[w]-=frog;b[x]-=frog;sum-=2*frog;
god[z]=0;
s.push(w);s.push(x);
//either both minbit + (>=1) or at least 1 die, another reset
}
else god[z]=x;
}
if(!check()) while(true);
/*
for(int i=1; i<=n ;i++) cout << b[i] << ' ';
cout << endl;*/
//now sum is O(nlogn)
vector<int>vip;
for(int i=1; i<=n ;i++) if(b[i]!=1) vip.push_back(i);
while(sum>2*n){//each iteration sum -2 at least
for(int i=0; i<=10 ;i++) god[i]=0;
while(!s.empty()) s.pop();
for(auto x:vip) s.push(x);
while(!s.empty() && sum>2*n){
int x=s.top();s.pop();
if(b[x]==1) continue;
int y=b[x]&-b[x];
int z=lg[y];
if(god[z]!=0){
int w=god[z];
int frog=min((sum-(2*n-2))/2,1<<z);
if(b[w]==(1<<z) || b[x]==(1<<z)) frog=min(frog,(1<<z)-1);
b[w]-=frog;b[x]-=frog;sum-=2*frog;
god[z]=0;
s.push(w);s.push(x);
//either both minbit + (>=1) or at least 1 die, another reset
}
else god[z]=x;
}
if(sum<=2*n) break;
for(int j=1; j<=10 ;j++){//cannot do nothing inside here
if(god[j]!=0 && god[0]!=0){
int w=god[0];
int x=god[j];
if(b[x]!=2){
int frog=2;
b[w]-=frog;b[x]-=frog;sum-=2*frog;
}
else{
b[w]-=3;b[x]-=1;sum-=4;
}
break;
}
}
}
if(!check()) while(true);
//now sum in [2n-2,2n]
/*
for(int i=1; i<=n ;i++) cout << b[i] << ' ';
cout << endl;*/
for(int i=1; i<=n ;i++) c[i]={b[i],i};
sort(c+1,c+n+1);
stack<int>st;
if(sum==2*n-2){
st.push(c[n].se);
treesolve(st,n-1);
}
else{
d[c[n].se]+=2;d[c[n-1].se]+=2;d[c[n-2].se]+=2;
add(c[n].se,c[n-1].se);add(c[n].se,c[n-2].se);add(c[n-1].se,c[n-2].se);
st.push(c[n].se);st.push(c[n-1].se);st.push(c[n-2].se);
treesolve(st,n-3);
}
cout << "YES\n";
out();return;
}
int main(){
ios::sync_with_stdio(false);cin.tie(0);
for(int i=0; i<=10 ;i++) lg[1<<i]=i;
int t;t=readInt(1,10000,'\n');while(t--){solve();/*cout << endl;*/}readEOF();
}