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>
using namespace std;

//repetition
#define FOR(i,a,b) for(ll i=(a);i<(b);++i)
#define rep(i, n) for(ll i = 0; i < (ll)(n); i++)

//container util
#define all(x) (x).begin(),(x).end()

//typedef
typedef long long ll;
typedef vector<int> VI;
typedef vector<VI> VVI;
typedef vector<ll> VLL;
typedef vector<VLL> VVLL;
typedef vector<string> VS;
typedef pair<int, int> PII;
typedef pair<ll, ll> PLL;

//const value
//const ll MOD = 1e9 + 7;
//const int dx[] = {0,1,0,-1};//{0,0,1,1,1,-1,-1,-1};
//const int dy[] = {1,0,-1,0};//{1,-1,0,1,-1,0,1,-1};

//conversion
inline int toInt(string s) {int v; istringstream sin(s);sin>>v;return v;}
inline ll toLL(string s) {ll v; istringstream sin(s);sin>>v;return v;}
template<class T> inline string toString(T x) {ostringstream sout;sout<<x;return sout.str();}

int n;
int col[201];
string b[201];
bool dfs(int current){
  bool flag = true;
  rep(i,n){
    if(b[current][i] == '1'){
      if(col[i] == 0) {
        col[i] = (col[current]==0)?1:0;
        flag &= dfs(i);
      }
      else if(col[i] == col[current]) return false;
      else continue;
    }
  }
  return flag;
}
int main(){
  ios::sync_with_stdio(false);
  cin.tie(0);

  cin >> n;

  rep(i,n) cin >> b[i];

  if (dfs(0) == false){
    cout << -1 << endl;
    return 0;
  }
  ll dist[n][n];
  rep(i,n) rep(j,n) {
    if(i == j ) dist[i][j] = 0;
    else if(b[i][j] == '1') dist[i][j] = 1;
    else dist[i][j] = INT_MAX;
  }

  rep(k,n) rep(i,n) rep(j,n)  {
    dist[i][j] = min(dist[i][k]+dist[k][j], dist[i][j]);
  }
  // rep(i,n){
  //   rep(j,n) cout << dist[i][j] << " ";
  //   cout << endl;
  // }
  ll ans = 0;
  rep(i,n){
    ll tmp = 0;
    rep(j,n){
      tmp = max(tmp,dist[i][j]);
    }
    ans = max(ans,tmp);
  }
  cout << ans + 1<< endl;
  return 0;
}