CodeEff/ECCO huggingface dataset:
# Original solution
n, m=list(map(int, input().split()))
grid = []
for i in range(m):
    array = list(map(int, input().strip().split()))
    grid.append(array)


maxa,mina=grid[0]
for i in range(1,m):
    if maxa<grid[i][0]:
        maxa=grid[i][0]
    if mina>grid[i][1]:
        mina=grid[i][1]

v=mina-maxa+1
if v>0:
    print(v)
else:
    print((0))

# Optimized solution
n,m = list(map(int, input().split()))
LR = [list(map(int, input().split())) for _ in range(m)]
L = max([i[0] for i in LR])
R = min([i[1] for i in LR])
print((max(R-L+1,0)))
# Original solution
n,m = list(map(int,input().split()))

kyotu_s = {k for k in range(1,n+1)}

for i in range(m):
    l,r = list(map(int,input().split()))
    s = {j for j in range(l,r+1)}
    kyotu_s = s & kyotu_s
    if len(kyotu_s)==0:
        break

print((len(kyotu_s)))

# Optimized solution
n,m = list(map(int,input().split()))

min_i = 1
max_i = n

for i in range(m):
    l,r = list(map(int,input().split()))
    min_i = max(min_i,l)
    max_i = min(max_i,r)

if max_i-min_i>=0:
    print((max_i-min_i+1))
else:
    print((0))
# Original solution
l, m = list(map(int, input().split()))
lr = [list(map(int, input().split())) for _ in range(m)]

ll, rr = 1, l
for l, r in lr:
    if ll <= l <= rr or l <= ll <= r:
        ll, rr = max(ll, l), min(rr, r)
    else:
        print((0))
        exit()
print((rr-ll+1))

# Optimized solution
n, m = list(map(int, input().split()))
lr = [list(map(int, input().split())) for _ in range(m)]

INF = float('inf')
ans_l, ans_r = -INF, INF
for l, r in lr:
    ans_l = max(ans_l, l)
    ans_r = min(ans_r, r)
print((max(0, ans_r-ans_l+1)))
# Original solution
n,m = list(map(int,input().split()))
lst_l = []
lst_r = []
for _ in range(m):
    l,r = list(map(int,input().split()))
    lst_l.append(l)
    lst_r.append(r)

count = 0
for i in range(n):
    if max(lst_l) <= i+1 <= min(lst_r):
        count += 1

print(count)

# Optimized solution
n,m = list(map(int,input().split()))
lst_l = []
lst_r = []
for _ in range(m):
    l,r = list(map(int,input().split()))
    lst_l.append(l)
    lst_r.append(r)

max_l = max(lst_l)
min_r = min(lst_r)

count = 0
for i in range(n):
    if max_l <= i+1 <= min_r:
        count += 1

print(count)
# Original solution
n,m=list(map(int,input().split()))
gate=[]
l,r=list(map(int,input().split()))
for i in range(l,r+1):
    gate.append(i)
for i in range(m-1):
    l,r=list(map(int,input().split()))
    g=[]
    for i in gate:
        if l<=i<=r:
            g.append(i)
    gate=g

print((len(gate)))

# Optimized solution
n,m=list(map(int,input().split()))
card=[]
L=1
R=n
for i in range(m):
    card.append([int(i) for i in input().split()])
for j in card:
    if j[0]<=R:
        if L<=j[0]:
            L=j[0]
            
    else:
        print((0))
        quit()
    if L<=j[1]:
        if j[1]<=R:
            R=j[1]
            
    else:
        print((0))
        quit()
print((R-L+1))
# Original solution
from collections import Counter

n, m = list(map(int, input().split()))
A = []
for i in range(m):
    l, r = list(map(int, input().split()))
    A.extend(list(range(l, r + 1)))
    
cnt = 0
for v in list(Counter(A).values()):
    if v == m:
        cnt += 1
        
print(cnt)

# Optimized solution
n, m = list(map(int, input().split()))

left = 0
right = float('inf')
for i in range(m):
    l, r = list(map(int, input().split()))
    left = max(left, l)
    right = min(right, r)
    
