In some social network, there are $n$ users communicating with each other in $m$ groups of friends. Let's analyze the process of distributing some news between users.

Initially, some user $x$ receives the news from some source. Then he or she sends the news to his or her friends (two users are friends if there is at least one group such that both of them belong to this group). Friends continue sending the news to their friends, and so on. The process ends when there is no pair of friends such that one of them knows the news, and another one doesn't know.

For each user $x$ you have to determine what is the number of users that will know the news if initially only user $x$ starts distributing it. 


-----Input-----

The first line contains two integers $n$ and $m$ ($1 \le n, m \le 5 \cdot 10^5$) — the number of users and the number of groups of friends, respectively.

Then $m$ lines follow, each describing a group of friends. The $i$-th line begins with integer $k_i$ ($0 \le k_i \le n$) — the number of users in the $i$-th group. Then $k_i$ distinct integers follow, denoting the users belonging to the $i$-th group.

It is guaranteed that $\sum \limits_{i = 1}^{m} k_i \le 5 \cdot 10^5$.


-----Output-----

Print $n$ integers. The $i$-th integer should be equal to the number of users that will know the news if user $i$ starts distributing it.


-----Example-----
Input
7 5
3 2 5 4
0
2 1 2
1 1
2 6 7

Output
4 4 1 4 4 2 2

Difficulty: interview

Starter code:

Solutions:
import sys
input = sys.stdin.readline

n,m=list(map(int,input().split()))
FR=[list(map(int,input().split())) for i in range(m)]

#UnionFind

Group=[[i,1] for i in range(n+1)]

def find(x):
    while Group[x][0] != x:
        x=Group[x][0]
    return x

def Union(x,y):
    if find(x) != find(y):
        SUM=Group[find(y)][1]+Group[find(x)][1]
        Group[find(y)][0]=Group[find(x)][0]=min(find(y),find(x))
        Group[find(y)][1]=SUM

        

for j in range(m):
    if len(FR[j])<=2:
        continue
    for k in range(2,len(FR[j])):
        Union(FR[j][k],FR[j][k-1])

ANS=[]
for i in range(1,n+1):
    ANS.append(Group[find(i)][1])

print(*ANS)


import sys
input = iter(sys.stdin.read().splitlines()).__next__

class mergefind:
    def __init__(self,n):
        self.parent = list(range(n))
        self.size = [1]*n
        self.num_sets = n

    def find(self,a):
        to_update = []
       
        while a != self.parent[a]:
            to_update.append(a)
            a = self.parent[a]
       
        for b in to_update:
            self.parent[b] = a

        return self.parent[a]

    def merge(self,a,b):
        a = self.find(a)
        b = self.find(b)

        if a==b:
            return

        if self.size[a]<self.size[b]:
            a,b = b,a

        self.num_sets -= 1
        self.parent[b] = a
        self.size[a] += self.size[b]

    def set_size(self, a):
        return self.size[self.find(a)]

    def __len__(self):
        return self.num_sets

n,m = list(map(int,input().split()))
mf = mergefind(n)

for _ in range(m):
    sz,*A = [int(x)-1 for x in input().split()]
    sz += 1

    for i in range(1,sz):
        prev,cur = A[i-1],A[i]
        mf.merge(prev,cur)

print(*[mf.set_size(i) for i in range(n)])


import sys

n, m = map(int, input().split())
par = [0] * (n + 1)
cnt = [0] * (n + 1)
for i in range(n + 1):
  par[i] = i

def find(a):
  if par[a] == a:
    return a
  par[a] = find(par[a])
  return par[a]  

for i in sys.stdin.readlines():
  x = list(map(int, i[:-1].split()))
  if x[0]:
    ta = find(x[1])
    for i in x[2:]:
      tb = find(i)
      if ta != tb:
        par[tb] = ta

for i in range(n + 1):
  cnt[find(i)] += 1

ans = []
for i in range(1, n + 1):
  ans.append(str(cnt[par[i]]))
print(' '.join(ans))

import sys
class UF():
    def __init__(self, num):
        self.par = [-1]*num
        self.size = [1]*num
    def find(self, x):
        if self.par[x] < 0:
            return x
        else:
            x = self.par[x]
            return self.find(x)
    
    def union(self, x, y):
        rx = self.find(x)
        ry = self.find(y)
        if rx != ry:
            if self.par[rx] < self.par[ry]:
                self.par[ry] = rx
                self.size[rx] += self.size[ry] 
            elif self.par[rx] > self.par[ry]:
                self.par[rx] = ry
                self.size[ry] += self.size[rx]
            else:
                self.par[rx] -= 1
                self.par[ry] = rx
                self.size[rx] += self.size[ry]
        return

def solve():
    N, M = map(int, sys.stdin.readline().split())
    G = UF(N)
    for _ in range(M):
        L = list(map(int, sys.stdin.readline().split()))
        if L[0] > 1:
            l = L[1]
            for r in L[2:]:
                G.union(l-1, r-1)
    Ans = [0]*N
    for i in range(N):
        Ans[i] = G.size[G.find(i)]
    print(*Ans)
def __starting_point():
    solve()
__starting_point()

# stdin=open('input.txt')
from sys import stdin, stdout
def input():
	return stdin.readline()[:-1]


# # stdout=open('output.txt',mode='w+')

# # def print(x, end='\n'):
# # 	stdout.write(str(x) +end)


# # a, b = map(int, input().split())

# # l = list(map(int, input().split()))







# CODE BEGINS HERE.................
import math

class disjoint_set:
	def __init__(self, n):
		self.parent = [i for i in range(n)]
		self.size = [1] * n
	def union(self, a, b):
		p1 = self.find(a)
		p2 = self.find(b)

		if p1 == p2:
			return False
		if self.size[p1] > self.size[p2]:
			self.parent[p2] = p1
			self.size[p1] += self.size[p2]
		else:
			self.parent[p1] = p2
			self.size[p2] += self.size[p1]

	def find(self, x):
		ans = x
		while ans != self.parent[ans]:
			ans = self.parent[ans]
		temp = x
		while temp != self.parent[temp]:
			temp2 = self.parent[temp]
			self.parent[temp] = ans
			temp = temp2
		return ans


n, m = map(int, input().split())
ds = disjoint_set(n)
for i in range(m):
	l = list(map(int, input().split()))
	for i in range(2, l[0] + 1):
		ds.union(l[i - 1] - 1, l[i] - 1)


for i in range(n):
	print(ds.size[ds.find(i)], end = ' ')
print('')

#CODE ENDS HERE....................

#stdout.close()



class UnionFind:
    def __init__(self, n):
        self.parent = list(range(n))
        self.size = [1] * n
        self.num_sets = n

    def find(self, a):
        to_update = []

        while a != self.parent[a]:
            to_update.append(a)
            a = self.parent[a]

        for b in to_update:
            self.parent[b] = a

        return self.parent[a]

    def merge(self, a, b):
        a = self.find(a)
        b = self.find(b)

        if a == b:
            return

        if self.size[a] < self.size[b]:
            a, b = b, a

        self.num_sets -= 1
        self.parent[b] = a
        self.size[a] += self.size[b]

    def set_size(self, a):
        return self.size[self.find(a)]


def main():
    from sys import stdin, stdout

    def read():
        return stdin.readline().rstrip('\n')

    def read_array(sep=None, maxsplit=-1):
        return read().split(sep, maxsplit)

    def read_int():
        return int(read())

    def read_int_array(sep=None, maxsplit=-1):
        return [int(a) for a in read_array(sep, maxsplit)]

    def write(*args, **kwargs):
        sep = kwargs.get('sep', ' ')
        end = kwargs.get('end', '\n')
        stdout.write(sep.join(str(a) for a in args) + end)

    def write_array(array, **kwargs):
        sep = kwargs.get('sep', ' ')
        end = kwargs.get('end', '\n')
        stdout.write(sep.join(str(a) for a in array) + end)

    n, m = read_int_array()
    uf = UnionFind(n)
    for _ in range(m):
        nums = read_int_array()
        sz = nums[0]
        leader = None
        for i in range(sz):
            p = nums[1 + i] - 1
            if leader is None:
                leader = p
            else:
                uf.merge(p, leader)

    ans = [uf.set_size(i) for i in range(n)]
    write(*ans)

main()


from collections import deque
import sys
n,m=list(map(int,sys.stdin.readline().split()))
a=[[] for i in range(n+1)]
d=deque([])
for i in range(m):
    b=list(map(int,sys.stdin.readline().split()))
    for j in b[2:]:
        a[b[1]].append(j)
        a[j].append(b[1])

ans=[1]*(n+1)
vis=[0]*(n+1)

for i in range(1,n+1):
    if vis[i]==0:
        vis[i]=1
        d.append(i)
    b=[]  
    while(d):
        # print(d,vis)
        p=d.popleft()
        b.append(p)
        for j in (a[p]):
            if vis[j]==0:
                d.append(j)
                vis[j]=1
    l=len(b)            
    # print(b)
    for j in b:
        ans[j]=l
print(*ans[1:])
    

        
        




from sys import stdin
input=stdin.readline
n,m=map(int,input().split())
a=[[] for i in range(n)]
for i in range(m):
    b=list(map(int,input().split()))
    for j in range(2,b[0]+1):
        a[b[j]-1].append(b[j-1]-1)
        a[b[j-1]-1].append(b[j]-1)
vis=[0]*n
ans=[0]*n
for i in range(n):
    if vis[i]==0:
        st=[i]
        c=0
        while st:
            x=st.pop()
            vis[x]=1
            c+=1
            for j in a[x]:
                if vis[j]==0:
                    vis[j]=1
                    st.append(j)
        st=[i]
        ans[i]=c
        while st:
            x=st.pop()
            for j in a[x]:
                if ans[j]==0:
                    ans[j]=c
                    st.append(j)
print(*ans)

import sys
class Union_Find():
    def __init__(self, num):
        self.par = [-1]*(num+1)
        self.size = [1]*(num+1)
    def find(self, x):
        if self.par[x] < 0:
            return x
        else:
            x = self.par[x]
            return self.find(x)

    def union(self, x, y):
        rx = self.find(x)
        ry = self.find(y)
        if rx != ry:
            if self.par[rx] < self.par[ry]:
                self.par[ry] = rx
                self.size[rx] += self.size[ry]
            elif self.par[rx] > self.par[ry]:
                self.par[rx] = ry
                self.size[ry] += self.size[rx]
            else:
                self.par[rx] -= 1
                self.par[ry] = rx
                self.size[rx] += self.size[ry]
        return

n, q = list(map(int, input().split()))
query = [tuple(map(int, sys.stdin.readline().split())) for _ in range(q)]
tree = Union_Find(n)
for a in query:
    k = a[0]
    if k >= 2:
        b = a[1]
        for i in a[2:]:
            tree.union(b, i)

ans = [tree.size[tree.find(i+1)] for i in range(n)]
print(" ".join(map(str, ans)))


import sys


class Node:
    def __init__(self, val):
        self.parent = self
        self.size = 1


def union(x, y):
    xRoot, yRoot = find(x), find(y)
    if xRoot == yRoot:
        return
    if xRoot.size >= yRoot.size:
        yRoot.parent = xRoot
        xRoot.size += yRoot.size
    else:
        xRoot.parent = yRoot
        yRoot.size += xRoot.size


def find(x):
    while x.parent != x:
        x = x.parent
    return x


n, m = [int(item) for item in sys.stdin.readline().strip().split()]
node = [Node(x) for x in range(n + 1)]
groups = [[int(item) for item in sys.stdin.readline().strip().split()]
          for _ in range(m)]
for g in range(m):
    group = groups[g]
    k = group[0]
    if k == 0:
        continue
    for i in range(2, k + 1):
        union(node[group[i]], node[group[i - 1]])


ans = [find(node[x]).size for x in range(1, n + 1)]

sys.stdout.write(' '.join(str(x) for x in ans) + '\n')


import sys


class Node:
    def __init__(self, val):
        self.parent = self
        self.size = 1
        self.rank = 0


def union(x, y):
    xRoot, yRoot = find(x), find(y)
    if xRoot == yRoot:
        return
    if xRoot.rank > yRoot.rank:
        yRoot.parent = xRoot
        xRoot.size += yRoot.size
    elif xRoot.rank < yRoot.rank:
        xRoot.parent = yRoot
        yRoot.size += xRoot.size
    else:
        yRoot.parent = xRoot
        xRoot.rank = xRoot.rank + 1
        xRoot.size += yRoot.size


def find(x):
    while x.parent != x:
        x = x.parent
    return x


n, m = [int(item) for item in sys.stdin.readline().strip().split()]
node = [Node(x) for x in range(n + 1)]
groups = [[int(item) for item in sys.stdin.readline().strip().split()]
          for _ in range(m)]
for g in range(m):
    group = groups[g]
    k = group[0]
    if k == 0:
        continue
    for i in range(2, k + 1):
        union(node[group[i]], node[group[i - 1]])


ans = [find(node[x]).size for x in range(1, n + 1)]

sys.stdout.write(' '.join(str(x) for x in ans) + '\n')


import sys
class Union_Find():
    def __init__(self, num):
        self.par = [-1]*(num+1)
        self.size = [1]*(num+1)
    def find(self, x):
        if self.par[x] < 0:
            return x
        else:
            x = self.par[x]
            return self.find(x)

    def union(self, x, y):
        rx = self.find(x)
        ry = self.find(y)
        if rx != ry:
            if self.par[rx] < self.par[ry]:
                self.par[ry] = rx
                self.size[rx] += self.size[ry]
            elif self.par[rx] > self.par[ry]:
                self.par[rx] = ry
                self.size[ry] += self.size[rx]
            else:
                self.par[rx] -= 1
                self.par[ry] = rx
                self.size[rx] += self.size[ry]
        return
    def size(self, x):
        return self.size[find(x)]

n, q = list(map(int, input().split()))
query = [tuple(map(int, sys.stdin.readline().split())) for _ in range(q)]
tree = Union_Find(n)
for a in query:
    k = a[0]
    if k >= 2:
        b = a[1]
        for i in a[2:]:
            tree.union(b, i)

ans = [tree.size[tree.find(i+1)] for i in range(n)]
print(" ".join(map(str, ans)))


import sys; input = sys.stdin.readline


class Node:
    def __init__(self, val):
        self.parent = self
        self.size = 1


def union(x, y):
    xRoot, yRoot = find(x), find(y)
    if xRoot == yRoot:
        return
    if xRoot.size >= yRoot.size:
        yRoot.parent = xRoot
        xRoot.size += yRoot.size
    else:
        xRoot.parent = yRoot
        yRoot.size += xRoot.size


def find(x):
    while x.parent != x:
        x = x.parent
    return x


class Problem:
    def __init__(self, In=sys.stdin, Out=sys.stdout):
        pass

    def solve(self):
        print(self._solve())

    def _solve(self):
        n, m = [int(item) for item in sys.stdin.readline().strip().split()]
        node = [Node(x) for x in range(n + 1)]
        groups = [[int(item) for item in sys.stdin.readline().strip().split()]
                  for _ in range(m)]
        for g in range(m):
            group = groups[g]
            k = group[0]
            if k == 0:
                continue
            for i in range(2, k + 1):
                union(node[group[i]], node[group[i - 1]])

        ans = [find(node[x]).size for x in range(1, n + 1)]
        return ' '.join(str(x) for x in ans)


def main():
    problem = Problem()
    problem.solve()


def __starting_point():
    main()

__starting_point()

import sys
class Union_Find():
    def __init__(self, num):
        self.par = [-1]*(num+1)
        self.size = [1]*(num+1)
    def find(self, x):
        if self.par[x] < 0:
            return x
        else:
            x = self.par[x]
            return self.find(x)

    def union(self, x, y):
        rx = self.find(x)
        ry = self.find(y)
        if rx != ry:
            if self.par[rx] < self.par[ry]:
                self.par[ry] = rx
                self.size[rx] += self.size[ry]
            elif self.par[rx] > self.par[ry]:
                self.par[rx] = ry
                self.size[ry] += self.size[rx]
            else:
                self.par[rx] -= 1
                self.par[ry] = rx
                self.size[rx] += self.size[ry]
        return
    def size_query(self, x):
        return self.size[self.find(x)]

n, q = list(map(int, input().split()))
query = [tuple(map(int, sys.stdin.readline().split())) for _ in range(q)]
tree = Union_Find(n)
for a in query:
    k = a[0]
    if k >= 2:
        b = a[1]
        for i in a[2:]:
            tree.union(b, i)

ans = [tree.size_query(tree.find(i+1)) for i in range(n)]
print(" ".join(map(str, ans)))


import sys
class Union_Find():
    def __init__(self, num):
        self.par = [-1]*(num+1)
        self.size = [1]*(num+1)
    def find(self, x):
        if self.par[x] < 0:
            return x
        else:
            x = self.par[x]
            return self.find(x)

    def union(self, x, y):
        rx = self.find(x)
        ry = self.find(y)
        if rx != ry:
            if self.par[rx] < self.par[ry]:
                self.par[ry] = rx
                self.size[rx] += self.size[ry]
            elif self.par[rx] > self.par[ry]:
                self.par[rx] = ry
                self.size[ry] += self.size[rx]
            else:
                self.par[rx] -= 1
                self.par[ry] = rx
                self.size[rx] += self.size[ry]
        return
    def size_query(self, x):
        return self.size[self.find(x)]

n, q = list(map(int, input().split()))
query = [tuple(map(int, sys.stdin.readline().split())) for _ in range(q)]
tree = Union_Find(n)
for a in query:
    k = a[0]
    if k >= 2:
        b = a[1]
        for i in a[2:]:
            tree.union(b, i)

print(" ".join(map(str, [tree.size_query(tree.find(i+1)) for i in range(n)])))


import sys
class Union_Find():
    def __init__(self, num):
        self.par = [-1]*(num+1)
        self.size = [1]*(num+1)
    def find(self, x):
        if self.par[x] < 0:
            return x
        else:
            x = self.par[x]
            return self.find(x)

    def union(self, x, y):
        rx = self.find(x)
        ry = self.find(y)
        if rx != ry:
            if self.par[rx] < self.par[ry]:
                self.par[ry] = rx
                self.size[rx] += self.size[ry]
            elif self.par[rx] > self.par[ry]:
                self.par[rx] = ry
                self.size[ry] += self.size[rx]
            else:
                self.par[rx] -= 1
                self.par[ry] = rx
                self.size[rx] += self.size[ry]
        return
    def size_query(self, x):
        return self.size[self.find(x)]

n, q = list(map(int, input().split()))
tree = Union_Find(n)

for _ in range(q):
    a = tuple(map(int, sys.stdin.readline().split()))
    k = a[0]
    if k >= 2:
        b = a[1]
        for i in a[2:]:
            tree.union(b, i)

print(" ".join(map(str, [tree.size_query(tree.find(i+1)) for i in range(n)])))


import sys
class Union_Find():
    def __init__(self, num):
        self.par = [-1]*(num+1)
        self.size = [1]*(num+1)
    def find(self, x):
        if self.par[x] < 0:
            return x
        else:
            x = self.par[x]
            return self.find(x)

    def union(self, x, y):
        rx = self.find(x)
        ry = self.find(y)
        if rx != ry:
            if self.par[rx] < self.par[ry]:
                self.par[ry] = rx
                self.size[rx] += self.size[ry]
            elif self.par[rx] > self.par[ry]:
                self.par[rx] = ry
                self.size[ry] += self.size[rx]
            else:
                self.par[rx] -= 1
                self.par[ry] = rx
                self.size[rx] += self.size[ry]
        return
    def size_query(self, x):
        return self.size[self.find(x)]

n, q = list(map(int, input().split()))
tree = Union_Find(n)

for _ in range(q):
    a = list(map(int, sys.stdin.readline().split()))
    k = a[0]
    if k >= 2:
        b = a[1]
        for i in a[2:]:
            tree.union(b, i)

print(" ".join(map(str, [tree.size_query(tree.find(i+1)) for i in range(n)])))


# coding: UTF-8
import sys

def find(x):
    if node[x] < 0:
        return x
    else:
        node[x] = find(node[x])
        return node[x]

def unite(x, y):
    x = find(x)
    y = find(y)
    ret = False
    if x != y:
        ret = True
        if rank[x] > rank[y]:
            node[x] += node[y]
            node[y] = x
        else:
            node[y] += node[x]
            node[x] = y
            if rank[x] == rank[y]:
                rank[y] += 1
    return ret

def is_same(x, y):
    return find(x) == find(y)

def size(x):
    return -node[find(x)]

n, m = map(int, input().split())
node = [-1 for i in range(n + 1)]
rank = [0 for _ in range(n + 1)]
query = [tuple(map(int, sys.stdin.readline().split())) for _ in range(m)]
for a in query:
    if a[0] >= 2:
        for j in a[2:]:
            unite(a[1], j)
for i in range(1, n + 1):
    print(size(i), end=" ")





from sys import stdin

def find(Set, x):
    while Set[x] != x:
        Set[x] = Set[Set[x]]
        x = Set[x]

    return x 

def union(Set, u, v):
    f_u = find(Set, u)
    f_v = find(Set, v)
    
    if f_u != f_v:
        Set[f_u] = f_v

