#include<bits/stdc++.h>
using namespace std;

#define int long long
#define double long double
#define rep(i, n) for (int i = 0; i < (int) n; i++)
#define reps(i, n) for (int i = 1; i <= (int) n; i++)
#define all(x) (x).begin(), (x).end()
#define uniq(v) v.erase(unique(v.begin(), v.end()), v.end());
#define bit(n) (1LL << (n))
#define dump(x) cerr << #x " = " << x << endl
using vint = vector<int>;
using vvint = vector<vint>;
using pint = pair<int, int>;
constexpr double pi = 3.1415926535897932384626433832795028;
constexpr int dy[8] = {0, 1, 0, -1, 1, 1, -1, -1};
constexpr int dx[8] = {1, 0, -1, 0, 1, -1, -1, 1};
inline int gcd(int a, int b) { return b ? gcd(b, a % b) : a; }
inline int lcm(int a, int b) { return a / gcd(a, b) * b; }
template<typename T> using priority_queue_rev = priority_queue<T, vector<T>, greater<T>>;
template<typename T1, typename T2> inline bool chmax(T1 &a, const T2 &b) {
    if (a < b) {
        a = b;
        return true;
    }
    return false;
}
template<typename T1, typename T2> inline bool chmin(T1 &a, const T2 &b) {
    if (b < a) {
        a = b;
        return true;
    }
    return false;
}
template<typename T1, typename T2> ostream &operator<<(ostream &os, const pair<T1, T2> &p) {
    os << "(" << p.first << ", " << p.second << ")";
    return os;
}
template<typename T> ostream &operator<<(ostream &os, const vector<T> &p) {
    os << "{";
    for (auto itr = p.begin(); itr != p.end(); itr++) {
        itr++;
        if (itr != p.end()) { os << ", "; }
        itr--;
    }
    os << "}";
    return os;
}
struct SetUp {
    static constexpr int PREC = 20;
    SetUp() {
        cout << fixed << setprecision(PREC);
        cerr << fixed << setprecision(PREC);
    };
} setUp;

template<typename T>
struct WarshallFloyd {
    const int n;
    const T INF;
    std::vector<std::vector<int>> G;
    WarshallFloyd(int n, T INF) : n(n), INF(INF), G(n, std::vector<int>(n, INF)) {
        for (int i = 0; i < n; i++) { G[i][i] = 0; }
    }
    void addEdge(int from, int to, T cost) { G[from][to] = cost; }
    std::vector<std::vector<T>> getDist() const {
        std::vector<std::vector<T>> dist(G);
        for (int k = 0; k < n; k++) {
            for (int i = 0; i < n; i++) {
                for (int j = 0; j < n; j++) {
                    if (dist[i][k] == INF || dist[k][j] == INF) { continue; }
                    dist[i][j] = std::min(dist[i][j], dist[i][k] + dist[k][j]);
                }
            }
        }
        return dist;
    }
};

int N;
bool S[220][220];
bool visited[220], color[220];
void dfs(int idx, bool c) {
    visited[idx] = true;
    color[idx] = c;
    rep(i, N) {
        if (i == idx || !S[idx][i]) { continue; }
        if (visited[i]) {
            if (color[i] == c) {
                cout << -1 << endl;
                exit(0);
            } else { continue; }
        }

        dfs(i, !c);
    }
}
signed main() {
    cin >> N;
    WarshallFloyd<int> wf(N, INT_MAX);
    rep(i, N) {
        string s;
        cin >> s;
        rep(j, N) {
            if (s[j] == '1') { S[i][j] = 1, wf.addEdge(i, j, 1); }
        }
    }
    dfs(0, 0);
    vector<vint> dist = wf.getDist();
    int ans = 0;
    rep(i, N)rep(j, N) { chmax(ans, dist[i][j] + 1); }
    cout << ans << endl;
}


Measured memory_bytes: 896