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++14 (GCC 5.4.1) (judge verdict: Wrong Answer)

#include<bits/stdc++.h>
using namespace std;
int f[410][410];
int n;
int k;
int u[410];
int tmp[410];int pl = 0;
int tt[410];int plt = 0;
int check(int x){
	memset(u,-1,sizeof(u));
	memset(tmp,0,sizeof(tmp));
	memset(tt,0,sizeof(tt));
	u[x] = 0;
	pl = plt = 0;
	for (int i=1;i<=n;i++){
		if (f[x][i]) ++pl, tmp[pl] = i, u[i] = 1;
	}
	for (int i=1;i<=n;i++){
		int opt = 1;
		for (int j=1;j<=n;j++){
			if (f[i][j]) if (u[j] == -1){
				opt = 0;
			}
		}
		if (u[i] == -1 && opt) u[i] = 0;
	}
	int res = 0;
	while (1){
		res ++;
		if (pl == 0){
			return res;
		}
		plt = 0;
		while (pl) {
			u[tmp[pl]] = res;
			++plt,tt[plt] = tmp[pl];
			pl--;
		}
		while (plt){
			for (int i=1;i<=n;i++){
				if (f[tt[plt]][i]){
					if (u[i] == res) return -1;
					else if (u[i] == -1) ++pl, tmp[pl] = i;
				//	else if (u[i] != res-1) return -1;
				}
			}
			plt --;
		}
	}
	return -1;
}
int main(){
	cin >> n;
	for (int i=1;i<=n;i++)
		for (int j=1;j<=n;j++){
			char tmp;
			cin >> tmp;
			f[i][j] = tmp - 48;
		}
	int MAX = -1;
	for (int i=1;i<=n;i++){
		MAX = max(MAX, check(i));
	}
	cout << MAX << endl;
}