Problem:


		
Problem F: Gather the Maps!

		

			はるか昔、八尾氏が残したとされる伝説の秘宝が八王子のどこかに眠っているという。 その在処を示すとされる宝の地図は、いくつかの断片に分割された状態で、八尾氏の n 人の子孫達によって受け継がれている。
		

		

			今、八尾氏の子孫達は協力してその秘宝を手に入れようとしていた。 ところが、秘宝の在処を指し示す宝の地図の一部分だけでは秘宝を見つけることができない。 そこで、八尾氏の子孫達は全員で集まって地図を 1 ヶ所に集めようとした。
			ところが、いざ実行に移そうとしてもなかなか予定が合わずに集まることができない。 しかしこの秘宝に関する情報は、一族において秘密裏に伝えられてきた貴重な情報である。 漏洩の危険性を考慮すると、公共の通信手段を用いて地図をやりとりすることなど問題外である。
		

		

			そこで、子孫同士が直接会って地図を手渡すということを繰り返すことで、ある 1 人の子孫のところに地図を集めることにした。
			なお、1 人が 1 日に会える人数に制限はないが、互いにスケジュールが空いていることが必要である。
		

		

			あなたの仕事は、それぞれの子孫に対するスケジュールの空いている日のリストから、地図を集めるには最低で何日必要かを求めるプログラムを書くことである。
		

		

			ちなみに、八尾氏一族の結束は非常に固い。 最終的に地図全体を手にした子孫が、他の子孫を裏切って秘宝を持ち逃げすれば、一族から制裁を受けることになる。その制裁はきわめて恐ろしいものであるため、実際にその子孫が秘宝を持ち逃げすることは事実上不可能である。
		

		
Input

		

			入力は複数のデータセットからなる。
		

		

			それぞれのデータセットは複数の行からなる。 その最初の行には、地図の断片を持った者の人数を表す整数 n (1 < n <= 50) が記述されている。 続く n 行には、それぞれの子孫のスケジュールが書かれている。
			i 行目は i 人目の子孫のスケジュールが表しており、いくつかの整数が 1 文字のスペースを区切りとして書かれている。
			最初の整数 fi (0 <= fi <= 30) は、その子孫のスケジュールが空いている日の日数を表す整数である。 続く fi 個の整数は、スケジュールが空いている日付を表す。 これらの日付は互いに異なり、全て 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



Sample input:
4
1 1
2 2 3
2 1 2
3 3 4 5
0


Sample output:
3

Submission status: Wrong Answer

Solution code:
N = int(input())
days = []
for i in range(N):
    day_num, *_days = [int(i) for i in input().split()]
    days.append(min(_days))
print(min(days))

Submission status: Wrong Answer

Solution code:
N = int(input())
days = []
for i in range(N):
    day_num, *_days = [int(i) for i in input().split()]
    days.append(min(_days))
print(max(days))

Submission status: Wrong Answer

Solution code:
while True:
    n = input()
    if (n == 0):
        break
    d = []
    for i in range(n):
        a = map(int, raw_input().split())
        d.append(a[1:])
    for i in range(31):
        ok = True
        for j in d:
            if (len(j) == 0):
                ok = False
                break
            t = min(j)
            if (i < t):
                ok = False
                break
        if (ok):
            print i
            break
    if (ok):
        continue
    else:
        print -1

Submission status: Wrong Answer

Solution code:
while True:
    n = input()
    if (n == 0):
        break
    d = []
    digit = set()
    for i in range(n):
        a = map(int, raw_input().split())
        for j in a[1:]:
            digit.add(j)
        d.append(a[1:])
    for i in digit:
        ok = True
        cnt = 0
        for j in d:
            if (len(j) == 0):
                ok = False
                break
            t = min(j)
            if (i < t):
                ok = False
                break
            elif (i == t):
               cnt += 1
        if (cnt != 1):
            ok = False
        if (ok):
            print i
            break
    if (ok):
        continue
    else:
        print -1

Submission status: Wrong Answer

