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: Accepted)

#include <bits/stdc++.h>
#include <algorithm>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
#define ass 1e18
#define MOD 1000000007
#define mp make_pair
#define pb push_back
#define fi first
#define se second
#define boost ios_base::sync_with_stdio(false);cin.tie(NULL);
#define debug(x) cout << #x << ": " << x << endl;
#define debug2(x,y) cout<<#x<<": "<< x<< ", "<< #y<< ": "<< y<< endl;
#define debug3(x,y,z) cout<<#x<<": "<< x<< ", "<< #y<< ": "<< y<<" "<<#z<<" : "<<z<< endl;
using namespace std;
typedef long long int ll;
#include <ext/pb_ds/assoc_container.hpp> 
#include <ext/pb_ds/tree_policy.hpp> 
using namespace __gnu_pbds;   
#define ordered_set tree<ll, null_type,less<ll>, rb_tree_tag,tree_order_statistics_node_update>
vector<ll>v[205];
ll vis[205];
string str;

ll bfs(ll x,ll k)
{
	queue<ll>q;
	q.push(x);
	vis[x]=k;
	while(!q.empty())
	{
		ll p=q.front();
		q.pop();
		for(ll i=0;i<v[p].size();i++)
		{
			if(vis[v[p][i]]==0)
			{
				vis[v[p][i]]=vis[p]+1;
				q.push(v[p][i]);
			}
			else
			{
				if(abs(vis[v[p][i]]-vis[p])!=1)
					return 1;
			}
		}
	}
	return 0;
}	

int main()
{
	boost
	ll maxi=-1,mini=ass,n,i,j,ind;
	cin>>n;
	for(i=1;i<=n;i++)
	{
		cin>>str;
		for(j=1;j<=n;j++)
		{
			if(str[j-1]=='1')
			{
				v[i].pb(j);
				v[j].pb(i);
			}
		}
	}
	for(i=1;i<=n;i++)
	{
		memset(vis,0,sizeof(vis));
		if(!bfs(i,1))	
		{
			for(ll j=1;j<=n;j++)
				maxi=max(maxi,vis[j]);
		}
	}
	cout<<maxi;
	return 0;
}