//{{{
#include<algorithm>
#include<cmath>
#include<deque>
#include<fstream>
#include<iomanip>
#include<iostream>
#include<map>
#include<numeric>
#include<queue>
#include<random>
#include<set>
#include<sstream>
#include<sys/time.h>
#include<unordered_map>
#include<unordered_set>
#include<vector>
using ll = long long;
enum : int { M = (int)1e9 + 7 };
enum : ll { MLL = (ll)1e18L + 9 };
using namespace std;
#ifdef LOCAL
#include"rprint2.hpp"
#else
#define FUNC(name) template <ostream& out = cout, class... T> void name(T&&...){ }
FUNC(printde) FUNC(printdbe) FUNC(printdwe) FUNC(printdu);
#endif
template <template <class T, class = std::allocator<T>> class V, class E>
istream& operator >> (istream& in, V<E>& v){ for(auto& e : v){ in >> e; } return in; }
//}}}
int n;
int memo[1000][1000];
int depth(vector<vector<int>>& as, vector<unordered_map<int, int>>& ras, int i, int j, int cnt = 0){
    if(memo[i][j]){
        return memo[i][j];
    }
    if(cnt > n * n){
        cout << -1 << '\n';
        exit(0);
    }
    int i2 = ras[i][j] - 1;
    int j2 = ras[j][i] - 1;
    int ret = 1;
    printde(i, j, i2, j2);
    if(i2 >= 0){
        int i3 = as[i][i2];
        printde(i, i3);
        ret = max(ret, depth(as, ras, i, i3, cnt + 1) + 1);
    }
    if(j2 >= 0){
        int j3 = as[j][j2];
        printde(j, j3);
        ret = max(ret, depth(as, ras, j, j3, cnt + 1) + 1);
    }
    return memo[i][j] = ret;
                            
}

int main(){
    cin.tie(0); ios::sync_with_stdio(false);
    cin >> n;
    vector<vector<int>> as(n, vector<int>(n - 1)); cin >> as;
    vector<unordered_map<int, int>> ras(n);
    for(int i = 0; i < n; i++){
        auto& v = as[i];
        for(int j = 0; j < n - 1; j++){
            auto& e = v[j];
            e--;
            ras[i][e] = j;
        }
    }
    int ans = 0;
    for(int i = 0; i < n; i++){
        for(int j = 0; j < i; j++){
            int ret = depth(as, ras, i, j);
            printde(i, j, ret);
            ans = max(ans, ret);
        }
    }
    cout << ans << '\n';
    // int ans = 0;
    // for(int i = 0; i < n; i++){
    //     int cnt = 0;
    //     int idx1 = i, idx2 = n - 2;
    //     while(idx2 >= 0){
    //         cnt++;
    //         printde(cnt, idx1, idx2);
    //         int op = as[idx1][idx2];
    //         int idx22 = ras[op][idx1] - 1;
    //         idx1 = op;
    //         idx2 = idx22;
    //         if(cnt > n * n){
    //             cout << -1 << '\n';
    //             return 0;
    //         }
    //     }
    //     ans = max(ans, cnt);
    // }
    // for(int i = 0; i < n; i++){
    //     int cnt = 0;
    //     int idx1 = i, idx2 = 0;
    //     while(idx2 >= 0){
    //         cnt++;
    //         printde(cnt, idx1, idx2);
    //         int op = as[idx1][idx2];
    //         int idx22 = ras[op][idx1] - 1;
    //         idx1 = op;
    //         idx2 = idx22;
    //         if(cnt > n * n){
    //             cout << -1 << '\n';
    //             return 0;
    //         }
    //     }
    //     ans = max(ans, cnt);
    // }
    // cout << ans << '\n';
    // // vector<int> idxs(n);
    // // unordered_map<int, int> mp;
    // // vector<int> is(n);
    // // iota(is.begin(), is.end(), 0);
    // // int cnt = 0;
    // // int ans= 0;
    // // while(is.size() && cnt < n * (n - 1) / 2){
    // //     ans++;
    // //     vector<int> nexts;
    // //     for(auto i : is){
    // //         if(mp.count(i)){
    // //             nexts.push_back(i);
    // //             nexts.push_back(mp[i]);
    // //             mp.erase(i);
    // //             idxs[i]++;
    // //             cnt++;
    // //         }else{
    // //             mp[as[i][idxs[i]]++] = i;
    // //         }
    // //         printde(mp);
    // //     }
    // //     is.swap(nexts);
    // //     printde(is, mp);
    // // }
    // // if(is.empty()){
    // //     cout << -1 << '\n';
    // // }else{
    // //     cout << ans << '\n';
    // // }
}


Measured memory_bytes: 141824