print((max(0, right - left + 1)))
# Original solution
# -*- coding: utf-8 -*-
n, m = list(map(int,input().split()))
lr = []
for i in range(m):
    lr.append([int(i) for i in input().split()])

if m == 1:
    print((lr[0][1] - lr[0][0] + 1))
    exit()

tmp1 = 0
tmp2 = pow(10, 6)
for i in range(m - 1):
    tmp1 = max(lr[i][0], lr[i + 1][0], tmp1)
    tmp2 = min(lr[i][1], lr[i + 1][1], tmp2)
#print(tmp1, tmp2)
ans = max(tmp2 - tmp1 + 1, 0)
print(ans)


# Optimized solution
n, m = list(map(int,input().split()))
lr = []
for i in range(m):
    lr.append([int(i) for i in input().split()])

tmp1 = 0
tmp2 = pow(10, 6)
for i in range(m):
    tmp1 = max(lr[i][0], tmp1)
    tmp2 = min(lr[i][1], tmp2)
print((max(0, tmp2 - tmp1 + 1)))
# Original solution
N,M=list(map(int,input().split()))
LR=[]
for i in range(M):
  LR.append(list(map(int,input().split())))
ans=[i+1 for i in range(N)]
for i in range(M):
  for j in range(LR[i][0]):
    if j in ans:
      ans.remove(j)
  for k in range(LR[i][1]+1,N+1):
    if k in ans:
      ans.remove(k)
print((len(ans)))

# Optimized solution
N,M=list(map(int,input().split()))
LR=[]
for i in range(M):
  LR.append(list(map(int,input().split())))
l,r=LR[0][0],LR[0][1]
for i in range(M):
  if LR[i][1]<=r:
    r=LR[i][1]
  if l<=LR[i][0]:
    l=LR[i][0]
ans=r-l+1
if ans>0:
  print(ans)
else:
  print((0))
# Original solution
N, M = list(map(int, input().split()))

l, r = list(map(int, input().split()))
lis = [i for i in range(l, r+1)]

for i in range(M-1):
    l, r = list(map(int, input().split()))
    tmp_lis = [i for i in range(l, r+1)]
    lis = set(lis) & set(tmp_lis)

lis = [i for i in lis if i <= N]
print((len(lis)))


# Optimized solution
N, M = list(map(int, input().split()))

min, max = list(map(int, input().split()))

for i in range(M-1):
    l, r = list(map(int, input().split()))
    if min < l:
        min = l
    if max > r:
        max = r



lis = [i for i in range(min, max+1)]
print((len(lis)))
# Original solution
#ABC-127-C
N, M = list(map(int, input().split()))
LR  = []
for _ in range(M):
    Li, Ri = list(map(int, input().split()))
    LR.append((Li, Ri))

possible_card_list = [i for i in range(LR[0][0], LR[0][1]+1)]

for Li, Ri in LR:
    for possible_card in possible_card_list[:]:
        if Li <= possible_card and possible_card <= Ri:
            #OK
            pass
        else:
            possible_card_list.remove(possible_card)
            
print((len(possible_card_list)))
        

# Optimized solution
#ABC-127-C
N, M = list(map(int, input().split()))
L_list  = []
R_list = []
for _ in range(M):
    Li, Ri = list(map(int, input().split()))
    L_list.append(Li)
    R_list.append(Ri)

max_L = max(L_list)
min_R = min(R_list)

if max_L > min_R:
    print((0))
else:
    print((min_R-max_L+1))
# Original solution
n,m = list(map(int,input().split()))
l = []
r = []

while True:
  try:
    tl,tr = list(map(int,input().split()))
    l.append(tl)
    r.append(tr)
  except:
    break

l = sorted(l)
r = sorted(r)
cnt = 0
for i in range(1,n+1):
  if i>=max(l) and i<=min(r):
    cnt +=1
    
print(cnt)
    

# Optimized solution
n,m = list(map(int,input().split()))
l = []
r = []

while True:
  try:
    tl,tr = list(map(int,input().split()))
    l.append(tl)
    r.append(tr)
  except:
    break

