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 5.4.1) (judge verdict: Accepted)

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

#ifdef DEBUG
struct test {
    int N;
    char S[200][201];
    int a;
} t[] = {
    {
        6, {"011000", "100100", "100010", "010001", "001001", "000110"}, 4
    },
    {
        2, {"01", "10"}, 2
    },
    {
        3, {"011", "101", "110"}, -1
    },
    {
        6, {"010110", "101001", "010100", "101000", "100000", "010000"}, 4
    }
};
#endif

#define min(a, b)   ((a)>(b)?(b):(a))
#define max(a, b)   ((a)<(b)?(b):(a))

void
solver(int n, char s[200][201])
{
    int i, j, k;
    int d[200][200];
    int a=0;
    int row;

    for (i=0; i<n; i++) {
        row = 0;
        for (j=0; j<n; j++) {
            if (i==j) {
                d[i][j] = 0;
            }
            else if (s[i][j]=='0') {
                d[i][j] = 2 * n;
            }
            else {
                d[i][j] = 1;
            }
            row = row + d[i][j];
        }
        if (row==2*n*(n-1)) {
            printf("-1\n");
            return;
        }
    }

#ifdef TRACE
    printf("Start\n");
    for (i=0; i<n; i++) {
        for (j=0; j<n; j++) {
            printf("%d ", d[i][j]);
        }
        printf("\n");
    }
#endif
    
    for (k=0; k<n; k++) {
        for (i=0; i<n; i++) {
            for (j=0; j<n; j++) {
                if (d[i][k]==2*n || d[k][j]==2*n)
                    continue;
                if (j!=k && ((d[k][j]==1 && d[i][j] == d[i][k]) || (d[i][k]==1 && d[i][j]==d[k][j]))) {
                    //printf("%d, %d, %d: %d %d %d\n", i, j, k, d[i][j], d[i][k], d[k][j]);
                    printf("-1\n");
                    return;
                }
                if (d[i][j]>=d[i][k]+d[k][j]) {
//                    printf ("%d <- %d + %d\n", d[i][j], d[i][k], d[k][j]);
                    d[i][j] = d[i][k]+d[k][j];
                }
            }
        }
    }
    for (i=0; i<n; i++) {
        for (j=0; j<n; j++) {
            a = max(a, d[i][j]);
        }
    }
#ifdef TRACE
    printf("End\n");
    for (i=0; i<n; i++) {
        for (j=0; j<n; j++) {
            printf("%d ", d[i][j]);
        }
        printf("\n");
    }
#endif
    printf("%d\n", a+1);
}
    
int
main(int argc, char *argv[])
{
    int i;
    int N;
    char S[200][201];
    
#ifdef DEBUG
    for (i=0; i<1; i++) {
        solver(t[i].N, t[i].S);
        printf("%d\n", t[i].a);
    }
#else
    scanf("%d", &N);
    for (i=0; i<N; i++) {
        scanf("%s", S[i]);
    }
    solver(N, S);
#endif

    return 0;
}