#include <bits/stdc++.h>

#define fi first
#define se second
#define sz(a) (int)(a).size()
#define all(a) (a).begin(), (a).end()
#define reset(a,v) memset((a), v, sizeof(a))

using namespace std;

typedef long long ll;
typedef pair<int,int> ii;
typedef vector<int> vi;
typedef vector<ll> vll;
typedef vector<ii> vii;

const int N = 2005;

int n;
vii pos[15];
char dat[N][N];
int maxPrex[15][N], minPrex[15][N], maxPrey[15][N], minPrey[15][N];
int minSufx[15][N], maxSufx[15][N], minSufy[15][N], maxSufy[15][N];
int maxInRow[15][N], minInRow[15][N], maxInCol[15][N], minInCol[15][N];
int ans[15];

int main() {
	int tc; scanf("%d", &tc);
	while (tc--) {
		// printf("tc = %d\n", tc);
		scanf("%d", &n);
		for (int i = 0; i < n; i++) {
			scanf("%s", dat[i]);
			for (int j = 0; j < n; j++) {
				int dig = dat[i][j] - '0';
				pos[dig].push_back({i,j});
			}
		}

		for (int dig = 0; dig < 10; dig++) {
			for (int i = 0; i < n; i++) {
				maxPrex[dig][i] = maxPrey[dig][i] = maxSufx[dig][i] = maxSufy[dig][i] = -1;
				minPrex[dig][i] = minPrey[dig][i] = minSufx[dig][i] = minSufy[dig][i] = INT_MAX;
				maxInRow[dig][i] = maxInCol[dig][i] = -1;
				minInRow[dig][i] = minInCol[dig][i] = INT_MAX;
			}
		}

		for (int dig = 0; dig < 10; dig++) {
			for (int i = 0; i < sz(pos[dig]); i++) {
				ii p = pos[dig][i];
				maxPrex[dig][p.se] = max(maxPrex[dig][p.se], p.fi);
				minPrex[dig][p.se] = min(minPrex[dig][p.se], p.fi);
				maxSufx[dig][p.se] = max(maxSufx[dig][p.se], p.fi);
				minSufx[dig][p.se] = min(minSufx[dig][p.se], p.fi);
			}
			for (int i = 1; i < n; i++) {
				maxPrex[dig][i] = max(maxPrex[dig][i], maxPrex[dig][i-1]);
				minPrex[dig][i] = min(minPrex[dig][i], minPrex[dig][i-1]);
			}
			for (int i = n-2; i >= 0; i--) {
				maxSufx[dig][i] = max(maxSufx[dig][i], maxSufx[dig][i+1]);
				minSufx[dig][i] = min(minSufx[dig][i], minSufx[dig][i+1]);
			}
		}

		for (int dig = 0; dig < 10; dig++) {
			for (int i = 0; i < sz(pos[dig]); i++) {
				ii p = pos[dig][i];
				maxPrey[dig][p.fi] = max(maxPrey[dig][p.fi], p.se);
				minPrey[dig][p.fi] = min(minPrey[dig][p.fi], p.se);
				maxSufy[dig][p.fi] = max(maxSufy[dig][p.fi], p.se);
				minSufy[dig][p.fi] = min(minSufy[dig][p.fi], p.se);
			}
			for (int i = 1; i < n; i++) {
				maxPrey[dig][i] = max(maxPrey[dig][i], maxPrey[dig][i-1]);
				minPrey[dig][i] = min(minPrey[dig][i], minPrey[dig][i-1]);
			}
			for (int i = n-2; i >= 0; i--) {
				maxSufy[dig][i] = max(maxSufy[dig][i], maxSufy[dig][i+1]);
				minSufy[dig][i] = min(minSufy[dig][i], minSufy[dig][i+1]);
			}
		}

		for (int dig = 0; dig < 10; dig++) {
			for (ii p : pos[dig]) {
				maxInRow[dig][p.fi] = max(maxInRow[dig][p.fi], p.se);
				minInRow[dig][p.fi] = min(minInRow[dig][p.fi], p.se);
				maxInCol[dig][p.se] = max(maxInCol[dig][p.se], p.fi);
				minInCol[dig][p.se] = min(minInCol[dig][p.se], p.fi);
			}
		}

		for (int i = 0; i < n; i++) {
			for (int j = 0; j < n; j++) {
				int dig = dat[i][j] - '0';
				int& res = ans[dig];
				if (maxPrex[dig][j] >= i) res = max(res, j * (maxPrex[dig][j]-i));
				if (minPrex[dig][j] <= i) res = max(res, j * (i-minPrex[dig][j]));
				if (maxSufx[dig][j] >= i) res = max(res, (n-1-j) * (maxSufx[dig][j]-i));
				if (minSufx[dig][j] <= i) res = max(res, (n-1-j) * (i-minSufx[dig][j]));
				if (maxPrey[dig][i] >= j) res = max(res, i * (maxPrey[dig][i]-j));
				if (minPrey[dig][i] <= j) res = max(res, i * (j-minPrey[dig][i]));
				if (maxSufy[dig][i] >= j) res = max(res, (n-1-i) * (maxSufy[dig][i]-j));
				if (minSufy[dig][i] <= j) res = max(res, (n-1-i) * (j-minSufy[dig][i]));
				if (maxInRow[dig][i] != -1) res = max(res, (maxInRow[dig][i]-j) * max(i, (n-1-i)));
				if (minInRow[dig][i] != INT_MAX) res = max(res, (j-minInRow[dig][i]) * max(i, (n-1-i)));
				if (maxInCol[dig][j] != -1) res = max(res, (maxInCol[dig][j]-i) * max(j, (n-1-j)));
				if (minInCol[dig][j] != INT_MAX) res = max(res, (i-minInCol[dig][j]) * max(j, (n-1-j)));
			}
		}

		for (int i = 0; i < 10; i++) {
			printf("%d%c", ans[i], i==9 ? '\n' : ' ');
			pos[i].clear();
			ans[i] = 0;
		}
	}
	return 0;
}