R = min(r)
L = max(l)
cnt = 0
for i in range(1,n+1):
  if i>=L and i<=R:
    cnt +=1
    
print(cnt)
# Original solution
N, M = list(map(int, input().split()))
A = [list(map(int, input().split())) for i in range(M)]
B = {x for x in range(A[0][0], A[0][1]+1)}
for i in range(1,M):
  C = {x for x in range(A[i][0],A[i][1]+1)}
  B = B & C
ans = len(B)
print(ans)
  
  


# Optimized solution
N, M = list(map(int, input().split()))
A = [0]*M
B = [0]*M
for i in range(M):
  A[i], B[i] = list(map(int, input().split()))
a = max(A)
b = min(B)
if a <= b:
  print((b+1-a))
else:
  print((0))
# Original solution
def resolve():
    N,M=list(map(int,input().split()))
    l, r = list(map(int, input().split()))
    s = {i for i in range(l, r + 1)}
    for i in range(1,M):
        l,r=list(map(int,input().split()))
        s=s&{i for i in range(l,r+1)}

    print((len(s)))


resolve()

# Optimized solution
# input = sys.stdin.readline

def resolve():
    N,M=list(map(int,input().split()))
    l, r = list(map(int, input().split()))
    for i in range(1,M):
        ll,rr=list(map(int,input().split()))
        l=max(l,ll)
        r=min(r,rr)

    print((r-l+1 if r-l+1>=0 else 0))


resolve()
# Original solution
N,M = list(map(int,input().split()))
 
LR = [[] for i in range(M)]
 
for i in range(M):
	L,R = list(map(int, input().split()))
	for j in range(L,R + 1):
		LR[i].append(j)
	LR[i] = set(LR[i])
 
for i in range(M):
	LR[i] = LR[i] & LR[i-1]
    
 
print((len(LR[M-1])))

# Optimized solution
N,M = list(map(int,input().split()))
 
LR = [set([]) for i in range(M)]
 
for i in range(M):
	L,R = list(map(int, input().split()))
	for j in range(L,R + 1):
		LR[i].add(j)

for i in range(M):
	LR[i] = LR[i] & LR[i-1]
    
 
print((len(LR[M-1])))
# Original solution
N,M = list(map(int,input().split()))
 
LR = [set([]) for i in range(M)]
 
for i in range(M):
	L,R = list(map(int, input().split()))
	for j in range(L,R + 1):
		LR[i].add(j)

for i in range(M):
	LR[i] = LR[i] & LR[i-1]
    
 
print((len(LR[M-1])))

# Optimized solution
N,M = list(map(int,input().split()))

inf = []
sup = []

for i in range(0,M):
	L,R = list(map(int,input().split()))
	inf.append(L)
	sup.append(R)
	
inf = max(inf)
sup = min(sup)

ran = sup - inf

if ran >= 0:
	print((ran + 1))
else:print((0))
# Original solution
N, M = list(map(int, input().split()))

id_list = [0] * N

for _ in range(M):
    L, R = list(map(int, input().split()))
    for i in range(L, R + 1):
        id_list[i - 1] += 1

print((sorted(id_list, reverse=True).count(M)))


# Optimized solution
N, M = list(map(int, input().split()))

L, R = 1, N
for _ in range(M):
    Li, Ri = list(map(int, input().split()))
    if L <= Li:
        L = Li
    if Ri <= R:
        R = Ri

print((R - L + 1 if (R >= L) else 0))
# Original solution
N,M=list(map(int,input().split()))
passable=set(range(1,N+1))
for m in range(M):
    L,R=list(map(int,input().split()))
    passable=passable&set(range(L,R+1))
print((len(passable)))

# Optimized solution
N,M=list(map(int,input().split()))
L=[]
R=[]
for m in range(M):
    Lm,Rm=list(map(int,input().split()))
    L.append(Lm)
    R.append(Rm)
