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 Rust (1.15.1) (judge verdict: Wrong Answer)

use std::io::Write;
use std::collections::VecDeque;

#[allow(unused)]
macro_rules! debug {
    ($($format:tt)*) => (write!(std::io::stderr(), $($format)*).unwrap());
}
#[allow(unused)]
macro_rules! debugln {
    ($($format:tt)*) => (writeln!(std::io::stderr(), $($format)*).unwrap());
}

fn main() {
    // 1つの数字
    let s = {
        let mut s = String::new();
        std::io::stdin().read_line(&mut s).unwrap();
        s.trim_right().to_owned()
    };
    let n: usize = s.parse().unwrap();

    // 1行ベクトル
    let mut graph_mat = vec![];
    for _ in 0..n {
        let s = {
            let mut s = String::new();
            std::io::stdin().read_line(&mut s).unwrap();
            s.trim_right().to_owned()
        };
        let v: Vec<usize> = s.split("").filter(|&x| x != "").map(|x| x.parse().unwrap()).collect();
        graph_mat.push(v);
    }
    debugln!("{:?}", graph_mat);

    // 配列形式からリスト形式に変換
    let mut graph_list = vec![vec![]; n];
    for i in 0..n {
        for j in 0..n {
            if graph_mat[i][j] == 1 {
                graph_list[i].push(j);
            }
        }
    }
    debugln!("{:?}", graph_list);

    // bfs(0, &graph_list);

    // 2部グラフかどうか判定
    // if 2部グラフなら、グラフの直径を求める
    if is_bipartite_graph(&graph_list) {
        let d = graph_diameter(&graph_list);
        println!("{}", d + 1);
    } else {
        println!("-1");
    }
}

// 幅優先探索
#[allow(unused)]
fn bfs(start: usize, graph_list: &Vec<Vec<usize>>) {
    let n = graph_list.len();

    let mut visited = vec![false; n];
    let mut queue: VecDeque<usize> = VecDeque::new();

    visited[start] = true;
    queue.push_back(start);

    while !queue.is_empty() {
        let vertex = queue.pop_front().unwrap();
        debugln!("visit {}", vertex);
        for &next in &graph_list[vertex] {
            if visited[next] == false {
                visited[next] = true;
                queue.push_back(next);
            }
        }
    }
}

// 2部グラフか判定
fn is_bipartite_graph(graph_list: &Vec<Vec<usize>>) -> bool {
    let n = graph_list.len();

    let mut visited = vec![false; n];
    let mut queue: VecDeque<(usize, bool)> = VecDeque::new();
    let mut colors = vec![true; n];

    let start = 0;
    visited[start] = true;
    queue.push_back((start, true));

    while !queue.is_empty() {
        let vertex = queue.pop_front().unwrap();

        debugln!("visit {:?}", vertex);
        colors[vertex.0] = vertex.1;

        for &next in &graph_list[vertex.0] {
            if visited[next] == false {
                visited[next] = true;
                queue.push_back((next, !vertex.1));
            } else {
                if colors[next] != !vertex.1 {
                    return false;
                }
            }
        }
    }

    true
}

// グラフの直径
fn graph_diameter(graph_list: &Vec<Vec<usize>>) -> usize {
    let start = 0;
    let d_v = distances(start, graph_list);

    let mut farthest = start;
    let mut d_max = 0;
    for (v, &d) in d_v.iter().enumerate() {
        if d > d_max {
            d_max = d;
            farthest = v;
        }
    }

    let start = farthest;
    let d_v = distances(start, graph_list);
    for (_, &d) in d_v.iter().enumerate() {
        if d > d_max {
            d_max = d;
        }
    }
    d_max
}

// startからの距離一覧を返す
#[allow(unused)]
fn distances(start: usize, graph_list: &Vec<Vec<usize>>) -> Vec<usize> {
    let n = graph_list.len();

    let mut visited = vec![false; n];
    let mut queue: VecDeque<(usize, usize)> = VecDeque::new();
    let mut distances = vec![std::usize::MAX; n];

    visited[start] = true;
    queue.push_back((start, 0));

    while !queue.is_empty() {
        let vertex = queue.pop_front().unwrap();

        debugln!("visit {:?}", vertex);
        if vertex.1 < distances[vertex.0] {
            distances[vertex.0] = vertex.1;
        }

        for &next in &graph_list[vertex.0] {
            if visited[next] == false {
                visited[next] = true;
                queue.push_back((next, vertex.1 + 1));
            } else {
                if distances[next] > vertex.1 + 1 {
                    queue.push_back((next, vertex.1 + 1));
                }
            }
        }
    }

    distances
}