#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <cmath>
#include <vector>
#include <set>
#include <map>
#include <unordered_set>
#include <unordered_map>
#include <queue>
#include <ctime>
#include <cassert>
#include <complex>
#include <string>
#include <cstring>
#include <chrono>
#include <random>
#include <bitset>
#include <array>
using namespace std;

#ifdef LOCAL
	#define eprintf(...) {fprintf(stderr, __VA_ARGS__);fflush(stderr);}
#else
	#define eprintf(...) 42
#endif

using ll = long long;
using ld = long double;
using uint = unsigned int;
using ull = unsigned long long;
template<typename T>
using pair2 = pair<T, T>;
using pii = pair<int, int>;
using pli = pair<ll, int>;
using pll = pair<ll, ll>;
mt19937_64 rng(chrono::steady_clock::now().time_since_epoch().count());
ll myRand(ll B) {
	return (ull)rng() % B;
}

#define pb push_back
#define mp make_pair
#define all(x) (x).begin(),(x).end()
#define fi first
#define se second

clock_t startTime;
double getCurrentTime() {
	return (double)(clock() - startTime) / CLOCKS_PER_SEC;
}

const int N = 2002;
int SUCC = 0;
int n;
pii ord[N];
int d[N];
int dp[N][2 * N + 3];
int par[N][2 * N + 3];
char g[N][N];

void printTree() {
	int sum = 0;
	int X = 0;
	for (int i = 0; i < n; i++) {
		sum += d[i];
		X ^= d[i];
		ord[i] = mp(d[i], i);
	}
	assert(X == 0);
	assert(sum >= 2 * n - 2);
	assert(sum < 2 * n + 6);
	sort(ord, ord + n);
	reverse(ord, ord + n);
	for (int i = 0; i < n; i++) {
		for (int j = 0; j < n; j++)
			g[i][j] = '0';
		g[i][n] = '\0';
	}
	int p = 0;
	vector<int> a = vector<int>();
	if (sum != 2 * n - 2) {
		sum = (sum - (2 * n - 2)) / 2;
		assert(ord[3].first >= 3);
		assert(ord[0].first >= 4);
		sum += 3;
		for (int i = 0; sum > 0 && i < 4; i++)
			for (int j = i + 1; sum > 0 && j < 4; j++) {
				int v = ord[i].second, u = ord[j].second;
				g[v][u] = g[u][v] = '1';
				d[v]--;
				d[u]--;
				sum--;
			}
		p = 4;
		for (int i = 0; i < 4; i++) {
			int v = ord[i].second;
			for (int j = 0; j < d[v]; j++)
				a.push_back(v);
		}
	} else {
		p = 1;
		for (int i = 0; i < 1; i++) {
			int v = ord[i].second;
			for (int j = 0; j < d[v]; j++)
				a.push_back(v);
		}
	}
	for (int i = p; i < n; i++) {
		int v = ord[i].second;
		assert(!a.empty());
		int u = a.back();
		a.pop_back();
		g[v][u] = g[u][v] = '1';
		for (int j = 1; j < d[v]; j++)
			a.push_back(v);
	}
	printf("YES\n");
	for (int i = 0; i < n; i++) {
		printf("%s\n", g[i]);
	}
	SUCC++;
}

void reduceFour() {
	int sum = 0, X = 0;
	for (int i = 0; i < n; i++) {
		sum += d[i];
		X ^= d[i];
	}
	assert(X == 0);
	assert(sum >= 2 * n - 2);
	assert(sum < 3 * n);
	while(sum >= 2 * n + 6) {
		int k = 30;
		for (int i = 0; i < n; i++) {
			if (d[i] < 8) continue;
			int x = (d[i] >> 2) << 2;
			while(x & ((1 << k) - 1)) k--;
		}
		if (k < 30) {
			int v = -1, u = -1;
			for (int i = 0; i < n; i++) {
				if (d[i] < 8) continue;
				if (((d[i] >> k) & 1) == 0) continue;
				if (v == -1) {
					v = i;
				} else if (u == -1) {
					u = i;
				}
			}
			assert(v != -1);
			if (u != -1) {
				sum -= 8;
				d[v] -= 4;
				d[u] -= 4;
				continue;
			}
			assert(k == 2);
			u = 0;
			while(u < n && (d[u] < 4 || d[u] >= 8)) u++;
			assert(u < n);
			int x = d[v] ^ d[u] ^ 3;
			assert(x < d[v]);
			assert((d[v] - x) + (d[u] - 3) <= 8);
			sum -= d[v] - x + d[u] - 3;
			d[v] = x;
			d[u] = 3;
			continue;
		}
		int v = -1, u = -1;
		for (int i = 0; i < n; i++) {
			if (d[i] < 4) continue;
			if ((d[i] & 2) == 0) continue;
			if (v == -1) {
				v = i;
			} else if (u == -1) {
				u = i;
			}
		}
		if (u != -1) {
			sum -= 4;
			d[v] -= 2;
			d[u] -= 2;
			continue;
		}
		v = -1; u = -1;
		for (int i = 0; i < n; i++) {
			if (d[i] < 4) continue;
			if ((d[i] & 1) == 0) continue;
			if (v == -1) {
				v = i;
			} else if (u == -1) {
				u = i;
			}
		}
		if (u != -1) {
			sum -= 2;
			d[v] -= 1;
			d[u] -= 1;
			continue;
		}
		for (int i = 0; i < n; i++)
			ord[i] = mp(d[i], i);
		sort(ord, ord + n);
		reverse(ord, ord + n);
		int p = 0;
		while(p < n && ord[p].first >= 4) p++;
		assert(p % 2 == 0);
		while(sum >= 2 * n + 6 && p > 0) {
			p -= 2;
			int v = ord[p].second, u = ord[p + 1].second;
			int x = d[v] ^ d[u];
			sum -= d[v] + d[u];
			if (x == 3) {
				d[v] = 2;
				d[u] = 1;
			} else {
				d[v] = 3;
				d[u] = 3 ^ x;
			}
			sum += d[v] + d[u];
		}
		return;
	}
}