maxL=max(L)
minR=min(R)
print((max(minR-maxL+1,0)))
# Original solution
def island(f,x,y,m):
    rf = f[:][:]
    rf[y][x] = m
    for i in [-1,1]:
        if 0 <= x+i <= 11 and rf[y][x+i] == 1:
            rf = island(rf,x+i,y,m)
        if 0 <= y+i <= 11 and rf[y+i][x] == 1:
            rf = island(rf,x,y+i,m)
    return rf

while True:
    f = []; m = 2
    for i in range(12):
        f.append(list(map(int, list(input()))))
    for y in range(12):
        for x in range(12):
            if f[y][x] == 1:
                f = island(f,x,y,m)
                m += 1
    ans = []
    for i in range(12):
        for j in range(12):
            ans.append(f[i][j])
    ans = list(set(ans))
    print(len(ans) - 1*ans.count(0))
    try:input()
    except: break

# Optimized solution
W,H = 12,12
dxy = [[1,0],[0,1],[-1,0],[0,-1]]
def solve(field,w,h):
	if 0 <= w < W and 0 <= h < H and field[h][w] == "1":
		field[h][w] = "0"
		for dx,dy in dxy:
			solve(field,w+dx,h+dy)

while 1:
	try:
		field = [list(input()) for i in range(H)]
		ans = 0
		for h in range(H):
			for w in range(W):
				if field[h][w] == "1":
					solve(field,w,h)
					ans += 1
		print(ans)
		input()
	except:
		break
# Original solution
import sys
A=list(range(12))
m=[[0 for i in A] for j in A]
def f(y,x,d):
    P=[]
    x+=d[0]
    y+=d[1]
    if 0<=x<12 and 0<=y<12 and m[y][x]==1:
        m[y][x]=c
        P=[[y,x]]
    return P
def v1(buf):
    global c
    while buf!=[]:
        y,x=buf.pop()
        m[y][x]=c
        for e in [(-1,0),(1,0),(0,-1),(0,1)]:buf+=f(y,x,e)
    c+=1
    return
def solve():
    global c
    c=2
    for i in A:
        while m[i].count(1)>0:v1([[i,m[i].index(1)]])
    print(c-2)
    return 0
y=0
for s in sys.stdin:
    if y<12:
        m[y]=list(map(int,list(s[:-1])))
        y+=1
    else:y=solve()
solve()

# Optimized solution
import sys
A=list(range(14))
m=[[0 for i in A] for j in A]
def f(y,x):
    if m[y][x]==1:
        m[y][x]=0
        f(y,x+1)
        f(y,x-1)
        f(y+1,x)
        f(y-1,x)
    return
def solve():
    c=2
    for i in A:
        while m[i].count(1)>0:
            f(i,m[i].index(1))
            c+=1
    print(c-2)
    return 0
y=0
for s in sys.stdin:
    if y<12:
        m[y+1]=[0]+list(map(int,list(s[:-1])))+[0]
        y+=1
    else:y=solve()
solve()
# Original solution
import sys
sys.setrecursionlimit(10**9)
input = sys.stdin.readline

N,M = list(map(int,input().split()))
L = []
for i in range(N):
  tmp = list(map(int,input().split()))
  L.append(tmp[1:])

dicL = {}
for i in range(N):
  for l in L[i]:
    if l not in dicL:
      dicL[l] = [i]
    else:
      dicL[l].append(i)
#print(dicL)
E = [[] for _ in range(N)]
for k,v in list(dicL.items()):
  if len(v) > 1:
    for i in range(len(v)-1):
      for j in range(i+1,len(v)):
        E[v[i]].append(v[j])
        E[v[j]].append(v[i])
#for i in range(N):
#  E[i] = set(E[i])
#print(E)
Visited = [0 for _ in range(N)]
def dfs(v):
  Visited[v] = 1
  for u in E[v]:
    if Visited[u] == 0:
      dfs(u)
dfs(0)
print(('YES' if sum(Visited) == N else 'NO'))
    

# Optimized solution
import sys
input = sys.stdin.readline
sys.setrecursionlimit(10 ** 9)

N,M = list(map(int,input().split()))
L = []
for i in range(N):
  tmp = list(map(int,input().split()))
  L.append(tmp[1:])
