#include <bits/stdc++.h>
using namespace std;
typedef long long int ll;
typedef vector<ll> vl;
typedef pair<ll, ll> PP;
#define rep(i, n) for(ll i = 0; i < ll(n); i++)
template <class T> void corner(bool flg, T hoge) {
    if(flg) {
        cout << hoge << endl;
        exit(0);
    }
}
#define all(v) v.begin(), v.end()
#define inputv(v, n)                                                           \
    vl v;                                                                      \
    rep(i, n) {                                                                \
        ll x;                                                                  \
        cin >> x;                                                              \
        v.push_back(x);                                                        \
    }
const ll INF = 999999999999999;
const ll MOD = 1000000007;
const ll MAX_N = 500010;
ll a, b, c, d, e, f, p, t, x, y, z, q, m, n, r, h, k, w, l, ans;
struct edge {
    ll to, cost;
};
struct Gragh {
    vector<vector<edge>> G;
    ll N;
    vl visited;
    void init(ll n) {
        N = n;
        G.resize(N);
        visited = vl(N, 0);
    }

    void add(ll a, ll b, ll c = 1) { G[a].push_back((edge){b, c}); }

    void resetv(void) { visited = vl(N, 0); }

    vl Dijkstra(ll r) {
        vl cost(N, INF);
        resetv();
        priority_queue<PP, vector<PP>, greater<PP>> pq;
        ll a, b = r;
        cost[b] = 0;
        visited[b] = 1;

        for(edge i : G[b]) {
            if(cost[b] + i.cost < cost[i.to]) {
                pq.push(make_pair(cost[b] + i.cost, i.to));
            }
        }
        while(!pq.empty()) {
            a = pq.top().first;
            b = pq.top().second;
            pq.pop();
            if(visited[b] == 1)
                continue;
            visited[b] = 1;
            cost[b] = a;
            for(edge i : G[b]) {
                if(cost[b] + i.cost < cost[i.to]) {
                    pq.push(make_pair(cost[b] + i.cost, i.to));
                }
            }
        }

        return cost;
    }

    vl active;
    ll isloop = 0;
    vl toposo;

    vl TOPOSO(void) {
        active.resize(N);
        active = vl(N, 0);
        visited = vl(N, 0);
        rep(i, N) {
            if(visited[i] == 0)
                dfs_toposo(i);
        }
        return toposo;
    }

    void dfs_toposo(ll x) {
        visited[x] = 1;
        active[x] = 1;
        for(edge P : G[x]) {
            ll i = P.to;
            if(visited[i] == 0) {
                dfs_toposo(i);
            } else {
                if(active[i] == 1)
                    isloop = 1;
            }
        }
        active[x] = 0;
        toposo.push_back(x);
    }
};
ll A[1000][1000], B[1000][1000],dp[1000000];
int main() {
    cin >> n;
    Gragh G;
    G.init(n*n);

    rep(i, n) {
        rep(j, n - 1) {
            cin >> A[i][j];
            k = A[i][j] - 1;
            if(i > k)
                a = k * n + i;
            else
                a = i * n + k;
            B[i][j]=a;
            if(j>0)G.add(B[i][j-1],B[i][j]);
        }
    }

    vl X = G.TOPOSO();
    corner(G.isloop == 1, -1);


    rep(i, n*n) {
        a = X[i];
        for(edge i : G.G[a]) {
            k = i.to;
            dp[a] = max(dp[a], dp[k] + 1);
        }
        ans=max(ans,dp[a]);
    }

    cout << ans + 1 << endl;
}

Measured memory_bytes: 104048