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>
#include<iostream>
#include<stack>
#include<string>
#include<vector>
#include<queue>
#include<map>
#include<algorithm>
#include<iomanip>
#include<set>
#include<bitset>
#include<cmath>
#include<numeric>
#include<limits>
#include<functional>
#include <bitset>

#define REP(i, m, n) for(int i = (m); i < (n); i++)
#define rep(i,n) REP(i,0,n)
#define NIL -1
#define INFTY (1 << 21)
using namespace std;

typedef long long ll;
typedef long long int lli;
// static const int MOD = 10000007;
// static const int MAX = 100005;
static const int ln = 201;
static const int WHITE = 0;
static const int GRAY = 1;
static const int BLACK = 2;

// static const int NMAX = 5005;
// static const lli INFTY = 1000000000000;

// typedef priority_queue<int, greater<int>> RevQ;
int N;
int color[ln], d[ln];
int M[ln][ln];
int tree[ln][ln];
bool flag = false;


void bfs(int s) { // sを始点としたBFS
  // initialization
  queue<int> Q;
  rep(i, N) {
    color[i] = WHITE;
    d[i] = INFTY;
  }
  color[s] = GRAY;
  d[s] = 0;
  Q.push(s);
  while ( !Q.empty() ) {
    int u = Q.front(); Q.pop();
    rep(v, N) {
      if ( M[u][v] && color[v] == WHITE ) {
        Q.push(v);
        tree[u][v] = tree[v][u] = 1;
        d[v] = d[u] + 1;
        color[v] = GRAY;
      } else if (M[u][v] && color[v] == GRAY && d[v] == d[u]) {
        flag = true;
        return;
      }
    }
    color[u] = BLACK;
    // cout << "u : " << u << endl;
  }
}
void bfs2(int s) { // sを始点としたBFS
  // initialization
  queue<int> Q;
  rep(i, N) {
    color[i] = WHITE;
    d[i] = INFTY;
  }
  color[s] = GRAY;
  d[s] = 0;
  Q.push(s);
  while ( !Q.empty() ) {
    int u = Q.front(); Q.pop();
    rep(v, N) {
      if ( tree[u][v] && color[v] == WHITE ) {
        Q.push(v);
        d[v] = d[u] + 1;
        color[v] = GRAY;
      } else if (tree[u][v] && color[v] == GRAY && d[v] == d[u]) {
        flag = true;
        return;
      }
    }
    color[u] = BLACK;
    // cout << "u : " << u << endl;
  }
}

int main(){
  cin >> N;
  string s;
  rep(i,N) {
    cin >> s;
    rep(j, N) {
      if (s[j] == '0') M[i][j] = 0;
      else M[i][j] = 1;
    }
  }
  rep(i, N) rep(j,N) {
    tree[i][j] = 0;
  }
  bfs(0);
  // cout << "first" << endl;
  if (flag) {
    cout << -1 << endl;
    return 0;
  }
  int maxv = 0;
  int tgt = 0;
  rep(i, N) {
    if(d[i] == INFTY) continue;
    if(maxv < d[i]) {
      maxv = d[i];
      tgt = i;
    }
  }
  bfs2(tgt);
  // cout << " second" << endl;
  maxv = 0;
  rep(i, N) {
    if(d[i] == INFTY) continue;
    maxv = max(maxv, d[i]);
  }

  cout << maxv+1 << endl;
}