#include <bits/stdc++.h>

using namespace std;

typedef long long ll;
typedef unsigned long long ull;
typedef long double ld;
typedef pair<ll, ll> P;

#define EACH(i,a) for (auto& i : a)
#define FOR(i,a,b) for (ll i=(a);i<(b);i++)
#define RFOR(i,a,b) for (ll i=(b)-1;i>=(a);i--)
#define REP(i,n) for (ll i=0;i<(n);i++)
#define RREP(i,n) for (ll i=(n)-1;i>=0;i--)
#define debug(x) cout<<#x<<": "<<x<<endl
#define pb push_back
#define ALL(a) (a).begin(),(a).end()

const ll linf = 1e18;
const int inf = 1e9;
const double eps = 1e-12;
const double pi = acos(-1);

template<typename T>
istream& operator>>(istream& is, vector<T>& vec) {
	EACH(x,vec) is >> x;
	return is;
}
/*
template<class... T>
ostream& operator<<(ostream& os, tuple<T...>& t) {
	for (size_t i = 0; i < tuple_size< tuple<T...> >::value; ++i) {
		if (i) os << " ";
		os << get<0>(t);
	}
	return os;
}
*/
template<typename T>
ostream& operator<<(ostream& os, vector<T>& vec) {
	REP(i,vec.size()) {
		if (i) os << " ";
		os << vec[i];
	}
	return os;
}
template<typename T>
ostream& operator<<(ostream& os, vector< vector<T> >& vec) {
	REP(i,vec.size()) {
		if (i) os << endl;
		os << vec[i];
	}
	return os;
}

/*
class UnionFind {
private:
	int size;
	vector<int> h, s, par;

public:
	UnionFind(int size) : size(size) {
		h = vector<int>(size, 0);
		par = vector<int>(size);
		s = vector<int>(size, 1);
		REP(i, size) par[i] = i;
	}
	int root(int n) {
		if (par[n] == n) return n;
		return par[n] = root(par[n]);
	}
	void unite(int a, int b) {
		a = root(a), b = root(b);
		if (a == b) return;

		int p, c;
		if (h[a] < h[b]) {
			p = b, c = a;
		}
		else if (h[b] > h[a]) {
			p = a, c = b;
		}
		else {
			p = a, c = b;
			++h[a], ++h[b];
		}
		par[p] = c;
		s[c] += s[p];
	}
	bool isUnited(int a, int b) {
		return root(a) == root(b);
	}
	int getGroupSize(int n) {
		return s[root(n)];
	}
};
*/

struct Edge {
	int to, day;
};
struct Node {
	int n, day;
};
bool operator<(const Node& n1, const Node& n2) {
	return n1.day < n2.day;
}

int check(vector< vector<Edge> >& G, int g, int d) {
	int N = G.size();
	vector<int> dp(N, -1); dp[g] = d;
	priority_queue<Node> Q; Q.push( (Node){g, dp[g]} );
	while ( !Q.empty() ) {
		Node node = Q.top(); Q.pop();
		int n = node.n, day = node.day;
		if (day < dp[n]) continue;
		EACH(e, G[n]) {
			if (e.day <= day && e.day > dp[e.to]) {
				dp[e.to] = e.day;
				Q.push({e.to, dp[e.to]});
			}
		}
	}
	for (int i = 0; i < N; ++i) {
		if (dp[i] < 0) return false;
	}
	return true;
}

int main() {
	std::ios::sync_with_stdio(false);
	std::cin.tie(0);
	int N;
	while ( cin >> N, N ) {
		map<int, vector<int> > e;
		for (int i = 0; i < N; ++i) {
			int f; cin >> f;
			for (int j = 0; j < f; ++j) {
				int d; cin >> d; --d;
				e[d].push_back(i);
			}
		}
		vector< vector<Edge> > G(N);
		EACH(p, e) {
			int day = p.first;
			vector<int>& target = p.second;
			for (int i = 1; i < target.size(); ++i) {
				int from = target[i], to = target[i-1];
				G[from].pb( (Edge){to, day} );
				G[to].pb( (Edge){from, day} );
			}
		}
		int ans = inf;
		for (int i = 0; i < N; ++i) {
			for (int j = 0; j < 30; ++j) {
				if ( check(G, i, j) ) {
					ans = min(ans, j);
				}
			}
		}
		if (ans == inf) {
			cout << -1 << endl;
		}
		else {
			cout << ans+1 << endl;
		}
	}
}

Measured memory_bytes: 3100