Buggy python submission (verdict: Time Limit Exceeded):
N,M = map(int,input().split())
a_list = []
b_list = []
c_list = []
for _ in range(M):
    a, b = map(int,input().split())
    c = list(map(int,input().split()))
    c = [cc-1 for cc in c]
    a_list.append(a)
    b_list.append(b)
    c_list.append(c)


takara_keys = {}
for i in range(N):
    takara = []
    for idx, c in enumerate(c_list):
        if i in c:
            takara.append(idx)
    takara_keys[i] = takara

clear = [1 for _ in range(N)]
def dp(memos, cost):
    if memos == clear:
        return cost
    costs = [10**9]
    for takara, memo in enumerate(memos):
        hoge_flg = 0
        if memo == 0:
            hoge_flg = 1
            next_keys = takara_keys[takara]
            for key in next_keys:
                tmp_memos = memos[:]
                for takara_idx in c_list[key]:
                    tmp_memos[takara_idx] = 1
                tmp_cost = cost + a_list[key]
                costs.append(dp(tmp_memos,tmp_cost))
        if hoge_flg == 1:
            break
    return min(costs)

length_0_flag = False
for v in takara_keys.values():
    if len(v)==0:
        length_0_flag = True

if length_0_flag:
    print(-1)
else:
    print(dp([0 for _ in range(N)],0))

Fixed submission:
#解説放送見てからの書き直し
import sys
import os
INF = 10**12
ans = INF
N, M = map(int,input().split())
A = [0 for _ in range(M)]
B = [0 for _ in range(M)]
C = []
for i in range(M):
    a, b = map(int,input().split())
    A[i] = a  #鍵の金額
    B[i] = b  #開けられる宝箱の種類数
    tmp = list((map(int,input().split())))
    s = 0
    for j in range(b):
        t = tmp.pop(0)-1
        s |= 1 << t
    C.append(s)
    
dp = [INF]*(1<<N) #2^N
dp[0] = 0 #0 = 0b0000の時、スコアは0（まだ1つも鍵を購入してないので）

for s in range(1<<N): #1<<Nは2^N。つまりどの宝箱が開くかの全ての状態
    for j in range(M): # 全ての鍵について見ていく
        t = s | C[j] # 論理和。sには現在どの宝箱が開けられるかの状態、
                     # C[j]にはその新たな鍵が開ける宝箱。
                     # その論理和はこれまでの鍵と新たな鍵でどの宝箱が開けられるか
        cost = dp[s] + A[j] # その鍵を買った時のコスト
        dp[t] = min(dp[t],cost) #新たな宝箱の状態について、コストがより低くなるようなら保存する。
ans = dp[-1] #dp[-1]、つまり0b1111。宝箱が全て開けられる状態。
if ans == INF: #もし0b1111がINFのまま（最初から変わってない）ということはそこにたどり着けなかったということ。
               #つまり、全ての鍵を使っても宝箱を開けられなかった。
    ans = -1
print(ans)

Buggy python submission (verdict: Runtime Error):
N,M = map(int,input().split())
a_list = []
b_list = []
c_list = []
for _ in range(M):
    a, b = map(int,input().split())
    c = list(map(int,input().split()))
    c = [cc-1 for cc in c]
    a_list.append(a)
    b_list.append(b)
    c_list.append(c)


takara_keys = {}
for i in range(N):
    takara = []
    for idx, c in enumerate(c_list):
        if i in c:
            takara.append(idx)
    takara_keys[i] = takara

clear = [1 for _ in range(N)]
def dp(memos, cost):
    if memos == clear:
        return cost
    costs = [10**9]
    for takara, memo in enumerate(memos):
        if memo == 0:
            next_keys = takara_keys[takara]
            for key in next_keys[0]:
                tmp_memos = memos[:]
                for takara_idx in c_list[key]:
                    tmp_memos[takara_idx] = 1
                tmp_cost = cost + a_list[key]
                costs.append(dp(tmp_memos,tmp_cost))
    return min(costs)

length_0_flag = False
for v in takara_keys.values():
    if len(v)==0:
        length_0_flag = True

if length_0_flag:
    print(-1)
else:
    print(dp([0 for _ in range(N)],0))