#print(L)

# 人(0~N-1)と言語(N~M-1)の間で二部グラフを作る
E = [set() for _ in range(N+M)]
for i in range(N):
  for l in L[i]:
    E[i].add(l+N-1)
    E[l+N-1].add(i)
#print(E)

# 人のノードすべてに到達可能であればYES
Visited = [0 for _ in range(N+M)]
def dfs(v):
  Visited[v] = 1
  for u in E[v]:
    if Visited[u] == 0:
      dfs(u)
dfs(0)
print(('YES' if sum(Visited[:N]) == N else 'NO'))
# Original solution
from collections import deque

N,M = list(map(int, input().split()))

es_lang = [[] for _ in range(M+1)] # 各言語の番号がidxで、それを話せる人が中身
es_p = [[] for _ in range(N+1)] # 各人の番号がidxで、その人の話せる言語が中身
for i in range(N):
    KL = list(map(int, input().split()))
    es_p[i+1].extend(KL[1:])
    for j in KL[1:]:
        es_lang[j].append(i+1)

checked_lang = [False] * (M+1)
checked_p = [False] * (N+1)

#人１からスタートする
stack_p = [1]
checked_p[1] = True
while len(stack_p) > 0:
    for p in stack_p:
        #p = stack_p.pop() # 調べる人を取り出す
        checked_p[p] = True
        stack_lang = []
        for lang in es_p[p]: #人ｐが話せる言語について調べる
            if checked_lang[lang] == False: # まだその言語を調査してないとき
                stack_lang.append(lang)
                checked_lang[lang] = True

        # 人pの持つ言語をだれが話せるか調べる
        new_stack_p = []
        for lang in stack_lang:
            for pp in es_lang[lang]:
                if checked_p[pp] == False:
                    new_stack_p.append(pp)
                    checked_p[pp] = True

    if all(checked_p[1:]):
        print("YES")
        exit()
    if len(new_stack_p) > 0:
        stack_p = new_stack_p



print("NO")


# Optimized solution
from collections import deque

N,M = list(map(int, input().split()))

es_lang = [[] for _ in range(M+1)] # 各言語の番号がidxで、それを話せる人が中身
es_p = [[] for _ in range(N+1)] # 各人の番号がidxで、その人の話せる言語が中身
for i in range(N):
    KL = list(map(int, input().split()))
    es_p[i+1].extend(KL[1:])
    for j in KL[1:]:
        es_lang[j].append(i+1)

checked_lang = [False] * (M+1)
checked_p = [False] * (N+1)

#人１からスタートする
stack_p = [1]
checked_p[1] = True
while len(stack_p) > 0:
    new_stack_p = [] # この次のループで調べる人の集合
    for p in stack_p:
        checked_p[p] = True
        stack_lang = []
        for lang in es_p[p]: #人ｐが話せる言語について調べる
            if checked_lang[lang] == False: # まだその言語を調査してないとき
                stack_lang.append(lang)
                checked_lang[lang] = True

        # 人pの持つ言語をだれが話せるか調べる
        for lang in stack_lang:
            for pp in es_lang[lang]: # 人ｐの話せる言語を話せる人について調べる
                if checked_p[pp] == False: # まだその人を調べてないなら次のループで調べる人に入れる
                    new_stack_p.append(pp)
                    checked_p[pp] = True

    if all(checked_p[1:]):
        print("YES")
        exit()
    if len(new_stack_p) > 0:
        stack_p = new_stack_p
    else:
        break



print("NO")
# Original solution
N,M = list(map(int,input().split()))
K = []
L = []
for _ in range(N):
    k,*l = list(map(int,input().split()))
    K.append(k)
    L.append(l)
    
graph = [[] for _ in range(N+M)]
for i in range(N):
    for l in L[i]:
        graph[i].append(N+l-1)
        graph[N+l-1].append(i)

visited = [0 for _ in range(N+M)]
visited[0] = 1
stack = [0]

while stack:
    node = stack.pop()
    for adj in graph[node]:
        if not visited[adj]:
            visited[adj] = 1
            stack.append(adj)
            
