from collections import deque class UnionFind: def __init__(self,n): self.n = n self.parent_size = [-1]*n def leader(self,a): if self.parent_size[a] < 0: return a self.parent_size[a] = self.leader(self.parent_size[a]) return self.parent_size[a] def merge(self,a,b): x, y = self.leader(a), self.leader(b) if x == y: return if abs(self.parent_size[x]) < abs(self.parent_size[y]): x, y = y, x self.parent_size[x] += self.parent_size[y] self.parent_size[y] = x return def same(self,a,b): return self.leader(a) == self.leader(b) def size(self,a): return abs(self.parent_size[self.leader(a)]) def groups(self): result = [[] for _ in range(self.n)] for i in range(self.n): result[self.leader(i)].append(i) return [r for r in result if r != []] def scc(N,edges): M=len(edges) start=[0]*(N+1) elist=[0]*M for e in edges: start[e[0]+1]+=1 for i in range(1,N+1): start[i]+=start[i-1] counter=start[:] for e in edges: elist[counter[e[0]]]=e[1] counter[e[0]]+=1 visited=[] low=[0]*N Ord=[-1]*N ids=[0]*N NG=[0,0] def dfs(v): stack=[(v,-1,0),(v,-1,1)] while stack: v,bef,t=stack.pop() if t: if bef!=-1 and Ord[v]!=-1: low[bef]=min(low[bef],Ord[v]) stack.pop() continue low[v]=NG[0] Ord[v]=NG[0] NG[0]+=1 visited.append(v) for i in range(start[v],start[v+1]): to=elist[i] if Ord[to]==-1: stack.append((to,v,0)) stack.append((to,v,1)) else: low[v]=min(low[v],Ord[to]) else: if low[v]==Ord[v]: while(True): u=visited.pop() Ord[u]=N ids[u]=NG[1] if u==v: break NG[1]+=1 low[bef]=min(low[bef],low[v]) for i in range(N): if Ord[i]==-1: dfs(i) for i in range(N): ids[i]=NG[1]-1-ids[i] group_num=NG[1] counts=[0]*group_num for x in ids: counts[x]+=1 groups=[[] for i in range(group_num)] for i in range(N): groups[ids[i]].append(i) return groups from types import GeneratorType def bootstrap(f, stack=[]): def wrappedfunc(*args, **kwargs): if stack: return f(*args, **kwargs) to = f(*args, **kwargs) while True: if type(to) is GeneratorType: stack.append(to) to = next(to) else: stack.pop() if not stack: break to = stack[-1].send(to) return to return wrappedfunc N = int(input()) edge = [] zero = 0 for i in range(N): MA = list(map(int, input().split())) M = MA[0] if M == 0: zero += 1 if zero >= 2: exit(print("No")) A = MA[1:] for j in range(M): edge.append((i, A[j]-1)) SCC = scc(N, edge) L = len(SCC) UF = UnionFind(N) for s in SCC: if len(s) >= 2: for i in range(len(s)-1): UF.merge(s[i], s[i+1]) G = [set() for _ in range(N)] for e in edge: u, v = e if not UF.same(u, v): G[UF.leader(u)].add(UF.leader(v)) for i in range(N): G[i] = list(G[i]) @bootstrap def dfs(n): visited[UF.leader(n)] = True for v in G[UF.leader(n)]: if not visited[UF.leader(v)]: yield dfs(UF.leader(v)) S.append(UF.leader(n)) yield visited = [False]*N S = [] dfs(0) S = S[::-1] cnt = 0 for i in range(N): if UF.leader(i) == i: cnt += 1 if cnt > len(S): exit(print("No")) for i in range(len(S)-1): for j in G[S[i]]: if S[i+1] == j: break else: print("No") break else: print("Yes")