Harryxun/sft_time huggingface dataset:
### BUGGY CODE ###

N = int(input())
S = input()

ans_list = []

for i in range(N):
    for j in range(i+1, N):
        for k in range(j+1, N):
            ans_list.append(S[i]+S[j]+S[k])
print(len(set(ans_list)))

### FIXED CODE ###

N = int(input())
S = list(input())
visited = {}

count = 0

for i, s in enumerate(S):
    if s in visited:
        continue
    visited[s] = []
    for j, s2 in enumerate(S[i+1:N-1]):
        # print(s, s2, S[i + j + 2:N])
        if s2 in visited[s]:
            continue
        count += len(set(S[i + j + 2:N]))
        visited[s].append(s2)
        # print(s, s2, set(S[j + 1:N]))
print(count)
### BUGGY CODE ###

R,G,B,N = map(int,input().split())

cnt = 0
for r in range(N//R+1):
    for g in range(N//G+1):
        b = (N - (R*r+G*g))//B
        b_judge = (N - (R*r+G*g))%B
        if b>= 0 and (b_judge == 0):
            cnt += 1

print(cnt)

### FIXED CODE ###

#19 B - RGB Boxes
R,G,B,N = map(int,input().split())
lis = sorted([R,G,B])
MA, MID, MI = lis[0],lis[1],lis[2]

cnt = 0
for ma in range(N//MA+1):
    for mid in range(N//MID+1):
        mi = (N - (MA*ma+MID*mid))//MI
        mi_judge = (N - (MA*ma+MID*mid))%MI
        if mi>= 0 and (mi_judge == 0):
            cnt += 1
print(cnt)
### BUGGY CODE ###

import re

S = input()
T = input()

def func(T,S,count=0):
    if count > len(T):
        return 'No'
    for i,j in zip(T,S):
        if i == j:
            pass
        else:
            new_str = ''
            for letter in T:
                if letter == i:
                    new_str += j
                elif letter == j:
                    new_str += i
                else:
                    new_str += letter
            return func(new_str,S,count+1)
    return 'Yes'

print(func(T,S))

### FIXED CODE ###

S = input()
T = input()

StoT = {}
TtoS = {}

for s,t in zip(S,T):
    if s in StoT.keys():
        if StoT[s] != t:
            print('No')
            exit()
    elif t in TtoS.keys():
        if TtoS[t] != s:
            print('No')
            exit()
    else:
        StoT[s] = t
        TtoS[t] = s
print('Yes')
### BUGGY CODE ###

n = int(input())

power = 1
for i in range(1,n+1):
    power = power * i

print(power%(7+10**9))


### FIXED CODE ###

n = int(input())

power = 1
for i in range(1,n+1):
    power = power * i
    power = power%(7+10**9)

print(power%(7+10**9))
### BUGGY CODE ###

import copy

N, M = [ int(x) for x in input().split()]

class Node:
    def __init__(self, id):
        self.id = id
        self.path = []
        self.passed = False
    def __str__(self):
        return "id: " + str(self.id) + " path: " + str(self.path) + " passed: " + str(self.passed)

nodes = []
for i in range(N):
    nodes.append(Node(i))

for i in range(M):
    from_id, to_id = [ int(x) - 1 for x in input().split()]
    nodes[from_id].path.append(to_id)
    nodes[to_id].path.append(from_id)

def if_all_passed(nodes_current):
    for node in nodes_current:
        if not node.passed:
            return False
    return True

def go_child(id_new, nodes_current):
    nodes_current[id_new].passed = True
    if if_all_passed(nodes_current):
        return 1

    count = 0
    for i in nodes[id_new].path:
        if not nodes_current[i].passed:
            count += go_child(i, copy.deepcopy(nodes_current))
    return count

count = go_child(0, nodes)
print(count)


### FIXED CODE ###

import copy

N, M = [ int(x) for x in input().split() ]

class Node:
    def __init__(self, id):
        self.id = id
        self.path = []
    def __str__(self):
        return "id: " + str(self.id) + " path: " + str(self.path)

nodes = []
for i in range(N):
    nodes.append(Node(i))

for i in range(M):
    from_id, to_id = [ int(x) - 1 for x in input().split() ]
    nodes[from_id].path.append(to_id)
    nodes[to_id].path.append(from_id)

def if_all_passed(passed_nodes):
    if len(passed_nodes) == N:
        return True
    else:
        return False

def go_child(id_new, passed_nodes):
    passed_nodes.append(id_new)
    if if_all_passed(passed_nodes):
        return 1

    count = 0
    for i in nodes[id_new].path:
        if not i in passed_nodes:
            count += go_child(i, copy.deepcopy(passed_nodes))
    return count

count = go_child(0, [])
print(count)
### BUGGY CODE ###

N = int(input())

student_list = input().rstrip().split(' ')

ans_list = []

for n in range(N):
  i = student_list.index(str(n+1))
  ans_list.append(str(i+1))
  
print(' '.join(ans_list))


### FIXED CODE ###

N = int(input())
A = list(map(int, input().split()))
ans = [0] * N
for i, a in enumerate(A):
    ans[a-1] = i+1

print(*ans)
### BUGGY CODE ###

s = input()
K = int(input())

l = len(s)

seq = set()
for i in range(l):
    for j in range(i + 1, l + 1):
        seq.add(s[i:j])

seq = list(seq)
seq.sort()

print(seq[K - 1])


### FIXED CODE ###

s = input()
K = int(input())

seq = set()
l = len(s)
for i in range(l):
    for j in range(1, K + 1):
        seq.add(s[i:i + j])

seq = list(seq)
seq.sort()
print(seq[K - 1])
### BUGGY CODE ###

from collections import deque
H, W = map(int, input().split())
s_list = []
for _ in range(H):
    s = input()
    s_list.append(s)
ans = 0
for h in range(H):
    for w in range(W):
        if s_list[h][w] == '.':
            d = deque()
            d.append([h, w])
            visited = set({})
            while d:
                i, j = d.pop()
                visited.add(str(i) + '_' + str(j))
                for ii, jj in [[1, 0], [-1, 0], [0, 1], [0, -1]]:
                    if (0 <= (i + ii) < H) & (0 <= (j + jj) < W):
                        if str(i + ii) + '_' + str(j + jj) not in visited:
                            if s_list[i][j] != s_list[i + ii][j + jj]:
                                d.append([i + ii, j + jj])
                                if s_list[i + ii][j + jj] == '#':                                    
                                    ans += 1
                            visited.add(str(i + ii) + '_' + str(j + jj))
print(ans)

### FIXED CODE ###

from collections import deque
H, W = map(int, input().split())
s_list = []
for _ in range(H):
    s = input()
    s_list.append(s)
ans = 0
visited = set({})
for h in range(H):
    for w in range(W):
        if s_list[h][w] == '.':
            if str(h) + '_' + str(w) not in visited:
                d = deque()
                d.append([h, w])
                plus = 1
                minus = 0
                while d:
                    i, j = d.pop()
                    visited.add(str(i) + '_' + str(j))
                    for ii, jj in [[1, 0], [-1, 0], [0, 1], [0, -1]]:
                        if (0 <= (i + ii) < H) & (0 <= (j + jj) < W):
                            if str(i + ii) + '_' + str(j + jj) not in visited:
                                if s_list[i][j] != s_list[i + ii][j + jj]:
                                    d.append([i + ii, j + jj])
                                    visited.add(str(i + ii) + '_' + str(j + jj))
                                    if s_list[i + ii][j + jj] == '.':
                                        plus += 1
                                    else:
                                        minus += 1                                
                ans += plus * minus
print(ans)
### BUGGY CODE ###

H,W=map(int,input().split())
A=[[None]*(W+2)]
A.extend([[i=="." for i in "#"+input()+"#"] for _ in range(H)])
A.append([None]*(W+2))

q=[[(i,j) for i in range(1,H+1) for j in range(1,W+1) if not A[i][j]]]

for k in range(2000):
    q.append([])
    for i,j in q[k]:
        if A[i-1][j]:
            A[i-1][j]=None
            q[k+1].append((i-1,j))
        if A[i+1][j]:
            A[i+1][j]=None
            q[k+1].append([i+1,j])
        if A[i][j-1]:
            A[i][j-1]=None
            q[k+1].append([i,j-1])
        if A[i][j+1]:
            A[i][j+1]=None
            q[k+1].append([i,j+1])
    if q[k+1]==[]:
        break
print(k)

### FIXED CODE ###

H,W = list(map(int,input().split()))
A = [list(str(input())) for i in range(H)]
 
black = []
 
cnt = 0
 
for i in range(H):
    for j in range(W):
        if A[i][j] == "#":
            black.append([i,j])
 
length = len(black)
            
while (length < H*W):
    gray = []
    for l in black:
        if l[1] != 0:
            c1 = (l[0],l[1]-1)
            if A[c1[0]][c1[1]] == ".":
                gray.append(c1)
                A[c1[0]][c1[1]] = "#"
        if l[1] != W-1:
            c2 = (l[0],l[1]+1)
            if  A[c2[0]][c2[1]] == ".":
                gray.append(c2)
                A[c2[0]][c2[1]] = "#"
        if l[0] != 0:
            c3 = (l[0]-1,l[1])
            if  A[c3[0]][c3[1]] == ".":
                gray.append(c3)
                A[c3[0]][c3[1]] = "#"
        if l[0] != H-1:
            c4 = (l[0]+1,l[1])
            if  A[c4[0]][c4[1]] == ".":
                gray.append(c4)
                A[c4[0]][c4[1]] = "#"
    
    gray = list(set(gray))
    black = [l for l in gray]
    
    cnt += 1
    length += len(black)
    
print(cnt)
### BUGGY CODE ###

n, k = map(int, input().split())
p = [0] + list(map(int, input().split()))
c = [0] + list(map(int, input().split()))

ans = - 10 ** 18
for i in range(1, n+1):
    base = i
    nxt = p[i]
    cnt = 0
    score = 0
    while True:
        cnt += 1
        if cnt > k:
            break
        score += c[nxt]
        ans = max(ans, score)
        #print("i = ", i, "ans = ", ans, "score = ", score)
        if nxt == base:
            break
        nxt = p[nxt]
    if cnt >= k:
        continue
    extra = k - cnt
    score_tmp = score
    nxt_tmp = nxt
    nxt = p[nxt]
    for j in range(extra):
        score += c[nxt]
        ans = max(ans, score)
        #print("ans = ", ans, "score = ", score, "nxt = ", nxt, "c[nxt] = ", c[nxt])
        nxt = p[nxt]
    score = score_tmp
    nxt = nxt_tmp
    a = extra // cnt
    score += score * a
    ans = max(ans, score)
    for j in range(extra - a * cnt):
        score += c[nxt]
        ans = max(ans, score)
        nxt = p[nxt]

print(ans)

### FIXED CODE ###

n, k = map(int, input().split())
p = [0] + list(map(int, input().split()))
c = [0] + list(map(int, input().split()))

ans = - 10 ** 18
for i in range(1, n+1):
    base = i
    nxt = p[i]
    cnt = 0
    score = 0
    while True:
        cnt += 1
        if cnt > k:
            break
        score += c[nxt]
        ans = max(ans, score)
        #print("i = ", i, "ans = ", ans, "score = ", score)
        if nxt == base:
            break
        nxt = p[nxt]
    if cnt >= k:
        continue
    extra = k - cnt
    score_tmp = score
    nxt = p[nxt]
    nxt_tmp = nxt
    for j in range(min(extra, cnt)):
        score += c[nxt]
        ans = max(ans, score)
        #print("ans = ", ans, "score = ", score, "nxt = ", nxt, "c[nxt] = ", c[nxt])
        nxt = p[nxt]
    #print("score = ", score, "ans = ", ans)
    score = score_tmp
    nxt = nxt_tmp
    a = extra // cnt
    if extra % cnt == 0:
        a -= 1
    score += score * max(a, 0)
    ans = max(ans, score)
    for j in range(extra - a * cnt):
        score += c[nxt]
        ans = max(ans, score)
        #print("ans = ", ans, "score = ", score, "nxt = ", nxt, "c[nxt] = ", c[nxt])
        nxt = p[nxt]

print(ans)
### BUGGY CODE ###

N = int(input())
*A, = map(int, input().split())

if not(N % 2):
	for i in range(1, N, 2):
		if A.count(i) != 2:
			print(0)
			exit()
else:
	if A.count(0) != 1:
		print(0)
		exit()
	for i in range(2, N, 2):
		if A.count(i) != 2:
			print(0)
			exit()

mod = 10**9+7
print(2**(N//2) % mod)


### FIXED CODE ###

N = int(input())
*A, = map(int, input().split())

count = dict()
if N % 2:
	for a in A:
		if a % 2:
			print(0)
			exit()
		if a in count:
			count[a] += 1
		else:
			count[a] = 1
	if count[0] != 1:
		print(0)
		exit()
	del count[0]
	for c in count.values():
		if c != 2:
			print(0)
			exit()
else:
	for a in A:
		if not(a % 2):
			print(0)
			exit()
		if a in count:
			count[a] += 1
		else:
			count[a] = 1
	for c in count.values():
		if c != 2:
			print(0)
			exit()

mod = 10**9+7
print(2**(N//2) % mod)
### BUGGY CODE ###

S = input()
Q = int(input())
N = len(S)

rev = list(reversed(S))
S_rev = ''.join(rev)

for i in range(Q):
	q = list(map(str, input().split()))
	if q[0] == '1':
		S, S_rev = S_rev, S
	else:
		if q[1] == '1':
			s = [q[2], S]
			s_rev = [S_rev, q[2]]
			S = ''.join(s)
			S_rev = ''.join(s_rev)
		else:
			s = [S, q[2]]
			s_rev = [q[2], S_rev]
			S = ''.join(s)
			S_rev = ''.join(s_rev)

print(S)

### FIXED CODE ###

from collections import deque

S = deque(input())
Q = int(input())
N = len(S)

flag = 0
for i in range(Q):
	q = list(map(str, input().split()))
	if q[0] == '1':
		flag = 1 - flag
	else:
		if (q[1] == '1' and flag == 1) or (q[1] == '2' and flag == 0):
			S.append(q[2])
		else:
			S.appendleft(q[2])
if flag == 1:
	S.reverse()
ans = ''.join(S)
print(ans)
### BUGGY CODE ###

L, R = map(int, input().split())
mi = 2019
for i in range(L,R+1):
    for j in range(i+1,R+1):
        mi = min(mi,(i*j)%2019)
    if mi == 0:
        break
print(mi)

### FIXED CODE ###

L, R = map(int, input().split())
target = R+1
if R - L > 10000:
    target = L + 10000
mi = 2019
for i in range(L,target):
    for j in range(i+1,target):
        mi = min(mi,(i*j)%2019)
print(mi)
### BUGGY CODE ###

def slove():
    import sys
    input = sys.stdin.readline
    n = int(input().rstrip('\n'))
    a = [list(map(int, input().rstrip('\n').split())) for _ in range(n)]
    ls = [0] * n
    mt = [0] * n
    cnt = 0
    for w in range(10 ** 15):
        cnt += 1
        f = [False] * n
        for i in range(n):
            if ls[i] != -1:
                mt[i] = a[i][ls[i]]
        for i in range(n):
            if not f[i]:
                if ls[i] != -1:
                    if i + 1 == mt[mt[i]-1]:
                        f[i] = True
                        f[mt[i]-1] = True
        bb = False
        for i in range(n):
            if f[i]:
                if ls[i] + 1 < n - 1:
                    ls[i] += 1
                    bb = True
                else:
                    ls[i] = -1
        b = True
        for i in range(n):
            if ls[i] != -1:
                b = False
                break
        if b:
            print(cnt)
            exit()
        if not bb:
            print(-1)
            exit()


if __name__ == '__main__':
    slove()


### FIXED CODE ###

def slove():
    import sys
    import collections
    input = sys.stdin.readline
    n = int(input().rstrip('\n'))
    a = [list(map(int, input().rstrip('\n').split())) for _ in range(n)]
    ad = [0] * n
    dq = collections.deque([[0, i + 1] for i in range(n)])
    for i in range(10 ** 15):
        fd = {}
        while True:
            if len(dq) != 0:
                d, q = dq.popleft()
                q -= 1
                if d <= i:
                    if ad[q] < n - 1:
                        qq = a[q][ad[q]] - 1
                        tq = a[qq][ad[qq]] - 1
                        if q == tq and qq not in fd and tq not in fd:
                            ad[qq] += 1
                            ad[tq] += 1
                            if ad[qq] < n - 1:
                                dq.append([d + 1, qq + 1])
                            if ad[tq] < n - 1:
                                dq.append([d + 1, tq + 1])
                            fd[qq] = 0
                            fd[tq] = 0
                else:
                    dq.append([d, q + 1])
                    break
            else:
                break
        if len(dq) == 0:
            b = True
            for v in ad:
                if v != n - 1:
                    b = False
                    break
            if b:
                print(i + 1)
                exit()
            else:
                print(-1)
                exit()


if __name__ == '__main__':
    slove()
### BUGGY CODE ###

from sys import stdin
import bisect
from collections import deque

N, K = [int(x) for x in stdin.readline().rstrip().split()]
P = [int(x) for x in stdin.readline().rstrip().split()]

ans = 0
Q = [-x for x in P[:K]]
Q.sort()
D = deque([x for x in P[:K]])
oc = 0
ordered_twice = False

for i in range(len(D) - 1):
    if D[i] <= D[i + 1]:
        oc += 1

for i in range(N - K + 1):
    if i == 0:
        ans += 1
        if oc == K - 1:
            ordered_twice = True
    else:
        D.popleft()
        D.append(P[i + K - 1])
        if P[i - 1] <= D[0]:
            oc -= 1
        if D[K - 2] <= D[K - 1]:
            oc += 1
        if oc == K - 1:
            if not ordered_twice:
                ordered_twice = True
                if -P[i - 1] != Q[-1] or Q[0] < -P[i + K - 1]:
                    ans += 1
            if -P[i - 1] == Q[-1]:
                Q.pop()
            bisect.insort_left(Q, -P[i + K - 1])
        else:
            if -P[i - 1] != Q[-1] or Q[0] < -P[i + K - 1]:
                ans += 1
            if -P[i - 1] == Q[-1]:
                Q.pop()
            bisect.insort_left(Q, -P[i + K - 1])

print(ans)

### FIXED CODE ###

from sys import stdin
from collections import deque

N, K = [int(x) for x in stdin.readline().rstrip().split()]
P = [int(x) for x in stdin.readline().rstrip().split()]

ans = N - K + 1

D = deque([x for x in P[:K]])
oc = 0
ordered_twice = False

for i in range(len(D) - 1):
    if D[i] <= D[i + 1]:
        oc += 1

Q = deque([])
Q_min = []
Q_max = []

for i in range(N):
    while len(Q) > 0 and P[Q[len(Q) - 1]] >= P[i]:
        Q.pop()
    Q.append(i)
    if Q[len(Q) - 1] >= K - 1:
        Q_min.append(P[Q[0]])
        if Q[0] == i + 1 - K:
            Q.popleft()

PP = [-x for x in P]
Q = deque([])

for i in range(N):
    while len(Q) > 0 and PP[Q[len(Q) - 1]] >= PP[i]:
        Q.pop()
    Q.append(i)
    if Q[len(Q) - 1] >= K - 1:
        Q_max.append(-PP[Q[0]])
        if Q[0] == i + 1 - K:
            Q.popleft()

for i in range(N - K + 1):
    if i > 0:
        D.popleft()
        D.append(P[i + K - 1])
        if P[i - 1] <= D[0]:
            oc -= 1
        if D[K - 2] <= D[K - 1]:
            oc += 1

        if (Q_min[i - 1] == P[i - 1] and Q_max[i] == D[-1]) or (oc == K - 1 and ordered_twice):
            ans -= 1

    if oc == K - 1:
        ordered_twice = True

print(ans)
### BUGGY CODE ###

N=int(input())
s=False
for i in range(1,3501):
    for j in range(1,3501):
        if (4*i*j-N*i-N*j)==0:
            continue
        else:
            w=(N*i*j)/(4*i*j-N*i-N*j)
            if w%1==0 and w>0:
                p=i
                q=j
                s=True
                break
            else:
                continue
    if s==True:
        break

print("{} {} {}".format(p,q,int(w)))


### FIXED CODE ###

N=int(input())
s=False
for i in range(1,3501):
    for j in range(1,3501):
        if (4*i*j-N*i-N*j)>0:
            w=(N*i*j)/(4*i*j-N*i-N*j)
            if w%1==0:
                p=i
                q=j
                s=True
                break
    if s==True:
        break

print("{} {} {}".format(p,q,int(w)))
### BUGGY CODE ###

N, K = map(int, input().split())

if N == K:
    print(0)

elif N<K and N<=K-N:
    print(N)

elif N<K and N>K-N:
    print(K-N)

elif N>K*(10**8):
    k = K*(10**8)
    for i in range(9):
        while N>k:
            k=k+K*(10**(8-i))
        k = k-K*(10**(8-i))
    k = k+K
    if k-N<N-k/K:
        print(k-N)
    else:
        print(N-k/K)


elif N>K:
    k = K
    while N>k:
        k=k+K
    if k-N<N-k/K:
        print(k-N)
    else:
        print(N-k/K)


### FIXED CODE ###

N, K = map(int, input().split())

if N%K == 0:
    print(0)

elif N<K and N<=K-N:
    print(N)

elif N<K and N>K-N:
    print(K-N)

elif N>K:
    if K-(N%K)>N%K:
        print(N%K)
    else:
        print(K-(N%K))
### BUGGY CODE ###

import sys
sys.setrecursionlimit(1000000)

n,q=map(int,input().split())
G=[[] for i in range(n)] #隣接配列
P=[0]*n #根のポイント
A=[0]*n #こたえ
for i in range(n-1):
    a,b=map(int,input().split())
    a-=1
    b-=1
    G[a].append(b)
    G[b].append(a)
for i in range(q):
    p,x=map(int,input().split())
    p-=1
    P[p]+=x
    

def dfs(s,p=-1,cnt=0):
    cnt+=P[s]
    A[s]=cnt
    for i in G[s]:
        if i!=p:
            dfs(i,s,cnt)

dfs(0)
for a in A:
    print(a,end=" ")

### FIXED CODE ###

import sys
input=sys.stdin.readline
sys.setrecursionlimit(1000000)
from collections import deque

def main():
    n,q=map(int,input().split())
    G=[[] for i in range(n)] #隣接配列
    P=[0]*n #親のポイント
    for i in range(n-1):
        a,b=map(int,input().split())
        a-=1
        b-=1
        G[a].append(b)
        G[b].append(a)
    for i in range(q):
        p,x=map(int,input().split())
        p-=1
        P[p]+=x
    
    Chk=[0]*n #訪問済みチェック
    q=deque([0])
    while q: #qが空になるまで(BFS:幅優先探索)
        now=q.popleft() #取り出す
        Chk[now]=1 #訪問済みにする
        for i in G[now]: #子に対し
            if Chk[i]==0: #未訪問のとき
                P[i]+=P[now] #ポイント加算
                q.append(i) #親としてqに入れる

    print(*P)

if __name__ == '__main__':
    main()
### BUGGY CODE ###

a=int(input())
l=list(map(int,input().split()))
b=int(input())
grand=0
for i in range(b):
  sum=0
  l1=list(map(int,input().split()))
  for i in range(len(l)):
    if l[i] ==l1[0]:
      l[i]=l1[1]
    sum+=l[i]
  print(sum)

### FIXED CODE ###

from collections import Counter
a=int(input())
l=list(map(int,input().split()))
b=int(input())
s=Counter(l)
initial_sum=sum(l)

for _ in range(b):
  x,y=map(int,input().split())
  k=s[x]
  s[x]=0
  s[y]+=k
  initial_sum+=(y-x)*k
  print(initial_sum)
### BUGGY CODE ###

#!/usr/bin/env python3
import sys
sys.setrecursionlimit(10**8)
INF = float("inf")


def yes():
    print("YES")  # type: str


def no():
    print("NO")  # type: str


class UnionFind(object):

    def __init__(self, N):
        self.tree = list(range(N))

    def root(self, i):
        if self.tree[i] == i:
            return i
        else:
            self.tree[i] = self.root(self.tree[i])
            return self.tree[i]

    def same(self, x, y):
        return self.root(x) == self.root(y)

    def unite(self, x, y):
        x = self.root(x)
        y = self.root(y)
        if x != y:
            self.tree[x] = y


def main():

    N, M = map(int, input().split())
    L = [0]*N
    for i in range(N):
        K, *L[i] = list(map(int, input().split()))
    # 前Nは人、後ろMは言語
    uf = UnionFind(N+M)

    for i in range(N):
        for l in L[i]:
            # 人iは言語L[i]と同じグループ
            uf.unite(i, N+l-1)

    # print(uf.tree)
    # 人はすべて同じグループであるか
    flag = True
    for i in range(N):
        if not uf.same(0, i):
            flag = False
            break
    if flag:
        yes()
    else:
        no()

    pass


if __name__ == '__main__':
    main()


### FIXED CODE ###

#!/usr/bin/env python3
import sys
sys.setrecursionlimit(10**8)
from collections import defaultdict
INF = float("inf")


def yes():
    print("YES")  # type: str


def no():
    print("NO")  # type: str


class UnionFind(object):

    def __init__(self, N):
        self.tree = list(range(N))

    def root(self, i):
        if self.tree[i] == i:
            return i
        else:
            self.tree[i] = self.root(self.tree[i])
            return self.tree[i]

    def same(self, x, y):
        return self.root(x) == self.root(y)

    def unite(self, x, y):
        x = self.root(x)
        y = self.root(y)
        if x != y:
            self.tree[x] = y


def main():

    N, M = map(int, input().split())
    L = [0]*N
    lang_leader = defaultdict(int)
    for i in range(N):
        K, *L[i] = list(map(int, input().split()))
    # 前Nは人
    uf = UnionFind(N+1)
    for i in range(N):
        for l in L[i]:
            if lang_leader[l] == 0:
                lang_leader[l] = i+1
            else:
                uf.unite(i, lang_leader[l]-1)

    # print(uf.tree)
    # 人はすべて同じグループであるか
    flag = True
    for i in range(N):
        if not uf.same(0, i):
            flag = False
            break
    if flag:
        yes()
    else:
        no()

    pass


if __name__ == '__main__':
    main()