Problem:
Problem F:
Gather the Maps!
はるか昔、八尾氏が残したとされる伝説の秘宝が八王子のどこかに眠っているという。 その在処を示すとされる宝の地図は、いくつかの断片に分割された状態で、八尾氏の
n
人の子孫達によって受け継がれている。
今、八尾氏の子孫達は協力してその秘宝を手に入れようとしていた。 ところが、秘宝の在処を指し示す宝の地図の一部分だけでは秘宝を見つけることができない。 そこで、八尾氏の子孫達は全員で集まって地図を 1 ヶ所に集めようとした。
			ところが、いざ実行に移そうとしてもなかなか予定が合わずに集まることができない。 しかしこの秘宝に関する情報は、一族において秘密裏に伝えられてきた貴重な情報である。 漏洩の危険性を考慮すると、公共の通信手段を用いて地図をやりとりすることなど問題外である。
そこで、子孫同士が直接会って地図を手渡すということを繰り返すことで、ある 1 人の子孫のところに地図を集めることにした。
			なお、1 人が 1 日に会える人数に制限はないが、互いにスケジュールが空いていることが必要である。
あなたの仕事は、それぞれの子孫に対するスケジュールの空いている日のリストから、地図を集めるには最低で何日必要かを求めるプログラムを書くことである。
ちなみに、八尾氏一族の結束は非常に固い。 最終的に地図全体を手にした子孫が、他の子孫を裏切って秘宝を持ち逃げすれば、一族から制裁を受けることになる。その制裁はきわめて恐ろしいものであるため、実際にその子孫が秘宝を持ち逃げすることは事実上不可能である。
Input
入力は複数のデータセットからなる。
それぞれのデータセットは複数の行からなる。 その最初の行には、地図の断片を持った者の人数を表す整数
n
(1 <
n
<= 50) が記述されている。 続く
n
行には、それぞれの子孫のスケジュールが書かれている。
i
行目は
i
人目の子孫のスケジュールが表しており、いくつかの整数が 1 文字のスペースを区切りとして書かれている。
			最初の整数
f
i
(0 <=
f
i
<= 30) は、その子孫のスケジュールが空いている日の日数を表す整数である。 続く
f
i
個の整数は、スケジュールが空いている日付を表す。 これらの日付は互いに異なり、全て 1 以上 30 以下である。
入力の最後に 0 のみを含んだ 1 行がある。
Output
各データセットに対して、1 つの整数を 1 行に出力せよ。
				もし、30 日以内に地図を集めることができる場合は、地図を集めるのに最低限必要となる日数を、集めることができない場合は -1 を出力せよ。
追記 :
上記の「地図を集めるのに最低限必要となる日数」は 1 日を起点として最も早く全ての地図が集まる日付を意味する．
Sample Input
4
1 1
2 2 3
2 1 2
3 3 4 5
0
Output for the Sample Input
3

Submitted solutions:

code_snippet: #include <bits/stdc++.h>
using namespace std;

int main()
{
	int n;
	while (cin >> n, n) {
		vector<vector<int>> v(31);
		for (int i = 0, f; i < n; i++) {
			cin >> f;
			for (int j = 0, d; j < f; j++) {
				cin >> d;
				v[d - 1].push_back(i);
			}
		}
		vector<vector<int>> dp(n, vector<int>(n));
		for (int i = 0; i < n; i++) {
			dp[i][i] = 1;
		}
		int res = -1;
		for (int i = 0; i <= 30; i++) {
			for (int k = 0; k < n; k++) {
				bool flag = true;
				for (int j = 0; j < n; j++) {
					if (dp[k][j] == 0) {
						flag = false;
						break;
					}
				}
				if (flag) {
					res = i;
					break;
				}
			}
			if (res != -1) {
				break;
			}
			if (v[i].size() > 1) {
				vector<int> su(n);
				for (auto m : v[i]) {
					for (int j = 0; j < n; j++) {
						su[j] = max(su[j], dp[m][j]);
					}
				}
				for (auto m : v[i]) {
					for (int j = 0; j < n; j++) {
						dp[m][j] = max(dp[m][j], su[j]);
					}
				}
			}
		}
		cout << res << endl;
	}
	return 0;
}
accuracy: 1
time_ms: 30
memory_kb: 3192
final_rank: 3

code_snippet: #line 1 "2005JAGF.cpp"
#include <bits/stdc++.h>
#line 1 "/home/ardririy/repos/cp-libs/libraries-cpp/input.hpp"


#line 6 "/home/ardririy/repos/cp-libs/libraries-cpp/input.hpp"
using namespace std;
vector<long long> i64_vec_IN(int n) {vector<long long> res(n); for(int i=0; i<n; i++) { cin >> res[i]; } return res; }
vector<string> str_vec_IN(int n) { vector<string> res(n); for(int i=0; i<n; i++) { cin >> res[i]; } return res; }
vector<vector<int>> graph_IN(int n, int m) { vector<vector<int>> g(n); int u, v; for(int i=0; i<m; i++) { cin >> u >> v; u--; v--; g[u].emplace_back(v); g[v].emplace_back(u); } return g; }
vector<vector<pair<int, long long>>> weighted_graph_IN(int n, int m) { vector<vector<pair<int, long long>>> g(n); int u, v; long long w; for(int i=0; i<m; i++) { cin >> u >> v >> w; u--; v--; g[u].push_back({v, w}); g[v].push_back({u, w}); } return g; }


#line 3 "2005JAGF.cpp"

using namespace std;

// using namespace atcoder;

#ifdef ADRY
#include <dbg.h>
#else
// DO NOTHING
#define dbg(x)
#endif


#define all(v) v.begin(),v.end()
#define resort(v) sort(v.rbegin(),v.rend())
using ll = long long;
using ull = unsigned long long;
using vll=vector<ll>;
using vvll = vector<vector<ll>>;
using P = pair<ll,ll>;
using vp=vector<pair<ll, ll>>;
using djks=priority_queue<P, vp, greater<P>>;

const int inf=1ll<<30;
#define mod10 (ll)1e9+7
#define mod99 (ll)998244353
const double PI = acos(-1);

#define rep(i,n) for (ll i=0;i<(n);++i)
#define per(i,n) for(ll i=(n)-1;i>=0;--i)
#define rep2(i,a,n) for (ll i=(a);i<(n);++i)
#define per2(i,a,n) for (ll i=(n)-1;i>=(a);--i)


template<class T>bool chmax(T &a, const T &b) { if (a<b) { a=b; return true; } return false; }
template<class T>bool chmin(T &a, const T &b) { if (b<a) { a=b; return true; } return false; }

ll dx[] = {1, 0, -1, 0, -1, 1, -1, 1};
ll dy[] = {0, 1, 0, -1, -1, 1, 1, -1};

ll pc(ll val) {
    ll res = 0;

    rep(i,60) {
        if(((val>>i)&1)==1) res++;
    }

    return res;
}