print(('YES' if all(visited[:N]) else 'NO'))

# Optimized solution
class UnionFind():
    def __init__(self, n):
        self.n = n
        self.parents = [i for i in range(n)]
        self.size = [1 for _ in range(n)]

    def find(self, x):
        root = x
        while self.parents[root] != root:
            root = self.parents[root]
        return root

    def unite(self, x, y):
        xroot = self.find(x)
        yroot = self.find(y)
        if xroot == yroot: return
        if self.size[xroot] <= self.size[yroot]:
            self.parents[xroot] = yroot
            self.size[yroot] += self.size[xroot]
        else:
            self.parents[yroot] = xroot
            self.size[xroot] += self.size[yroot]

N, M = list(map(int, input().split()))

uf = UnionFind(M)
L = []

for _ in range(N):
    k, *l = list(map(int, input().split()))
    for i in range(1, k):
        uf.unite(l[0] - 1, l[i] - 1)
    L.append(l[0] - 1)

if len(set([uf.find(L[i]) for i in range(N)])) == 1:
    print('YES')
else:
    print('NO')
# Original solution
# cf16-finalC - Interpretation
class UnionFind:  # O(α(N))
    def __init__(self, size):  # construct a Union-Find tree (1-idx)
        self.parent = [i for i in range(size + 1)]
        self.rank = [0] * (size + 1)

    def find(self, x):  # find the group (root) of a vertex
        if self.parent[x] == x:
            return x
        self.parent[x] = self.find(self.parent[x])
        return self.parent[x]

    def unite(self, x, y):  # unite two groups
        x, y = self.find(x), self.find(y)
        if x == y:  # in the same group
            return
        # unite a small one to a bigger one to balance trees
        if self.rank[x] < self.rank[y]:
            self.parent[x] = y
        else:
            self.parent[y] = x
            if self.rank[x] == self.rank[y]:
                self.rank[x] += 1


def main():
    # Union-Find on spoken languages -> check all langs are in the same group?
    N, M = list(map(int, input().split()))
    A = [(list(map(int, input().split()))) for _ in range(N)]
    uf, spoken = UnionFind(M), set()
    for _, *langs in A:
        spoken.update(langs)
        primary = langs[0]  # primary language for the person
        for l in langs[1:]:
            uf.unite(primary, l)
    cur = uf.find(spoken.pop())  # group of one of spoken languages
    flg = all(uf.find(lang) == cur for lang in spoken)
    print(("YES" if flg else "NO"))


if __name__ == "__main__":
    main()

