// Original C++ solution (slower):
#include <iostream>

#include <iomanip>

#include <cstdlib>

#include <algorithm>

#include <vector>

#include <queue>

#include <stack>

#include <climits>

#include <string>

#include <set>

#include <cmath>

#include <map>

#include <unordered_map>

#include <numeric>

#include <random>

#include <memory>

#include <chrono>

#include <iterator>

#include <functional>

#ifdef LOCAL

#include "debug.h"

#else

#define debug(x...)

#endif

//#pragma GCC optimize("Ofast")



using namespace std;

typedef long long ll;

typedef long double ld;

typedef pair <int, int> pii;

#define mp make_pair

#define pb push_back

#define sz(x) int((x).size())



mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());

const int N = 1e3 + 7;

const int inf = INT_MAX / 2;

const ll INF = LLONG_MAX / 3;

const int MOD = 998244353;

const ld eps = 1e-6;

const string cars[] = {"🚗", "🚕", "🚙"};



deque < int > q[N];

short used[N];



signed main() {

#ifdef LOCAL

    freopen("input.txt", "r", stdin);

    freopen("output.txt", "w", stdout);

#endif

    cout << fixed << setprecision(3);

    cin.tie();

    cout.tie();



    int n, r;

    cin >> n;

    r = n * (n - 1);



    for (int i = 1; i <= n; i++) {

        for (int j = 0; j < n - 1; j++) {

            int t;

            cin >> t;



            q[i].push_back(t);

        }

    }



    set < int > now;

    for (int i = 1; i <= n; i++) {

        now.insert(now.end(), i);

    }

    for (int t = 1; ; t++) {

        debug(now);

        int flag = 0;

        set < int > later;



        for (int i : now) {

            if (q[i].empty()) {

                continue;

            }



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

            if (q[j].front() == i && later.find(i) == later.find(j)) {

                q[i].pop_front();

                q[j].pop_front();



                later.insert(i);

                later.insert(j);

                debug(later);

                r -= 2;

                flag = 1;



                if (r == 0) {

                    return cout << t, 0;

                }

            }

        }



        if (!flag) {

            return cout << "-1", 0;

        }

        swap(now, later);

    }



    return 0;

}


// Optimized solution to the same problem (faster):
#include <iostream>

#include <iomanip>

#include <cstdlib>

#include <algorithm>

#include <vector>

#include <queue>

#include <stack>

#include <climits>

#include <string>

#include <set>

#include <cmath>

#include <map>

#include <unordered_map>

#include <numeric>

#include <random>

#include <memory>

#include <chrono>

#include <functional>

#include <unordered_set>

#include <cstring>

#include <cassert>

#include <bitset>

#ifdef LOCAL

#include "debug.h"

#else

#define debug(x...)

#endif

//#define int ll

//#pragma GCC optimize("Ofast")





using namespace std;

typedef long long ll;

typedef long double ld;

typedef pair <int, int> pii;

typedef pair <ll, ll> pll;

#define sz(x) int((x).size())



#ifndef LOCAL

	mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());

#else

	mt19937 rng(228);

#endif



const int N = 1e3 + 7;

const int inf = INT_MAX / 2;

const ll INF = LLONG_MAX / 3;

const int MOD = 998244353;

const ld eps = 1e-6;

const string cars[] = {"🚗", "🚕", "🚙"};



int a[N][N], pos[N][N], dp[N][N], c[N][N], n;



void calc(int x, int y) {

	if (dp[x][y] || x == 0 || y == 0) {

		return;

	}

	if (c[x][y] == 1) {

		cout << "-1\n";

		exit(0);

	}

	c[x][y] = 1;



	int i = a[x][pos[x][y] - 1];

	int j = a[y][pos[y][x] - 1];



	calc(x, i);

	calc(y, j);



	dp[x][y] = max(dp[x][i], dp[y][j]) + 1;

	c[x][y] = 2;

}



signed main() {

#ifdef LOCAL

	freopen("input.txt", "r", stdin);

	freopen("output.txt", "w", stdout);

#endif

	cout << fixed << setprecision(9);

	ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);



	cin >> n;



	for (int i = 1; i <= n; i++) {

		for (int j = 1; j < n; j++) {

			cin >> a[i][j];

			pos[i][a[i][j]] = j;

		}

	}



	int ans = 0;

	for (int i = 1; i <= n; i++) {

		for (int j = i + 1; j <= n; j++) {

			calc(i, j);

			ans = max(ans, dp[i][j]);

		}

	}



	cout << ans << endl;



	return 0;

}

// Fastest known solution for this problem: