1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
#include <bits/stdc++.h>
using namespace std;

const int NAX = 400;
const int INF = 1e9+5;

void test_case() {
	int n;
	cin >> n;
	vector<vector<int>> dist(n, vector<int>(n));
	for (int i = 0; i < n; i++) {
		string s;
		cin >> s;
		for (int j = 0; j < n; j++) {
			dist[i][j] = (s[j] == '1' ? 1 : INF);
		}
		dist[i][i] = 0;
	}
	for (int j = 0; j < n; j++) {
		for (int i = 0; i < n; i++) {
			for (int k = 0; k < n; k++) {
				dist[i][k] = min(dist[i][k], dist[i][j] + dist[j][k]);
			}
		}
	}
	// far[i][d] -- bitset of nodes at distance >= d from node i
	vector<vector<bitset<NAX>>> far(n, vector<bitset<NAX>>(n));
	for (int i = 0; i < n; i++) {
		for (int j = 0; j < n; j++) {
			far[i][dist[i][j]][j] = 1;
		}
		for (int d = (int) far[i].size() - 1; d >= 1; d--) {
			far[i][d-1] |= far[i][d];
		}
	}
	int answer = n - 1;
	for (int A = 0; A < n; A++) {
		for (int B = A + 1; B < n; B++) {
			auto improve = [&]() {
				for (int i = 0; i < n; i++) {
					int closer = (dist[A][i] < dist[B][i] ? A : B);
					int other = A + B - closer;
					if (dist[closer][i] > answer) {
						return false;
					}
					if ((far[i][answer] & far[other][answer-dist[closer][i]]) != 0) {
						return false;
					}
				}
				return true;
			};
			while (answer > 0 && improve()) {
				answer--;
			}
		}
	}
	cout << answer << "\n";
}

int main() {
	int T;
	cin >> T;
	while (T--) {
		test_case();
	}
}