int solve(){
    int n; cin >> n;
    if(n==0) return 1;
    vector<vector<bool>> has_time(n,vector<bool>(31, false));
    rep(i,n) {
        int k;
        cin >> k;
        rep(_,k) {
            int t; cin >> t;
            t--;
            has_time[i][t] = true;
        }
    }

    vll dp(n,0);
    rep(i,n) dp[i] = 1ll << i;

    rep(i,31) {
        ll nxt = 0;
        rep(j,n) {
            if(has_time[j][i]) nxt = nxt | dp[j];
        }

        if(pc(nxt) == n) {
            cout << i+1 << '\n';
            return 0;
        }

        vll ndp = dp;
        rep(j,n) if(has_time[j][i]) ndp[j] = nxt;

        dp = ndp;
        dbg(dp);

    }
    cout << "-1\n";
    return 0;
}

int main() {
    cin.tie(0);
    ios::sync_with_stdio(false);
    while(!solve());
}
accuracy: 1
time_ms: 10
memory_kb: 3396
final_rank: 7

code_snippet: #include <bits/stdc++.h>
using namespace std;

bool solve();
int main() {
  while (solve());
  return 0;
}

using ll = long long;
bool solve() {
  int N;
  cin >> N;
  if (N == 0) return false;
  vector<int> F(N);
  for (int i = 0; i < N; i++) {
    int ff;
    cin >> ff;
    for (int j = 0; j < ff; j++) {
      int f;
      cin >> f;
      f--;
      F[i] |= 1 << f;
    }
  }
  vector<ll> dp(N);
  // dp=各要素が獲得できる地図集合
  for (ll i = 0; i < N; i++) dp[i] |= 1LL << i;
  for (int d = 0; d < 30; d++) {
    ll x = 0;
    for (int i = 0; i < N; i++) {
      if (F[i] >> d & 1) {
        x |= dp[i];
      }
    }
    if (popcount((unsigned long long)x) == N) {
      cout << d + 1 << endl;
      return true;
    }
    for (int i = 0; i < N; i++) {
      if (F[i] >> d & 1) dp[i] = x;
    }
  }
  cout << -1 << endl;
  return true;
}
accuracy: 1
time_ms: 10
memory_kb: 3584
final_rank: 12

code_snippet: #include <bits/stdc++.h>
using namespace std;

bool solve();
int main() {
  while (solve());
  return 0;
}

struct UF {
  vector<int> p, s;
  UF(int n) : p(n, 0), s(n, 1) { iota(p.begin(), p.end(), 0); }
  int leader(int u) {
    if (p[u] == u) return u;
    return p[u] = leader(p[u]);
  }
  void merge(int u, int v) {
    u = leader(u), v = leader(v);
    if (u == v) return;
    int ns = s[u] + s[v];
    p[u] = v;
    s[v] = ns;
  }
  int size(int a) { return s[leader(a)]; }
};

using ll = long long;
bool solve() {
  int N;
  cin >> N;
  if (N == 0) return false;
  vector<int> F(N);
  for (int i = 0; i < N; i++) {
    int ff;
    cin >> ff;
    for (int j = 0; j < ff; j++) {
      int f;
      cin >> f;
      f--;
      F[i] |= 1 << f;
    }
  }
  vector<ll> dp(N);
  // dp=各要素が獲得できる地図集合
  for (ll i = 0; i < N; i++) dp[i] |= 1LL << i;
  for (int d = 0; d < 30; d++) {
    ll x = 0;
    for (int i = 0; i < N; i++) {
      if (F[i] >> d & 1) {
        x |= dp[i];
      }
    }
    if (popcount((unsigned long long)x) == N) {
      cout << d + 1 << endl;
      return true;
    }
    for (int i = 0; i < N; i++) {
      if (F[i] >> d & 1) dp[i] = x;
    }
  }
  cout << -1 << endl;
  return true;
}
accuracy: 1
time_ms: 10
memory_kb: 3584
final_rank: 12

code_snippet: #include<bits/stdc++.h>
using namespace std;
typedef long double ld;
typedef long long ll;
typedef vector<ll> vi;
typedef vector<vi> vvi;
typedef pair<ll,ll> pi;
#define FOR(i,l,r) for(ll i=l;i<r;i++)
#define REP(i,n) FOR(i,0,n)
#define RFOR(i,l,r) for(ll i=r-1;i>=l;i--)
#define RREP(i,n) RFOR(i,0,n)
#define F first
#define S second
#define sz(A) ((ll)(A.size()))
struct dsu{
    vector<int>nec;
    dsu(int N):nec(N,-1){}
    int leader(int v){while(nec[v]>=0)v=nec[v];return v;}
    int merge(int u,int v){
        assert(0<=u&&u<nec.size());
        assert(0<=v&&v<nec.size());
        //cout<<u<<" "<<v<<endl;
        u=leader(u);
        v=leader(v);
        if(u==v)return u;
        if(nec[u]<nec[v])swap(u,v);
        nec[v]+=nec[u];
        nec[u]=v;
        return v;
    }
    bool same(int u,int v){return leader(u)==leader(v);}
    int size(int v){return -nec[leader(v)];}
};
int main(){
    while(1){
        ll N;cin>>N;
        if(!N)return 0;
        vvi E(31);
        REP(i,N){
            ll f;cin>>f;
            while(f--){ll t;cin>>t;E[t].emplace_back(i);}
        }
        REP(i,31){
            bool ok=0;
            REP(v,N){
                dsu D(N);
                RREP(j,i+1){
                    bool ex=0;
                    REP(k,E[j].size())if(D.same(E[j][k],v))ex=1;
                    if(ex)REP(k,E[j].size()-1)D.merge(E[j][k+1],E[j][k]);
                }
                if(D.size(0)==N)ok=1;
            }
            if(ok){cout<<i<<endl;break;}
            if(i==30)cout<<-1<<endl;
        }
    }
    return 0;
}
accuracy: 1
time_ms: 200
memory_kb: 3456
final_rank: 11