# Optimized solution
# cf16-finalC - Interpretation
class UnionFind:
    def __init__(self, size):
        self.parent = [i for i in range(size + 1)]
        self.rank = [0] * (size + 1)

    def find(self, x):
        if self.parent[x] == x:
            return x
        self.parent[x] = self.find(self.parent[x])
        return self.parent[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.parent[x] = y
        else:
            self.parent[y] = x
            if self.rank[x] == self.rank[y]:
                self.rank[x] += 1


def main():
    N, M = list(map(int, input().split()))
    A = [(list(map(int, input().split()))) for _ in range(N)]
    uf, spoken = UnionFind(M), set()
    for _, *langs in A:
        spoken.update(langs)
        primary = langs[0]
        for l in langs[1:]:
            uf.unite(primary, l)
    cur = uf.find(spoken.pop())
    flg = all(uf.find(lang) == cur for lang in spoken)
    print(("YES" if flg else "NO"))


if __name__ == "__main__":
    main()
# Original solution
N,M = list(map(int,input().split()))
KL = [list(map(int,input().split())) for _ in [0]*N ]

E = [[[] for _ in [0]*N] , [[] for _ in [0]*M]]
for i,kl in enumerate(KL):
    for l in kl[1:]:
        E[0][i].append(l-1)
        E[1][l-1].append(i)

Check = [[False]*N,[False]*M]
Check[0][0] = True
q = [[0,0]]
while q:
    cl,i = q.pop()
    for j in E[cl][i]:
        if Check[1-cl][j]:continue
        q.append([1-cl,j])
        Check[1-cl][j] = True

if sum(Check[0]) == N:
    print("YES")
else:
    print("NO")

# Optimized solution
#二部グラフで連結判定
N,M = list(map(int,input().split()))
KL = [list(map(int,input().split())) for _ in [0]*N]

c = [False]*(N+M) #d[0] - d[N-1]:人, d[N] - D[N+M-1]:言語
E = [[] for _ in [0]*(N+M)]
for i,kl in enumerate(KL):
    for l in kl[1:]:
        E[i].append(N+l-1)
        E[N+l-1].append(i)

start = 0
q = [start]
c[start] = True
while q:
    i = q.pop()
    for j in E[i]:
        if c[j]:continue
        c[j] = True
        q.append(j)

ans = True
for b in c[:N]:
    ans = ans and b
print(("YES" if ans else "NO"))
# Original solution
import heapq
N,M = list(map(int,input().split()))
KL = [list(map(int,input().split())) for _ in [0]*N]

E = [{} for _ in [0]*(N+M)]
for i,kl in enumerate(KL):
    for l in kl[1:]:
        E[i][N+l-1] = 1
        E[N+l-1][i] = 1

def Dijkstra(N,E,start):
    d = [-1]*N
    q = [(0,start)]
    while q:
        ci,i = heapq.heappop(q)
        if d[i]!= -1:continue
        d[i] = ci
        for j,cj in list(E[i].items()):
            if d[j]!=-1:continue
            heapq.heappush(q,(ci+cj,j))
    return d

d = Dijkstra(N+M,E,0)
ans = d[:N].count(-1)==0
print(("YES" if ans else "NO"))

# Optimized solution
#二部グラフで連結判定
N,M = list(map(int,input().split()))
KL = [list(map(int,input().split())) for _ in [0]*N]

E = [[] for _ in [0]*(N+M)] #E[0] - E[N-1]:人, E[N] - E[N+M-1]:言語
for i,kl in enumerate(KL):
    for l in kl[1:]:
        E[i].append(N+l-1)
        E[N+l-1].append(i)

def connect_bfs(N,E,start):
    connect = {start}
    q = [start]
    while q:
        i = q.pop()
        for j in E[i]:
            if j in connect:continue
            connect.add(j)
            q.append(j)
    return connect

c = connect_bfs(N+M,E,0)
ans = len(c & set(range(N)))==N
print(("YES" if ans else "NO"))
# Original solution
#二部グラフで連結判定
N,M = list(map(int,input().split()))
KL = [list(map(int,input().split())) for _ in [0]*N]

E = [[] for _ in [0]*(N+M)] #E[0] - E[N-1]:人, E[N] - E[N+M-1]:言語
for i,kl in enumerate(KL):
    for l in kl[1:]:
        E[i].append(N+l-1)
        E[N+l-1].append(i)

def connect_bfs(N,E,start):
    connect = {start}
    q = [start]
    while q:
        i = q.pop()
        for j in E[i]:
            if j in connect:continue
            connect.add(j)
            q.append(j)
    return connect

c = connect_bfs(N+M,E,0)
ans = len(c & set(range(N)))==N
print(("YES" if ans else "NO"))

# Optimized solution
#二部グラフで連結判定
N,M = list(map(int,input().split()))
KL = [list(map(int,input().split())) for _ in [0]*N]

E = [[] for _ in [0]*(N+M)] #E[0] - E[N-1]:人, E[N] - E[N+M-1]:言語
for i,kl in enumerate(KL):
    for l in kl[1:]:
        E[i].append(N+l-1)
        E[N+l-1].append(i)

def dist_bfs(N,E,start):
    d = [-1]*N
    d[start] = 0
    q = [start]
    while q:
        qq = []
        for i in q:
            di = d[i]
            for j in E[i]:
                if d[j]!=-1:continue
                d[j] = di+1
                q.append(j)
        q = qq
    return d

d = dist_bfs(N+M,E,0)
ans = d[:N].count(-1)==0
print(("YES" if ans else "NO"))