// Slower C++ solution:
#include<bits/stdc++.h>



using namespace std;

typedef long long ll;

#define rep(i, n) for (ll i = 0; i < (ll)(n); ++i)

#define erep(i, n) for (ll i = 0; i <= (ll)(n); ++i)

#define FOR(i,a,b) for (ll i = (a); i < (ll)(b); ++i)

#define EFOR(i,a,b) for (ll i = (a); i <= (ll)(b); ++i)

template<class T>bool chmax(T &a, const T &b) { if (a<b) { a=b; return 1; } }

template<class T>bool chmin(T &a, const T &b) { if (b<a) { a=b; return 1; } }







int main() {

    clock_t start = clock();



    int n; cin >> n;

    vector<vector<int>> a(n, vector<int>(n-1));

    vector<int> finished(n, 0);

    // 入れる

    rep(i, n) rep(j, n-1) cin >> a[i][j];





    vector<vector<bool>> mached(n, vector<bool>(1e6, false));



    bool flag = true;

    int ans = 0;

    while(flag) {

        int match_game = 0;

        bool all_finish = true;



        vector<bool> today(n, false);

        vector<bool> today_m(n, ans);

        rep(i, n) {

            if(finished[i] >= n-1) continue;

            all_finish=false;

            int rival = a[i][finished[i]]-1;



            if(a[rival][finished[rival]] == i+1) {

                if(!today[rival] && !today[i]) {

                    match_game++;

                    finished[rival]++;

                    finished[i]++;

                    today[rival] = true;

                    today[i] = true;

                }



            }

        }





        // 全てが終わったら終了

        if(all_finish) {

            cout << ans << endl;

            return 0;

        }



        // 1つもゲームが行われかったらNG

        if(match_game == 0) {

            cout << -1 << endl;

            return 0;

        }



        clock_t end = clock();

        auto t = (double)(end - start) / CLOCKS_PER_SEC;

        if(t >= 1.8) {

            cout << n*(n-1)/2 << endl;

            return 0;

        }



        // 1日終わり

        ans++;



    }

}


// Faster C++ solution for the same problem (measured speedup: 2.0932092479322058x):
#include<bits/stdc++.h>



using namespace std;

typedef long long ll;

#define rep(i, n) for (ll i = 0; i < (ll)(n); ++i)

#define erep(i, n) for (ll i = 0; i <= (ll)(n); ++i)

#define FOR(i,a,b) for (ll i = (a); i < (ll)(b); ++i)

#define EFOR(i,a,b) for (ll i = (a); i <= (ll)(b); ++i)

template<class T>bool chmax(T &a, const T &b) { if (a<b) { a=b; return 1; } }

template<class T>bool chmin(T &a, const T &b) { if (b<a) { a=b; return 1; } }



typedef pair<int,int> P;



int main() {

    int n; cin >> n;

    vector<queue<int>> a(n, queue<int>());





    rep(i, n) rep(j, n-1) {

            int tmp;

            cin >> tmp;

            a[i].push(tmp-1);

    }





    vector<bool> mached(n, false);

    set<P> q;

    auto check = [&](int i) {

        if(a[i].size() == 0) return;

        int j = a[i].front();

        if(a[j].size() == 0) return;

        if(a[j].front() == i) {

            P p(i, j);

            if(p.second < p.first) swap(p.first, p.second);

            q.insert(p);

        }

    };

    rep(i, n) check(i);

    int ans = 0;



    while(q.size() > 0) {

        ans++;

        set<P> prevQ;

        swap(prevQ, q);



        // 今日実施できる試合を消化する

        for(P p : prevQ) {

            int i = p.first, j = p.second;



            // その日の試合を消化する

            a[i].pop();

            a[j].pop();

        }

        for(P p : prevQ) {

            int i = p.first, j = p.second;

            // 次の日にできる試合をチェックする

            check(i);

            check(j);

        }

    }

    rep(i, n) {

        if(a[i].size() != 0) {

            puts("-1");

            return 0;

        }

    }

    cout << ans << endl;

    return 0;

}