bool checkThree(int a, int b, int c, int ones, int twos) {
	int sum = a + b + c + ones * 1 + twos * 2;
	if (sum < 2 * n - 2) return false;
	assert(sum % 2 == 0);
	if (a < b) swap(a, b);
	if (b < c) swap(b, c);
	if (a < b) swap(a, b);
	assert(a > 1);
	if (b == 1) {
		return true;
	}
	if (c == 1) {
		if (twos > 0) {
			c = 2;
			ones++;
			twos--;
		}
	}
	if (c == 1) {
		return sum == 2 * n - 2;
	}
	return (sum - (2 * n - 2)) / 2 <= 1 + twos;
}

void printThree() {
	/*
	eprintf("print 3\n");
	for (int i = 0; i < n; i++)
		eprintf("%d ", d[i]);
	eprintf("\n");
	*/
	int sum = 0;
	int X = 0;
	for (int i = 0; i < n; i++) {
		sum += d[i];
		X ^= d[i];
		ord[i] = mp(d[i], i);
	}
	assert(X == 0);
	assert(sum >= 2 * n - 2);
	sort(ord, ord + n);
	reverse(ord, ord + n);
	assert(ord[3].first <= 2);
	if (ord[0].first == 2) {
		if (sum == 2 * n) {
			d[ord[0].second] = d[ord[1].second] = 1;
			sum -= 2;
		}
	}
	if (sum == 2 * n - 2) {
		printTree();
		return;
	}
	for (int i = 0; i < n; i++) {
		for (int j = 0; j < n; j++)
			g[i][j] = '0';
		g[i][n] = '\0';
	}
	int A = ord[0].second, B = ord[1].second, C = ord[2].second;
	sum = (sum - (2 * n - 2)) / 2;
	assert(sum > 0);
	assert(d[C] >= 2);
	g[A][B] = g[B][A] = g[A][C] = g[C][A] = g[B][C] = g[C][B] = '1';
	d[A] -= 2;
	d[B] -= 2;
	d[C] -= 2;
	sum--;
	int p = 3;
	while(sum > 1) {
		assert(p < n);
		int v = ord[p++].second;
		assert(d[v] == 2);
		if (d[A] < d[B]) swap(A, B);
		if (d[B] < d[C]) swap(B, C);
		if (d[A] < d[B]) swap(A, B);
		assert(d[A] + d[B] >= 2);
		if (d[B] == 0) {
			assert(p < n);
			int u = ord[p++].second;
			assert(d[u] == 2);
			g[A][v] = g[v][A] = g[A][u] = g[u][A] = g[v][u] = g[u][v] = '1';
			d[A] -= 2;
			d[v] -= 2;
			d[u] -= 2;
			sum--;
		} else {
			g[A][v] = g[B][v] = g[v][A] = g[v][B] = '1';
			sum--;
			d[A]--;
			d[B]--;
			d[v] -= 2;
		}
	}
	if (d[A] < d[B]) swap(A, B);
	if (d[B] < d[C]) swap(B, C);
	if (d[A] < d[B]) swap(A, B);
	if (p < n && ord[p].first == 2) {
		int v = ord[p].second;
		d[A]--;
		g[A][v] = g[v][A] = '1';
		p++;
		while(p < n && ord[p].first == 2) {
			int u = ord[p++].second;
			g[v][u] = g[u][v] = '1';
			v = u;
		}
		if (sum == 0) {
			assert(p < n);
			int u = ord[p++].second;
			g[v][u] = g[u][v] = '1';
		} else {
			if (d[B] > 0) {
				d[B]--;
				g[B][v] = g[v][B] = '1';
			} else {
				assert(d[A] > 0);
				d[A]--;
				g[A][v] = g[v][A] = '1';
			}
		}
	}
	while(p < n) {
		int v = ord[p].second;
		assert(d[v] == 1);
		if (d[B] > 0) swap(A, B);
		if (d[C] > 0) swap(A, C);
		assert(d[A] > 0);
		d[A]--;
		g[A][v] = g[v][A] = '1';
		p++;
	}
	printf("YES\n");
	for (int i = 0; i < n; i++) {
		printf("%s\n", g[i]);
	}
	SUCC++;
}

