#include <bits/stdc++.h>
using namespace std;
#define ll long long int
#define MOD 1000000007
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
using namespace __gnu_pbds;
#define INF 100000000000000 //INF - 1e14
#define vi vector<ll>
#define pb push_back
#define mpl map<ll,ll>
#define ff first
#define ss second
#define pll pair<ll,ll>
#define vpll vector<pair<ll,ll> >
#define fer(i, a, n) for( ll i = a; i <= n; i++)
#define fdr(i, a, n) for( ll i = a; i >= n; i--)
#define invec(n,v) vi v(n); fer(i,0,n-1) cin >> v[i]
#define insvec(n,v) rin(n); vi v(n); fer(i,0,n-1) cin >> v[i]
#define MK2DV(v,row,col,val) vector<vector<ll> > v(row, vector<ll>(col,val))
#define matrix vector<vector<ll> >
#define printv(v,i,j) for(ll it =i; it <= j; it++) cout << v[it] << ' '; cout << '\n';
#define printpartition cout << "-------------------------------------------------------------" << endl;
#define printmat(mat,row,col) fer(i,0,row-1)fer(j,0,col-1)cout << mat[i][j] << " \n"[j == col-1];
#define ordered_set tree<ll, null_type,less<ll>, rb_tree_tag,tree_order_statistics_node_update>
void __print(int x) {cout << x;}
void __print(long x) {cout << x;}
void __print(long long x) {cout << x;}
void __print(unsigned x) {cout << x;}
void __print(unsigned long x) {cout << x;}
void __print(unsigned long long x) {cout << x;}
void __print(float x) {cout << x;}
void __print(double x) {cout << x;}
void __print(long double x) {cout << x;}
void __print(char x) {cout << '\'' << x << '\'';}
void __print(const char *x) {cout << '\"' << x << '\"';}
void __print(const string &x) {cout << '\"' << x << '\"';}
void __print(bool x) {cout << (x ? "true" : "false");}
template<typename T, typename V>
void __print(const pair<T, V> &x) {cout << '{'; __print(x.first); cout << ','; __print(x.second); cout << '}';}
template<typename T>
void __print(const T &x) {int f = 0; cout << '{'; for (auto &i : x) cout << (f++ ? "," : ""), __print(i); cout << "}";}
void _print() {cout << "]\n";}
template <typename T, typename... V>
void _print(T t, V... v) {__print(t); if (sizeof...(v)) cout << ", "; _print(v...);}
template <typename T> inline void inp(T &any) {cin >> any;} template <typename T, typename... U>inline void inp(T &a, U &...b) {cin >> a; inp(b...);}
#define rin(args...) ll args; inp(args);
#ifndef ONLINE_JUDGE
#define debug(x...) cout << "[" << #x << "] = ["; _print(x)
#define matdeb(mat,row,col) cout << #mat << "::" << endl; printmat(mat,row,col); printpartition;
#define debugv(v,n) cout << #v << ":" << endl; printv(v,0,n-1); printpartition;
#else
#define debug(x...)
#define matdeb(mat,row,col)
#define debugv(v,n)
#endif
ll fast_pow(ll base, ll exp, ll M = MOD) { base = base % M; ll result = 1; while (exp > 0) { if (exp % 2 == 1) result = (result * base) % M; base = (base * base) % M; exp = exp / 2; } return result; }
ll modInverse(ll A, ll M = MOD) { return fast_pow(A, M - 2, M); } // only when M is prime
ll lcm(ll x, ll y) { return x / __gcd(x, y) * y;}
void coordinatecompress(vector<ll> &arr) { ll n = arr.size(); vector<pair<ll, ll> > temparr(n); fer(i, 0, n - 1) temparr[i] = {arr[i], i}; sort(temparr.begin(), temparr.end()); arr[temparr[0].second] = 0; fer(i, 1, n - 1) arr[temparr[i].second] = arr[temparr[i - 1].second] + (temparr[i - 1].first != temparr[i].first); }
string yes = "Yes", no = "No";
// void dfs(ll s, ll p) {
// 	for (auto nbr : adj[s]) {
// 		if (nbr != p) {
// 			dfs(nbr, s);
// 		}
// 	}
// }

int nd;
set<int> adj[1000000];
int indeg[1000000];
bool vis[1000000];
int main() {
	ios_base::sync_with_stdio(false); cin.tie(NULL); cout.tie(NULL);
// #ifndef ONLINE_JUDGE
// 	freopen("intt.txt", "r", stdin);
// 	freopen("outt.txt", "w", stdout);
// #endif

	ll test_cases = 1;
	// cin >> test_cases;
	for (ll test_case = 1; test_case <= test_cases; test_case++) {
		int n;
		cin >> n;
		map<pair<int, int>, int > mp;
		MK2DV(mat, n, n - 1, 0);
		for (int i = 0; i < n; i++) {
			for (int j = 0; j < n - 1; j++) {
				cin >> mat[i][j];
				mat[i][j]--;
			}
		}
		for (int i = 0; i < n; i++) {
			for (int j = 0; j < n - 2; j++) {
				pair<int, int> p1 = {i, mat[i][j]};
				pair<int, int> p2 = {i, mat[i][j + 1]};
				if (p1.first > p1.second)
					swap(p1.first, p1.second);
				if (p2.first > p2.second)
					swap(p2.first, p2.second);
				if (mp.find(p1) == mp.end()) {
					mp[p1] = nd++;
				}
				if (mp.find(p2) == mp.end()) {
					mp[p2] = nd++;
				}
				if (adj[mp[p1]].find(mp[p2]) == adj[mp[p1]].end()) {
					adj[mp[p1]].insert(mp[p2]);
					indeg[mp[p2]]++;
				}

			}
		}
		queue<pair<int, int> > q;
		for (int i = 0; i < nd; i++) {
			if (indeg[i] == 0) {
				vis[i] = true;
				q.push({i, 1});
			}
		}
		int ans = -1;
		// de
		while (!q.empty()) {
			int v = q.front().first, d = q.front().second;
			q.pop();
			for (auto nbr : adj[v])
				indeg[nbr]--;
			ans = max(ans, d);
			for (auto nbr : adj[v]) {
				if (!vis[nbr] && indeg[nbr] == 0) {
					vis[nbr] = true;
					q.push({nbr, d + 1});
				}
			}

		}
		for (int i = 0; i < n; i++) {
			if (!vis[i])
				ans = -1;
		}
		cout << ans;

	}
	return 0;
}


Measured memory_bytes: 138796