import java.lang.Math
import java.util.ArrayDeque

val INF = 1000000000

fun main(args: Array<String>) {
    val N = readInputLine().toInt()
    val S = Array(N) { readInputLine().toCharArray() }
    val edges = Array(N) { mutableListOf<Int>() }

    for (i in 0 until N) {
        for (j in 0 until N) {
            if (S[i][j] == '1') {
                edges[i].add(j)
            }
        }
    }

    val (ok, color) = isBipartite(N, edges)

    if (!ok) {
        println(-1)
        return
    }

    val d = warshallFloyd(N, edges)

    var maxDist = 0

    for (i in 0 until N) {
        for (j in 0 until N) {
            if (d[i][j] < INF) {
                maxDist = Math.max(d[i][j], maxDist)
            }
        }
    }

    for (i in 0 until N) {
        val nextNodes = mutableSetOf<Int>()
        for (j in 0 until N) {
            if (d[i][j] == 1) {
                nextNodes.add(j)
            }
        }
        for (k in nextNodes) {
            for (l in nextNodes) {
                if (k == l) {
                    continue
                }
                if (d[k][l] == 1) {
                    println(-1)
                    return
                }
            }
        }
    }

    println(maxDist + 1)
}

fun readInputLine(): String {
    return readLine()!!
}

// ワーシャル-フロイド法
// O(V^3)のグラフ全ノード間の距離を求めるアルゴリズム
fun warshallFloyd(n: Int, edges: Array<MutableList<Int>>): Array<IntArray> {
    val d = Array(n) { IntArray(n) { INF } }

    for (i in 0 until n) {
        d[i][i] = 0
    }

    for ((i, es) in edges.withIndex()) {
        for (e in es) {
            d[i][e] = 1
        }
    }

    for (k in 0 until n) {
        for (i in 0 until n) {
            for (j in 0 until n) {
                d[i][j] = Math.min(d[i][j], d[i][k] + d[k][j])
            }
        }
    }

    return d
}

// 2部グラフ判定
// グラフを2つの頂点集合に分割し、集合内の頂点同士では辺が存在しないグラフが存在するか判定する
// 分割できる場合は分割の方法も返す
fun isBipartite(n: Int, edges: Array<MutableList<Int>>): Pair<Boolean, IntArray> {
    val color = IntArray(n) { -1 }
    color[0] = 0

    val queue = ArrayDeque<Int>(n)
    queue.add(0)

    while (queue.isNotEmpty()) {
        val node = queue.poll()!!
        val nodeColor = color[node]
        for (e in edges[node]) {
            if (color[e] == -1) {
                color[e] = (nodeColor + 1) % 2
                queue.add(e)
            } else if (color[e] == nodeColor) {
                return Pair(false, color)
            }
        }
    }

    return Pair(true, color)
}
