#include <iostream>
#include <vector>
#include <algorithm>
#include <queue>
using namespace std;
vector<int> solve_degseq(vector<int> D) {
int N = D.size();
if(N == 2) return {1,1};
if(N == 3 || D[3] == 1) {
// bruteforce
vector<int> d(N, 1);
for(d[0] = 1; d[0] <= D[0]; d[0]++) for(d[1] = 1; d[1] <= D[1]; d[1]++) {
d[2] = d[0]^d[1]^(1^N&1);
if(d[2] > D[2]) continue;
if(d[0] < d[1] || d[1] < d[2] || d[2] == 0) continue;
if(d[0]+d[1] > 2+min(2,d[2])+(N-3)) continue;
if(d[0]+d[1]+d[2] > 6+(N-3)) continue;
if(d[0]+d[1]+d[2]+(N-3) < 2*(N-1)) continue;
return d;
}
return {};
}
// init. sequence
int D_sum = 0;
for(int i = 0; i < N; i++) D_sum += D[i];
vector<int> d_init(N);
if(D_sum >= 5*N+4) {
for(int i = 0; i < N; i++) {
d_init[i] = 1;
while(2*d_init[i] <= D[i]) d_init[i] *= 2;
}
int x = 0;
for(int i = 0; i < N; i++) x ^= d_init[i];
for(int b = 16; b >= 1; b--) if((x>>b)&1) {
for(int i = N-1; i >= 0; i--) if(d_init[i] == (1<<b)) {
x ^= (1<<b)^(1<<(b-1));
d_init[i] = 1<<(b-1);
break;
}
}
if(x) {
for(int i = 0; i < N; i++) if(d_init[i]%2 == 0 && d_init[i] < D[i]) {
d_init[i]++;
x = 0;
break;
}
}
if(x) {
for(int i = N-1; i > 0; i--) if(d_init[i] == d_init[0]) {
d_init[i] -= 2;
d_init[i-1]--;
x = 0;
break;
}
}
}
else {
vector< vector<int> > max_d_sum(N+1, vector<int>(2*N, -4*N));
max_d_sum[0][0] = 0;
for(int i = 0; i < N; i++)
for(int x = 0; x < 2*N; x++) if(max_d_sum[i][x] >= 0)
for(int j = 1; j <= D[i]; j++)
max_d_sum[i+1][x^j] = max(max_d_sum[i+1][x^j], max_d_sum[i][x]+j);
if(max_d_sum[N][0] < 2*(N-1)) return {};
int x = 0, s = max_d_sum[N][0];
for(int i = N-1; i >= 0; i--) {
for(int j = 1; j <= min(s,D[i]); j++) if(max_d_sum[i][x^j] == s-j) {
s -= j;
x ^= j;
d_init[i] = j;
break;
}
}
sort(rbegin(d_init), rend(d_init));
}
// valid sequence
vector<int> lsb(N);
for(int i = 1; i < N; i++) {
lsb[i] = 0;
while((i&(1<<lsb[i])) == 0) lsb[i]++;
}
vector<int> d = d_init;
int B = 0;
while((2<<B) < N) B++;
vector< vector<int> > id_by_lsb(B+1);
for(int i = 0; i < N; i++) if(d[i] > 1) id_by_lsb[lsb[d[i]]].push_back(i);
int d_sum = 0;
for(int i = 0; i < N; i++) d_sum += d[i];
while(d_sum > 2*(N-1)) {
int b = -1;
for(int i = 0; i <= B; i++) if((int)id_by_lsb[i].size() >= 2) {
b = i;
break;
}
bool sub1 = (b == -1 && d_sum > 2*N);
if(sub1) {
int id0 = id_by_lsb[0].back();
id_by_lsb[0].pop_back();
d[id0]--;
id_by_lsb[lsb[d[id0]]].push_back(id0);
for(int i = 0; i <= B; i++) if((int)id_by_lsb[i].size() >= 2) {
b = i;
break;
}
}
if(b == -1) break;
int id1 = id_by_lsb[b].back();
id_by_lsb[b].pop_back();
int id2 = id_by_lsb[b].back();
id_by_lsb[b].pop_back();
int s = sub1 ? 1 : min(d_sum/2-N+1, min(1<<b, min(d[id1],d[id2])-1));
d[id1] -= s, d[id2] -= s;
if(d[id1] > 1) id_by_lsb[lsb[d[id1]]].push_back(id1);
if(d[id2] > 1) id_by_lsb[lsb[d[id2]]].push_back(id2);
if(sub1) {
int id0 = id_by_lsb[0].back();
id_by_lsb[0].pop_back();
d[id0]--;
id_by_lsb[lsb[d[id0]]].push_back(id0);
d_sum -= 2+2*s;
}
else d_sum -= 2*s;
}
sort(rbegin(d), rend(d));
if(d[2] == 1 && d_sum == 2*N) d[2] = d[3] = 2;
return d;
}
vector< vector<int> > construct(vector<int> d) {
int N = d.size();
vector< pair<int,int> > ds(N);
for(int i = 0; i < N; i++) ds[i] = {d[i], i};
vector< vector<int> > G(N);
for(int i = 0; i < N-1; i++) {
for(int j = 1; j <= ds[0].first; j++) {
G[ds[0].second].push_back(ds[j].second);
G[ds[j].second].push_back(ds[0].second);
ds[j].first--;
}
vector< pair<int,int> > ds_nw(N-1-i);
merge(rbegin(ds), rbegin(ds)+(N-1-i-ds[0].first), rbegin(ds)+(N-1-i-ds[0].first), rend(ds)-1, rbegin(ds_nw));
ds = ds_nw;
}
return G;
}
void DFS(int v, int v_prev, vector< vector<int> > & G, vector<char> & vis, pair<int, int> & e) {
for(auto v_nxt : G[v]) if(v_nxt != v_prev) {
if(vis[v_nxt]) {
if(e.first == -1) e = {v, v_prev};
break;
}
vis[v_nxt] = 1;
DFS(v_nxt, v, G, vis, e);
}
}
pair<int,int> find_edge_on_cycle(vector< vector<int> > & G, int v_init) {
int N = G.size();
vector<char> vis(N, 0);
pair<int, int> e = {-1,-1};
vis[v_init] = 1;
DFS(v_init, v_init, G, vis, e);
return e;
}
vector< vector<int> > make_connected(vector< vector<int> > G) {
int N = G.size();
vector<int> in_comp(N, -1), edges;
vector< vector<int> > comp;
int C = 0;
for(int i = 0; i < N; i++) if(in_comp[i] == -1) {
in_comp[i] = C;
comp.push_back({i});
edges.push_back(0);
static queue<int> q;
q.push(i);
while(!q.empty()) {
for(auto v : G[q.front()]) if(in_comp[v] == -1) {
in_comp[v] = C;
comp.back().push_back(v);
q.push(v);
}
q.pop();
}
for(auto v : comp.back()) edges.back() += G[v].size();
C++;
}
while(C > 1) {
pair<int,int> e1, e2;
int c1 = 0;
if(edges.back()+2 == 2*(int)comp.back().size()) {
while(edges[c1]+2 == 2*(int)comp[c1].size()) c1++;
e2 = {comp.back()[0], G[comp.back()[0]].back()};
e1 = find_edge_on_cycle(G, comp[c1][0]);
}
else {
e2 = find_edge_on_cycle(G, comp.back()[0]);
e1 = {comp[c1][0], G[comp[c1][0]].back()};
}
replace(begin(G[e1.first]), end(G[e1.first]), e1.second, e2.second);
replace(begin(G[e1.second]), end(G[e1.second]), e1.first, e2.first);
replace(begin(G[e2.first]), end(G[e2.first]), e2.second, e1.second);
replace(begin(G[e2.second]), end(G[e2.second]), e2.first, e1.first);
for(auto v : comp.back()) in_comp[v] = c1;
comp[c1].insert(end(comp[c1]), begin(comp.back()), end(comp.back()));
edges[c1] += edges.back();
comp.pop_back();
edges.pop_back();
C--;
}
return G;
}
int main() {
cin.sync_with_stdio(0);
cin.tie(0);
int T;
cin >> T;
while(T--) {
int N;
cin >> N;
vector<int> D(N);
for(int i = 0; i < N; i++) cin >> D[i];
vector< pair<int,int> > Ds(N);
for(int i = 0; i < N; i++) Ds[i] = {D[i], i};
sort(rbegin(Ds), rend(Ds));
vector<int> id(N);
for(int i = 0; i < N; i++) id[Ds[i].second] = i;
for(int i = 0; i < N; i++) D[i] = Ds[i].first;
auto d = solve_degseq(D);
if(d.empty()) {
cout << "NO\n";
continue;
}
cout << "YES\n";
auto G = construct(d);
auto G_conn = make_connected(G);
for(int i = 0; i < N; i++) {
string s(N, '0');
for(auto v : G_conn[id[i]]) s[Ds[v].second] = '1';
cout << s << "\n";
}
}
}