code_snippet: #include <bits/stdc++.h>
    using namespace std;
    #include <ext/pb_ds/assoc_container.hpp>
    using namespace __gnu_pbds;
    
    template<class T> inline bool chmax(T& a, T b) { if (a < b) { a = b; return 1; } return 0; }
    template<class T> inline bool chmin(T& a, T b) { if (a > b) { a = b; return 1; } return 0; }
    #define rep(i,n) for (int i = 0; i < (n); ++i)

    typedef long long ll;
    typedef unsigned long long ull;
    typedef long double ld;
    using P=pair<ll,ll>;
    using T=tuple<int,int,int>;
    const ll INF=1001001001; 
    const ll INFL=1e18;
    const ll mod=998244353;

    struct Unionfind{
      vector<int>d;
      Unionfind(int n):d(n,-1){}
      int root(int x){
        if(d[x]<0){return x;}
        return d[x]=root(d[x]);
      }
      bool unite(int x,int y){
        x=root(x);y=root(y);
        if(x==y){return false;}
        if(d[x]>d[y]){swap(x,y);}
        d[x]+=d[y];
        d[y]=x;
        return true;
      }
      bool same(int x,int y){return root(x)==root(y);}
      int size(int x){return -d[root(x)];}
    };

    void solve(int n){
        vector<ll>ok(35);
        rep(i,n){
            int d;
            cin>>d;
            rep(j,d){
                int x;
                cin>>x;
                ok[x]|=1ll<<i;
            }
        }
        vector<ll>can(n);
        rep(i,n)can[i]|=1ll<<i;
        for(int d=1;d<=30;d++){
            rep(i,n){
                rep(j,i){
                    if(ok[d]>>i&1 && ok[d]>>j&1){
                        ll I=can[i],J=can[j];
                        can[j]|=I;
                        can[i]|=J;
                    }
                }
            }
            rep(i,n){
                if(can[i]==(1ll<<n)-1){
                    cout<<d<<endl;
                    return;
                }
            }
        }
        cout<<-1<<endl;
    }

    int main(){
        ios_base::sync_with_stdio(false);
        cin.tie(NULL);
        
        int n;
        while(1){
            cin>>n;
            if(n==0)break;
            solve(n);
        }
        
        return 0;
    }
accuracy: 1
time_ms: 10
memory_kb: 3584
final_rank: 12

code_snippet: #include <bits/stdc++.h>
    using namespace std;
    #include <ext/pb_ds/assoc_container.hpp>
    using namespace __gnu_pbds;
    
    template<class T> inline bool chmax(T& a, T b) { if (a < b) { a = b; return 1; } return 0; }
    template<class T> inline bool chmin(T& a, T b) { if (a > b) { a = b; return 1; } return 0; }
    #define rep(i,n) for (int i = 0; i < (n); ++i)

    typedef long long ll;
    typedef unsigned long long ull;
    typedef long double ld;
    using P=pair<ll,ll>;
    using T=tuple<int,int,int>;
    const ll INF=1001001001; 
    const ll INFL=1e18;
    const ll mod=998244353;

    struct Unionfind{
      vector<int>d;
      Unionfind(int n):d(n,-1){}
      int root(int x){
        if(d[x]<0){return x;}
        return d[x]=root(d[x]);
      }
      bool unite(int x,int y){
        x=root(x);y=root(y);
        if(x==y){return false;}
        if(d[x]>d[y]){swap(x,y);}
        d[x]+=d[y];
        d[y]=x;
        return true;
      }
      bool same(int x,int y){return root(x)==root(y);}
      int size(int x){return -d[root(x)];}
    };

    void solve(int n){
        vector<vector<int>>ok(35);
        rep(i,n){
            int d;
            cin>>d;
            rep(j,d){
                int x;
                cin>>x;
                ok[x].push_back(i);
            }
        }
        vector<int>mx(n);
        rep(i,n){
            vector<int>dist(n,INF);
            dist[i]=0;
            for(int d=1;d<=30;d++){
                int mn=INF;
                for(int j:ok[d]){
                    chmin(mn,dist[j]);
                }
                if(mn<=d){
                    for(int j:ok[d]){
                        chmin(dist[j],d);
                    }
                }
                
            }
            rep(j,n){
                chmax(mx[j],dist[j]);
            }
        }
        int ans=INF;
        rep(i,n){
            chmin(ans,mx[i]);
        }
        if(ans==INF)ans=-1;
        cout<<ans<<endl;
    }

    int main(){
        ios_base::sync_with_stdio(false);
        cin.tie(NULL);
        
        int n;
        while(1){
            cin>>n;
            if(n==0)break;
            solve(n);
        }
        
        return 0;
    }
accuracy: 1
time_ms: 20
memory_kb: 3584
final_rank: 15

code_snippet: #include <bits/stdc++.h>

using namespace std;

#define rep(i, a, b) for (int i = (int)(a); i < (int)(b); i++)
#define rrep(i, a, b) for (int i = (int)(b)-1; i >= (int)(a); i--)
#define ALL(v) (v).begin(), (v).end()
#define UNIQUE(v) sort(ALL(v)), (v).erase(unique(ALL(v)), (v).end())
#define SZ(v) (int)v.size()
#define MIN(v) *min_element(ALL(v))
#define MAX(v) *max_element(ALL(v))
#define LB(v, x) int(lower_bound(ALL(v), (x)) - (v).begin())
#define UB(v, x) int(upper_bound(ALL(v), (x)) - (v).begin())

using uint = unsigned int;
using ll = long long int;
using ull = unsigned long long;
using i128 = __int128_t;
using u128 = __uint128_t;
const int inf = 0x3fffffff;
const ll INF = 0x1fffffffffffffff;

template <typename T> inline bool chmax(T &a, T b) {
    if (a < b) {
        a = b;
        return 1;
    }
    return 0;
}
template <typename T> inline bool chmin(T &a, T b) {
    if (a > b) {
        a = b;
        return 1;
    }
    return 0;
}
template <typename T, typename U> T ceil(T x, U y) {
    assert(y != 0);
    if (y < 0)
        x = -x, y = -y;
    return (x > 0 ? (x + y - 1) / y : x / y);
}
template <typename T, typename U> T floor(T x, U y) {
    assert(y != 0);
    if (y < 0)
        x = -x, y = -y;
    return (x > 0 ? x / y : (x - y + 1) / y);
}
template <typename T> int popcnt(T x) {
    return __builtin_popcountll(x);
}
template <typename T> int topbit(T x) {
    return (x == 0 ? -1 : 63 - __builtin_clzll(x));
}
template <typename T> int lowbit(T x) {
    return (x == 0 ? -1 : __builtin_ctzll(x));
}

template <class T, class U>
ostream &operator<<(ostream &os, const pair<T, U> &p) {
    os << "P(" << p.first << ", " << p.second << ")";
    return os;
}
template <typename T> ostream &operator<<(ostream &os, const vector<T> &vec) {
    os << "{";
    for (int i = 0; i < vec.size(); i++) {
        os << vec[i] << (i + 1 == vec.size() ? "" : ", ");
    }
    os << "}";
    return os;
}
template <typename T, typename U>
ostream &operator<<(ostream &os, const map<T, U> &map_var) {
    os << "{";
    for (auto itr = map_var.begin(); itr != map_var.end(); itr++) {
        os << "(" << itr->first << ", " << itr->second << ")";
        itr++;
        if (itr != map_var.end())
            os << ", ";
        itr--;
    }
    os << "}";
    return os;
}
template <typename T> ostream &operator<<(ostream &os, const set<T> &set_var) {
    os << "{";
    for (auto itr = set_var.begin(); itr != set_var.end(); itr++) {
        os << *itr;
        ++itr;
        if (itr != set_var.end())
            os << ", ";
        itr--;
    }
    os << "}";
    return os;
}
#ifdef LOCAL
#define show(...) _show(0, #__VA_ARGS__, __VA_ARGS__)
#else
#define show(...) true
#endif
template <typename T> void _show(int i, T name) {
    cerr << '\n';
}
template <typename T1, typename T2, typename... T3>
void _show(int i, const T1 &a, const T2 &b, const T3 &...c) {
    for (; a[i] != ',' && a[i] != '\0'; i++)
        cerr << a[i];
    cerr << ":" << b << " ";
    _show(i + 1, a, c...);
}

