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 Java8 (OpenJDK 1.8.0) (judge verdict: Wrong Answer)

import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.Scanner;
import java.util.AbstractMap.SimpleEntry;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Queue;

class Main {

    static final int MOD = 1000000007;

    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int size = sc.nextInt();

        for (int i = 0; i < size; i++)
            Node.nodeList.add(new Node(i));
        for (int i = 0; i < size; i++) {
            String s = sc.next();
            for (int k = 0; k < size; k++) {
                if (s.charAt(k) == '1') {
                    Node.nodeList.get(i).addEdge(Node.nodeList.get(k));
                }
            }
        }

        // ArrayList<HashSet> arset = new ArrayList<HashSet>();
        int ans = 0;
        for (Node node : Node.nodeList) {
            // if(node.isLeaf){
            ArrayList<HashSet<Node>> solver = new ArrayList<HashSet<Node>>();
            ArrayDeque<SimpleEntry<Node,Integer>> queue = new ArrayDeque<SimpleEntry<Node,Integer>>();
            HashSet<Node> qset = new HashSet<Node>();
            queue.add(new SimpleEntry<>(node,0));
            while(!queue.isEmpty()){
                SimpleEntry<Node,Integer> se = queue.poll();
                if(qset.contains(se.getKey()))continue;
                qset.add(se.getKey());
                if(!se.getKey().check(solver, queue, se.getValue())){
                    break;
                }
            }
            if (queue.isEmpty()) {
                ans = Math.max(solver.size(), ans);
            }
            //System.out.println(Arrays.toString(solver.toArray()));
        }

        System.out.println(ans != 0 ? ans : -1);
    }
}

class Node {
    static ArrayList<Node> nodeList = new ArrayList<Node>();
    final int number;
    // HashSet myset = ;
    boolean isLeaf = true;
    ArrayList<Node> edge = new ArrayList<Node>();

    Node(int number) {
        this.number = number;
    }

    ArrayList<Node> exs = new ArrayList<Node>();
    public boolean check(ArrayList<HashSet<Node>> arset, ArrayDeque<SimpleEntry<Node,Integer>> queue, int set) {
        //System.out.println("call"+number+"  "+ set);
        if (set >= arset.size()) {
            arset.add(new HashSet<Node>());
            arset.get(set).add(this);
        }
        int con = 0;
        for (int k = 0; k < arset.size(); k++) {
            HashSet<Node> hs = arset.get(k);
            if (hs.contains(this)) {
                con++;
                if (con > 1)
                    return false;
                if (k == set)
                    continue;
                return false;
            }
        }
        exs = new ArrayList<Node>();
        for (int i = 0; i < edge.size(); i++) {
            Node n = edge.get(i);
            for (int k = 0; k < arset.size(); k++) {
                HashSet<Node> hs = arset.get(k);
                if (hs.contains(n)) {
                    if (Math.abs(k - set) == 1)
                        continue;
                    return false;
                }
            }
            if (set >= 1 && arset.get(set - 1).contains(n))
                continue;
            queue.add(new SimpleEntry<>(n,set+1));
        }
        return true;
    }

    void addEdge(Node n) {
        edge.add(n);
        if (edge.size() <= 1)
            isLeaf = true;
        else
            isLeaf = false;
    }
}