Solution code:
N = int(raw_input())
free = [map(int,raw_input().split())[1:] for i in xrange(N)]
have = [set([i]) for i in xrange(N)]
for day in xrange(1,31):
    gather = set([])
    for i in xrange(N):
        if day in free[i]:
            gather |= have[i]
    if len(gather) == N:
        print day
        break
    for i in xrange(N):
        if day in free[i]:
            have[i] = gather.copy()
else:
    print -1

Submission status: Wrong Answer

Solution code:
while 1:
	n = int(raw_input())
	if n == 0:
		break
	all_member = 2 ** n - 1
	schedule = [0 for i in range(31)]
	for i in range(n):
		member_idx = 1 << i
		free_day = map(int,raw_input().split(" "))
		for j in range(1,free_day[0]+1):
			schedule[free_day[j]] |= member_idx
	print schedule
	gathered_map = [0]
	for d in range(1,31):
		next = []
		for m in gathered_map:
			if m & schedule[d] == 0:
				next.append(schedule[d])
			else:
				next.append(m | schedule[d])
		if all_member in next:
			print d
			break
		gathered_map = next
	else:
		print -1

Submission status: Wrong Answer

Solution code:
while 1:
	n = int(raw_input())
	if n == 0:
		break
	all_member = 2 ** n - 1
	schedule = [0 for i in range(31)]
	for i in range(n):
		member_idx = 1 << i
		free_day = map(int,raw_input().split(" "))
		for j in range(1,free_day[0]+1):
			schedule[free_day[j]] |= member_idx
	gathered_map = [0]
	for d in range(1,31):
		next = []
		for m in gathered_map:
			if m & schedule[d] == 0:
				next.append(schedule[d])
			else:
				next.append(m | schedule[d])
		if all_member in next:
			print d
			break
		gathered_map = next
	else:
		print -1

Submission status: Wrong Answer

Solution code:
while 1:
	n = int(raw_input())
	if n == 0:
		break
	all_member = 2 ** n - 1
	schedule = [0 for i in range(31)]
	for i in range(n):
		member_idx = 1 << i
		free_day = map(int,raw_input().split(" "))
		for j in range(1,free_day[0]+1):
			schedule[free_day[j]] |= member_idx
	gathered_map = set([0])
	for d in range(1,31):
		next = set()
		for m in gathered_map:
			if m & schedule[d] == 0:
				next.add(m)
				next.add(schedule[d])
			else:
				next.add(m | schedule[d])
		if all_member in next:
			print d
			break
		gathered_map = next
	else:
		print -1

Submission status: Wrong Answer

Solution code:
while(1):
    n=int(raw_input())
    if n==0:
        break
    else:
        win=2**n-1
        know=[2**x for x in range(n)]
        date=[[] for x in range(31)]
        for i in range(n):
            indata=[int(x) for x in raw_input().split()]
            for j in indata[1:]:
                date[j].append(i)
        #print know,date
        for dd in range(1,31):
            m=0
            d=date[dd]
            for pd in d:
                m+=know[pd]
            if m==win:
                print dd
                break
            else:
                for pd in d:
                    know[pd]=m
        else:
            print -1

Submission status: Wrong Answer

Solution code:
while(1):
    n=int(raw_input())
    if n==0:
        break
    else:
        win=2**n-1
        know=[2**x for x in range(n)]
        date=[[] for x in range(31)]
        for i in range(n):
            indata=[int(x) for x in raw_input().split()]
            for j in indata[1:]:
                date[j].append(i)
        #print know,date
        for dd in range(1,31):
            m=0
            d=date[dd]
            for pd in d:
                m|=know[pd]
            if m==win:
                print dd
                break
            else:
                for pd in d:
                    know[pd]=m
        else:
            print -1
        print win, know

Submission status: Wrong Answer

Solution code:
#!/usr/bin/env python
# -*- coding: utf-8 -*-