#include <unistd.h>

namespace fastio {
static constexpr uint32_t SZ = 1 << 17;
char ibuf[SZ];
char obuf[SZ];
char out[100];
// pointer of ibuf, obuf


uint32_t pil = 0, pir = 0, por = 0;

struct Pre {
    char num[10000][4];
    constexpr Pre() : num() {
        for (int i = 0; i < 10000; i++) {
            int n = i;
            for (int j = 3; j >= 0; j--) {
                num[i][j] = n % 10 | '0';
                n /= 10;
            }
        }
    }
} constexpr pre;

inline void load() {
    memmove(ibuf, ibuf + pil, pir - pil);
    pir = pir - pil + fread(ibuf + pir - pil, 1, SZ - pir + pil, stdin);
    pil = 0;
    if (pir < SZ)
        ibuf[pir++] = '\n';
}

inline void flush() {
    fwrite(obuf, 1, por, stdout);
    por = 0;
}

void rd(char &c) {
    do {
        if (pil + 1 > pir)
            load();
        c = ibuf[pil++];
    } while (isspace(c));
}

void rd(string &x) {
    x.clear();
    char c;
    do {
        if (pil + 1 > pir)
            load();
        c = ibuf[pil++];
    } while (isspace(c));
    do {
        x += c;
        if (pil == pir)
            load();
        c = ibuf[pil++];
    } while (!isspace(c));
}

template <typename T> void rd_real(T &x) {
    string s;
    rd(s);
    x = stod(s);
}

template <typename T> void rd_integer(T &x) {
    if (pil + 100 > pir)
        load();
    char c;
    do
        c = ibuf[pil++];
    while (c < '-');
    bool minus = 0;
    if constexpr (is_signed<T>::value || is_same_v<T, i128>) {
        if (c == '-') {
            minus = 1, c = ibuf[pil++];
        }
    }
    x = 0;
    while ('0' <= c) {
        x = x * 10 + (c & 15), c = ibuf[pil++];
    }
    if constexpr (is_signed<T>::value || is_same_v<T, i128>) {
        if (minus)
            x = -x;
    }
}

void rd(int &x) {
    rd_integer(x);
}
void rd(ll &x) {
    rd_integer(x);
}
void rd(i128 &x) {
    rd_integer(x);
}
void rd(uint &x) {
    rd_integer(x);
}
void rd(ull &x) {
    rd_integer(x);
}
void rd(u128 &x) {
    rd_integer(x);
}
void rd(double &x) {
    rd_real(x);
}
void rd(long double &x) {
    rd_real(x);
}

template <class T, class U> void rd(pair<T, U> &p) {
    return rd(p.first), rd(p.second);
}
template <size_t N = 0, typename T> void rd_tuple(T &t) {
    if constexpr (N < std::tuple_size<T>::value) {
        auto &x = std::get<N>(t);
        rd(x);
        rd_tuple<N + 1>(t);
    }
}
template <class... T> void rd(tuple<T...> &tpl) {
    rd_tuple(tpl);
}

template <size_t N = 0, typename T> void rd(array<T, N> &x) {
    for (auto &d : x)
        rd(d);
}
template <class T> void rd(vector<T> &x) {
    for (auto &d : x)
        rd(d);
}

void read() {}
template <class H, class... T> void read(H &h, T &...t) {
    rd(h), read(t...);
}

void wt(const char c) {
    if (por == SZ)
        flush();
    obuf[por++] = c;
}
void wt(const string s) {
    for (char c : s)
        wt(c);
}
void wt(const char *s) {
    size_t len = strlen(s);
    for (size_t i = 0; i < len; i++)
        wt(s[i]);
}

template <typename T> void wt_integer(T x) {
    if (por > SZ - 100)
        flush();
    if (x < 0) {
        obuf[por++] = '-', x = -x;
    }
    int outi;
    for (outi = 96; x >= 10000; outi -= 4) {
        memcpy(out + outi, pre.num[x % 10000], 4);
        x /= 10000;
    }
    if (x >= 1000) {
        memcpy(obuf + por, pre.num[x], 4);
        por += 4;
    } else if (x >= 100) {
        memcpy(obuf + por, pre.num[x] + 1, 3);
        por += 3;
    } else if (x >= 10) {
        int q = (x * 103) >> 10;
        obuf[por] = q | '0';
        obuf[por + 1] = (x - q * 10) | '0';
        por += 2;
    } else
        obuf[por++] = x | '0';
    memcpy(obuf + por, out + outi + 4, 96 - outi);
    por += 96 - outi;
}

template <typename T> void wt_real(T x) {
    ostringstream oss;
    oss << fixed << setprecision(15) << double(x);
    string s = oss.str();
    wt(s);
}

void wt(int x) {
    wt_integer(x);
}
void wt(ll x) {
    wt_integer(x);
}
void wt(i128 x) {
    wt_integer(x);
}
void wt(uint x) {
    wt_integer(x);
}
void wt(ull x) {
    wt_integer(x);
}
void wt(u128 x) {
    wt_integer(x);
}
void wt(double x) {
    wt_real(x);
}
void wt(long double x) {
    wt_real(x);
}

template <class T, class U> void wt(const pair<T, U> val) {
    wt(val.first);
    wt(' ');
    wt(val.second);
}
template <size_t N = 0, typename T> void wt_tuple(const T t) {
    if constexpr (N < std::tuple_size<T>::value) {
        if constexpr (N > 0) {
            wt(' ');
        }
        const auto x = std::get<N>(t);
        wt(x);
        wt_tuple<N + 1>(t);
    }
}
template <class... T> void wt(tuple<T...> tpl) {
    wt_tuple(tpl);
}
template <class T, size_t S> void wt(const array<T, S> val) {
    auto n = val.size();
    for (size_t i = 0; i < n; i++) {
        if (i)
            wt(' ');
        wt(val[i]);
    }
}
template <class T> void wt(const vector<T> val) {
    auto n = val.size();
    for (size_t i = 0; i < n; i++) {
        if (i)
            wt(' ');
        wt(val[i]);
    }
}

void print() {
    wt('\n');
}
template <class Head, class... Tail> void print(Head &&head, Tail &&...tail) {
    wt(head);
    if (sizeof...(Tail))
        wt(' ');
    print(forward<Tail>(tail)...);
}
void __attribute__((destructor)) _d() {
    flush();
}
} // namespace fastio


