Problem:
Score : 500 points

Problem Statement

Given is a connected undirected graph with N vertices and M edges. The vertices are numbered 1 to N, and the edges are described by a grid of characters S.
If S_{i,j} is 1, there is an edge connecting Vertex i and j; otherwise, there is no such edge.

Determine whether it is possible to divide the vertices into non-empty sets V_1, \dots, V_k such that the following condition is satisfied. If the answer is yes, find the maximum possible number of sets, k, in such a division.

Every edge connects two vertices belonging to two "adjacent" sets. More formally, for every edge (i,j), there exists 1\leq t\leq k-1 such that i\in V_t,j\in V_{t+1} or i\in V_{t+1},j\in V_t holds.

Constraints

2 \leq N \leq 200

S_{i,j} is 0 or 1.

S_{i,i} is 0.

S_{i,j}=S_{j,i}

The given graph is connected.

N is an integer.

Input

Input is given from Standard Input in the following format:

N
S_{1,1}...S_{1,N}
:
S_{N,1}...S_{N,N}

Output

If it is impossible to divide the vertices into sets so that the condition is satisfied, print -1.
Otherwise, print the maximum possible number of sets, k, in a division that satisfies the condition.

Sample Input 1

2
01
10

Sample Output 1

2

We can put Vertex 1 in V_1 and Vertex 2 in V_2.

Sample Input 2

3
011
101
110

Sample Output 2

-1

Sample Input 3

6
010110
101001
010100
101000
100000
010000

Sample Output 3

4

Solution in C (GCC 9.2.1) (judge verdict: Accepted)

#include <stdio.h>
#include <stdlib.h>

typedef struct List {
	struct List *next;
	int v;
} list;

int main()
{
	int i, N;
	char S[202][202];
	scanf("%d", &N);
	for (i = 1; i <= N; i++) scanf("%s", &(S[i][1]));
	
	int j, k;
	list **adj = (list**)malloc(sizeof(list*) * (N + 1)), *d = (list*)malloc(sizeof(list) * N * (N - 1));
	for (i = 1; i <= N; i++) adj[i] = NULL;
	for (i = 1, k = 0; i < N; i++) {
		for (j = i + 1; j <= N; j++) {
			if (S[i][j] == '0') continue;
			d[k*2].v = j;
			d[k*2+1].v = i;
			d[k*2].next = adj[i];
			d[k*2+1].next = adj[j];
			adj[i] = &(d[k*2]);
			adj[j] = &(d[k*2+1]);
			k++;
		}
	}
	
	int dist[201] = {}, q[201], head, tail;
	list *p;
	dist[1] = 1;
	q[0] = 1;
	for (head = 0, tail = 1; head < tail; head++) {
		for (p = adj[q[head]]; p != NULL; p = p->next) {
			if (dist[p->v] == 0) {
				dist[p->v] = dist[q[head]] + 1;
				q[tail++] = p->v;
			} else if ((dist[p->v] + dist[q[head]]) % 2 == 0) break;
		}
		if (p != NULL) break;
	}
	if (head < tail) {
		printf("-1\n");
		fflush(stdout);
		return 0;
	}
	
	int diam = dist[q[tail-1]];
	for (i = 2; i < N; i++) {
		for (j = 1; j <= N; j++) dist[j] = 0;
		dist[i] = 1;
		q[0] = i;
		for (head = 0, tail = 1; head < tail; head++) {
			for (p = adj[q[head]]; p != NULL; p = p->next) {
				if (dist[p->v] == 0) {
					dist[p->v] = dist[q[head]] + 1;
					q[tail++] = p->v;
				}
			}
		}
		if (diam < dist[q[tail-1]]) diam = dist[q[tail-1]];
	}
	
	printf("%d\n", diam);
	fflush(stdout);
	return 0;
}