while True:
    N = int(input())
    if N == 0:
        break
    dates = [[] for i in range(31)]
    people = set(range(N))

    for i in range(N):
        D = list(map(int,input().split()))
        for d in D[1:]:
            dates[d].append(i)

    for i in range(30):
        if len(dates[i]) < 2:
            continue
        people = people - set(dates[i])
        if len(people) == 0:
            break
    else:
        print(-1)
        continue
    print(i)

Submission status: Wrong Answer

Solution code:
import itertools
class UnionFindTree:
    """Disjoint-Set Data Structure
       Union-Find Tree
       complexity: 
          init: O(n)
          find, unite, same: O(alpha(n))
       used in SRM505 div.2 900, ATC001 A, DSL1A(AOJ)
    """
    def __init__(self, n):
        self.par = list(range(n)) # parent
        self.rank = [0] * n # depth of tree

    def find(self, x):
        if self.par[x] == x:
            return x
        else:
            self.par[x] = self.find(self.par[x])
            return self.par[x]

    def unite(self, x, y):
        x, y = self.find(x), self.find(y)
        if x == y: return
        if self.rank[x] < self.rank[y]:
            self.par[x] = y
        else:
            self.par[y] = x
            if self.rank[x] == self.rank[y]:
                self.rank[x] += 1

    def same(self, x, y):
        return self.find(x) == self.find(y)
    
while True:
    N = int(input())
    if not N: break
    uf = UnionFindTree(N)
    days = [[] for _ in range(30)]
    for i in range(N):
        for d in (int(x) for x in input().split()[1:]):
            days[d-1].append(i)
    for i in range(30):
        for n1, n2 in itertools.combinations(days[i], 2):
            uf.unite(n1, n2)
        for j in range(N):
            if not uf.same(0, j):
                break
        else:
            print(i+1)
            break
    else:
        print(-1)

Submission status: Wrong Answer

Solution code:
def solve(n, meetables):
    parts = [set()]

    for d, meetable in enumerate(meetables[1:]):
        todays_parts = [meetable]
        for part in parts:
            if meetable & part:
                meetable.update(part)
                if len(meetable) == n:
                    return d + 1
            else:
                todays_parts.append(part)
        parts = todays_parts
    return -1


while True:
    n = int(input())
    if not n:
        break

    meetables = [set() for _ in range(31)]

    for i in range(n):
        for d in map(int, input().split()[1:]):
            meetables[d].add(i)

    print(solve(n, meetables))

Submission status: Wrong Answer

Solution code:
while True:
    N = int(input())
    if not N:
        break
    f = [0] * N
    for i in range(N):
        f[i] = list(map(int,input().split()[1:]))

    G = [ [int(1e8)] * N for i in range(N)]
    ans = -1
    for i in range(31):
        for j in range(N):
            for k in range(j+1,N):
                if (i in f[j]) and (i in f[k]):
                    G[j][k] = min((G[j][k],i))
                    G[k][j] = min((G[k][j],i))

    used = [int(1e8)] * N
    head = 0
    q = [0]
    ans = int(1e8)
    while len(q) > head:
        x = q[head]
        head += 1
        for i in range(N):
            if G[x][i] < used[i]:
                used[i] = G[x][i]
                q.append(i)

    if int(1e8) in used:
        print(-1)
    else:
        print(max(used))

Submission status: Wrong Answer

Solution code:
import heapq
while True:
    N = int(input())
    if not N:
        break
    f = [0] * N
    for i in range(N):
        f[i] = list(map(int,input().split()[1:]))

    G = [ [int(1e8)] * N for i in range(N)]
    for i in range(31):
        for j in range(N):
            for k in range(j+1,N):
                if (i in f[j]) and (i in f[k]):
                    G[j][k] = min((G[j][k],i))
                    G[k][j] = min((G[k][j],i))

    used = [0] * N
    q = list(zip(G[0],range(100)))
    q.sort()
    head = 0
    ans = int(1e8)
    while len(q) > head:
        v,x = q[head]
        head += 1
        if used[x] == 0:
            used[x] = v
            for j in range(N):
                q.append((G[x][j],j))
            q.sort()

    if int(1e8) in used:
        print(-1)
    else:
        print(max(used))

