#include <algorithm>
#include <bitset>
#include <complex>
#include <deque>
#include <exception>
#include <fstream>
#include <functional>
#include <iomanip>
#include <ios>
#include <iosfwd>
#include <iostream>
#include <istream>
#include <iterator>
#include <limits>
#include <list>
#include <locale>
#include <map>
#include <memory>
#include <new>
#include <numeric>
#include <ostream>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <stdexcept>
#include <streambuf>
#include <string>
#include <typeinfo>
#include <utility>
#include <valarray>
#include <vector>
#include <climits>
#include <cstring>

#define rep(i, m, n) for(int i=int(m);i<int(n);i++)
#define all(c) begin(c),end(c)

template<typename T1, typename T2>
inline void chmin(T1 &a, T2 b) { if (a > b) a = b; }

template<typename T1, typename T2>
inline void chmax(T1 &a, T2 b) { if (a < b) a = b; }

typedef long long int ll;
using ll = long long int;
using ull = long long unsigned int;
using Int = long long int;
using namespace std;
#define INF (1 << 30) - 1
#define INFl (ll)5e15
#define DEBUG 0
#define dump(x)  cerr << #x << " = " << (x) << endl
#define MOD 1000000007


//edit
class Solve {
public:
    vector<vector<Int>> G;
    vector<int> col;

    set<int> cir;
    vector<int> dig;

    bool dfs(int v = 0, int c = 0, int p = -1) {
        if (col[v] != -1) {
            return col[v] == c;
        }
        bool ret = true;
        col[v] = c;
        for (auto e : G[v]) {
            if (v != p) {
                bool tmp = dfs(e, 1 - c, v);
                if (!tmp) ret = false;
            }
        }
        return ret;
    }

    // 派生元, 深さ
    pair<int, int> dfs2(int v, int p = -1) {
        if (cir.count(v)) {
            return make_pair(col[v], 0);
        }
        for (auto e : G[v]) {
            if (e != p) {
                auto ret = dfs2(e, v);
                ret.second++;
                return ret;
            }
        }
    }

    pair<int, int> dfs3(int v, int p = -1) {
        pair<int, int> ret = make_pair(v, 1);
        for (auto e : G[v]) {
            if (e != p) {
                auto tmp = dfs3(e, v);
                tmp.second++;
                if (ret.second < tmp.second) {
                    ret = tmp;
                }
            }
        }
        return ret;
    };

    void solve() {
        Int N;
        cin >> N;
        G.resize(N);
        vector<vector<Int>> d(N, vector<Int>(N, INFl));
        col.resize(N, -1);
        dig.resize(N);

        for (int i = 0; i < N; ++i) {
            cir.insert(i);
            for (int j = 0; j < N; ++j) {
                if (i == j) d[i][j] = 0;
                char c;
                cin >> c;
                if (c == '1') {
                    G[i].push_back(j);
                    dig[i]++;
                    d[i][j] = 1;
                }
            }
        }

        if (!dfs()) {
            cout << -1 << endl;
            return;
        }

        for (int k = 0; k < N; k++) {
            for (int i = 0; i < N; i++) {
                for (int j = 0; j < N; j++) {
                    if (d[i][j] > d[i][k] + d[k][j]) {
                        d[i][j] = d[i][k] + d[k][j];
                    }
                }
            }
        }

        Int ans = 0;
        for (int i = 0; i < N; ++i) {
            for (int j = 0; j < N; ++j) {
                int tmp = d[i][j] + 1;
                chmax(ans, tmp);
            }
        }
        cout << ans << endl;

    }
};

void gene() {
    Int N, M;
    cin >> N >> M;
    vector<vector<Int>> G(N, vector<Int>(N));
    for (int i = 0; i < M; ++i) {
        int a, b;
        cin >> a >> b;
        G[a][b] = 1;
        G[b][a] = 1;
    }
    cout << N << endl;
    for (int i = 0; i < N; ++i) {
        for (int j = 0; j < N; ++j) {
            cout << G[i][j];
        }
        cout << endl;
    }

}


int main() {
    cin.tie(0);
    ios::sync_with_stdio(false);
    cout << fixed << setprecision(10);
//    gene();

    Solve().solve();


    return 0;
}


Measured memory_bytes: 1024