// Slower C++ solution:
#include<bits/stdc++.h>

using namespace std;

typedef long long ll;

#define rep(i, n) for(int i = 0; i < (n); i++)

#define rep1(i, n) for(int i = 1; i <= (n); i++)

#define co(x) cout << (x) << "\n"

#define cosp(x) cout << (x) << " "

#define ce(x) cerr << (x) << "\n"

#define cesp(x) cerr << (x) << " "

#define pb push_back

#define mp make_pair

#define Would

#define you

#define please



int main() {

	cin.tie(0);

	ios::sync_with_stdio(false);





	int N;

	cin >> N;



	int A[1001][999];

	rep1(i, N) rep(j, N - 1) {

		cin >> A[i][j];

	}



	int k[1001] = {};

	vector<int> V;

	rep1(i, N) {

		V.pb(i);

	}



	set<pair<int, int>> ST;



	int kotae = 0;

	int OK = 1;

	while (V.size()) {



		vector<int> kari;



		int hiita = 0;

		pair<int, int> mae = mp(-1, -1);

		for (auto v : V) {





			int a = A[v][k[v]];

			int b = v;

			if (a > b) swap(a, b);

			k[v]++;



			auto itr = ST.find(mp(a, b));

			if (itr != ST.end()) {

				hiita = 1;

				ST.erase(itr);

				if (k[a] < N - 1) {

					kari.pb(a);

				}

				if (k[b] < N - 1) {

					kari.pb(b);

				}

				//if (k[a] < N - 1) {

				//	int aa = A[a][k[a]];

				//	int bb = a;

				//	if (aa > bb) swap(aa, bb);

				//	kari.pb(mp(aa, bb));

				//	k[a]++;

				//}

				//if (k[b] < N - 1) {

				//	int aa = A[b][k[b]];

				//	int bb = b;

				//	if (aa > bb) swap(aa, bb);

				//	kari.pb(mp(aa, bb));

				//	k[b]++;

				//}

			}

			else {

				ST.insert(mp(a, b));

			}

		}



		V = kari;



		if (hiita == 0) {

			OK = 0;

			break;

		}



		kotae++;

	}



	if (OK) co(kotae);

	else co(-1);





	Would you please return 0;

}

// Faster C++ solution for the same problem (measured speedup: 1.0951474820344653x):
//#include<bits/stdc++.h>

#include<cstdio>

#include<algorithm>

#include<vector>

using namespace std;

typedef long long ll;

#define rep(i, n) for(int i = 0; i < (n); i++)

#define rep1(i, n) for(int i = 1; i <= (n); i++)

#define co(x) cout << (x) << "\n"

#define cosp(x) cout << (x) << " "

#define ce(x) cerr << (x) << "\n"

#define cesp(x) cerr << (x) << " "

#define pb push_back

#define mp make_pair

#define Would

#define you

#define please



const int cm = 1 << 17;

char cn[cm], * ci = cn + cm, ct;

inline char getcha() {

	if (ci - cn == cm) { fread(cn, 1, cm, stdin); ci = cn; }

	return *ci++;

}

inline int getint() {

	int A = 0;

	if (ci - cn + 16 > cm) while ((ct = getcha()) >= '0') A = A * 10 + ct - '0';

	else while ((ct = *ci++) >= '0') A = A * 10 + ct - '0';

	return A;

}



int main() {

	//cin.tie(0);

	//ios::sync_with_stdio(false);





	int N = getint();



	int A[1001][1000];

	rep1(i, N) {

		rep(j, N - 1) A[i][j] = getint();

		A[i][N - 1] = 0;

	}

	int* k[1001];

	rep1(i, N) k[i] = A[i];

	int k2[1001] = {};

	k2[0] = 1e9;

	vector<int> V;

	rep1(i, N) V.pb(i);



	int kotae = 0;

	while (V.size()) {

		kotae++;

		vector<int> kari;

		for (auto v : V) {

			if (k2[v] < kotae) {

				int a = *k[v];

				if (k2[a] < kotae && *k[a] == v) {

					kari.pb(v);

					k[v]++;

					k2[v] = kotae;

					kari.pb(a);

					k[a]++;

					k2[a] = kotae;

				}

			}

		}

		swap(V, kari);

	}



	int OK = 1;

	rep1(i, N) if (k[i] - A[i] != N - 1) OK = 0;

	if (OK) printf("%d", kotae - 1);

	else printf("-1");



	Would you please return 0;

}