def get_int
  gets.chop.to_i
end

def get_ints
  gets.chop.split.map(&:to_i)
end

def get_double
  gets.chop.to_f
end

def get_str
  gets.chop
end

def get_strs
  gets.chop.split
end

def get_max(x1, x2)
  x1 > x2 ? x1 : x2
end

def get_min(x1, x2)
  x1 < x2 ? x1 : x2
end

def main
  n = get_int
  edges_by_node = []
  n.times do |i|
    edges_by_node << get_str.chars.map(&:to_i)
  end
  if not is_bi_graph(n, edges_by_node)
    puts -1
    exit 0
  end

  d = calc_max_distant(n, edges_by_node)
  puts (d + 1)
end

def is_bi_graph(n, edges_by_node)
  colors = [-1] * n

  colors[0] = 0
  stack = [0]
  while stack.size >= 1
    node = stack.pop
    color = colors[node]
    next_color = color == 0 ? 1 : 0
    edges_by_node[node].each_with_index do |cnt, next_node|
      next if cnt == 0
      return false if colors[next_node] == color
      if colors[next_node] == -1
        colors[next_node] = next_color
        stack << next_node
      end
    end
  end
  true
end

INF = 10 ** 5

def calc_max_distant(n, edges_by_node)
  dp = Array.new(n) { [0] * n }
  edges_by_node.each_with_index do |edges, i|
    edges.each_with_index do |e, j|
      if i == j
        dp[i][j] = 0
      else
        dp[i][j] = e == 0 ? INF : 1
      end
    end
  end
  max_d = 0
  (0...n).each do |k|
    (0...n).each do |i|
      (0...n).each do |j|
        d1 = dp[i][j]
        d2 = dp[i][k]
        d3 = dp[k][j]
        d = get_min(d1, d2 + d3)
        dp[i][j] = d
        if d < INF and d > max_d and i != j
          max_d = d
        end
      end
    end
  end
  max_d
end

if __FILE__ == $0
  main
end