using fastio::flush;
using fastio::print;
using fastio::read;

inline void first(bool i = true) {
    print(i ? "first" : "second");
}
inline void Alice(bool i = true) {
    print(i ? "Alice" : "Bob");
}
inline void Takahashi(bool i = true) {
    print(i ? "Takahashi" : "Aoki");
}
inline void yes(bool i = true) {
    print(i ? "yes" : "no");
}
inline void Yes(bool i = true) {
    print(i ? "Yes" : "No");
}
inline void No() {
    print("No");
}
inline void YES(bool i = true) {
    print(i ? "YES" : "NO");
}
inline void NO() {
    print("NO");
}
inline void Yay(bool i = true) {
    print(i ? "Yay!" : ":(");
}
inline void Possible(bool i = true) {
    print(i ? "Possible" : "Impossible");
}
inline void POSSIBLE(bool i = true) {
    print(i ? "POSSIBLE" : "IMPOSSIBLE");
}

/**
 * @brief Fast IO
 */

int main() {
while(1) {
    int N;
    cin >> N;
    if (N == 0) return 0;
    vector<vector<int>> V(30);
    rep(i,0,N) {
        int K;
        cin >> K;
        rep(j,0,K) {
            int A;
            cin >> A;
            A--;
            V[A].push_back(i);
        }
    }
    if (N == 1) {
        cout << 0 << endl;
        continue;
    }
    vector<ll> DP(N);
    rep(i,0,N) DP[i] = 1LL << i;
    ll MAX = (1LL << N) - 1;
    bool ans = false;
    rep(i,0,30) {
        ll COUNT = 0;
        for (int A : V[i]) COUNT |= DP[A];
        for (int A : V[i]) DP[A] = COUNT;
        rep(j,0,N) {
            if (DP[j] == MAX) {
                cout << i+1 << endl;
                ans = true;
                break;
            }
        }
        if (ans) break;
    }
    if (!ans) cout << -1 << endl;

}
}
accuracy: 1
time_ms: 20
memory_kb: 3252
final_rank: 4

code_snippet: #include <bits/stdc++.h>
using namespace std;

#ifdef LOCAL
#include "./debug.hpp"
#else
#define debug(...)
#define print_line
#endif

using ll = long long;
using vi = vector<int>;
using vl = vector<ll>;
using pi = pair<int,int>;
using pl = pair<ll,ll>;
const int INF = 1e9 + 10;
const ll INFL = 4e18;
#define rep(i, a, b) for (ll i = (a); i < (ll)(b); i++)
#define all(x) x.begin(),x.end()

template <typename T> bool chmax(T &a, const T &b) { if (a < b) { a = b; return true; } return false; }
template <typename T> bool chmin(T &a, const T &b) { if (a > b) { a = b; return true; } return false; }

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

const int MX=31;

int main(){
	while(true){
		int N;cin>>N;
		if(N==0)break;
		vector<vector<int>>D(MX);
		for(int i=0;i<N;i++){
			int m;cin>>m;
			for(int j=0;j<m;j++){
				int d;cin>>d;
				D[d].push_back(i);
			}
		}

		int ans=INF;
		vector<set<int>>st(N);
		for(int i=0;i<N;i++)st[i].insert(i);
		for(int i=0;i<MX;i++){
			for(int j=0;j<(int)D[i].size();j++){
				for(int k=j+1;k<(int)D[i].size();k++){
					for(int x:st[D[i][j]])st[D[i][k]].insert(x);
					for(int x:st[D[i][k]])st[D[i][j]].insert(x);
				}
			}
			for(int j=0;j<N;j++){
				debug(st[j]);
				if(st[j].size()==N)ans=i;
			}
			if(ans!=INF)break;
		}

		if(ans==INF)ans=-1;
		cout<<ans<<endl;
	}
}
accuracy: 1
time_ms: 1100
memory_kb: 3508
final_rank: 20

code_snippet: #include <bits/stdc++.h>
using namespace std;

#define rep(i,k,n) for (int i = k; i < (n); ++i)
const long long MOD1 = 1000000007;
const long long MOD2 = 998244353;
typedef long long ll;
typedef pair<ll, ll> P;
const long long INF = 1e17;

int main(){
    while(true){
        int n;
        cin >> n;
        if(n==0){
            break;
        }

        //dp[i] =　
        //人iに最適に地図を集めたときの断片の集合
        vector<vector<int>> dp(n+10);

        for(int i=1;i<=n;i++){
            dp[i].push_back(i);
        }

        vector<vector<int>> free(n+10);
        vector<vector<int>> date(40);
        for(int i=1;i<=n;i++){
            int f;
            cin >> f;
            for(int j=0;j<f;j++){
                int x;
                cin >> x;
                free[i].push_back(x);
                date[x].push_back(i);
            }
        }

        int ans = -1;
        for(int i=1;i<=30;i++){
            //j->kにあげる
            for(int j=0;j<date[i].size();j++){
                for(int k=0;k<date[i].size();k++){
                    if(j==k)continue;
                    //dp[from]に含まれて、
                    //dp[to]に含まれない要素を
                    //dp[to]に追加  
                    for(auto x:dp[date[i][j]]){
                        bool have = false;
                        for(auto y:dp[date[i][k]]){
                            if(x==y)have = true;
                        }
                        if(!have)dp[date[i][k]].push_back(x);
                    }
                }
            }

            bool ok = false;
            for(int j=1;j<=n;j++){
                if(dp[j].size()==n){
                    ans = i;
                    ok = true;
                    break;
                }
            }
            if(ok){
                break;
            }
        }

        cout << ans << endl;
    }
    return 0;
}
accuracy: 1
time_ms: 1030
memory_kb: 3432
final_rank: 18