Submission status: Wrong Answer

Solution code:
import heapq
while True:
    N = int(input())
    if not N:
        break
    f = [0] * N
    for i in range(N):
        f[i] = list(map(int,input().split()[1:]))

    G = [ [int(1e8)] * N for i in range(N)]
    for i in range(31):
        for j in range(N):
            for k in range(j+1,N):
                if (i in f[j]) and (i in f[k]):
                    G[j][k] = min((G[j][k],i))
                    G[k][j] = min((G[k][j],i))

    used = [0] * N
    used[0] = 1
    q = list(zip(G[0],range(100)))
    q.sort()
    head = 0
    ans = int(1e8)
    while len(q) > head:
        v,x = q[head]
        head += 1
        if used[x] == 0:
            used[x] = v
            for j in range(N):
                q.append((G[x][j],j))
            q.sort()

    if int(1e8) in used:
        print(-1)
    else:
        print(max(used))

Submission status: Wrong Answer

Solution code:
import heapq
while True:
    N = int(input())
    if not N:
        break
    f = [0] * N
    for i in range(N):
        f[i] = list(map(int,input().split()[1:]))

    GG = [ [int(1e8)] * N for j in range(N)]
    for i in range(31):
        for j in range(N):
            for k in range(j+1,N):
                if (i in f[j]) and (i in f[k]):
                    GG[j][k] = i
                    GG[k][j] = i

    ans = 40
    for d in range(1,31):
        G = [ [int(1e8)] * N for j in range(N) ]
        for i in range(N):
            for j in range(i+1,N):
                if GG[i][j] <= d:
                    G[i][j] = GG[i][j]
                    G[j][i] = GG[j][i]

        used = [False] * N
        q = [0]
        head = 0
        while len(q)>head and False in used:
            x = q[head]
            head += 1
            for i in range(N):
                if G[x][i] < 31 and not used[i]:
                    q.append(i)
                    used[i] = True
        if not (False in used):
            ans = d
            break
    if ans > 30:
        print(-1)
    else:
        print(ans)

Submission status: Wrong Answer

Solution code:
import heapq
while True:
    N = int(input())
    if not N:
        break
    f = [0] * N
    for i in range(N):
        f[i] = list(map(int,input().split()[1:]))

    GG = [ [int(1e8)] * N for j in range(N)]
    for i in range(31,0,-1):
        for j in range(N):
            for k in range(j+1,N):
                if (i in f[j]) and (i in f[k]):
                    GG[j][k] = i
                    GG[k][j] = i

    ans = 40
    l = 0
    r = 31
    m = (l+r)//2
    while r-l>1:
        G = [ [int(1e8)] * N for j in range(N) ]
        for i in range(N):
            for j in range(i+1,N):
                if GG[i][j] <= m:
                    G[i][j] = GG[i][j]
                    G[j][i] = GG[j][i]

        used = [False] * N
        q = [0]
        head = 0
        while len(q)>head and False in used:
            x = q[head]
            head += 1
            for i in range(N):
                if G[x][i] < 31 and not used[i]:
                    q.append(i)
                    used[i] = True

        if not (False in used):
            r = m
            ans = min( (ans,m) )
        else:
            l = m
        m = (r+l)//2
    if ans > 30:
        print(-1)
    else:
        print(ans)

Submission status: Wrong Answer

Solution code:
import heapq
while True:
    N = int(input())
    if not N:
        break
    f = [0] * N
    for i in range(N):
        f[i] = list(map(int,input().split()[1:]))

    dp = [ [0] * 51 for i in range(51) ]

    for i in range(N):
        for j in range(N):
            dp[j][i] = 1<<i
    for i in range(1,31):
        ds = [ j for j in range(N) if i in f[j]]
        for d1 in ds:
            for d2 in ds:
                dp[i][d1] |= dp[i-1][d2]

    ans = 40
    for i in range(31):
        for j in range(N):
            if dp[i][j] == (1<<N)-1:
                ans = min( (ans,i) )
    if ans > 30:
        print(-1)
    else:
        print(ans)