def solve():
    #stdin = open("C. News Distribution.txt")
    
    N, M = map(int, stdin.readline().split())
    
    Set = list(range(N+1))
    
    for _ in range(M):
        group = [int(k) for k in stdin.readline().split()][1:]
        
        for x in group[1:]:
            Set[find(Set, x)] = find(Set, group[0])

    cnt = [0]*(N+1)
    
    for i in range(1, N+1):
        cnt[find(Set, i)] += 1
                
    print (' '.join(map(str, [cnt[find(Set, i)] for i in range(1,N+1)])))

def __starting_point():  
    solve()
__starting_point()

import sys
input = sys.stdin.readline
class Union_Find():
    def __init__(self, num):
        self.par = [-1]*(num+1)
        self.siz = [1]*(num+1)

    def same_checker(self, x, y):
        return self.find(x) == self.find(y)

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

    def union(self, x, y):
        rx = self.find(x)
        ry = self.find(y)
        if rx != ry:
            if self.par[rx] < self.par[ry]:
                self.par[ry] = rx
                self.siz[rx] += self.siz[ry]
            elif self.par[rx] > self.par[ry]:
                self.par[rx] = ry
                self.siz[ry] += self.siz[rx]
            else:
                self.par[rx] -= 1
                self.par[ry] = rx
                self.siz[rx] += self.siz[ry]
        return

    def size(self, x):
        return self.siz[self.find(x)]
        
n, q = map(int, input().split())
union_find_tree = Union_Find(n)
for i in range(q):
    a = list(map(int, input().split()))
    k = a[0]
    if k >= 2:
        for i in range(2, k+1):
            union_find_tree.union(a[1], a[i])
ans = []
for i in range(1, n+1):
    ans.append(union_find_tree.size(i))
print(" ".join(map(str, ans)))

from sys import stdin

def find(parent, x):
    while parent[x] != x:
        parent[x] = parent[parent[x]]
        x = parent[x]

    return x

def solve():
    #stdin = open("C. News Distribution.txt")
    
    N, M = map(int, stdin.readline().split())
    
    parent = list(range(N+1))
    
    for _ in range(M):
        group = [int(k) for k in stdin.readline().split()][1:]
        if group:
            p = find(parent, group[0])
            
            for x in group[1:]:
                parent[find(parent, x)] = p

    cnt = [0]*(N+1)
    
    for i in range(1, N+1):
        cnt[find(parent, i)] += 1
                
    print (' '.join(map(str, [cnt[find(parent, i)] for i in range(1,N+1)])))

def __starting_point():  
    solve()
__starting_point()

import sys
sys.setrecursionlimit(1000000)

nUsers, nGroups = map(int, sys.stdin.readline().split())
parent = list(range(nUsers + 1))
rank = [0] * (nUsers + 1)

def find(a):
    if parent[a] != a:
        parent[a] = find(parent[a])
    return parent[a]

def union(a, b):
    idA, idB = find(a), find(b)
    if idA == idB:
        return
    if rank[idA] > rank[idB]:
        parent[idB] = idA
    else:
        parent[idA] = idB
        if rank[idA] == rank[idB]:
            rank[idB] += 1

for _ in range(nGroups):
    g = sys.stdin.readline()
    if g[0] >= '1':
        g = list(map(int, g.split()))
        for i in range(2, len(g)):
            union(g[1], g[i])

count = [0] * (nUsers + 1)
for user in range(nUsers + 1):
    count[find(user)] += 1

ret = []
for user in range(1, nUsers + 1):
    ret.append(str(count[parent[user]]))
sys.stdout.write('%s\n' % ' '.join(ret))

import sys
sys.setrecursionlimit(1000000)

nUsers, nGroups = map(int, sys.stdin.readline().split())
parent = list(range(nUsers + 1))
rank = [0] * (nUsers + 1)

def find(a):
    if parent[a] != a:
        parent[a] = find(parent[a])
    return parent[a]

def union(a, b):
    idA, idB = find(a), find(b)
    if idA == idB:
        return
    if rank[idA] > rank[idB]:
        parent[idB] = idA
    else:
        parent[idA] = idB
        if rank[idA] == rank[idB]:
            rank[idB] += 1

for _ in range(nGroups):
    g = sys.stdin.readline()
    if g[0] >= '1':
        g = list(map(int, g.split()))
        for i in range(2, len(g)):
            union(g[1], g[i])

count = [0] * (nUsers + 1)
for user in range(nUsers + 1):
    count[find(user)] += 1

ret = []
for user in range(1, nUsers + 1):
    ret.append(str(count[parent[user]]))
sys.stdout.write('%s\n' % ' '.join(ret))