code_snippet: #include<bits/stdc++.h>
using namespace std;
int main() {
  while (1) {
    int n;
    cin >> n;
    if (n == 0) {
      break;
    }
    vector<int> f(n);
    vector<vector<int>> e(n);
    for (int i = 0; i < n; i++) {
      cin >> f[i];
      e[i].resize(f[i]);
      for (int j = 0; j < f[i]; j++) {
        cin >> e[i][j];
        e[i][j]--;
      }
    }
    vector<vector<int>> S(31);
    //S[i] はi(0-idx)日目の集まれる人の集合
    for (int i = 0; i < n; i++) {
      for (int j = 0; j < f[i]; j++) {
        S[e[i][j]].push_back(i);
      }
    }
    vector dp(31, vector(n, vector<int> (n, 0)));
    for (int i = 0; i < n; i++) {
      dp[0][i][i] = 1;
    }
    for (int i = 0; i < 30; i++) {
      for (int j = 0; j < n; j++) {
        dp[i + 1][j] = dp[i][j];
      }
      int N = S[i].size();
      vector<int> tmp(n, 0);
      for (int j = 0; j < N; j++) {
        //S[i][j]
        for (int k = 0; k < n; k++) {
          tmp[k] |= dp[i][S[i][j]][k];
        }
      }
      for (int j = 0; j < N; j++) {
        for (int k = 0; k < n; k++) {
          dp[i + 1][S[i][j]][k] |= tmp[k];
        }
      }
    }
    int ans = 31;
    vector<int> Check(n, 1);
    for (int i = 0; i < 31; i++) {
      bool ok = false;
      for (int j = 0; j < n; j++) {
        if (dp[i][j] == Check) {
          ans = i;
          ok = true;
          break;
        }
      }
      if (ok) break;
    }
    if (ans == 31) {
      ans = -1;
    }
    cout << ans << '\n';
  }
}
accuracy: 1
time_ms: 50
memory_kb: 3584
final_rank: 16

code_snippet: #include <bits/stdc++.h>
#define rep(i, n) for (int i = 0; i < (int)(n); i++)
#define all(x) (x).begin(),(x).end()
#define eb emplace_back
using namespace std;
using ll = long long;
using ld = long double;
using vl = vector<long long>;
using vvl = vector<vector<long long>>; using vs = vector<string>;
using pl = pair<long long, long long>;
template <typename T> inline bool chmin(T& a, const T& b) {bool compare = a > b; if (a > b) a = b; return compare;}
template <typename T> inline bool chmax(T& a, const T& b) {bool compare = a < b; if (a < b) a = b; return compare;}
template<class T>using rp_queue=priority_queue<T,vector<T>,greater<T>>;
template <typename T> T gcd(T a, T b) {if (b == 0)return a; else return gcd(b, a % b);}
template <typename T> inline T lcm(T a, T b) {return a /gcd(a, b)*b;}
const ll INF = 1LL << 60;
const ld PI = acos(-1);
template <class OStream, class T> OStream &operator<<(OStream &os, const std::vector<T> &vec);
template <class OStream, class T, size_t sz> OStream &operator<<(OStream &os, const std::array<T, sz> &arr);
template <class OStream, class T, class TH> OStream &operator<<(OStream &os, const std::unordered_set<T, TH> &vec);
template <class OStream, class T, class U> OStream &operator<<(OStream &os, const pair<T, U> &pa);
template <class OStream, class T> OStream &operator<<(OStream &os, const std::deque<T> &vec);
template <class OStream, class T> OStream &operator<<(OStream &os, const std::set<T> &vec);
template <class OStream, class T> OStream &operator<<(OStream &os, const std::multiset<T> &vec);
template <class OStream, class T> OStream &operator<<(OStream &os, const std::unordered_multiset<T> &vec);
template <class OStream, class T, class U> OStream &operator<<(OStream &os, const std::pair<T, U> &pa);
template <class OStream, class TK, class TV> OStream &operator<<(OStream &os, const std::map<TK, TV> &mp);
template <class OStream, class TK, class TV, class TH> OStream &operator<<(OStream &os, const std::unordered_map<TK, TV, TH> &mp);
template <class OStream, class... T> OStream &operator<<(OStream &os, const std::tuple<T...> &tpl);
 
template <class OStream, class T> OStream &operator<<(OStream &os, const std::vector<T> &vec) { os << '['; for (auto v : vec) os << v << ','; os << ']'; return os; }
template <class OStream, class T, size_t sz> OStream &operator<<(OStream &os, const std::array<T, sz> &arr) { os << '['; for (auto v : arr) os << v << ','; os << ']'; return os; }
template <class... T> std::istream &operator>>(std::istream &is, std::tuple<T...> &tpl) { std::apply([&is](auto &&... args) { ((is >> args), ...);}, tpl); return is; }
template <class OStream, class... T> OStream &operator<<(OStream &os, const std::tuple<T...> &tpl) { os << '('; std::apply([&os](auto &&... args) { ((os << args << ','), ...);}, tpl); return os << ')'; }
template <class OStream, class T, class TH> OStream &operator<<(OStream &os, const std::unordered_set<T, TH> &vec) { os << '{'; for (auto v : vec) os << v << ','; os << '}'; return os; }
template <class OStream, class T> OStream &operator<<(OStream &os, const std::deque<T> &vec) { os << "deq["; for (auto v : vec) os << v << ','; os << ']'; return os; }
template <class OStream, class T> OStream &operator<<(OStream &os, const std::set<T> &vec) { os << '{'; for (auto v : vec) os << v << ','; os << '}'; return os; }
template <class OStream, class T> OStream &operator<<(OStream &os, const std::multiset<T> &vec) { os << '{'; for (auto v : vec) os << v << ','; os << '}'; return os; }
template <class OStream, class T> OStream &operator<<(OStream &os, const std::unordered_multiset<T> &vec) { os << '{'; for (auto v : vec) os << v << ','; os << '}'; return os; }
template <class OStream, class T, class U> OStream &operator<<(OStream &os, const std::pair<T, U> &pa) { return os << '(' << pa.first << ',' << pa.second << ')'; }
template <class OStream, class TK, class TV> OStream &operator<<(OStream &os, const std::map<TK, TV> &mp) { os << '{'; for (auto v : mp) os << v.first << "=>" << v.second << ','; os << '}'; return os; }
template <class OStream, class TK, class TV, class TH> OStream &operator<<(OStream &os, const std::unordered_map<TK, TV, TH> &mp) { os << '{'; for (auto v : mp) os << v.first << "=>" << v.second << ','; os << '}'; return os; }
#ifdef LOCAL
const string COLOR_RESET = "\033[0m", BRIGHT_GREEN = "\033[1;32m", BRIGHT_RED = "\033[1;31m", BRIGHT_CYAN = "\033[1;36m", NORMAL_CROSSED = "\033[0;9;37m", RED_BACKGROUND = "\033[1;41m", NORMAL_FAINT = "\033[0;2m";
#define dbg(x) std::cerr << BRIGHT_CYAN << #x << COLOR_RESET << " = " << (x) << NORMAL_FAINT << " (L" << __LINE__ << ") " << __FILE__ << COLOR_RESET << std::endl
#define dbgif(cond, x) ((cond) ? std::cerr << BRIGHT_CYAN << #x << COLOR_RESET << " = " << (x) << NORMAL_FAINT << " (L" << __LINE__ << ") " << __FILE__ << COLOR_RESET << std::endl : std::cerr)
#else
#define dbg(x) ((void)0)
#define dbgif(cond, x) ((void)0)
#endif
void solve();
int main(){
  cin.tie(nullptr);
  ios_base::sync_with_stdio(false);
  cout<<fixed<<setprecision(15);
  int num_tc = 1;
  //cin >> num_tc;
  rep(tc,num_tc){
    //cout << "Case #" << tc+1 << ": " ;// << endl;
    solve();
  }
}
//見切り発車で実装しては行けない．頭の中でコードが完全に出来上がるまで書き始めるな．
void solve(){
  while(true){
    int n;cin>>n;
    if(n==0)return;
    vvl A(n);
    vvl day(31);
    rep(i,n){
      ll f;cin>>f;
      A[i].resize(f);
      rep(j,f)cin>>A[i][j],A[i][j]--,day[A[i][j]].push_back(i);
    }
    vector<bitset<60>> p(n);
    rep(i,n)p[i].set(i,1);
    ll ans = INF;
    rep(i,31){
      bitset<60> now;
      for(auto a:day[i])now|=p[a];
      for(auto a:day[i])p[a]|=now;
      dbg(day[i]);
      dbg(now);
      rep(j,n){
        if(p[j].count()==n){
          chmin(ans,(ll)i+1);
        }
      }
    }
    cout<<(ans==INF?-1:ans)<<endl;
  }
}
accuracy: 1
time_ms: 10
memory_kb: 3452
final_rank: 9