Submission status: Wrong Answer

Solution code:
class UnionFind:
  def __init__(self, size):
    self.table = [-1 for _ in xrange(size)]

  def find(self, x):
    while self.table[x] >= 0: x = self.table[x]
    return x

  def union(self, x, y):
    s1 = self.find(x)
    s2 = self.find(y)
    if s1 != s2:
      if self.table[s1] >= self.table[s2]:
        self.table[s1] += self.table[s2]
        self.table[s2] = s1
      else:
        self.table[s2] += self.table[s1]
        self.table[s1] = s2
      return True
    return False

  def allUnion(self):
    isUnioned = True
    for i in xrange(1, len(self.table)):
      if self.find(0) != self.find(i):
        isUnioned = False
        break
    return isUnioned

# main
while True:
  n = int(raw_input())
  if n==0: break
  calender = {}
  isFailed = True
  for i in xrange(n):
    a = map(int, raw_input().split())
    for j in xrange(1, a[0]+1):
      if a[j] not in calender:
        calender[a[j]] = []
      calender[a[j]].append(i)
  uf = UnionFind(n)
  for k,v in sorted(calender.items()):
    if len(v) > 1:
      for i in xrange(1, len(v)):
        uf.union(v[0], v[i])
    if uf.allUnion():
      print k
      isFailed = False
      break
  if isFailed: print "-1"

Submission status: Wrong Answer

Solution code:
def root(x):
    if x == parent[x]:
        return x
    parent[x] = root(parent[x])
    return parent[x]
def unite(x, y):
    px = root(x); py = root(y)
    if px < py:
        parent[py] = px
    else:
        parent[px] = py
while 1:
    n = input()
    if n == 0:
        break
    dic = {}
    parent = range(n)
    for i in xrange(n):
        for d in map(int, raw_input().split())[1:]:
            dic.setdefault(d, []).append(i)
    for i in xrange(1, 31):
        if i not in dic: continue
        ds = dic[i]
        for j in xrange(len(ds)-1):
            unite(ds[j], ds[j+1])
        if sum(parent) == 0:
            print i
            break
    else:
        print -1

Submission status: Wrong Answer

Solution code:
def root(x):
    if x == parent[x]:
        return x
    parent[x] = root(parent[x])
    return parent[x]
def unite(x, y):
    px = root(x); py = root(y)
    if px < py:
        parent[py] = px
    else:
        parent[px] = py
while 1:
    n = input()
    if n == 0:
        break
    dic = {}
    parent = range(n)
    for i in xrange(n):
        for d in map(int, raw_input().split())[1:]:
            dic.setdefault(d, []).append(i)
    for i in xrange(1, 31):
        if i not in dic: continue
        ds = dic[i]
        for j in xrange(len(ds)-1):
            unite(ds[j], ds[j+1])
        for i in xrange(n):root(i)
        if sum(parent) == 0:
            print i
            break
    else:
        print -1

Submission status: Wrong Answer

Solution code:
while(True):
    n = int(input())
    if n == 0:
        break
    d = []
    for i in range(n):
        ll = input().split()
        l = [int(_) for _ in ll]
        f = l[0]

        tmp = []
        for j in range(1, f+1):
            tmp.append(l[j])
        d += [tmp]

    mp = [[0 for i in range(31)] for j in range(n)]
    for member in range(n):
        for day in d[member]:
            mp[member][day] = 1
    clr = [0 for i in range(n)]
    ans = [1 for i in range(n)]
    flg = 0
    for day in range(31):
        tmp = []
        s = 0
        for member in range(n):
            s += mp[member][day]
            if mp[member][day] == 1:
                tmp.append(member)
        if s > 1:
            for member in tmp:
                clr[member] = 1
        if clr == ans and flg == 0:
            print(day)
            flg = 1

    if flg == 0:
        print(-1)

