#include <iostream>
#include <string>
#include <utility>
#include <stack>
#include <vector>
#include <queue>
#include <algorithm>
#include <map>
#include <climits>
#include <set>
#include <cmath>
#include <numeric>

using namespace std;


vector <pair<int, int>> edges[1000][1000];
vector <pair<int, int>> reverse_edges[1000][1000];
vector <pair<int, int> > tp_ord;
int in_degree[1000][1000];
bool visited[1000][1000];
bool in_stack[1000][1000];
int dp[1000][1000];

bool cycle_dfs(pair <int, int> cur){
    visited[cur.first][cur.second] = true;
    in_stack[cur.first][cur.second] = true;

    for(int i = 0; i < edges[cur.first][cur.second].size(); i++){
        auto next = edges[cur.first][cur.second][i];
        if(visited[next.first][next.second] && in_stack[next.first][next.second]){
            return false;
        }
        if(!visited[next.first][next.second]){
            if(!cycle_dfs(next)){
                return false;
            }
        }
    }
    in_stack[cur.first][cur.second] = false;
    return true;
}

void tp_dfs(pair <int, int> cur){
    visited[cur.first][cur.second] = true;
    for(int i = 0; i < edges[cur.first][cur.second].size(); i++){
        auto next = edges[cur.first][cur.second][i];
        if(!visited[next.first][next.second]){
           tp_dfs(next); 
        }
    }
    tp_ord.push_back(cur);
}

int A[1000][1000];



int main(){
    int N;
    cin >> N;

    for(int i = 0; i < N; i++){
        for(int j = 0; j < N - 1; j++){
            cin >> A[i][j];
        }
    }

    for(int i = 0; i < N; i++){
        for(int j = 0; j < N - 2; j++){
            edges[min(i, A[i][j] - 1)][max(i, A[i][j] - 1)].push_back(make_pair(min(i, A[i][j + 1] - 1), max(i, A[i][j + 1] - 1)));
            reverse_edges[min(i, A[i][j + 1] - 1)][max(i, A[i][j + 1] - 1)].push_back(make_pair(min(i, A[i][j] - 1), max(i, A[i][j] - 1)));
            in_degree[min(i, A[i][j + 1] - 1)][max(i, A[i][j + 1] - 1)] ++;
        }
    }


    for(int i = 0; i < N - 1; i++){
        for(int j = i + 1; j < N; j++){
            if(!visited[i][j]){
                if(!cycle_dfs(make_pair(i, j))){
                    cout << -1 << endl;
                    return 0;
                }
            }
        }
        
    }
    
    for(int i = 0; i < N - 1; i++){
        for(int j = i + 1; j < N; j++){
            visited[i][j] =  false;
        }
    }

    for(int i = 0; i < N - 1; i ++){
        for(int j = i + 1; j < N; j++){
            if(!visited[i][j] && in_degree[i][j] == 0){
                tp_dfs(make_pair(i, j));
            }
        }
    }

    //reverse(tp_ord.begin(), tp_ord.end());

    for(int i = 0; i < tp_ord.size(); i++){
        auto cur = tp_ord[i];
        for(int j = 0; j < reverse_edges[cur.first][cur.second].size(); j++){
            auto next = reverse_edges[cur.first][cur.second][j];
            dp[next.first][next.second] = max(dp[next.first][next.second], dp[cur.first][cur.second] + 1);
        }
    }

    int ans = 0;
    for(int i = 0; i < N - 1; i++){
        for(int j = 0; j < N; j++){
            if(in_degree[i][j] == 0){
                ans = max(ans, dp[i][j]);
            }
        }
    }
    cout << ans + 1 << endl;
    
    /*
    cout << tp_ord.size() << endl;
    for(int i = 0; i < tp_ord.size(); i++){
        cout << tp_ord[i].first << " " << tp_ord[i].second << endl;
    }
    cout << endl;
    for(int i = 0; i < N - 1; i++){
        for(int j = i + 1; j < N; j++){
            cout << dp[i][j] << " ";
        }
    }
    cout << endl;
    */
    return 0;
}

Measured memory_bytes: 96240