code_snippet: #include <bits/stdc++.h>
//#include <atcoder/all>
using namespace std;

using ll = long long;
using i64 = long long;
using pll = pair<ll,ll>;
using plll = pair<pll,ll>;

constexpr ll mod = 998244353;

int dx[4]={1,0,-1,0};
int dy[4]={0,1,0,-1};

bool is_ok(ll S,int n){
    for (ll k=0; k<n; k++){
        if ((S&((ll)1<<k))==0)return false;
    }
    return true;
}

int main(){
    while (true){
        int n;
        cin>>n;
        if (n==0)break;

        vector<vector<ll>> dp(32,vector<ll>(n));
        vector<vector<int>> vec(31);
        for (int i=0; i<n; i++){
            int m;
            cin>>m;
            for (int j=0; j<m; j++) {
                int t;
                cin >> t;
                vec[t].push_back(i);
            }
        }

        for (ll i=0; i<n; i++){
            dp[0][i]=((ll)1<<i);
            
        }

        int ans=-1;
        for (int t=0; t<31; t++){
            ll S=0;
            for (auto v: vec[t]){

                S=(S|dp[t][v]);
            }


            if (is_ok(S,n)){
                ans=t;
                break;
            }
            for (auto v: vec[t]){
                dp[t][v]=S;
            }
            for (int v=0; v<n; v++){
                dp[t+1][v]=dp[t][v];
            }
        }
        cout<<ans<<endl;

    }





}
accuracy: 1
time_ms: 20
memory_kb: 3440
final_rank: 8

code_snippet: #include<bits/stdc++.h>
using namespace std;
vector<int>can_go[30];
bool solve()
{
    int N;
    cin>>N;
    if(N==0)return 0;
    for(int i=0;i<30;i++)can_go[i].clear();
    for(int i=0;i<N;i++)
    {
        int K;
        cin>>K;
        for(;K--;)
        {
            int a;
            cin>>a;
            can_go[a-1].push_back(i);
        }
    }
    vector<set<int>>dp(N);
    for(int i=0;i<N;i++)dp[i].insert(i);
    int day=0;
    bool fn=false;
    while(day<30)
    {
        auto V=can_go[day];
        for(int u:V)
        {
            for(int v:V)
            {
                for(int w:dp[v])dp[u].insert(w);
            }
            if(dp[u].size()==N)fn=true;
        }
        day++;
        if(fn)break;
    }
    cout<<(fn?day:-1)<<'\n';
    return 1;
}
int main(){while(solve()){}}
accuracy: 1
time_ms: 950
memory_kb: 3500
final_rank: 19

code_snippet: #include <bits/stdc++.h>
using namespace std;
#define ll long long 
#define rep(i,n) for(ll i = 0;i < (ll)(n);i++)


void solve(ll n){
  vector<vector<ll>> day(30);
  rep(i,n){
    ll c;cin >> c;
    rep(j,c){
      ll v;cin >> v;
      v--;
      day[v].push_back(i);
    }
  }
  vector<ll> ticket(n);
  rep(i,n){
    ticket[i] = 1LL << i;
  }
  rep(i,30){
    ll ntk = 0;
    for(ll &p:day[i]){
      ntk |= ticket[p];
    }
    if(ntk == (1LL << n)-1){
      cout << i+1 << endl;
      return ;
    }
    for(ll &p:day[i]){
      ticket[p] = ntk;
    }
  }
  cout << -1 << endl;
  return ;
}

int main(){
  while(true){
    ll n;cin >> n;
    if(n == 0)break;
    solve(n);
  }
}
accuracy: 1
time_ms: 20
memory_kb: 3096
final_rank: 1

code_snippet: #include<bits/stdc++.h>
using namespace std;
const int MAX = 1000000005;

bool solve() {
    int n;
    cin >> n;
    if (n == 0) return false;
    vector<int> f(n);
    vector<vector<int>> s(n);
    for (int i = 0; i < n; i++) {
        cin >> f[i];
        for (int j = 0; j < f[i]; j++) {
            int d;
            cin >> d;
            s[i].push_back(d);
        }
    }
    vector<vector<int>> free(31);
    for (int i = 1; i <= 30; i++) {
        for (int j = 0; j < n; j++) {
            for (int d : s[j]) {
                if (d == i) free[i].push_back(j);
            }
        }
    }
    vector<long long> dp(n);
    for (int i = 0; i < n; i++) dp[i] = (1LL << i);
    for (int i = 1; i <= 30; i++) {
        for (int j : free[i]) {
            for (int k : free[i]) {
                if (j == k) continue;
                dp[j] |= dp[k];
            }
        }
        for (int j = 0; j < n; j++) {
            if (dp[j] == (1LL << n) - 1) {
                cout << i << endl;
                return true;
            }
        }
    }
    cout << -1 << endl;

    return true;
}

int main() {
    ios::sync_with_stdio(0); cin.tie();
    while (solve()) {}
}
accuracy: 1
time_ms: 20
memory_kb: 3360
final_rank: 6

code_snippet: #include <bits/stdc++.h>
using namespace std;

#define rep(i,n) for(int i=0;i<n;i++)
#define Rep(i,a,b) for(int i=a;i<b;i++)
#define ALL(x) (x).begin(),(x).end()
#define dbgv(x); for(auto now : x) cout << now << " "; cout << endl;

struct UnionFind {
  vector<int> par;
  UnionFind(int n=0): par(n,-1) {}
  int find(int x) {
    if(par[x] < 0) return x;
    return par[x] = find(par[x]);
  }
  bool unite(int x, int y){
    x = find(x); y = find(y);
    if(x==y) return false;
    if(par[x] > par[y]) swap(x,y);
    par[x] += par[y];
    par[y] = x;
    return true;
  }
  bool same(int x, int y) {return find(x) == find(y);}
  int size(int x) {return -par[find(x)];}
};