Submission status: Wrong Answer

Solution code:
import math,string,itertools,fractions,heapq,collections,re,array,bisect,sys,random,time,copy,functools

sys.setrecursionlimit(10**7)
inf = 10**20
eps = 1.0 / 10**10
mod = 998244353
dd = [(0,-1),(1,0),(0,1),(-1,0)]
ddn = [(0,-1),(1,-1),(1,0),(1,1),(0,1),(-1,-1),(-1,0),(-1,1)]

def LI(): return [int(x) for x in sys.stdin.readline().split()]
def LI_(): return [int(x)-1 for x in sys.stdin.readline().split()]
def LF(): return [float(x) for x in sys.stdin.readline().split()]
def LS(): return sys.stdin.readline().split()
def I(): return int(sys.stdin.readline())
def F(): return float(sys.stdin.readline())
def S(): return input()
def pf(s): return print(s, flush=True)

class UnionFind:
    def __init__(self, size):
        self.table = [-1 for _ in range(size)]

    def find(self, x):
        if self.table[x] < 0:
            return x
        else:
            self.table[x] = self.find(self.table[x])
            return self.table[x]

    def union(self, x, y):
        s1 = self.find(x)
        s2 = self.find(y)
        if s1 != s2:
            if self.table[s1] <= self.table[s2]:
                self.table[s1] += self.table[s2]
                self.table[s2] = s1
            else:
                self.table[s2] += self.table[s1]
                self.table[s1] = s2
            return True
        return False

    def subsetall(self):
        a = []
        for i in range(len(self.table)):
            if self.table[i] < 0:
                a.append((i, -self.table[i]))
        return a

def main():
    rr = []

    while True:
        n = I()
        if n == 0:
            break
        a = [LI()[1:] for _ in range(n)]
        d = collections.defaultdict(list)
        for i in range(n):
            for c in a[i]:
                d[c].append(i)
        t = 0
        uf = UnionFind(n)
        r = -1
        for k in sorted(list(d.keys())):
            b = d[k][0]
            for c in d[k][1:]:
                if uf.union(b,c):
                    t += 1
            if t == n - 1:
                r = k
                break
        rr.append(r)

    return '\n'.join(map(str,rr))


print(main())

Submission status: Wrong Answer

Solution code:
N = int(input())

while N:
    days = [0]*31
    for i in range(N):
        x = 2**i
        for j in list(map(int, input().split()))[1:]:
            days[j] |= x
    for i in range(1, 31):
        days[i] |= days[i-1]
        if days[i] == 2**N - 1:
            print(i)
            break
    else:
        print(-1)
    N = int(input())

Submission status: Accepted

Solution code:
while True:
    n = input()
    if (n == 0):
        break
    state = []
    schedule = []
    ok = True
    for i in range(n):
        temp = map(int, raw_input().split())
        if temp[0] != 0:
            schedule.append(set(temp[1:]))
        else:
            ok = False
        state.append(set([i]))
    if (ok == False):
        print -1
        continue
    for day in range(1, 31):
        temp = []
        Maps = set()
        for i in range(len(schedule)):
            if day in schedule[i]:
                temp.append(i)
                Maps |= state[i]
        for c in temp:
            state[c] = Maps
        if len(Maps) == n:
            print day
            break
    else:
        print -1

Submission status: Accepted

Solution code:
while 1:
    N = int(raw_input())
    if N == 0: break
    free = [map(int,raw_input().split())[1:] for i in xrange(N)]
    have = [set([i]) for i in xrange(N)]
    for day in xrange(1,31):
        gather = set([])
        for i in xrange(N):
            if day in free[i]:
                gather |= have[i]
        if len(gather) == N:
            print day
            break
        for i in xrange(N):
            if day in free[i]:
                have[i] = gather.copy()
    else:
        print -1

Submission status: Accepted

