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# (Mono 4.6.2.0) (judge verdict: Accepted)

using System;
using System.Collections;
using System.Collections.Generic;
using System.Text;
using System.Linq;
using static MyIO;


public class B
{
	public static void Main() => (new Solver()).Solve();
}


public class Solver
{
	public void Solve()
	{
		int N = GetInt();
		int[,] G = new int[N, N];
		for(int i = 0; i < N; i++)
		{
			string S = GetString();
			for(int j = 0; j < N; j++)
				G[i, j] = (S[j] == '1') ? 1 : 0;
		}

		int[] color = Enumerable.Repeat(-1, N).ToArray();
		if(!isBipartite(N, G, color, 0, 0))
		{
			Console.WriteLine(-1);
			return;
		}

		int[,] d = new int[N, N];
		for(int i = 0; i < N; i++)
			for(int j = 0; j < N; j++)
				d[i, j] = (i == j) ? 0 : (G[i, j] == 1) ? 1 : 100000;

		warshall_floyd(ref d);
		int D = 0;
		for(int i = 0; i < N; i++)
			for(int j = 0; j < N; j++)
				chmax(ref D, d[i, j]);

		Console.WriteLine(D + 1);
	}

	private bool isBipartite(int N, int[,] G, int[] color, int v, int c)
	{
		color[v] = c;
		for(int u = 0; u < N; u++)
		{
			if(G[v, u] == 0)
				continue;

			if(color[u] == -1)
			{
				if(!isBipartite(N, G, color, u, c ^ 1))
					return false;
			}
			else if(color[u] == c)
				return false;			
		}
		return true;
	}

	private static void warshall_floyd(ref int[,] d)
	{
		int V = d.GetLength(0);
		for(int k = 0; k < V; k++)
			for(int i = 0; i < V; i++)
				for(int j = 0; j < V; j++)
					d[i, j] = Math.Min(d[i, j], d[i, k] + d[k, j]);
	}

	private void chmax(ref int x, int y) => x = Math.Max(x, y);
}


public static class MyIO
{
	private static string[] args = null;
	private static int num = -1;
	private static int used = -1;

	private static string getArg()
	{
		if(used == num)
		{
			args = Console.ReadLine().Split(' ');
			num = args.Length;
			used = 0;
		}
		return args[used++];
	}

	public static int GetInt() => int.Parse(getArg());
	public static long GetLong() => long.Parse(getArg());
	public static double GetDouble() => double.Parse(getArg());
	public static string GetString() => getArg();
	public static char GetChar() => getArg()[0];
	public static int[] GetInts(int N) => Enumerable.Range(0, N).Select(_ => GetInt()).ToArray();
	public static long[] GetLongs(int N) => Enumerable.Range(0, N).Select(_ => GetLong()).ToArray();
	public static double[] GetDoubles(int N) => Enumerable.Range(0, N).Select(_ => GetDouble()).ToArray();
	public static string[] GetStrings(int N) => Enumerable.Range(0, N).Select(_ => GetString()).ToArray();
}