#include <stdio.h>
#include <iostream>

#include <bits/stdc++.h>


using namespace std;

#define INPUT_INT(valName) int valName; cin >> valName
#define INPUT_LLINT(valName) long long int valName; cin >> valName;
#define INPUT_STR(valName) string valName; cin >> valName;
#define INPUT_LINE(valName) string valName; getline(cin,s);
#define INPUT_VECTOR_INT(valName, N) vector<int> valName(N); for(int i=0; i < N; ++i) { cin >> valName[i]; }
#define INPUT_VECTOR_DOUBLE(valName, N) vector<double> valName(N); for(int i=0; i < N; ++i) { cin >> valName[i]; }

#define OUTPUT(A) cout << (A) << endl;
#define OUTPUT2(A, B) cout << (A) << " " << (B) << endl;
#define OUTPUT3(A, B, C) cout << (A) << " " << (B) << " " << (C) << endl;

#define REP(valName, N) for(int valName = 0; valName < N; ++valName)

vector<string> split(const string& str, char delimiter) {
	vector<string> ret;
	string tmp = "";
	for (auto c : str) {
		if (c != delimiter) {
			tmp.push_back(c);
		} else {
			ret.push_back(tmp);
			tmp = "";
		}
	}
	ret.push_back(tmp);
	return ret;
}

template <typename T> void sortAsc(vector<T>& v) { sort(v.begin(), v.end(), less<T>()); }
template <typename T> void sortDesc(vector<T>& v) { sort(v.begin(), v.end(), greater<T>()); }

template <typename T> void insert(vector<T>& dest, const vector<T>& src) { copy(src.begin(), src.end(), back_inserter(dest)); }

template <long long int MOD> long long int mod_inv(long long int a) {
	long long b = MOD, u = 1, v = 0;
	while (b) {
		long long int t = a / b;
		a -= t * b; swap(a, b);
		u -= t * v; swap(u, v);
	}
	u %= MOD;
	if (u < 0) u += MOD;
	return u;
}

template <long long int MOD> long long int mod_add(long long int a, long long int b) {
	return (a + b) % MOD;
}

template <long long int MOD> long long int mod_sum(long long int a, long long int b) {
	return (a - b) % MOD;
}

template <long long int MOD> long long int mod_mul(long long int a, long long int b) {
	return (a % MOD) * (b % MOD) % MOD;
}

template <long long int MOD> long long int mod_mul(long long int a, long long int b, long long int c) {
	return mod_mul<MOD>(a, mod_mul<MOD>(b, c));
}

template <long long int MOD> long long int mod_div(long long int a, long long int b) {
	return (a % MOD) * mod_inv<MOD>(b) % MOD;
}


//------------------------------------------------------------------------------------------------------------------------------

int f(vector<vector<int>>& A, vector<int>& consumed, int N) {
	
	bool changed = false;
	vector<int> consumedNext = consumed;

	for (int i = 0; i < N-1; ++i) {
		for (int j = i + 1; j < N; ++j) {
			
			if (A[i][consumed[i]] == A[j][consumed[j]]) {
				++consumedNext[i];
				++consumedNext[j];
				changed = true;
			}

		}
	}

	consumed = consumedNext;

}

int main() {
	cin.tie(0); ios::sync_with_stdio(false);

	INPUT_INT(N);

	vector<vector<int>> A;
	A.resize(N);
	REP(i, N) {
		A[i].resize(N - 1);
		REP(j, N - 1) {
			cin >> A[i][j];
			A[i][j] -= 1;
		}
	}

	vector<int> consumed(N, 0);


	int day = 0;

	vector<int> changedList(N, false);
	while (true) {
		bool changed = false;
		memset(changedList.data(), 0, sizeof(int)* N);

		for (int i = 0; i < N - 1; ++i) {
			if (consumed[i] >= N-1) continue;
			if (changedList[i]) continue;

			int j = A[i][consumed[i]];

			if (consumed[j] >= N-1) continue;
			if (changedList[j]) continue;

			if (A[j][consumed[j]] == i) {
				++consumed[i];
				++consumed[j];
				changed = true;
				changedList[i] = 1;
				changedList[j] = 1;
			}

		}

		if (!changed) {
			break;
		}

		++day;
	}

	bool valid = true;
	for (int i = 0; i < N; ++i) {
		if (consumed[i] < N - 1) { valid = false; break; }
	}

	if (valid) {
		OUTPUT(day);
	} else {
		OUTPUT(-1);
	}


	return 0;
}

Measured memory_bytes: 6272