Solution code:
while 1:
    N = int(raw_input())
    if N == 0: break
    free = [map(int,raw_input().split())[1:] for i in xrange(N)]
    have = [set([i]) for i in xrange(N)]
    for day in xrange(1,31):
        gather = set([])
        come = [i for i in xrange(N) if day in free[i]]
        for i in come:
            gather |= have[i]
        if len(gather) == N:
            print day
            break
        for i in come:
            have[i] = gather.copy()
    else:
        print -1

Submission status: Accepted

Solution code:
while(1):
    n=int(raw_input())
    if n==0:
        break
    else:
        win=2**n-1
        know=[2**x for x in range(n)]
        date=[[] for x in range(31)]
        for i in range(n):
            indata=[int(x) for x in raw_input().split()]
            for j in indata[1:]:
                date[j].append(i)
        #print know,date
        for dd in range(1,31):
            m=0
            d=date[dd]
            for pd in d:
                m|=know[pd]
            if m==win:
                print dd
                break
            else:
                for pd in d:
                    know[pd]=m
        else:
            print -1
        #print win, know

Submission status: Accepted

Solution code:
#!/usr/bin/env python
# -*- coding: utf-8 -*-

while True:
    N = int(input())
    if N == 0:
        break
    dates = [[] for i in range(31)]
    meets = [[] for i in range(N)]

    for i in range(N):
        D = list(map(int,input().split()))
        for d in D[1:]:
            dates[d].append(i)

    for i in range(31):
        hoge = []
        for p in dates[i]:
            hoge = set(hoge) | set(meets[p])
        for p in dates[i]:
            meets[p] = set(hoge) | set(dates[i])
            if len(meets[p]) == N:
                break
        else:
            continue
        break
    else:
        print(-1)
        continue
    print(i)

Submission status: Accepted

Solution code:
def check(day):
	tmp = meet[day]
	for i in range(day,0,-1):
		if tmp & meet[i] != 0:
			tmp |= meet[i]
	return tmp == all_maps

while 1:
	n = int(raw_input())
	if n == 0:
		break
	all_maps = 2**n-1
	meet = [0 for i in range(31)]
	for i in range(n):
		freeday = map(int,raw_input().split(" "))
		for j in freeday[1:]:
			meet[j] += 1 << i
	for i in range(1,31):
		if check(i):
			print i
			break
	else:
		print -1

Submission status: Accepted

Solution code:
MAX_N = 50
MAX_DAY = 30

def solve(n, f):
    dp = [[set() for j in range(n)] for i in range(MAX_DAY + 1)]
    for i in range(n):
        dp[0][i].add(i)

    for d in range(1, MAX_DAY + 1):

        # for line in dp[:5]:
        #     print(line)

        for i in range(n):
            dp[d][i] |= dp[d - 1][i]
            for j in range(n):
                if f[d][i] and f[d][j]:
                    dp[d][i] |= dp[d - 1][j]

            if len(dp[d][i]) == n:
                return d

    return -1

######################################

while True:
    n = int(input())
    if n == 0:
        exit()

    f = [[False] * n for i in range(MAX_DAY + 1)]
    for i in range(n):
        _, *li = map(int, input().split())
        for x in li:
            f[x][i] = True

    # for line in f:
    #     print(line)

    print(solve(n, f))

Submission status: Accepted

Solution code:
MAX_N = 50
MAX_DAY = 30

def solve(n, f):
    dp = [{i} for i in range(n)]

    for d in range(1, MAX_DAY + 1):
        for i in range(n):
            for j in range(n):
                if f[d][i] and f[d][j]:
                    dp[i] |= dp[j]

            if len(dp[i]) == n:
                return d

    return -1

######################################

while True:
    n = int(input())
    if n == 0:
        exit()

    f = [[False] * n for i in range(MAX_DAY + 1)]
    for i in range(n):
        _, *li = map(int, input().split())
        for x in li:
            f[x][i] = True

    print(solve(n, f))

Submission status: Accepted

Solution code:
def solve(n, meetables):
    mets = [set() for _ in range(n)]

    for d, meetable in enumerate(meetables[1:]):
        today = meetable.copy()
        for i in meetable:
            today.update(mets[i])
            mets[i] = today
        if len(today) == n:
            return d + 1
    return -1


