// वाह मोदी जी वाह!

#include<iostream>
#include<algorithm>
#include<bitset>

#include<cmath>
#include<cstring>
#include<climits>

#include<deque>
#include<vector>
#include<set>
#include<map>
#include<unordered_set>
#include<unordered_map>

#include<fstream>
#include<chrono>
using namespace std;

typedef long long LL;
typedef pair<LL,LL> p64;
typedef vector<LL> v64;

#define pb push_back
#define mp make_pair
#define ff first
#define ss second
#define rep(i,s,e) for(long long i=s;i<=e;i++)
#define brep(i,s,e) for(long long i=s;i>=e;i--)
#define all(x) x.begin(),x.end()
#define mem(x,y) memset(x,y,sizeof(x))
#define DANGER std::ios::sync_with_stdio(false); cin.tie(NULL); cout.tie(NULL)

vector< p64 > adj[1001][1001];

LL state[1001][1001];
LL dist[1001][1001];
bool cycle = false;

void DFS(LL ni, LL nj)
{
    if( state[ni][nj]==2 ) return;
    state[ni][nj] = 1;
    for(auto i:adj[ni][nj])
    {
        if( state[i.ff][i.ss]==1 ) cycle = true;
        else DFS( i.ff,i.ss );
    }
    state[ni][nj] = 2;
}

LL mxDEP = 1;

void DFS2(LL ni, LL nj)
{
    if( state[ni][nj]==1 ) return;
    state[ni][nj] = 1;
    LL sm = 0;
    for(auto i:adj[ni][nj])
    {
        DFS2( i.ff,i.ss );
        sm = max( dist[i.ff][i.ss],sm );
    }
    dist[ni][nj] = sm + 1;
}

// Problem E - League

int main()
{
    // DANGER;
    ofstream out("output.txt");

    auto start = chrono::high_resolution_clock::now();
    
    LL n;
    cin>>n;

    LL grid[n][n-1];
    rep(i,0,n-1) rep(j,0,n-2) cin>>grid[i][j], grid[i][j]--;

    // Construct the graph
    rep(i,0,n-1)
    {
        p64 prv = mp( min( i,grid[i][0] ),max( i,grid[i][0] ) );
        rep(j,1,n-2)
        {
            p64 cur = mp( min( i,grid[i][j] ),max( i,grid[i][j] ) );
            adj[prv.ff][prv.ss].pb( cur );
            prv = cur;
        }
    }

    // Check if answer will be -1 by checking for cycle in the graph
    mem( state,0 );
    // 0 Unvisited, 1 Not fully discovered, 2 Discovered
    rep(i,0,n-1) DFS( min( i,grid[i][0] ),max( i,grid[i][0] ) );

    if( cycle )
    {
        cout<<"-1\n";
        return 0;
    }

    // Calculate the minimum number of days required

    mem( state,0 ), mem( dist,0 );
    rep(i,0,n-1) DFS2( min( i,grid[i][0] ),max( i,grid[i][0] ) );

    rep(i,0,n-1) rep(j,0,n-1) mxDEP = max( mxDEP,dist[i][j] );

    cout<<mxDEP<<"\n";

    // LL par[n][n], day[n][n];
    // mem( par,0 ), mem( day,0 );

    // // rep(x,1,10)
    // rep(i,0,n-1)
    // {
    //     rep(j,0,n-2)
    //     {
    //         LL P = i, Q = grid[i][j];
    //         LL p = min( P,Q ), q = max( P,Q );
    //         day[p][q] = max( day[p][q],par[p][q]+1 );
    //         for(auto k:adj[p][q])
    //         par[k.ff][k.ss] = max( par[k.ff][k.ss],day[p][q] );
    //     }
    // }

    // // rep(x,1,10)
    // rep(i,0,n-1)
    // {
    //     rep(j,0,n-1)
    //     {
    //         LL P = i, Q = j;
    //         LL p = min( P,Q ), q = max( P,Q );
    //         day[p][q] = max( day[p][q],par[p][q]+1 );
    //         for(auto k:adj[p][q])
    //         par[k.ff][k.ss] = max( par[k.ff][k.ss],day[p][q] );
    //     }
    // }

    // rep(i,0,n-1)
    // {
    //     rep(j,0,n-1) cout<<par[i][j]<<" ";
    //     cout<<endl;
    // }

    // rep(i,0,n-1)
    // {
    //     rep(j,0,n-1) cout<<day[i][j]<<" ";
    //     cout<<endl;
    // }

    // LL ans = 0;
    // rep(i,0,n-1) rep(j,0,n-1) ans = max( ans,day[i][j] );

    // cout<<ans<<"\n";
    
    auto stop = chrono::high_resolution_clock::now();
    // auto duration = chrono::duration_cast<chrono::milliseconds>(stop - start); 
    // cout << "Time taken by function: " << duration.count() << " milliseconds" << endl;
}

Measured memory_bytes: 72576