void solve() {
	//eprintf("SOLVE\n");
	scanf("%d", &n);
	for (int i = 0; i < n; i++) {
		scanf("%d", &ord[i].first);
		ord[i].second = i;
	}
	if (n == 2) {
		printf("YES\n01\n10\n");
		SUCC++;
		return;
	}
	if (n == 3) {
		printf("NO\n");
		return;
	}
	sort(ord, ord + n);
	reverse(ord, ord + n);
	int ones = 0;
	while(ones < n - 3 && ord[n - 1 - ones].first == 1) ones++;
	int twos = n - 3 - ones;
	for (int x = 0; x <= 1 && x <= twos; x++) {
		int nones = ones + x, ntwos = twos - x;
		int X = (nones & 1) ^ ((ntwos & 1) << 1);
		for (int c = 1; c <= ord[2].first; c++)
			for (int b = 1; b <= ord[1].first; b++) {
				int a = b ^ c ^ X;
				if (a == 0 || a > ord[0].first) continue;
				if (!checkThree(a, b, c, nones, ntwos)) continue;
				d[ord[0].second] = a;
				d[ord[1].second] = b;
				d[ord[2].second] = c;
				for (int i = 3; i < n - nones; i++)
					d[ord[i].second] = 2;
				for (int i = n - nones; i < n; i++)
					d[ord[i].second] = 1;
				printThree();
				return;
			}
	}
	if (ord[3].first <= 2) {
		printf("NO\n");
		return;
	}
	int sum = 0;
	for (int i = 0; i < n; i++)
		sum += ord[i].first;
	if (sum >= 3 * n) {
		for (int i = 0; i + 1 < n; i += 2)
			ord[i].first = ord[i + 1].first;
		if (n & 1) {
			ord[n - 1].first = 1;
			if (ord[0].first % 2 == 0) {
				ord[0].first--;
				ord[1].first--;
			}
			ord[0].first--;
		}
		sum = 0;
		for (int i = 0; i < n; i++)
			sum += ord[i].first;
		assert(sum >= 2 * n - 2);
		assert(sum % 2 == 0);
		for (int i = 0; i + 1 < n; i += 2) {
			int x = (ord[i].first - 1);
			x = min(x, (sum - (2 * n - 2)) / 2);
			if ((n & 1) && i == 0) x -= x & 1;
			sum -= 2 * x;
			ord[i].first -= x;
			ord[i + 1].first -= x;
		}
		assert(sum == 2 * n - 2);
		for (int i = 0; i < n; i++)
			d[ord[i].second] = ord[i].first;
		printTree();
	} else {
		for (int i = 0; i <= n; i++)
			for (int x = 0; x < 2 * ord[0].first; x++)
				dp[i][x] = -1;
		dp[n][0] = 0;
		for (int i = n - 1; i >= 0; i--)
			for (int x = 0; x < 2 * ord[i].first; x++) {
				if (dp[i + 1][x] == -1) continue;
				for (int y = (i <= 3 ? 3 : 1); y <= ord[i].first; y++) {
					int z = x ^ y;
					int w = dp[i + 1][x] + y;
					if (w <= dp[i][z]) continue;
					dp[i][z] = w;
					par[i][z] = y;
				}
			}
		if (dp[0][0] < 2 * n - 2) {
			printf("NO\n");
			return;
		}
		int z = 0;
		for (int p = 0; p < n; p++) {
			int x = par[p][z];
			d[ord[p].second] = x;
			z ^= x;
		}
		reduceFour();
		bool all3 = true;
		int sum = 0;
		for (int i = 0; i < n; i++) {
			all3 &= d[i] <= 3;
			sum += d[i];
		}
		assert(sum >= 2 * n - 2);
		if (all3) {
			sum = (sum - (2 * n - 2)) / 2;
			int L3 = -1, L2 = -1;
			for (int i = 0; sum > 0 && i < n; i++) {
				if (d[i] == 1) continue;
				if (d[i] == 2) {
					if (L2 == -1) {
						L2 = i;
					} else {
						d[i]--;
						d[L2]--;
						sum--;
						L2 = -1;
					}
				} else if (d[i] == 3) {
					if (L3 == -1) {
						L3 = i;
					} else {
						d[i]--;
						d[L3]--;
						sum--;
						if (sum == 0) break;
						d[i]--;
						d[L3]--;
						sum--;
						L3 = -1;
					}
				} else assert(false);
			}
			assert(sum == 0);
		} else {
			assert(sum < 2 * n + 6);
		}
		printTree();
	}
}

int main()
{
	startTime = clock();
//	freopen("input.txt", "r", stdin);
//	freopen("output.txt", "w", stdout);

	int t;
	scanf("%d", &t);
	while(t--) {
		solve();
	}
	fprintf(stderr, "YES = %d\n", SUCC);

	return 0;
}