while True:
    n = int(input())
    if not n:
        break

    meetables = [set() for _ in range(31)]

    for i in range(n):
        for d in map(int, input().split()[1:]):
            meetables[d].add(i)

    print(solve(n, meetables))

Submission status: Accepted

Solution code:
import heapq
while True:
    N = int(input())
    if not N:
        break
    f = [0] * N
    for i in range(N):
        f[i] = list(map(int,input().split()[1:]))

    dp = [ [0] * 51 for i in range(51) ]

    for i in range(N):
        for j in range(N):
            dp[j][i] = 1<<i
    for i in range(1,31):
        ds = [ j for j in range(N) if i in f[j]]
        for d1 in ds:
            for d2 in ds:
                dp[i][d1] |= dp[i-1][d2]
        for j in range(N):
            dp[i][j] |= dp[i-1][j]
    ans = 40
    for i in range(31):
        for j in range(N):
            if dp[i][j] == (1<<N)-1:
                ans = min( (ans,i) )
    if ans > 30:
        print(-1)
    else:
        print(ans)

Submission status: Accepted

Solution code:
while True:
  n = int(raw_input())
  if n==0: break
  lst = [0] * n
  for i in xrange(n):
    lst[i] = 1 << i
  isFailed = True
  calender = {}

  for i in xrange(n):
    a = map(int, raw_input().split())
    for j in xrange(1, a[0]+1):
      if a[j] not in calender:
        calender[a[j]] = []
      calender[a[j]].append(i)
  for k,v in sorted(calender.items()):
    stat = 0
    for i in xrange(len(v)):
      stat = stat | lst[v[i]]
    for i in xrange(len(v)):
      lst[v[i]] = stat
    if stat == (1 << n) - 1:
      print k
      isFailed = False
      break
  if isFailed: print "-1"

Submission status: Accepted

Solution code:
while 1:
    n = input()
    if n == 0:
        break
    dic = {}
    for i in xrange(n):
        for d in map(int, raw_input().split())[1:]:
            dic.setdefault(d, []).append(i)
    E = [{i} for i in xrange(n)]
    for i in xrange(1, 31):
        if i not in dic:
            continue
        di = dic[i]
        su = set()
        for j in di:
            su |= E[j]
        for j in di:
            E[j] = su
        if len(su) == n:
            print i
            break
    else:
        print -1

Submission status: Accepted

Solution code:
while True:
    N = int(input())
    if not N:
        break
    D = [[] for _ in range(30)]
    for i in range(N):
        for x in map(int, input().split()[1:]):
            D[x - 1].append(i)
    C = [1 << i for i in range(N)]
    for d in range(30):
        for i in D[d]:
            for j in D[d]:
                C[i] = C[i] | C[j]
        if any(x == (1 << N) - 1 for x in C):
            print(d + 1)
            break
    else:
        print(-1)

Submission status: Accepted

Solution code:
import itertools
while True:
    N = int(input())
    if not N:
        break
    D = [[] for _ in range(30)]
    for i in range(N):
        for x in map(int, input().split()[1:]):
            D[x - 1].append(i)
    C = [1 << i for i in range(N)]
    for d in range(30):
        for i, j in itertools.permutations(D[d], 2):
            C[i] = C[i] | C[j]
        if any(x == (1 << N) - 1 for x in C):
            print(d + 1)
            break
    else:
        print(-1)

Submission status: Accepted

Solution code:
import itertools
while True:
    N = int(input())
    if not N:
        break
    D = [[] for _ in range(30)]
    for i in range(N):
        for x in map(int, input().split()[1:]):
            D[x - 1].append(i)
    C = [1 << i for i in range(N)]
    for d in range(30):
        for i, j in itertools.combinations(D[d], 2):
            C[i] = C[j] = C[i] | C[j]
        if any(x == (1 << N) - 1 for x in C):
            print(d + 1)
            break
    else:
        print(-1)