int main(){
    while (1){
        int n; cin >> n;
        if(n == 0) break;
        vector<set<int>> v(n);
        rep(i,n){
            v[i].insert(i);
        }
        vector<vector<int>> days(30);
        rep(i,n){
            int k; cin >> k;
            rep(j,k){
                int x; cin >> x;
                x--;
                days[x].push_back(i);
            }
        }
        bool ok = false;
        for(int i = 0;i < 30;i++){
            set<int> now;
            for(int idx : days[i]){
                for(int test : v[idx]) now.insert(test);
            }
            if(now.size() == n){
                cout << i+1 << endl;
                ok = true;
                break;
            }
            for(int idx : days[i]) v[idx]= now;
        }
        if(!ok) cout << -1 << endl;
    }
}
accuracy: 1
time_ms: 100
memory_kb: 3284
final_rank: 5

code_snippet: #include <bits/stdc++.h>
using namespace std;
using ll = long long;
#define all(a) a.begin(),a.end()
#define reps(i, a, n) for (int i = (a); i < (int)(n); i++)
#define rep(i, n) reps(i, 0, n)
#define rreps(i, a, n) for (int i = (a); i > (int)(n); i--)
const long long mod = 1000000007;
const long long INF = 1e18;

int n;

void solve() {
    vector<set<int>> st (n);
    rep(i,n) {
        st[i].insert(i);
    }
    vector<vector<int>> date (30);
    int x,d;
    rep(i,n) {
        cin >> x;
        rep(j,x) {
            cin >> d;
            date[d-1].push_back(i);
        }
    }
    set<int> mx;
    rep(i,30) {
        mx.clear();
        for (auto w : date[i]) {
            for (auto e : st[w]) {
                mx.insert(e);
            }
        }
        for (auto w : date[i]) {
            for (auto e : mx) {
                st[w].insert(e);
            }
        }
        rep(j,n) {
            if (st[j].size() == n) {
                cout << i+1 << endl;
                return;
            }
        }
    }
    cout << -1 << endl;
    return;
}

int main() {
    while (true) {
        cin >> n; 
        if (!n) {
            return 0;
        }
        solve();
    }
}
accuracy: 1
time_ms: 160
memory_kb: 3580
final_rank: 17

code_snippet: #include <bits/stdc++.h>
using namespace std;
using ll = long long;
using P = pair<ll, ll>;
#define rep(i, a, b) for(ll i = a; i < b; ++i)
#define rrep(i, a, b) for(ll i = a; i >= b; --i)
constexpr ll inf = 4e18;
struct SetupIO {
    SetupIO() {
        ios::sync_with_stdio(0);
        cin.tie(0);
        cout << fixed << setprecision(30);
    }
} setup_io;
int main(void) {
    while(true) {
        int n;
        cin >> n;
        if(n == 0) break;
        vector<vector<int>> p(30);
        rep(i, 0, n) {
            int f;
            cin >> f;
            rep(j, 0, f) {
                int d;
                cin >> d;
                d--;
                p[d].push_back(i);
            }
        }
        vector<ll> m(n);
        rep(i, 0, n) {
            m[i] = 1ll << i;
        }
        int ans = -1;
        rep(i, 0, 30) {
            ll mask = 0;
            rep(j, 0, (int)p[i].size()) {
                mask |= m[p[i][j]];
            }
            if(mask + 1 == (1ll << n)) {
                ans = i + 1;
                break;
            }
            rep(j, 0, (int)p[i].size()) {
                m[p[i][j]] = mask;
            }
        }
        cout << ans << '\n';
    }
}
accuracy: 1
time_ms: 10
memory_kb: 3164
final_rank: 2

code_snippet: // (⁠◕⁠ᴗ⁠◕⁠✿⁠)

// #pragma GCC target("avx2")
// #pragma GCC optimize("O3")
// #pragma GCC optimize("unroll-loops")
#include <bits/stdc++.h>
#define rep(i, n) for (ll i = 0; i < (n); i++)
#define srep(i, s, n) for (ll i = s; i < (n); i++)
#define len(x) ((int)(x).size())
#define all(x) (x).begin(), (x).end()
using namespace std;
template<typename T> using vc = vector<T>;
template<typename T> using vv = vc<vc<T>>;
template<typename T> using vvv = vv<vc<T>>;
using vi = vc<int>;using vvi = vv<int>; using vvvi = vv<vi>;
using ll = long long;using vl = vc<ll>;using vvl = vv<ll>; using vvvl = vv<vl>;
using ld = long double; using vld = vc<ld>; using vvld = vc<vld>; using vvvld = vc<vvld>;
using uint = unsigned int;
using ull = unsigned long long;
const ld pi = 3.141592653589793;
const int inf = 0x3f3f3f3f;
const ll INF = 0x3f3f3f3f3f3f3f3f;
// const ll mod = 1000000007;
const ll mod = 998244353;
inline bool inside(ll y, ll x, ll H, ll W) {return 0 <= (y) and (y) < (H) and 0 <= (x) and (x) < (W); }

#define debug(var)  do{std::cout << #var << " : \n";view(var);}while(0)
template<typename T> void view(T e){cout << e << endl;}
template<typename T> void view(const vc<T>& v){for(const auto& e : v){ cout << e << " "; } cout << endl;}
template<typename T> void view(const vv<T>& vv){ for(const auto& v : vv){ view(v); } }

int solve(int N){
    int D = 31;
    vvi day(31);
    vvi g(N * D);
    rep(i, N) rep(j, D - 1) g[i * D + j + 1].push_back(i * D + j);
    rep(p, N){
        int M; cin >> M;
        rep(i, M){
            int d; cin >> d;
            day[d].push_back(p);
        }
    }
    rep(i, D) if (len(day[i])){
        rep(b, len(day[i])) rep(a, b){
            g[day[i][a] * D + i].push_back(day[i][b] * D + i);
            g[day[i][b] * D + i].push_back(day[i][a] * D + i);
        }
        deque<int> q;
        vi seen(N * D, 0);
        q.push_back(day[i][0] * D + i);
        seen[day[i][0] * D + i] = 1;
        set<int> canget = {day[i][0]};
        while (!q.empty()){
            auto v = q.front(); q.pop_front();
            for (auto u : g[v]) if (!seen[u]){
                canget.insert(u / D);
                seen[u] = 1;
                q.push_back(u);
            }
        }
        if (len(canget) == N) return i;
    }
    return -1;
}

int main(){
    vc<int> ans;
    while(true){
        int N; cin >> N;
        if (N == 0) break;
        ans.push_back(solve(N));
    }
    for (auto x : ans) cout << fixed << setprecision(4) << x << endl;
}
accuracy: 1
time_ms: 180
memory_kb: 3380
final_rank: 10