Fixed submission:
#解説放送見てからの書き直し
import sys
import os
INF = 10**12
ans = INF
N, M = map(int,input().split())
A = [0 for _ in range(M)]
B = [0 for _ in range(M)]
C = []
for i in range(M):
    a, b = map(int,input().split())
    A[i] = a  #鍵の金額
    B[i] = b  #開けられる宝箱の種類数
    tmp = list((map(int,input().split())))
    s = 0
    for j in range(b):
        t = tmp.pop(0)-1
        s |= 1 << t
    C.append(s)
    
dp = [INF]*(1<<N) #2^N
dp[0] = 0 #0 = 0b0000の時、スコアは0（まだ1つも鍵を購入してないので）

for s in range(1<<N): #1<<Nは2^N。つまりどの宝箱が開くかの全ての状態
    for j in range(M): # 全ての鍵について見ていく
        t = s | C[j] # 論理和。sには現在どの宝箱が開けられるかの状態、
                     # C[j]にはその新たな鍵が開ける宝箱。
                     # その論理和はこれまでの鍵と新たな鍵でどの宝箱が開けられるか
        cost = dp[s] + A[j] # その鍵を買った時のコスト
        dp[t] = min(dp[t],cost) #新たな宝箱の状態について、コストがより低くなるようなら保存する。
ans = dp[-1] #dp[-1]、つまり0b1111。宝箱が全て開けられる状態。
if ans == INF: #もし0b1111がINFのまま（最初から変わってない）ということはそこにたどり着けなかったということ。
               #つまり、全ての鍵を使っても宝箱を開けられなかった。
    ans = -1
print(ans)

Buggy python submission (verdict: Time Limit Exceeded):
N,M = map(int,input().split())
a_list = []
b_list = []
c_list = []
for _ in range(M):
    a, b = map(int,input().split())
    c = list(map(int,input().split()))
    c = [cc-1 for cc in c]
    a_list.append(a)
    b_list.append(b)
    c_list.append(c)


takara_keys = {}
for i in range(N):
    takara = []
    for idx, c in enumerate(c_list):
        if i in c:
            takara.append(idx)
    takara_keys[i] = takara

clear = [1 for _ in range(N)]
def dp(memos, cost):
    if memos == clear:
        return cost
    costs = [10**9]
    for takara, memo in enumerate(memos):
        if memo == 0:
            next_keys = takara_keys[takara]
            for key in next_keys:
                tmp_memos = memos[:]
                for takara_idx in c_list[key]:
                    tmp_memos[takara_idx] = 1
                tmp_cost = cost + a_list[key]
                costs.append(dp(tmp_memos,tmp_cost))
    return min(costs)

length_0_flag = False
for v in takara_keys.values():
    if len(v)==0:
        length_0_flag = True

if length_0_flag:
    print(-1)
else:
    print(dp([0 for _ in range(N)],0))

Fixed submission:
#解説放送見てからの書き直し
import sys
import os
INF = 10**12
ans = INF
N, M = map(int,input().split())
A = [0 for _ in range(M)]
B = [0 for _ in range(M)]
C = []
for i in range(M):
    a, b = map(int,input().split())
    A[i] = a  #鍵の金額
    B[i] = b  #開けられる宝箱の種類数
    tmp = list((map(int,input().split())))
    s = 0
    for j in range(b):
        t = tmp.pop(0)-1
        s |= 1 << t
    C.append(s)
    
dp = [INF]*(1<<N) #2^N
dp[0] = 0 #0 = 0b0000の時、スコアは0（まだ1つも鍵を購入してないので）

for s in range(1<<N): #1<<Nは2^N。つまりどの宝箱が開くかの全ての状態
    for j in range(M): # 全ての鍵について見ていく
        t = s | C[j] # 論理和。sには現在どの宝箱が開けられるかの状態、
                     # C[j]にはその新たな鍵が開ける宝箱。
                     # その論理和はこれまでの鍵と新たな鍵でどの宝箱が開けられるか
        cost = dp[s] + A[j] # その鍵を買った時のコスト
        dp[t] = min(dp[t],cost) #新たな宝箱の状態について、コストがより低くなるようなら保存する。
ans = dp[-1] #dp[-1]、つまり0b1111。宝箱が全て開けられる状態。
if ans == INF: #もし0b1111がINFのまま（最初から変わってない）ということはそこにたどり着けなかったということ。
               #つまり、全ての鍵を使っても宝箱を開けられなかった。
    ans = -1
print(ans)