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)

#pragma GCC optimize("Ofast,fast-math,unroll-loops")
 
#include <bits/stdc++.h>
 
#define int ll
//#define double long double
#define endl '\n'
#define all(C) (C).begin(), (C).end()
#define rall(C) (C).rbegin(), (C).rend()
#define mp make_pair 
#define pb emplace_back
#define dbg(x) cerr << #x << " : " << x << endl
//#define PI 3.141592653589
 
using namespace std;
       
using ll = long long;
using ull = unsigned long long;
using ld = long double;
using pii = pair <int, int>;
       
/* 
const ll MAX_MEM = 7e8;
char MEM[MAX_MEM];
ll MEM_POS = 0;
void* operator new(size_t x)
{
    auto ret = MEM + MEM_POS;
    MEM_POS += x;
    assert(MEM_POS < MAX_MEM);
    return ret;
}
void operator delete(void*)
{}
*/
       
template <class T>
istream& operator>> (istream &in, vector <T> &a)
{
    for (auto &i : a)
        in >> i;
    return in;
}
       
template <class T> 
ostream& operator<< (ostream &out, vector <T> a)
{
    for (auto &i : a)
        out << i << ' ';
    return out;
}
       
template <class T, class U>
istream& operator>> (istream &in, pair <T, U> &p)
{
    in >> p.first >> p.second;
    return in;
}
       
template <class T, class U>
ostream& operator<< (ostream &out, pair <T, U> p)
{
    out << p.first << " " << p.second << " ";
    return out;
}
       
inline void Start()
{
    ios_base::sync_with_stdio(0);
    cin.tie(0), cout.tie(0);
    //freopen(".in", "r", stdin);
    //freopen(".out", "w", stdout);
}

int n;
vector <vector <int>> g;
vector <int> cl;
bool dfs(int v, int p = -1, int c = 0)
{
    cl[v] = c;
    bool f = true;
    for (auto &to : g[v])
    {
        if (to == p)
            continue;
        if (cl[to] == c)
            return false;
        if (cl[to] == -1)
            f = f && dfs(to, v, c ^ 1);
    }
    return f;
}

signed main()
{
    Start();
    cin >> n;
    g.resize(n);
    for (int i = 0; i < n; ++i)
    {
        for (int j = 0; j < n; ++j)
        {
            char c;
            cin >> c;
            if (c - '0')
                g[i].pb(j);
        }
    }
    cl.resize(n, -1);
    if (!dfs(0))
        return cout << -1, 0;
    const int INF = 1e9 + 7;
    cl.assign(n, INF);
    vector <int> tcl(n, INF);
    int ans = 0;
    cl[0] = 0;
    queue <int> q;
    pair <int, int> p(-1, -1);
    q.emplace(0);
    while (!q.empty())
    {
        int v = q.front();
        q.pop();
        p = max(p, mp(cl[v], v));
        for (auto &to : g[v])
        {
            if (cl[to] > cl[v] + 1)
            {
                cl[to] = cl[v] + 1;
                q.emplace(to);
            }
        }
    }
    int s = p.second;
    p = mp(-1, -1);
    tcl[s] = 0;
    q.emplace(s);
    while (!q.empty())
    {
        int v = q.front();
        q.pop();
        p = max(p, mp(tcl[v], v));
        for (auto &to : g[v])
        {
            if (tcl[to] > tcl[v] + 1)
            {
                tcl[to] = tcl[v] + 1;
                q.emplace(to);
            }
        }
    }
    ans = p.first + 1;
    cout << ans;
    return 0;
}