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: MEDIUM
Tags: Spanning trees

Graph algorithms

Graph traversal

Starter code:

Solutions:
import math
import sys
input = iter(sys.stdin.buffer.read().decode().splitlines()).__next__
ilele = lambda : map(int, input().split())
alele = lambda : list(map(int, input().split()))

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

def merge(a, b):
	if a != b:
		par[a] += par[b]
		par[b] = a
(n, m) = ilele()
par = [-1 for i in range(n + 1)]
for i in range(1, m + 1):
	A = alele()
	for j in range(2, A[0] + 1):
		a = find(A[j - 1])
		b = find(A[j])
		if a != b:
			merge(a, b)
for i in range(1, len(par)):
	x = find(i)
	print(-par[x], end=' ')


import sys
from collections import deque
fast_reader = sys.stdin.readline
fast_writer = sys.stdout.write

def input():
	return fast_reader().strip()

def print(*argv):
	fast_writer(' '.join((str(i) for i in argv)))
	fast_writer('\n')
for _ in range(1):
	(n, m) = map(int, input().split())
	d = {}
	for i in range(1, n + 1):
		d[i] = []
	a = []
	for __ in range(m):
		l = list(map(int, input().split()))
		if len(l) == 1:
			continue
		a.append(l[1])
		for i in range(2, len(l)):
			d[l[i]].append(l[1])
			d[l[1]].append(l[i])
	v = set()
	ans = [0 for i in range(n + 1)]
	for i in range(len(a)):
		if a[i] in v:
			continue
		else:
			q = deque()
			q.append(a[i])
			p = []
			while len(q) != 0:
				t = q.popleft()
				if t in v:
					continue
				else:
					v.add(t)
					p.append(t)
					for j in d[t]:
						q.append(j)
			for j in p:
				ans[j] = len(p)
	ans = ans[1:]
	for i in range(len(ans)):
		if ans[i] == 0:
			ans[i] += 1
	print(*ans)


from collections import Counter
from collections import defaultdict
import sys

def get_root(arr, i):
	j = i
	path = []
	while arr[j] != j:
		path.append(j)
		j = arr[j]
	for p in path:
		arr[p] = j
	return j
(n, m) = map(int, input().split())
arr = list(range(n))
lines = sys.stdin.readlines()
for line in lines:
	gs = list(map(lambda x: int(x) - 1, line.split()))[1:]
	if len(gs) == 0:
		continue
	prev = gs[0]
	i1 = get_root(arr, prev)
	for curr in gs[1:]:
		i2 = get_root(arr, curr)
		if i1 != i2:
			arr[i2] = arr[i1]
output = [0] * n
for i in range(n):
	r = get_root(arr, i)
	output[r] += 1
print(' '.join(map(lambda x: str(output[x]), arr)))


from sys import stdin
input = stdin.readline
(n, m) = map(int, input().split(' '))
parent = [i for i in range(n)]
size = [1 for _ in range(n)]
rank = [1 for _ in range(n)]

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

def union(a, b):
	pa = find(a)
	pb = find(b)
	if pa == pb:
		return
	if rank[pa] < rank[pb]:
		(pa, pb) = (pb, pa)
	parent[pb] = pa
	size[pa] += size[pb]
	if rank[pa] == rank[pb]:
		rank[pa] += 1
for g in range(m):
	row = list(map(int, input().split()))[1:]
	for x in row:
		union(row[0] - 1, x - 1)
result = []
for i in range(n):
	pi = find(i)
	result.append(str(size[pi]))
print(' '.join(result))


from sys import stdin, stdout

def input():
	return stdin.readline()[:-1]
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('')


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) = 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)])


from collections import defaultdict
from collections import deque
(n, m) = map(int, input().split())
q = deque([])

def solve(n, adj):
	count = [1] * (n + 1)
	vs = [0] * (n + 1)
	for j in range(1, n + 1):
		if vs[j] == 0:
			node = j
			reachable = []
			q.append(node)
			vs[node] = 1
			while len(q) > 0:
				node = q.popleft()
				reachable.append(node)
				for nei in adj[node]:
					if vs[nei] == 0:
						q.append(nei)
						vs[nei] = 1
			for r in reachable:
				count[r] = len(reachable)
	print(*count[1:])
import sys
adj = [[] for x in range(n + 1)]
for i in range(m):
	b = list(map(int, sys.stdin.readline().split()))
	for j in b[2:]:
		adj[b[1]].append(j)
		adj[j].append(b[1])
solve(n, adj)


from sys import stdin, stdout
cin = stdin.readline
cout = stdout.write

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

def union(x, y):
	xset = find(x)
	yset = find(y)
	if xset == yset:
		return
	if rank[xset] > rank[yset]:
		t = xset
		xset = yset
		yset = t
	parent[xset] = yset
	rank[yset] += rank[xset]

def getSize(x):
	if parent[x] == x:
		return rank[x]
	return getSize(parent[x])
(n, m) = map(int, cin().split())
rank = [1] * (n + 1)
parent = [i for i in range(n + 1)]
for _ in range(m):
	x = list(map(int, cin().split()))
	if x[0] <= 1:
		continue
	for i in range(2, len(x)):
		union(x[i], x[1])
for i in range(1, n + 1):
	cout(str(getSize(i)) + ' ')


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) = 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
from collections import Counter, defaultdict

def main():
	(n, m) = [int(x) for x in sys.stdin.readline().split(' ')]
	graph = {v: set() for v in range(n)}
	for group in sys.stdin.read().split('\n'):
		if len(group) < 1:
			continue
		if group[0] == '0':
			continue
		members = [int(x) for x in group.split(' ')]
		for i in range(2, len(members)):
			graph[members[i - 1] - 1].add(members[i] - 1)
			graph[members[i] - 1].add(members[i - 1] - 1)
	components = [-1 for i in range(n)]
	counts = {}
	stack = []
	for v in range(n):
		if components[v] != -1:
			continue
		components[v] = v
		counts[v] = 1
		stack.append(v)
		while stack:
			curr = stack.pop()
			for edge in graph[curr]:
				if components[edge] == -1:
					components[edge] = v
					counts[v] += 1
					stack.append(edge)
	print(' '.join((str(counts[components[i]]) for i in range(n))))
main()


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():
	(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()


def use_fast_io():
	import sys

	class InputStorage:

		def __init__(self, lines):
			lines.reverse()
			self.lines = lines

		def input_func(self):
			if self.lines:
				return self.lines.pop()
			else:
				return ''
	input_storage_obj = InputStorage(sys.stdin.readlines())
	return input_storage_obj.input_func
input = use_fast_io()
(n, m) = map(int, input().split())
adj = {}
for i in range(1, n + 1):
	adj[i] = set()
for __ in range(m):
	arr = list(map(int, input().split()))
	if arr[0] == 0:
		continue
	key = arr[1]
	for i in arr[2:]:
		adj[key].add(i)
		adj[i].add(key)
cache = {}
results = []
for i in range(1, n + 1):
	if i in cache:
		results.append(cache[i])
		continue
	visited = set()
	queue = [i]
	while queue:
		current = queue.pop()
		visited.add(current)
		for friend in adj[current]:
			if friend in visited:
				continue
			visited.add(friend)
			queue.append(friend)
	for people in visited:
		cache[people] = len(visited)
	results.append(cache[i])
print(' '.join(map(str, results)))


from sys import stdin

class dforest(object):

	def __init__(self, n=10):
		self.__parent = [i for i in range(n)]
		self.__rank = [0 for _ in range(n)]
		self.__ccnt = [1 for _ in range(n)]
		self.__size = n

	def __str__(self):
		return ' '.join((str(x) for x in self.__parent))

	def find(self, x):
		if self.__parent[x] != x:
			self.__parent[x] = self.find(self.__parent[x])
		return self.__parent[x]

	def union(self, x, y):
		(ax, ay) = (self.find(x), self.find(y))
		if ax != ay:
			(rax, ray) = (self.__rank[ax], self.__rank[ay])
			if rax <= ray:
				self.__parent[ax] = ay
				self.__ccnt[ay] += self.__ccnt[ax]
				if rax == ray:
					self.__rank[ay] += 1
			else:
				self.__parent[ay] = ax
				self.__ccnt[ax] += self.__ccnt[ay]

	def ccnt(self, x):
		return self.__ccnt[self.find(x)]

def main():
	(n, m) = map(int, stdin.readline().split())
	df = dforest(n)
	for i in range(m):
		tok = [int(x) - 1 for x in stdin.readline().split()]
		for j in range(2, len(tok)):
			df.union(tok[j - 1], tok[j])
	print(' '.join((str(df.ccnt(i)) for i in range(n))))
main()


from sys import stdin
from sys import stdout

def find(x):
	if x == par[x]:
		return x
	par[x] = find(par[x])
	return par[x]
(n, m) = map(int, input().split())
par = [i for i in range(n + 1)]
ans = [0] * (n + 1)
for i in range(m):
	line = [int(u) for u in stdin.readline().split()][1:]
	if len(line) == 0:
		continue
	x = find(line[0])
	for y in line[1:]:
		par[find(y)] = x
for i in range(1, n + 1):
	ans[find(i)] += 1
pprintit = ' '.join(map(str, [ans[find(u)] for u in range(1, n + 1)]))
stdout.write('%s' % pprintit)


import sys

def mul(xs):
	r = 1
	for x in xs:
		r *= x
	return r

class Main:

	def __init__(self):
		self.buff = None
		self.index = 0

	def next(self):
		if self.buff is None or self.index == len(self.buff):
			self.buff = self.next_line()
			self.index = 0
		val = self.buff[self.index]
		self.index += 1
		return val

	def next_line(self):
		return sys.stdin.readline().split()

	def next_ints(self):
		return [int(x) for x in sys.stdin.readline().split()]

	def next_int(self):
		return int(self.next())

	def solve(self):
		(n, m) = self.next_ints()
		fa = [-1 for _ in range(n)]
		sz = [1 for _ in range(n)]
		for _ in range(m):
			cs = self.next_ints()
			if len(cs) < 2:
				continue
			a = self.find(cs[1] - 1, fa)
			for c in cs[2:]:
				b = self.find(c - 1, fa)
				if a != b:
					fa[b] = a
					sz[a] += sz[b]
		print(' '.join((str(sz[self.find(i, fa)]) for i in range(n))))

	def find(self, k, fa):
		if fa[k] == -1:
			return k
		t = self.find(fa[k], fa)
		fa[k] = t
		return t
Main().solve()


import sys, bisect
from sys import stdin, stdout
from bisect import bisect_left, bisect_right, bisect, insort, insort_left, insort_right
from math import gcd, ceil, floor, sqrt
from collections import Counter, defaultdict, deque, OrderedDict
from queue import Queue, PriorityQueue
from string import ascii_lowercase
from heapq import *
from itertools import islice
sys.setrecursionlimit(10 ** 6)
INF = float('inf')
MOD = 998244353
mod = 10 ** 9 + 7

def st():
	return list(stdin.readline().strip())

def inp():
	return int(stdin.readline())

def li():
	return list(map(int, stdin.readline().split()))

def mp():
	return map(int, stdin.readline().split())

def solve():
	(n, m) = mp()
	d = {i: [] for i in range(1, n + 1)}
	for _ in range(m):
		l = li()
		x = l[0]
		if x > 1:
			for i in range(1, x):
				d[l[i]].append(l[i + 1])
				d[l[i + 1]].append(l[i])
	ans = [-1 for i in range(n + 1)]
	vi = [-1 for i in range(n + 1)]
	for i in range(1, n + 1):
		if vi[i] == -1:
			vi[i] = i
			stack = [i]
			ans[i] = 1
			while stack:
				a = stack.pop()
				for x in d[a]:
					if vi[x] == -1:
						ans[i] += 1
						vi[x] = i
						stack.append(x)
	print(' '.join((str(ans[vi[i]]) for i in range(1, n + 1))))
for _ in range(1):
	solve()


from collections import Counter
import sys

class UnionFind:

	def __init__(self, size):
		self.rank = [0] * size
		self.p = [i for i in range(size)]

	def find_set(self, i):
		if self.p[i] == i:
			return i
		else:
			self.p[i] = self.find_set(self.p[i])
			return self.p[i]

	def is_same_set(self, i, j):
		return self.find_set(i) == self.find_set(j)

	def union_set(self, i, j):
		if not self.is_same_set(i, j):
			(x, y) = (self.find_set(i), self.find_set(j))
			if self.rank[x] > self.rank[y]:
				self.p[y] = x
			else:
				self.p[x] = y
				if self.rank[x] == self.rank[y]:
					self.rank[y] += 1
(n, m) = map(int, sys.stdin.readline().strip().split())
union_find = UnionFind(n)
for i in range(m):
	(k, *group) = list(map(int, sys.stdin.readline().strip().split()))
	if k == 0 or k == 1:
		continue
	first = group[0] - 1
	for j in group[1:]:
		union_find.union_set(first, j - 1)
counts = Counter()
results = [0] * n
for i in range(n):
	result = union_find.find_set(i)
	counts[result] += 1
	results[i] = result
s = ' '.join(map(str, map(lambda x: counts[x], results)))
sys.stdout.write(s)


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
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))


from __future__ import division, print_function
from fractions import Fraction
import sys
import os
from io import BytesIO, IOBase
from functools import cmp_to_key
from heapq import *
from math import gcd, factorial, floor, ceil, sqrt
from copy import deepcopy
from collections import deque
from bisect import bisect_left as bl
from bisect import bisect_right as br
from bisect import bisect
BUFSIZE = 8192

class FastIO(IOBase):
	newlines = 0

	def __init__(self, file):
		self._fd = file.fileno()
		self.buffer = BytesIO()
		self.writable = 'x' in file.mode or 'r' not in file.mode
		self.write = self.buffer.write if self.writable else None

	def read(self):
		while True:
			b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
			if not b:
				break
			ptr = self.buffer.tell()
			(self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
		self.newlines = 0
		return self.buffer.read()

	def readline(self):
		while self.newlines == 0:
			b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
			self.newlines = b.count(b'\n') + (not b)
			ptr = self.buffer.tell()
			(self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
		self.newlines -= 1
		return self.buffer.readline()

	def flush(self):
		if self.writable:
			os.write(self._fd, self.buffer.getvalue())
			(self.buffer.truncate(0), self.buffer.seek(0))

class IOWrapper(IOBase):

	def __init__(self, file):
		self.buffer = FastIO(file)
		self.flush = self.buffer.flush
		self.writable = self.buffer.writable
		self.write = lambda s: self.buffer.write(s.encode('ascii'))
		self.read = lambda : self.buffer.read().decode('ascii')
		self.readline = lambda : self.buffer.readline().decode('ascii')

def print(*args, **kwargs):
	(sep, file) = (kwargs.pop('sep', ' '), kwargs.pop('file', sys.stdout))
	at_start = True
	for x in args:
		if not at_start:
			file.write(sep)
		file.write(str(x))
		at_start = False
	file.write(kwargs.pop('end', '\n'))
	if kwargs.pop('flush', False):
		file.flush()
if sys.version_info[0] < 3:
	(sys.stdin, sys.stdout) = (FastIO(sys.stdin), FastIO(sys.stdout))
else:
	(sys.stdin, sys.stdout) = (IOWrapper(sys.stdin), IOWrapper(sys.stdout))
from types import GeneratorType

def iterative(f, stack=[]):

	def wrapped_func(*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)
				continue
			stack.pop()
			if not stack:
				break
			to = stack[-1].send(to)
		return to
	return wrapped_func

def inp():
	return sys.stdin.readline().rstrip('\r\n')

def out(var):
	sys.stdout.write(str(var))

def lis():
	return list(map(int, inp().split()))

def stringlis():
	return list(map(str, inp().split()))

def sep():
	return map(int, inp().split())

def strsep():
	return map(str, inp().split())

def testcase(t):
	for pp in range(t):
		solve(pp)

def google(p):
	print('Case #' + str(p) + ': ', end='')

def lcm(a, b):
	return a * b // gcd(a, b)

def power(x, y, p):
	y %= p - 1
	res = 1
	x = x % p
	if x == 0:
		return 0
	while y > 0:
		if y & 1 == 1:
			res = res * x % p
		y = y >> 1
		x = x * x % p
	return res

def ncr(n, r):
	return factorial(n) // (factorial(r) * factorial(max(n - r, 1)))

def isPrime(n):
	if n <= 1:
		return False
	if n <= 3:
		return True
	if n % 2 == 0 or n % 3 == 0:
		return False
	i = 5
	while i * i <= n:
		if n % i == 0 or n % (i + 2) == 0:
			return False
		i = i + 6
	return True
inf = pow(10, 20)
mod = 10 ** 9 + 7

class DisjointSetUnion:

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

	def find(self, a):
		acopy = a
		while a != self.parent[a]:
			a = self.parent[a]
		while acopy != a:
			(self.parent[acopy], acopy) = (a, self.parent[acopy])
		return a

	def union(self, a, b):
		(a, b) = (self.find(a), self.find(b))
		if a != b:
			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

def solve(case):
	(n, m) = sep()
	dsu = DisjointSetUnion(n)
	for i in range(m):
		a = lis()
		if a[0] < 2:
			continue
		a = a[1:]
		for j in range(len(a)):
			a[j] -= 1
		for j in range(1, len(a)):
			dsu.union(a[0], a[j])
	group = {}
	for i in range(n):
		if dsu.find(i) not in group:
			group[dsu.find(i)] = 1
		else:
			group[dsu.find(i)] += 1
	ans = []
	for i in range(n):
		ans.append(group[dsu.find(i)])
	print(' '.join((str(ans[i]) for i in range(n))))
testcase(1)


from sys import stdin, stdout
(n, m) = map(int, input().split())
g = [-i for i in range(n + 1)]
r = [1 for x in range(n + 1)]

def find(a):
	v = []
	while g[a] > 0:
		v.append(a)
		a = g[a]
	for i in v:
		g[i] = a
	return a

def merge(a, b):
	a = find(a)
	b = find(b)
	if r[a] > r[b]:
		g[b] = a
		r[a] += r[b]
	else:
		g[a] = b
		r[b] += r[a]
for group in stdin.read().split('\n'):
	if len(group) < 1:
		continue
	elif group[0] == '0':
		continue
	mem = [int(i) for i in group.split()]
	for i in range(2, len(mem)):
		if find(mem[i]) == find(mem[i - 1]):
			continue
		else:
			merge(mem[i], mem[i - 1])
cnt = [0] * (n + 1)
for i in range(1, n + 1):
	cnt[find(i)] += 1
print(' '.join(map(str, [cnt[find(i)] for i in range(1, n + 1)])))


import sys, bisect
from sys import stdin, stdout
from bisect import bisect_left, bisect_right, bisect, insort, insort_left, insort_right
from math import gcd, ceil, floor, sqrt
from collections import Counter, defaultdict, deque, OrderedDict
from queue import Queue, PriorityQueue
from string import ascii_lowercase
from heapq import *
from itertools import islice
sys.setrecursionlimit(10 ** 6)
INF = float('inf')
MOD = 998244353
mod = 10 ** 9 + 7

def isPrime(n):
	if n <= 1:
		return False
	if n <= 3:
		return True
	if n % 2 == 0 or n % 3 == 0:
		return False
	for i in range(5, ceil(sqrt(n)) + 1, 6):
		if n % i == 0 or n % (i + 2) == 0:
			return False
	return True

def st():
	return list(stdin.readline().strip())

def inp():
	return int(stdin.readline())

def li():
	return list(map(int, stdin.readline().split()))

def mp():
	return map(int, stdin.readline().split())

def pr(n):
	stdout.write(str(n) + '\n')

def DFS(dictionary, vertex, visited):
	visited[vertex] = True
	stack = [vertex]
	print(vertex)
	while stack:
		a = stack.pop()
		for i in dictionary[a]:
			if not visited[i]:
				print(i)
				visited[i] = True
				stack.append(i)

def BFS(dictionary, vertex, visited):
	visited[vertex] = True
	q = deque()
	q.append(vertex)
	while q:
		a = q.popleft()
		for i in dictionary[a]:
			if not visited[i]:
				visited[i] = True
				q.append(i)
				print(i)

def soe(limit):
	l = [1] * (limit + 1)
	l[0] = 0
	l[1] = 0
	prime = []
	for i in range(2, limit + 1):
		if l[i]:
			for j in range(i * i, limit + 1, i):
				l[j] = 0
	for i in range(2, limit + 1):
		if l[i]:
			prime.append(i)
	return prime

def segsoe(low, high):
	limit = int(high ** 0.5) + 1
	prime = soe(limit)
	n = high - low + 1
	l = [0] * (n + 1)
	for i in range(len(prime)):
		lowlimit = low // prime[i] * prime[i]
		if lowlimit < low:
			lowlimit += prime[i]
		if lowlimit == prime[i]:
			lowlimit += prime[i]
		for j in range(lowlimit, high + 1, prime[i]):
			l[j - low] = 1
	for i in range(low, high + 1):
		if not l[i - low]:
			if i != 1:
				print(i)

def gcd(a, b):
	while b:
		a = a % b
		(b, a) = (a, b)
	return a

def power(a, n):
	r = 1
	while n:
		if n & 1:
			r = r * a
		a *= a
		n = n >> 1
	return r

def don(d, ans, vi, i):
	vi[i] = i
	stack = [i]
	ans[i] = 1
	while stack:
		a = stack.pop()
		for x in d[a]:
			if vi[x] == -1:
				ans[i] += 1
				vi[x] = i
				stack.append(x)

def solve():
	(n, m) = mp()
	d = {i: [] for i in range(1, n + 1)}
	for _ in range(m):
		l = li()
		x = l[0]
		if x > 1:
			for i in range(1, x):
				d[l[i]].append(l[i + 1])
				d[l[i + 1]].append(l[i])
	ans = [-1 for i in range(n + 1)]
	vi = [-1 for i in range(n + 1)]
	for i in range(1, n + 1):
		if vi[i] == -1:
			vi[i] = i
			stack = [i]
			ans[i] = 1
			while stack:
				a = stack.pop()
				for x in d[a]:
					if vi[x] == -1:
						ans[i] += 1
						vi[x] = i
						stack.append(x)
	print(' '.join((str(ans[vi[i]]) for i in range(1, n + 1))))
for _ in range(1):
	solve()


from collections import defaultdict, Counter
from math import sqrt, log10, log2, log, gcd, floor, factorial
from bisect import bisect_left, bisect_right
from itertools import combinations, combinations_with_replacement
import sys, io, os
input = sys.stdin.readline
input = io.BytesIO(os.read(0, os.fstat(0).st_size)).readline
mod = 10 ** 9 + 7
inf = float('inf')

def get_list():
	return [int(i) for i in input().split()]
yn = lambda a: print('YES' if a else 'NO')
ceil = lambda a, b: (a + b - 1) // b

class DisjointSetUnion:

	def __init__(self, l=[]):
		self.parent = defaultdict(int)
		self.size = defaultdict(lambda : 1)
		self.num_sets = 0
		for i in l:
			self.add(i)

	def add(self, val):
		if val not in self.parent:
			self.parent[val] = val
			self.size[val] = 1
			self.num_sets += 1

	def find(self, a):
		acopy = a
		while a != self.parent[a]:
			a = self.parent[a]
		while acopy != a:
			(self.parent[acopy], acopy) = (a, self.parent[acopy])
		return a

	def union(self, a, b):
		(a, b) = (self.find(a), self.find(b))
		if a != b:
			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]
			return 1
		return 0

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

	def __len__(self):
		return self.num_sets
t = 1
for i in range(t):
	(n, m) = get_list()
	l = []
	for i in range(m):
		l.append([int(i) for i in input().split()])
	seta = DisjointSetUnion([i for i in range(1, n + 1)])
	for i in l:
		for j in range(2, len(i)):
			seta.union(i[1], i[j])
	print(*[seta.set_size(i) for i in range(1, n + 1)])


import sys
input = sys.stdin.readline
(n, m) = map(int, input().split())
A = list(range(n + 1))

def find(x):
	while A[x] != x:
		A[x] = A[A[x]]
		x = A[x]
	return x
for _ in range(m):
	line = input().split()[1:]
	if line:
		V = [int(j) for j in line]
		k = find(V[0])
		for v in V[1:]:
			A[find(v)] = k
count = [0] * (n + 1)
for i in range(1, n + 1):
	count[find(i)] += 1
print(' '.join(map(str, [count[find(i)] for i in range(1, n + 1)])))


import sys
input = sys.stdin.readline

def get_set_of(a):
	parent = parents[a]
	if parent == a:
		return a
	while True:
		grandparent = parents[parent]
		if grandparent == parent:
			return parent
		parents[a] = grandparent
		a = parent
		parent = grandparent

def merge_sets(a, b):
	(set_a, set_b) = (get_set_of(a), get_set_of(b))
	if set_a == set_b:
		return False
	if ranks[set_a] == ranks[set_b]:
		ranks[set_a] += 1
	elif ranks[set_a] < ranks[set_b]:
		(set_a, set_b) = (set_b, set_a)
	parents[set_b] = set_a
	sizes[set_a] += sizes[set_b]
	sizes[set_b] = 0
	return True
(numelems, m) = map(int, input().split())
parents = list(range(numelems))
ranks = [0] * numelems
sizes = [1] * numelems
for _ in range(m):
	l = list(map(lambda x: int(x) - 1, input().split()))[1:]
	for i in range(1, len(l)):
		merge_sets(l[i], l[0])
print(' '.join(map(str, [sizes[get_set_of(i)] for i in range(numelems)])))


from collections import defaultdict
from collections import Counter
import math
import sys
import os
from io import BytesIO, IOBase
BUFSIZE = 8192

class FastIO(IOBase):
	newlines = 0

	def __init__(self, file):
		self._fd = file.fileno()
		self.buffer = BytesIO()
		self.writable = 'x' in file.mode or 'r' not in file.mode
		self.write = self.buffer.write if self.writable else None

	def read(self):
		while True:
			b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
			if not b:
				break
			ptr = self.buffer.tell()
			(self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
		self.newlines = 0
		return self.buffer.read()

	def readline(self):
		while self.newlines == 0:
			b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
			self.newlines = b.count(b'\n') + (not b)
			ptr = self.buffer.tell()
			(self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
		self.newlines -= 1
		return self.buffer.readline()

	def flush(self):
		if self.writable:
			os.write(self._fd, self.buffer.getvalue())
			(self.buffer.truncate(0), self.buffer.seek(0))

class IOWrapper(IOBase):

	def __init__(self, file):
		self.buffer = FastIO(file)
		self.flush = self.buffer.flush
		self.writable = self.buffer.writable
		self.write = lambda s: self.buffer.write(s.encode('ascii'))
		self.read = lambda : self.buffer.read().decode('ascii')
		self.readline = lambda : self.buffer.readline().decode('ascii')
(sys.stdin, sys.stdout) = (IOWrapper(sys.stdin), IOWrapper(sys.stdout))
input = lambda : sys.stdin.readline().rstrip('\r\n')

def listt():
	return [int(i) for i in input().split()]

def gcd(a, b):
	return math.gcd(a, b)

def lcm(a, b):
	return a * b // gcd(a, b)

def factors(n):
	step = 2 if n % 2 else 1
	return set(reduce(list.__add__, ([i, n // i] for i in range(1, int(math.sqrt(n)) + 1, step) if n % i == 0)))

def comb(n, k):
	factn = math.factorial(n)
	factk = math.factorial(k)
	fact = math.factorial(n - k)
	ans = factn // (factk * fact)
	return ans

def is_prime(n):
	if n <= 1:
		return False
	if n == 2:
		return True
	if n > 2 and n % 2 == 0:
		return False
	max_div = math.floor(math.sqrt(n))
	for i in range(3, 1 + max_div, 2):
		if n % i == 0:
			return False
	return True

def maxpower(n, x):
	B_max = int(math.log(n, x))
	return B_max

def binaryToDecimal(n):
	return int(n, 2)
parent = {}
rank = {}
l = []
parent = {}

def find(x):
	lii = []
	while parent[x] != x:
		lii.append(x)
		x = parent[x]
	for i in lii:
		parent[i] = x
	return x

def union(a, b):
	a = find(a)
	b = find(b)
	if a == b:
		return
	if rank[a] > rank[b]:
		parent[b] = a
		rank[a] += rank[b]
	else:
		parent[a] = b
		rank[b] += rank[a]
t = 1
for i in range(t):
	(n, m) = map(int, input().split())
	for i in range(1, n + 1):
		parent[i] = i
		rank[i] = 1
	for i in range(m):
		l = listt()
		if l[0] > 1:
			for i in range(2, l[0] + 1):
				union(l[i], l[i - 1])
	for i in range(1, n + 1):
		print(rank[find(i)], end=' ')
	print()


from sys import stdin

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

def solve():
	(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)])))
solve()


import sys
input = sys.stdin.readline
from math import log2, log, ceil

def swaparr(arr, a, b):
	temp = arr[a]
	arr[a] = arr[b]
	arr[b] = temp

def gcd(a, b):
	if a == 0:
		return b
	return gcd(b % a, a)

def nCr(n, k):
	if k > n - k:
		k = n - k
	res = 1
	for i in range(k):
		res = res * (n - i)
		res = res / (i + 1)
	return res

def upper_bound(a, x, lo=0):
	hi = len(a)
	while lo < hi:
		mid = (lo + hi) // 2
		if a[mid] < x:
			lo = mid + 1
		else:
			hi = mid
	return lo

def primefs(n):
	primes = {}
	while n % 2 == 0:
		primes[2] = primes.get(2, 0) + 1
		n = n // 2
	for i in range(3, int(n ** 0.5) + 2, 2):
		while n % i == 0:
			primes[i] = primes.get(i, 0) + 1
			n = n // i
	if n > 2:
		primes[n] = primes.get(n, 0) + 1
	return primes

def power(x, y, p):
	res = 1
	x = x % p
	if x == 0:
		return 0
	while y > 0:
		if y & 1 == 1:
			res = res * x % p
		y = y >> 1
		x = x * x % p
	return res

def swap(a, b):
	temp = a
	a = b
	b = temp
	return (a, b)

def find(x, link):
	if link[x] == x:
		return x
	link[x] = find(link[x], link)
	return link[x]

def union(x, y, link, size):
	x = find(x, link)
	y = find(y, link)
	if size[x] < size[y]:
		(x, y) = swap(x, y)
	if x != y:
		size[x] += size[y]
		link[y] = x

def sieve(n):
	prime = [True for i in range(n + 1)]
	p = 2
	while p * p <= n:
		if prime[p] == True:
			for i in range(p * p, n + 1, p):
				prime[i] = False
		p += 1
	return prime
MAXN = int(1000000.0 + 5)

def spf_sieve():
	spf[1] = 1
	for i in range(2, MAXN):
		spf[i] = i
	for i in range(4, MAXN, 2):
		spf[i] = 2
	for i in range(3, ceil(MAXN ** 0.5), 2):
		if spf[i] == i:
			for j in range(i * i, MAXN, i):
				if spf[j] == j:
					spf[j] = i

def factoriazation(x):
	ret = {}
	while x != 1:
		ret[spf[x]] = ret.get(spf[x], 0) + 1
		x = x // spf[x]
	return ret

def int_array():
	return list(map(int, input().strip().split()))

def str_array():
	return input().strip().split()
MOD = int(1000000000.0) + 7
CMOD = 998244353
INF = float('inf')
NINF = -float('inf')
(n, m) = int_array()
link = [i for i in range(n)]
size = [1] * n
for _ in range(m):
	arr = int_array()
	if arr[0] < 2:
		continue
	for i in range(2, len(arr)):
		union(arr[i - 1] - 1, arr[i] - 1, link, size)
info = []
dick = {}
for i in range(n):
	info.append(find(link[i], link))
for i in info:
	dick[i] = dick.get(i, 0) + 1
for i in info:
	print(dick[i], end=' ')


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, stdout

def find(node):
	if dsu[node] == node:
		return node
	else:
		dsu[node] = find(dsu[node])
		return dsu[node]
(n, m) = map(int, stdin.readline().strip().split())
dsu = [i for i in range(n + 1)]
for i in range(m):
	arr = list(map(int, stdin.readline().strip().split()))
	if arr[0] != 0:
		prev_parent = find(arr[1])
		for i in arr[2:]:
			dsu[find(i)] = prev_parent
outputs = []
stat = [0] * (n + 1)
for i in range(1, n + 1):
	stat[find(i)] += 1
for i in range(1, n + 1):
	outputs.append(stat[find(i)])
print(*outputs)


from sys import stdin, stdout
(n, m) = map(int, stdin.readline().split())
p = [i for i in range(n)]
r = [0 for i in range(n)]

def find_s(v):
	if v == p[v]:
		return v
	p[v] = find_s(p[v])
	return p[v]

def un_s(a, b):
	a = find_s(a)
	b = find_s(b)
	if a != b:
		if r[a] < r[b]:
			(a, b) = (b, a)
		p[b] = a
		if r[a] == r[b]:
			r[a] += 1
for i in range(m):
	s = list(map(int, stdin.readline().split()))
	for w in range(2, len(s)):
		un_s(s[1] - 1, s[w] - 1)
r = [0 for i in range(n + 1)]
for i in range(n):
	r[find_s(i)] += 1
ans = []
for i in range(n):
	ans.append(str(r[p[i]]))
print(' '.join(ans))


import sys
(n, m) = map(int, input().split())
parent = [i for i in range(n + 1)]
tamanho = [1 for i in range(n + 1)]

def find(u):
	if u == parent[u]:
		return u
	parent[u] = find(parent[u])
	return parent[u]

def union(u, v):
	p_u = find(u)
	p_v = find(v)
	if p_u != p_v:
		if tamanho[p_u] > tamanho[p_v]:
			parent[p_v] = p_u
			tamanho[p_u] += tamanho[p_v]
		else:
			parent[p_u] = p_v
			tamanho[p_v] += tamanho[p_u]
for entrada in sys.stdin.readlines():
	g = list(map(int, entrada.split()))
	i = 1
	j = 2
	while j < len(g):
		union(g[i], g[j])
		j += 1
for i in range(1, n + 1):
	pai = find(i)
	print(tamanho[pai], end=' ')


import sys
input = sys.stdin.readline
(n, m) = map(int, input().split())
FR = [list(map(int, input().split())) for i in range(m)]
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
from typing import Any

def solution_uf_1():

	class UF:

		def __init__(self, n: int) -> None:
			self.parent = list(range(n + 1))
			self.rank = [1] * (n + 1)
			self.count = n

		def find(self, p: Any):
			while p != self.parent[p]:
				p = self.parent[p]
			return p

		def connected(self, p: Any, q: Any):
			return self.find(p) == self.find(q)

		def union(self, p: Any, q: Any):
			root_p = self.find(p)
			root_q = self.find(q)
			if root_p == root_q:
				return
			if self.rank[root_p] > self.rank[root_q]:
				(root_p, root_q) = (root_q, root_p)
			self.parent[root_p] = root_q
			self.rank[root_q] += self.rank[root_p]
	(n, m) = map(int, input().split())
	uf = UF(n)
	for i in range(m):
		a = list(map(int, sys.stdin.readline().split()))
		for j in range(1, a[0]):
			uf.union(a[1], a[j + 1])
	print(' '.join(map(str, (uf.rank[uf.find(i)] for i in range(1, n + 1)))))
solution_uf_1()


import sys
from math import sqrt, gcd, ceil, log
inp = sys.stdin.readline
read = lambda : list(map(int, inp().strip().split()))

def main():

	def find(p):
		while par[p] != p:
			par[p] = par[par[p]]
			p = par[p]
		return p
	(n, m) = read()
	par = list(range(n + 1))
	for i in range(m):
		grp = read()[1:]
		if grp:
			p = find(grp[0])
			for j in grp[1:]:
				par[find(j)] = p
	ans = ''
	cnt = [0] * (n + 1)
	for i in range(1, n + 1):
		cnt[find(i)] += 1
	print(' '.join(map(str, [cnt[find(i)] for i in range(1, n + 1)])))
main()


import os
import re
import sys
from bisect import bisect, bisect_left, insort, insort_left
from collections import Counter, defaultdict, deque
from copy import deepcopy
from decimal import Decimal
from fractions import gcd
from io import BytesIO, IOBase
from itertools import accumulate, combinations, combinations_with_replacement, groupby, permutations, product
from math import acos, asin, atan, ceil, cos, degrees, factorial, hypot, log2, pi, radians, sin, sqrt, tan
from operator import itemgetter, mul
from string import ascii_lowercase, ascii_uppercase, digits

def inp():
	return int(input())

def inlist():
	return list(map(int, input().split()))

def instr():
	s = input()
	return list(s[:len(s)])

def invr():
	return map(int, input().split())
BUFSIZE = 8192

class FastIO(IOBase):
	newlines = 0

	def __init__(self, file):
		self._fd = file.fileno()
		self.buffer = BytesIO()
		self.writable = 'x' in file.mode or 'r' not in file.mode
		self.write = self.buffer.write if self.writable else None

	def read(self):
		while True:
			b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
			if not b:
				break
			ptr = self.buffer.tell()
			(self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
		self.newlines = 0
		return self.buffer.read()

	def readline(self):
		while self.newlines == 0:
			b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
			self.newlines = b.count(b'\n') + (not b)
			ptr = self.buffer.tell()
			(self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
		self.newlines -= 1
		return self.buffer.readline()

	def flush(self):
		if self.writable:
			os.write(self._fd, self.buffer.getvalue())
			(self.buffer.truncate(0), self.buffer.seek(0))

class IOWrapper(IOBase):

	def __init__(self, file):
		self.buffer = FastIO(file)
		self.flush = self.buffer.flush
		self.writable = self.buffer.writable
		self.write = lambda s: self.buffer.write(s.encode('ascii'))
		self.read = lambda : self.buffer.read().decode('ascii')
		self.readline = lambda : self.buffer.readline().decode('ascii')
(sys.stdin, sys.stdout) = (IOWrapper(sys.stdin), IOWrapper(sys.stdout))

def input():
	return sys.stdin.readline().rstrip('\r\n')

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

def union(a, b):
	x = find(a)
	y = find(b)
	if x == y:
		return
	par[x] += par[y]
	par[y] = x
(n, m) = invr()
par = [-1] * (n + 1)
for _ in range(m):
	temp = inlist()
	l = temp[0]
	for i in range(1, l):
		union(temp[i], temp[i + 1])
res = []
for i in range(1, n + 1):
	res.append(abs(par[find(i)]))
print(*res)


import sys
inf = float('inf')
(mod, MOD) = (1000000007, 998244353)

def get_array():
	return list(map(int, sys.stdin.readline().strip().split()))

def get_ints():
	return map(int, sys.stdin.readline().strip().split())

def input():
	return sys.stdin.readline().strip()

class DisjointSetUnion:

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

	def find(self, a):
		acopy = a
		while a != self.parent[a]:
			a = self.parent[a]
		while acopy != a:
			(self.parent[acopy], acopy) = (a, self.parent[acopy])
		return a

	def union(self, a, b):
		(a, b) = (self.find(a), self.find(b))
		if a == b:
			return
		if a != b:
			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) = get_ints()
obj = DisjointSetUnion(n)
for i in range(m):
	(sz, *A) = [int(x) - 1 for x in input().split()]
	sz += 1
	for j in range(1, sz):
		(prev, curr) = (A[j - 1], A[j])
		obj.union(prev, curr)
result = []
for i in range(n):
	result.append(obj.set_size(i))
print(*result)


import sys, os, io

def rs():
	return sys.stdin.readline().rstrip()

def ri():
	return int(sys.stdin.readline())

def ria():
	return list(map(int, sys.stdin.readline().split()))

def ws(s):
	sys.stdout.write(s + '\n')

def wi(n):
	sys.stdout.write(str(n) + '\n')

def wia(a):
	sys.stdout.write(' '.join([str(x) for x in a]) + '\n')
import math, datetime, functools, itertools, operator, bisect, fractions, statistics
from collections import deque, defaultdict, OrderedDict, Counter
from fractions import Fraction
from decimal import Decimal
from sys import stdout
from heapq import heappush, heappop, heapify, _heapify_max, _heappop_max, nsmallest, nlargest
sys.setrecursionlimit(111111)
INF = 99999999999999999999999999999999

def main():
	mod = 1000000007
	starttime = datetime.datetime.now()
	if os.path.exists('input.txt'):
		sys.stdin = open('input.txt', 'r')
		sys.stdout = open('output.txt', 'w')
	tc = 1
	for _ in range(tc):
		(n, m) = ria()
		visited = [False] * (n + 1)
		graph = [[] for i in range(n + 1)]
		for i in range(m):
			a = ria()
			na = a[0]
			if na >= 2:
				for j in range(1, len(a) - 1):
					graph[a[j]].append(a[j + 1])
					graph[a[j + 1]].append(a[j])
		ans = [0] * (n + 1)

		def dfs(graph, start=0):
			n = len(graph)
			stack = [start]
			out = []
			t = 0
			while stack:
				start = stack[-1]
				if not visited[start]:
					out.append(start)
					visited[start] = True
					for child in graph[start]:
						if not visited[child]:
							stack.append(child)
				else:
					stack.pop()
			return out
		for i in range(1, n + 1):
			if not visited[i]:
				group = dfs(graph, i)
				for i in group:
					ans[i] = len(group)
		wia(ans[1:])
	endtime = datetime.datetime.now()
	time = (endtime - starttime).total_seconds() * 1000
	if os.path.exists('input.txt'):
		print('Time:', time, 'ms')

class FastReader(io.IOBase):
	newlines = 0

	def __init__(self, fd, chunk_size=1024 * 8):
		self._fd = fd
		self._chunk_size = chunk_size
		self.buffer = io.BytesIO()

	def read(self):
		while True:
			b = os.read(self._fd, max(os.fstat(self._fd).st_size, self._chunk_size))
			if not b:
				break
			ptr = self.buffer.tell()
			(self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
		self.newlines = 0
		return self.buffer.read()

	def readline(self, size=-1):
		while self.newlines == 0:
			b = os.read(self._fd, max(os.fstat(self._fd).st_size, self._chunk_size if size == -1 else size))
			self.newlines = b.count(b'\n') + (not b)
			ptr = self.buffer.tell()
			(self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
		self.newlines -= 1
		return self.buffer.readline()

class FastWriter(io.IOBase):

	def __init__(self, fd):
		self._fd = fd
		self.buffer = io.BytesIO()
		self.write = self.buffer.write

	def flush(self):
		os.write(self._fd, self.buffer.getvalue())
		(self.buffer.truncate(0), self.buffer.seek(0))

class FastStdin(io.IOBase):

	def __init__(self, fd=0):
		self.buffer = FastReader(fd)
		self.read = lambda : self.buffer.read().decode('ascii')
		self.readline = lambda : self.buffer.readline().decode('ascii')

class FastStdout(io.IOBase):

	def __init__(self, fd=1):
		self.buffer = FastWriter(fd)
		self.write = lambda s: self.buffer.write(s.encode('ascii'))
		self.flush = self.buffer.flush
sys.stdin = FastStdin()
sys.stdout = FastStdout()
main()


from sys import stdin
ii = lambda : int(input())
mi = lambda : map(int, input().split())
li = lambda : list(mi())
si = lambda : input()
msi = lambda : map(int, stdin.readline().split())
lsi = lambda : list(msi())

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

def solve():
	(n, m) = map(int, stdin.readline().split())
	S = list(range(n + 1))
	for _ in range(m):
		group = [int(k) for k in stdin.readline().split()][1:]
		for x in group[1:]:
			S[find(S, x)] = find(S, group[0])
	cnt = [0] * (n + 1)
	for i in range(1, n + 1):
		cnt[find(S, i)] += 1
	print(' '.join(map(str, [cnt[find(S, i)] for i in range(1, n + 1)])))
solve()


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

def solve():
	(n, m) = map(int, input().split())
	from sys import stdin
	parent = {i: i for i in range(1, n + 1)}
	for _ in range(m):
		k = [*map(int, stdin.readline().split()[1:])]
		if k != []:
			p = find_parent(k[0], parent)
			for (i, x) in enumerate(k[1:]):
				parent[find_parent(x, parent)] = p
	cnt = {i: 0 for i in range(1, n + 1)}
	for i in range(1, n + 1):
		cnt[find_parent(i, parent)] += 1
	print(' '.join(map(str, [cnt[find_parent(i, parent)] for i in range(1, n + 1)])))
solve()


from sys import stdin
input = stdin.readline

def find(x):
	while x != link[x]:
		x = link[x]
	return x
(n, m) = map(int, input().split())
link = [i for i in range(n + 1)]
size = [1] * (n + 1)
for i in range(m):
	k = list(map(int, input().split()))[1:]
	if not k:
		continue
	t = find(k[0])
	for i in k[1:]:
		i = find(i)
		if t != i:
			if size[t] < size[i]:
				(t, i) = (i, t)
			link[i] = t
			size[t] += size[i]
for i in range(1, n + 1):
	i = find(i)
	print(size[i], end=' ')


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()
main()


import sys
input = sys.stdin.readline
(n, m) = map(int, input().split())
g = [[] for _ in range(n)]
for i in range(m):
	(k, *group) = map(int, input().split())
	for i in range(1, k):
		(u, v) = (group[i - 1] - 1, group[i] - 1)
		g[u].append(v)
		g[v].append(u)
	if k > 1:
		(u, v) = (group[0] - 1, group[-1] - 1)
		g[u].append(v)
		g[v].append(u)
cs = [-1 for _ in range(n)]
for i in range(n):
	if cs[i] == -1:
		cs[i] = 0
		q = [i]
		(j, lq) = (0, 1)
		while j < lq:
			for t in g[q[j]]:
				if cs[t] == -1:
					q.append(t)
					cs[t] = 0
					lq += 1
			j += 1
		for qi in q:
			cs[qi] = lq
print(*cs)


import sys
import math
import heapq
import bisect
from collections import Counter
from collections import defaultdict
from io import BytesIO, IOBase
import string

class FastIO(IOBase):
	newlines = 0

	def __init__(self, file):
		import os
		self.os = os
		self._fd = file.fileno()
		self.buffer = BytesIO()
		self.writable = 'x' in file.mode or 'r' not in file.mode
		self.write = self.buffer.write if self.writable else None
		self.BUFSIZE = 8192

	def read(self):
		while True:
			b = self.os.read(self._fd, max(self.os.fstat(self._fd).st_size, self.BUFSIZE))
			if not b:
				break
			ptr = self.buffer.tell()
			(self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
		self.newlines = 0
		return self.buffer.read()

	def readline(self):
		while self.newlines == 0:
			b = self.os.read(self._fd, max(self.os.fstat(self._fd).st_size, self.BUFSIZE))
			self.newlines = b.count(b'\n') + (not b)
			ptr = self.buffer.tell()
			(self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
		self.newlines -= 1
		return self.buffer.readline()

	def flush(self):
		if self.writable:
			self.os.write(self._fd, self.buffer.getvalue())
			(self.buffer.truncate(0), self.buffer.seek(0))

class IOWrapper(IOBase):

	def __init__(self, file):
		self.buffer = FastIO(file)
		self.flush = self.buffer.flush
		self.writable = self.buffer.writable
		self.write = lambda s: self.buffer.write(s.encode('ascii'))
		self.read = lambda : self.buffer.read().decode('ascii')
		self.readline = lambda : self.buffer.readline().decode('ascii')
(sys.stdin, sys.stdout) = (IOWrapper(sys.stdin), IOWrapper(sys.stdout))
input = lambda : sys.stdin.readline().rstrip('\r\n')

def get_int():
	return int(input())

def get_ints():
	return list(map(int, input().split(' ')))

def get_int_grid(n):
	return [get_ints() for _ in range(n)]

def get_str():
	return input().split(' ')

def yes_no(b):
	if b:
		return 'YES'
	else:
		return 'NO'

def binary_search(good, left, right, delta=1, right_true=False):
	limits = [left, right]
	while limits[1] - limits[0] > delta:
		if delta == 1:
			mid = sum(limits) // 2
		else:
			mid = sum(limits) / 2
		if good(mid):
			limits[int(right_true)] = mid
		else:
			limits[int(~right_true)] = mid
	if good(limits[int(right_true)]):
		return limits[int(right_true)]
	else:
		return False

def prefix_sums(a, drop_zero=False):
	p = [0]
	for x in a:
		p.append(p[-1] + x)
	if drop_zero:
		return p[1:]
	else:
		return p

def prefix_mins(a, drop_zero=False):
	p = [float('inf')]
	for x in a:
		p.append(min(p[-1], x))
	if drop_zero:
		return p[1:]
	else:
		return p

class DSU:

	def __init__(self, nodes):
		self.p = [i for i in range(nodes)]
		self.r = [0 for i in range(nodes)]
		self.s = [1 for i in range(nodes)]

	def get(self, u):
		if u != self.p[u]:
			self.p[u] = self.get(self.p[u])
		return self.p[u]

	def union(self, u, v):
		u = self.get(u)
		v = self.get(v)
		if u != v:
			if self.r[u] > self.r[v]:
				(u, v) = (v, u)
			self.p[u] = v
			if self.r[u] == self.r[v]:
				self.r[v] += 1
			self.s[v] += self.s[u]

	def size(self, u):
		return self.s[self.get(u)]

def solve_c():
	(n, m) = get_ints()
	dsu = DSU(n)
	for group in range(m):
		(k, *g) = get_ints()
		for p in range(1, k):
			dsu.union(g[0] - 1, g[p] - 1)
	return [dsu.size(v) for v in range(n)]
print(*solve_c())


import sys
input = lambda : sys.stdin.readline().rstrip('\r\n')

class DSU(object):

	def __init__(self, n):
		self.parent = [i for i in range(n)]
		self.rank = [1] * n
		self.cycle = False

	def find(self, key):
		if self.parent[key] != key:
			self.parent[key] = self.find(self.parent[key])
		return self.parent[key]

	def union(self, a, b):
		(s1, s2) = (self.find(a), self.find(b))
		if s1 != s2:
			if self.rank[s1] < self.rank[s2]:
				self.parent[s1] = s2
				self.rank[s2] += self.rank[s1]
			else:
				self.parent[s2] = s1
				self.rank[s1] += self.rank[s2]
		else:
			self.cycle = True

	@property
	def has_cycle(self):
		return self.cycle

	@property
	def get_parent(self):
		return self.parent

	@property
	def get_rank(self):
		return self.rank

def solve():
	(n, m) = map(int, input().split())
	d = DSU(n + 1)
	for _ in range(m):
		a = list(map(int, input().split()))
		if a[0] != 0:
			for i in range(2, a[0] + 1):
				d.union(a[i - 1], a[i])
	for i in range(1, n + 1):
		print(d.get_rank[d.find(i)], end=' ')
	print()
solve()


from sys import stdout, stdin, setrecursionlimit
from io import BytesIO, IOBase
from collections import *
from itertools import *
from bisect import *
from string import *
from queue import *
from heapq import *
from math import *
from re import *
from os import *

class FastIO(IOBase):
	newlines = 0

	def __init__(self, file):
		self._fd = file.fileno()
		self.buffer = BytesIO()
		self.writable = 'x' in file.mode or 'r' not in file.mode
		self.write = self.buffer.write if self.writable else None

	def read(self):
		while True:
			b = read(self._fd, max(fstat(self._fd).st_size, 8192))
			if not b:
				break
			ptr = self.buffer.tell()
			(self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
		self.newlines = 0
		return self.buffer.read()

	def readline(self):
		while self.newlines == 0:
			b = read(self._fd, max(fstat(self._fd).st_size, 8192))
			self.newlines = b.count(b'\n') + (not b)
			ptr = self.buffer.tell()
			(self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
		self.newlines -= 1
		return self.buffer.readline()

	def flush(self):
		if self.writable:
			write(self._fd, self.buffer.getvalue())
			(self.buffer.truncate(0), self.buffer.seek(0))

class IOWrapper(IOBase):

	def __init__(self, file):
		self.buffer = FastIO(file)
		self.flush = self.buffer.flush
		self.writable = self.buffer.writable
		self.write = lambda s: self.buffer.write(s.encode('ascii'))
		self.read = lambda : self.buffer.read().decode('ascii')
		self.readline = lambda : self.buffer.readline().decode('ascii')
(stdin, stdout) = (IOWrapper(stdin), IOWrapper(stdout))
(graph, mod, szzz) = ({}, 10 ** 9 + 7, lambda : sorted(zzz()))

def getStr():
	return input()

def getInt():
	return int(input())

def listStr():
	return list(input())

def getStrs():
	return input().split()

def isInt(s):
	return '0' <= s[0] <= '9'

def input():
	return stdin.readline().strip()

def zzz():
	return [int(i) for i in input().split()]

def output(answer, end='\n'):
	stdout.write(str(answer) + end)

def lcd(xnum1, xnum2):
	return xnum1 * xnum2 // gcd(xnum1, xnum2)
dx = [-1, 1, 0, 0, 1, -1, 1, -1]
dy = [0, 0, 1, -1, 1, -1, -1, 1]
daysInMounth = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
(n, k) = zzz()
for i in range(n):
	graph[i + 1] = []
for i in range(k):
	l1 = zzz()
	if l1[0] > 1:
		for i in range(2, l1[0] + 1):
			t = l1[i]
			graph[l1[1]].append(t)
			graph[t].append(l1[1])

def bfs(start, n, visited, out):
	count = 0
	l2 = [i + 1]
	q = [i + 1]
	q = deque(q)
	count += 1
	visited[i] = 1
	while len(q) != 0:
		y = graph[q[0]]
		for j in y:
			if visited[j - 1] == 0:
				visited[j - 1] = 1
				l2.append(j)
				q.append(j)
				count += 1
		q.popleft()
	for k in l2:
		out[k - 1] = count
visited = [0] * n
out = [0] * n
for i in range(n):
	if visited[i] == 0:
		bfs(i, n, visited, out)
for i in out:
	print(i, end=' ')


from sys import stdin, stdout, setrecursionlimit
import threading

class Tail_Recursion_Optimization:

	def __init__(self, RECURSION_LIMIT, STACK_SIZE):
		setrecursionlimit(RECURSION_LIMIT)
		threading.stack_size(STACK_SIZE)
		return None

class SOLVE:

	def dfs(self, u, ancestor, node, parent):
		parent[u] = ancestor
		total = 1
		for v in node[u]:
			if parent[v] == None:
				total += self.dfs(v, ancestor, node, parent)
		return total

	def solve(self):
		R = stdin.readline
		W = stdout.write
		ans = []
		(n, m) = [int(x) for x in R().split()]
		node = [[] for i in range(n + 1)]
		for i in range(m):
			a = [int(x) for x in R().split()]
			if a[0] > 1:
				for j in range(2, a[0] + 1):
					node[a[1]].append(a[j])
					node[a[j]].append(a[1])
		dsu = {}
		parent = [None for i in range(n + 1)]
		for i in range(1, n + 1):
			if parent[i] == None:
				dsu[i] = self.dfs(i, i, node, parent)
		for i in range(1, n + 1):
			ans.append(str(dsu[parent[i]]))
		W(' '.join(ans))
		return 0

def main():
	s = SOLVE()
	s.solve()
Tail_Recursion_Optimization(10 ** 7, 2 ** 26)
threading.Thread(target=main).start()


import sys, collections
input = sys.stdin.readline
import collections

def ExeBfs(edges, n, sv, visited, q):
	A = collections.deque([sv])
	visited[sv] = True
	while A:
		front = A.popleft()
		q.append(front)
		for i in edges[front]:
			if visited[i] == False:
				A.append(i)
				visited[i] = True

def bfss(edges, n):
	visited = [False] * n
	for i in range(n):
		if visited[i] == False:
			q = []
			ExeBfs(edges, n, i, visited, q)
			a = len(q)
			for i in q:
				ans[i] = a
	print(*ans)
(n, m) = map(int, input().split())
ans = [0] * n
adj_list = [[] for _ in range(n)]
for _ in range(m):
	l = list(map(int, input().split()))
	if l[0] > 1:
		k = l[1] - 1
		for j in l[2:]:
			j -= 1
			adj_list[k].append(j)
			adj_list[j].append(k)
bfss(adj_list, n)


from math import *
from copy import *
from string import *
from random import *
from sys import stdin
from sys import maxsize
from operator import *
from itertools import *
from collections import Counter
from collections import defaultdict

class DSU:

	def __init__(self, n):
		self.n = n
		self.par = list(range(self.n))
		self.size = [1 for i in range(self.n)]

	def find(self, i):
		while i != self.par[i]:
			self.par[i] = self.par[self.par[i]]
			i = self.par[i]
		return i

	def unite(self, a, b):
		par_a = self.find(a)
		par_b = self.find(b)
		if par_a == par_b:
			return False
		else:
			if par_a <= par_b:
				self.par[par_b] = par_a
				self.size[par_a] += self.size[par_b]
				self.size[par_b] = 0
			else:
				self.par[par_a] = par_b
				self.size[par_b] += self.size[par_a]
				self.size[par_a] = 0
			return True

	def same(self, a, b):
		return self.par[a] == self.par[b]

	def size(self, a):
		return self.size[a]
(N, M) = map(int, stdin.readline().rstrip().split())
groups = {}
for _ in range(M):
	l = list(map(int, stdin.readline().rstrip().split()))[1:]
	groups[_] = l
dsu = DSU(N)
for i in groups:
	l = groups[i]
	for ii in range(1, len(l)):
		dsu.unite(l[ii] - 1, l[ii - 1] - 1)
spread = [0] * N
for i in range(N):
	spread[i] = dsu.size[dsu.find(i)]
print(*spread)


import sys

def find(x):
	if x == parent[x]:
		return x
	parent[x] = find(parent[x])
	return parent[x]
input = sys.stdin.readline
(n, m) = map(int, input().split())
ans = [0] * (n + 1)
parent = [i for i in range(n + 1)]
for i in range(m):
	A = list(map(int, input().split()))
	if A[0] != 0:
		a = find(A[1])
		for j in A[2:]:
			b = find(j)
			if b != a:
				parent[b] = parent[a]
for i in range(1, n + 1):
	ans[find(i)] += 1
for i in range(1, n + 1):
	print(ans[parent[i]], end=' ')


import sys, os
from io import BytesIO, IOBase
from math import floor, gcd, fabs, factorial, fmod, sqrt, inf, log
from collections import defaultdict as dd, deque
from heapq import merge, heapify, heappop, heappush, nsmallest
from bisect import bisect_left as bl, bisect_right as br, bisect
BUFSIZE = 8192

class FastIO(IOBase):
	newlines = 0

	def __init__(self, file):
		self._fd = file.fileno()
		self.buffer = BytesIO()
		self.writable = 'x' in file.mode or 'r' not in file.mode
		self.write = self.buffer.write if self.writable else None

	def read(self):
		while True:
			b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
			if not b:
				break
			ptr = self.buffer.tell()
			(self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
		self.newlines = 0
		return self.buffer.read()

	def readline(self):
		while self.newlines == 0:
			b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
			self.newlines = b.count(b'\n') + (not b)
			ptr = self.buffer.tell()
			(self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
		self.newlines -= 1
		return self.buffer.readline()

	def flush(self):
		if self.writable:
			os.write(self._fd, self.buffer.getvalue())
			(self.buffer.truncate(0), self.buffer.seek(0))

class IOWrapper(IOBase):

	def __init__(self, file):
		self.buffer = FastIO(file)
		self.flush = self.buffer.flush
		self.writable = self.buffer.writable
		self.write = lambda s: self.buffer.write(s.encode('ascii'))
		self.read = lambda : self.buffer.read().decode('ascii')
		self.readline = lambda : self.buffer.readline().decode('ascii')
(stdin, stdout) = (IOWrapper(sys.stdin), IOWrapper(sys.stdout))
mod = pow(10, 9) + 7
mod2 = 998244353

def inp():
	return stdin.readline().strip()

def iinp():
	return int(inp())

def out(var, end='\n'):
	stdout.write(str(var) + '\n')

def outa(*var, end='\n'):
	stdout.write(' '.join(map(str, var)) + end)

def lmp():
	return list(mp())

def mp():
	return map(int, inp().split())

def l1d(n, val=0):
	return [val for i in range(n)]

def l2d(n, m, val=0):
	return [l1d(m, val) for j in range(n)]

def ceil(a, b):
	return (a + b - 1) // b
S1 = 'abcdefghijklmnopqrstuvwxyz'
S2 = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'

def isprime(x):
	if x <= 1:
		return False
	if x in (2, 3):
		return True
	if x % 2 == 0:
		return False
	for i in range(3, int(sqrt(x)) + 1, 2):
		if x % i == 0:
			return False
	return True

def find(x):
	while x != par[x]:
		par[x] = par[par[x]]
		x = par[x]
	return x
(n, m) = mp()
par = list(range(n + 1))
for i in range(m):
	group = lmp()[1:]
	for user in group[1:]:
		par[find(user)] = find(group[0])
size = dd(int)
for i in range(1, n + 1):
	size[find(i)] += 1
print(*[size[find(i)] for i in range(1, n + 1)])


def use_fast_io():
	import sys

	class InputStorage:

		def __init__(self, lines):
			lines.reverse()
			self.lines = lines

		def input_func(self):
			if self.lines:
				return self.lines.pop()
			else:
				return ''
	input_storage_obj = InputStorage(sys.stdin.readlines())
	return input_storage_obj.input_func
input = use_fast_io()
(n, m) = map(int, input().split())
from collections import defaultdict
graph = defaultdict(list)
for i in range(m):
	group = list(map(int, input().split()))[1:]
	for j in range(len(group) - 1):
		graph[group[j]].append(group[j + 1])
		graph[group[j + 1]].append(group[j])
cache = [-1] * (n + 1)
for i in range(1, n + 1):
	if cache[i] == -1:
		queue = []
		visited = {i}
		queue.extend(graph[i])
		while queue:
			item = queue.pop()
			if item not in visited:
				visited.add(item)
				queue.extend(graph[item])
		size = len(visited)
		for v in visited:
			cache[v] = size
print(*cache[1:])


from collections import deque
import sys
(n, m) = 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:
		p = d.popleft()
		b.append(p)
		for j in a[p]:
			if vis[j] == 0:
				d.append(j)
				vis[j] = 1
	l = len(b)
	for j in b:
		ans[j] = l
print(*ans[1:])


import sys, os, io
import math, bisect, operator
(inf, mod) = (float('inf'), 10 ** 9 + 7)
from itertools import groupby, accumulate
from heapq import heapify, heappop, heappush
from collections import deque, Counter, defaultdict
I = lambda : int(sys.stdin.buffer.readline())
Neo = lambda : list(map(int, sys.stdin.buffer.readline().split()))
G = defaultdict(list)

def addEdge(a, b):
	G[a].append(b)
	G[b].append(a)
(n, m) = Neo()
for i in range(m):
	A = Neo()
	if A[0] != 0:
		for j in range(1, len(A) - 1):
			addEdge(A[j], A[j + 1])
vis = [0] * (n + 1)

def dfs(node, Id):
	s = deque()
	count = 1
	s.append(node)
	vis[node] = Id
	while s:
		v = s.pop()
		for i in G.get(v, []):
			if not vis[i]:
				count += 1
				vis[i] = Id
				s.append(i)
	return count
Ans = {}
Id = 1
for i in range(1, n + 1):
	if not vis[i]:
		Ans[Id] = dfs(i, Id)
		Id += 1
for i in range(1, n + 1):
	print(Ans[vis[i]], end=' ')


from types import GeneratorType
import io, os, sys
input = io.BytesIO(os.read(0, os.fstat(0).st_size)).readline

def bootstrap(f, stack=[]):

	def wrappedfunc(*args, **kwargs):
		if stack:
			return f(*args, **kwargs)
		else:
			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, m) = map(int, input().split())
adj = [[] for i in range(n + 1)]
for i in range(m):
	t = list(map(int, input().split()))
	for a in range(1, t[0] + 1 - 1):
		(s, e) = (t[a], t[a + 1])
		adj[s].append(e)
		adj[e].append(s)

@bootstrap
def dfs(node, old):
	global ma
	if visited[node]:
		yield
	visited[node] = 1
	ma = old + 1
	visits.append(node)
	for i in adj[node]:
		yield dfs(i, ma)
	yield
visited = [0] * (n + 1)
dist = [0] * (n + 1)
for i in range(1, n + 1):
	if visited[i] == 0:
		ma = 0
		visits = []
		dfs(i, ma)
		for a in visits:
			dist[a] = ma
for i in range(1, n + 1):
	print(dist[i], end=' ')


from sys import *

def bfs(st, nd, ind, n):
	mn = set()
	ans = 0
	can = [ind]
	mn.add(ind)
	nd[ind] = 1
	while can:
		ndc = []
		for c in can:
			if c <= n:
				ans += 1
				mn.add(c)
			for sl in st[c]:
				if nd[sl] == 0:
					ndc.append(sl)
					nd[sl] = 1
		can = ndc
	return (ans, mn)
(n, m) = map(int, input().split())
vet = [[] for i in range(n + m + 1)]
mm = [0] * (m + n + 1)
ans = [0] * n
for i in range(m):
	a = list(map(int, stdin.readline().split()))
	for j in range(1, len(a)):
		vet[1 + n + i].append(a[j])
		vet[a[j]].append(1 + n + i)
for i in range(n):
	if ans[i] == 0:
		(zn, point) = bfs(vet, mm, i + 1, n)
		for j in point:
			ans[j - 1] = zn
print(*ans)


import sys
sys.setrecursionlimit(100000000)
(n, m) = map(int, sys.stdin.readline().split())
mark = [set() for _ in range(n + 1)]
score = [-1 for _ in range(n + 1)]
group = []
groupSet = []
ans = []
for i in range(m):
	a = list(map(int, sys.stdin.readline().split()))
	group.append(a)
groupSet.append(set(group[0][1:]))

def search(value):
	if score[value] < 0:
		return value
	else:
		ret = search(score[value])
		score[value] = ret
		return ret
for i in range(m):
	if group[i][0] > 0:
		mx = min(group[i][1:])
		main = search(mx)
		for v in group[i][1:]:
			cur = search(v)
			if main != cur:
				if main < cur:
					score[main] += score[cur]
					score[cur] = main
				else:
					score[cur] += score[main]
					score[main] = cur
					main = cur
for i in range(1, n + 1):
	ans.append(str(abs(score[search(i)])))
sys.stdout.write('%s\n' % ' '.join(ans))


from sys import stdin, stdout
from itertools import combinations
from collections import defaultdict, OrderedDict
import math

def listIn():
	return list(map(int, stdin.readline().strip().split()))

def stringListIn():
	return [x for x in stdin.readline().split()]

def intIn():
	return int(stdin.readline())

def stringIn():
	return stdin.readline().strip()

class DSU:

	def __init__(self, n):
		self.parent = [i for i in range(n + 1)]
		self.arr_size = [1] * (n + 1)

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

	def find(self, x, y):
		if find_root[x] == find_root[y]:
			return True
		else:
			return False

	def union(self, x, y):
		root_x = self.find_root(x)
		root_y = self.find_root(y)
		if root_x == root_y:
			return False
		if self.arr_size[root_x] < self.arr_size[root_y]:
			self.parent[root_x] = self.parent[root_y]
			self.arr_size[root_y] += self.arr_size[root_x]
		else:
			self.parent[root_y] = self.parent[root_x]
			self.arr_size[root_x] += self.arr_size[root_y]
(n, m) = listIn()
dsu = DSU(n)
for i in range(m):
	l = listIn()
	k = l[0]
	if k > 0:
		root = l[1]
		a = l[2:]
		for j in a:
			dsu.union(root, j)
ans = [0] * (n + 1)
for i in range(1, n + 1):
	ans[i] = dsu.arr_size[dsu.find_root(i)]
print(*ans[1:])


from bisect import insort, bisect_right, bisect_left
from sys import stdout, stdin, setrecursionlimit
from heapq import heappush, heappop, heapify
from io import BytesIO, IOBase
from collections import *
from itertools import *
from random import *
from string import *
from queue import *
from math import *
from re import *
from os import *

class FastIO(IOBase):
	newlines = 0

	def __init__(self, file):
		self._fd = file.fileno()
		self.buffer = BytesIO()
		self.writable = 'x' in file.mode or 'r' not in file.mode
		self.write = self.buffer.write if self.writable else None

	def read(self):
		while True:
			b = read(self._fd, max(fstat(self._fd).st_size, 8192))
			if not b:
				break
			ptr = self.buffer.tell()
			(self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
		self.newlines = 0
		return self.buffer.read()

	def readline(self):
		while self.newlines == 0:
			b = read(self._fd, max(fstat(self._fd).st_size, 8192))
			self.newlines = b.count(b'\n') + (not b)
			ptr = self.buffer.tell()
			(self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
		self.newlines -= 1
		return self.buffer.readline()

	def flush(self):
		if self.writable:
			write(self._fd, self.buffer.getvalue())
			(self.buffer.truncate(0), self.buffer.seek(0))

class IOWrapper(IOBase):

	def __init__(self, file):
		self.buffer = FastIO(file)
		self.flush = self.buffer.flush
		self.writable = self.buffer.writable
		self.write = lambda s: self.buffer.write(s.encode('ascii'))
		self.read = lambda : self.buffer.read().decode('ascii')
		self.readline = lambda : self.buffer.readline().decode('ascii')
(stdin, stdout) = (IOWrapper(stdin), IOWrapper(stdout))
(graph, mod, szzz) = ({}, 10 ** 9 + 7, lambda : sorted(zzz()))

def getStr():
	return input()

def getInt():
	return int(input())

def listStr():
	return list(input())

def getStrs():
	return input().split()

def isInt(s):
	return '0' <= s[0] <= '9'

def input():
	return stdin.readline().strip()

def zzz():
	return [int(i) for i in input().split()]

def output(answer, end='\n'):
	stdout.write(str(answer) + end)

def lcd(xnum1, xnum2):
	return xnum1 * xnum2 // gcd(xnum1, xnum2)

def getPrimes(N=10 ** 5):
	SN = int(sqrt(N))
	sieve = [i for i in range(N + 1)]
	sieve[1] = 0
	for i in sieve:
		if i > SN:
			break
		if i == 0:
			continue
		for j in range(2 * i, N + 1, i):
			sieve[j] = 0
	prime = [i for i in range(N + 1) if sieve[i] != 0]
	return prime

def primeFactor(n, prime=getPrimes()):
	lst = []
	mx = int(sqrt(n)) + 1
	for i in prime:
		if i > mx:
			break
		while n % i == 0:
			lst.append(i)
			n //= i
	if n > 1:
		lst.append(n)
	return lst
dx = [-1, 1, 0, 0, 1, -1, 1, -1]
dy = [0, 0, 1, -1, 1, -1, -1, 1]
daysInMounth = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
(n, m) = zzz()
for i in range(n + 1):
	graph[i] = []
for i in range(m):
	arr = zzz()
	if arr[0] == 0 or arr[0] == 1:
		continue
	for ii in arr[2:]:
		graph[arr[1]].append(ii)
		graph[ii].append(arr[1])
visited = [0] * (n + 1)
ans = [0] * n

def DFS(node):
	lst = [node]
	que = deque([node])
	visited[node] = 1
	s = 1
	while que:
		node = que.pop()
		for i in graph[node]:
			if not visited[i]:
				visited[i] = 1
				que.append(i)
				lst.append(i)
				s += 1
	for i in lst:
		ans[i - 1] = s
for i in range(n):
	if visited[i + 1]:
		continue
	DFS(i + 1)
print(*ans)


import math, string, itertools, fractions, heapq, collections, re, array, bisect, sys, copy, functools
inf = 10 ** 20
eps = 1.0 / 10 ** 10
mod = 10 ** 9 + 7
mod2 = 998244353
dd = [(-1, 0), (0, 1), (1, 0), (0, -1)]
ddn = [(-1, 0), (-1, 1), (0, 1), (1, 1), (1, 0), (1, -1), (0, -1), (-1, -1)]

def LI():
	return list(map(int, sys.stdin.readline().split()))

def LLI():
	return [list(map(int, l.split())) for l in sys.stdin.readlines()]

def LI_():
	return [int(x) - 1 for x in sys.stdin.readline().split()]

def LF():
	return [float(x) for x in sys.stdin.readline().split()]

def LS():
	return sys.stdin.readline().split()

def I():
	return int(sys.stdin.readline())

def F():
	return float(sys.stdin.readline())

def S():
	return input()

def pf(s):
	return print(s, flush=True)

def pe(s):
	return print(str(s), file=sys.stderr)

def JA(a, sep):
	return sep.join(map(str, a))

def JAA(a, s, t):
	return s.join((t.join(map(str, b)) for b in a))

def IF(c, t, f):
	return t if c else f

def YES(c):
	return IF(c, 'YES', 'NO')

def Yes(c):
	return IF(c, 'Yes', 'No')

class UnionFind:

	def __init__(self, size):
		self.table = [-1 for _ in range(size)]

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

	def union(self, x, y):
		s1 = self.find(x)
		s2 = self.find(y)
		if s1 != s2:
			if self.table[s1] <= self.table[s2]:
				self.table[s1] += self.table[s2]
				self.table[s2] = s1
			else:
				self.table[s2] += self.table[s1]
				self.table[s1] = s2
			return True
		return False

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

	def subsetall(self):
		a = []
		for i in range(len(self.table)):
			if self.table[i] < 0:
				a.append((i, -self.table[i]))
		return a

def main():
	t = 1
	rr = []
	for _ in range(t):
		(n, m) = LI()
		aa = [LI_()[1:] for _ in range(m)]
		uf = UnionFind(n)
		for a in aa:
			if not a:
				continue
			b = a[0]
			for c in a[1:]:
				uf.union(b, c)
		r = [-uf.table[uf.find(i)] for i in range(n)]
		rr.append(JA(r, ' '))
	return JA(rr, '\n')
print(main())


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)]
readl = lambda : list(map(int, sys.stdin.readline().split()))
readt = lambda : tuple(map(int, sys.stdin.readline().split()))
readr = lambda : sys.stdin.readline().rstrip()
read = lambda : int(readr())
(n, m) = map(int, input().split())
node = [-1 for i in range(n + 1)]
rank = [0 for _ in range(n + 1)]
query = [readt() 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=' ')


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()


import sys
input = sys.stdin.readline
from bisect import *
import math
from collections import *
from heapq import *
from itertools import *
inf = 10 ** 18
mod = 10 ** 9 + 7
(n, m) = map(int, input().split())
dic = defaultdict(list)
for _ in range(m):
	x = list(map(int, input().split()))
	if x[0] > 1:
		for i in range(1, x[0]):
			dic[x[i]].append(x[i + 1])
			dic[x[i + 1]].append(x[i])
vis = [-1] * (n + 1)
ans = [-1] * (n + 1)
for i in range(1, n + 1):
	if vis[i] == -1:
		stack = [i]
		vis[i] = i
		ans[i] = 1
		while len(stack):
			temp = stack.pop()
			for child in dic[temp]:
				if vis[child] == -1:
					stack.append(child)
					vis[child] = i
					ans[i] += 1
for i in range(1, n + 1):
	print(ans[vis[i]], end=' ')


from __future__ import division, print_function
import os
import sys
from io import BytesIO, IOBase
if sys.version_info[0] < 3:
	from __builtin__ import xrange as range
	from future_builtins import ascii, filter, hex, map, oct, zip

class DSU(object):

	def __init__(self, n):
		self.parent = [i for i in range(n)]
		self.rank = [1] * n
		self.cycle = False

	def find(self, key):
		if self.parent[key] != key:
			self.parent[key] = self.find(self.parent[key])
		return self.parent[key]

	def union(self, a, b):
		(s1, s2) = (self.find(a), self.find(b))
		if s1 != s2:
			if self.rank[s1] < self.rank[s2]:
				self.parent[s1] = s2
				self.rank[s2] += self.rank[s1]
			else:
				self.parent[s2] = s1
				self.rank[s1] += self.rank[s2]
		else:
			self.cycle = True

	@property
	def has_cycle(self):
		return self.cycle

	@property
	def get_parent(self):
		return self.parent

	@property
	def get_rank(self):
		return self.rank

def main():
	(n, m) = map(int, input().split())
	d = DSU(n + 1)
	for _ in range(m):
		a = list(map(int, input().split()))
		if a[0] != 0:
			for i in range(2, a[0] + 1):
				d.union(a[i - 1], a[i])
	for i in range(1, n + 1):
		print(d.get_rank[d.find(i)], end=' ')
	print()
BUFSIZE = 8192

class FastIO(IOBase):
	newlines = 0

	def __init__(self, file):
		self._fd = file.fileno()
		self.buffer = BytesIO()
		self.writable = 'x' in file.mode or 'r' not in file.mode
		self.write = self.buffer.write if self.writable else None

	def read(self):
		while True:
			b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
			if not b:
				break
			ptr = self.buffer.tell()
			(self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
		self.newlines = 0
		return self.buffer.read()

	def readline(self):
		while self.newlines == 0:
			b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
			self.newlines = b.count(b'\n') + (not b)
			ptr = self.buffer.tell()
			(self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
		self.newlines -= 1
		return self.buffer.readline()

	def flush(self):
		if self.writable:
			os.write(self._fd, self.buffer.getvalue())
			(self.buffer.truncate(0), self.buffer.seek(0))

class IOWrapper(IOBase):

	def __init__(self, file):
		self.buffer = FastIO(file)
		self.flush = self.buffer.flush
		self.writable = self.buffer.writable
		self.write = lambda s: self.buffer.write(s.encode('ascii'))
		self.read = lambda : self.buffer.read().decode('ascii')
		self.readline = lambda : self.buffer.readline().decode('ascii')

def print(*args, **kwargs):
	(sep, file) = (kwargs.pop('sep', ' '), kwargs.pop('file', sys.stdout))
	at_start = True
	for x in args:
		if not at_start:
			file.write(sep)
		file.write(str(x))
		at_start = False
	file.write(kwargs.pop('end', '\n'))
	if kwargs.pop('flush', False):
		file.flush()
if sys.version_info[0] < 3:
	(sys.stdin, sys.stdout) = (FastIO(sys.stdin), FastIO(sys.stdout))
else:
	(sys.stdin, sys.stdout) = (IOWrapper(sys.stdin), IOWrapper(sys.stdout))
input = lambda : sys.stdin.readline().rstrip('\r\n')
main()


from sys import stdin, stdout
input = stdin.readline

def main():
	(n, m) = map(int, input().split())
	sets = list(range(n + 1))
	sizes = [1] * (n + 1)

	def get(a):
		if sets[a] != a:
			sets[a] = get(sets[a])
		return sets[a]

	def union(a, b):
		a = get(a)
		b = get(b)
		if a == b:
			return
		if sizes[a] > sizes[b]:
			(a, b) = (b, a)
		sets[a] = b
		sizes[b] += sizes[a]
	for i in range(m):
		num = list(map(int, input().split()))
		for i in range(2, num[0] + 1):
			union(num[i - 1] - 1, num[i] - 1)
	for i in range(n):
		print(sizes[get(i)], end=' ')
main()


from sys import stdin
from sys import stdout
(n, m) = map(int, stdin.readline().split())
parent = list(range(n + 1))
cnt = [0] * (n + 1)

def find(u):
	if parent[u] == u:
		return u
	parent[u] = find(parent[u])
	return parent[u]
for i in range(m):
	group = [int(u) for u in stdin.readline().split()][1:]
	for v in group[1:]:
		parent[find(v)] = find(group[0])
for u in range(1, n + 1):
	cnt[find(u)] += 1
ans = ' '.join(map(str, [cnt[find(u)] for u in range(1, n + 1)]))
stdout.write('%s' % ans)


import sys
input = sys.stdin.readline
from collections import deque
from collections import defaultdict
(n, m) = list(map(int, input().split()))
d = defaultdict(list)
for i in range(m):
	l = list(map(int, input().split()))
	for k in range(2, len(l)):
		d[l[k]].append(l[k - 1])
		d[l[k - 1]].append(l[k])
ans = [0] * (n + 1)
visited = [0] * (n + 1)
for i in range(1, n + 1):
	if visited[i] == 0:
		q = deque()
		q.append(i)
		visited[i] = 1
		c = 0
		x = []
		while q:
			j = q.popleft()
			x.append(j)
			c = c + 1
			for k in d[j]:
				if visited[k] == 0:
					visited[k] = 1
					q.append(k)
		for i in x:
			ans[i] = c
sys.stdout.write(' '.join(map(str, ans[1:])) + '\n')


from sys import stdin
from sys import stdout

def find(x, p):
	while x != p[x]:
		p[x] = p[p[x]]
		x = p[x]
	return x
(n, m) = map(int, stdin.readline().split())
g = [i for i in range(n)]
for i in range(m):
	arr = list(map(int, stdin.readline().split()))
	for j in range(2, len(arr)):
		g[find(arr[j] - 1, g)] = find(arr[1] - 1, g)
freq = [0] * n
for i in range(n):
	freq[find(i, g)] += 1
count = [0] * n
for i in range(n):
	count[i] = freq[find(i, g)]
print(' '.join([str(i) for i in count]))


import sys
from collections import deque
input = sys.stdin.readline
l = list(map(int, input().split()))
n = l[0]
k = l[1]
dict = {}
for i in range(n):
	dict[i + 1] = []
for i in range(k):
	l1 = list(map(int, input().split()))
	if l1[0] > 1:
		for i in range(2, l1[0] + 1):
			t = l1[i]
			dict[l1[1]].append(t)
			dict[t].append(l1[1])

def bfs(start, n, visited, out):
	count = 0
	l2 = [i + 1]
	q = [i + 1]
	q = deque(q)
	count += 1
	visited[i] = 1
	while len(q) != 0:
		y = dict[q[0]]
		for j in y:
			if visited[j - 1] == 0:
				visited[j - 1] = 1
				l2.append(j)
				q.append(j)
				count += 1
		q.popleft()
	for k in l2:
		out[k - 1] = count
visited = [0] * n
out = [0] * n
for i in range(n):
	if visited[i] == 0:
		bfs(i, n, visited, out)
for i in out:
	print(i, end=' ')


from sys import stdin

def li():
	return list(map(int, stdin.readline().split()))

def mp():
	return map(int, stdin.readline().split())

def solve():
	(n, m) = mp()
	d = {i: [] for i in range(1, n + 1)}
	for _ in range(m):
		l = li()
		x = l[0]
		if x > 1:
			for i in range(1, x):
				d[l[i]].append(l[i + 1])
				d[l[i + 1]].append(l[i])
	ans = [-1 for i in range(n + 1)]
	vi = [-1 for i in range(n + 1)]
	for i in range(1, n + 1):
		if vi[i] == -1:
			vi[i] = i
			stack = [i]
			ans[i] = 1
			while stack:
				a = stack.pop()
				for x in d[a]:
					if vi[x] == -1:
						ans[i] += 1
						vi[x] = i
						stack.append(x)
	print(' '.join((str(ans[vi[i]]) for i in range(1, n + 1))))
for _ in range(1):
	solve()


from sys import stdin, stdout
from math import gcd, sqrt
from collections import deque
input = stdin.readline
R = lambda : map(int, input().split())
I = lambda : int(input())
S = lambda : input().rstrip('\n')
L = lambda : list(R())
P = lambda x: stdout.write(x)
hg = lambda x, y: (y + x - 1) // x * x
pw = lambda x: 1 if x == 1 else 1 + pw(x // 2)
chk = lambda x: chk(x // 2) if not x % 2 else True if x == 1 else False
dgnl = lambda x: sqrt(2 * x ** 2)

def dsu(x):
	while x != p[x]:
		p[x] = p[p[x]]
		x = p[x]
	return x
N = 10 ** 6 + 7
(n, k) = R()
p = [i for i in range(n)]
for _ in range(k):
	a = L()
	if a[0]:
		for el in a[2:]:
			p[dsu(el - 1)] = dsu(a[1] - 1)
val = [0] * n
for i in range(n):
	val[dsu(i)] += 1
print(*[val[dsu(i)] for i in range(n)])


import sys

def find(x):
	if x == parent[x]:
		return x
	parent[x] = find(parent[x])
	return parent[x]
(n, m) = map(int, input().split())
size = [0] * (n + 1)
parent = [i for i in range(n + 1)]
for i in sys.stdin.readlines():
	amigos = list(map(int, i.split()))
	if amigos[0] == 0:
		continue
	else:
		pai1 = find(amigos[1])
		for z in amigos[2:]:
			pai2 = find(z)
			if pai1 != pai2:
				parent[pai2] = pai1
for i in range(n + 1):
	size[find(i)] += 1
resposta = []
for i in range(1, n + 1):
	resposta.append(str(size[parent[i]]))
print(' '.join(resposta))


import sys
input = sys.stdin.readline

def gt(x):
	while x != d[x]:
		d[x] = d[d[x]]
		x = d[x]
	return x
(n, m) = map(int, input().split())
d = [i for i in range(n)]
l = [0] * n
for _ in range(m):
	cl = list(map(int, input().split()))
	for i in cl[2:]:
		d[gt(i - 1)] = gt(cl[1] - 1)
for i in range(n):
	l[gt(i)] += 1
r = [0] * n
for i in range(n):
	r[i] = l[gt(i)]
print(*r)


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)
solve()


from collections import Counter
from collections import defaultdict
import math
import random
import heapq as hq
from math import sqrt
import sys

def input():
	return sys.stdin.readline().strip()

def iinput():
	return int(input())

def tinput():
	return input().split()

def rinput():
	return map(int, tinput())

def rlinput():
	return list(rinput())
mod = int(1000000000.0) + 7

def solve(adj, colors, n):
	pass

def root(parent, a):
	while parent[a] != a:
		parent[a] = parent[parent[a]]
		a = parent[a]
	return a

def union(parent, size, a, b):
	(roota, rootb) = (root(parent, a), root(parent, b))
	if roota == rootb:
		return
	parent[rootb] = roota
	size[roota] += size[rootb]
	size[rootb] = 0
(n, m) = rinput()
parent = list(range(n))
size = [1] * n
for _ in range(m):
	a = rlinput()
	for i in range(1, a[0]):
		union(parent, size, a[i] - 1, a[i + 1] - 1)
for i in [size[root(parent, i)] for i in range(n)]:
	print(i, end=' ')
print('')


import sys
input = sys.stdin.readline

class Unionfind:

	def __init__(self, n):
		self.par = [-1] * n
		self.rank = [1] * n

	def root(self, x):
		p = x
		while not self.par[p] < 0:
			p = self.par[p]
		while x != p:
			tmp = x
			x = self.par[x]
			self.par[tmp] = p
		return p

	def unite(self, x, y):
		(rx, ry) = (self.root(x), self.root(y))
		if rx == ry:
			return False
		if self.rank[rx] < self.rank[ry]:
			(rx, ry) = (ry, rx)
		self.par[rx] += self.par[ry]
		self.par[ry] = rx
		if self.rank[rx] == self.rank[ry]:
			self.rank[rx] += 1

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

	def count(self, x):
		return -self.par[self.root(x)]
(n, m) = map(int, input().split())
uf = Unionfind(n)
for _ in range(m):
	l = list(map(int, input().split()))
	for i in range(1, len(l) - 1):
		uf.unite(l[i] - 1, l[i + 1] - 1)
ans = []
for i in range(n):
	ans.append(uf.count(i))
print(*ans)


import sys
yash = sys.stdin.readline
(n, m) = map(int, yash().split())
vertex_info = {node_id: [] for node_id in range(1, n + 1)}
visited = [0 for i in range(n + 1)]
communicating_pairs = [0 for i in range(n + 1)]
for _ in range(m):
	info = tuple(map(int, yash().split()))
	if info[0] >= 2:
		for i in range(1, info[0]):
			vertex_info[info[i]].append(info[i + 1])
			vertex_info[info[i + 1]].append(info[i])
for node in range(1, n + 1):
	if visited[node] == 0:
		visited[node] = node
		communicating_pairs[node] = 1
		stack = [node]
		while stack:
			current_top_node = stack.pop()
			for neighbour in vertex_info[current_top_node]:
				if visited[neighbour] == 0:
					visited[neighbour] = node
					communicating_pairs[node] += 1
					stack.append(neighbour)
print(*[communicating_pairs[visited[i]] for i in range(1, n + 1)])


import math, sys, bisect, heapq
from collections import defaultdict, Counter, deque
from itertools import groupby, accumulate
int1 = lambda x: int(x) - 1

def input():
	return sys.stdin.readline().strip()
ilele = lambda : map(int, input().split())
alele = lambda : list(map(int, input().split()))
ilelec = lambda : map(int1, input().split())
alelec = lambda : list(map(int1, input().split()))

def list2d(a, b, c):
	return [[c] * b for i in range(a)]

def list3d(a, b, c, d):
	return [[[d] * c for j in range(b)] for i in range(a)]

def Y(c):
	print(['NO', 'YES'][c])

def y(c):
	print(['no', 'yes'][c])

def Yy(c):
	print(['No', 'Yes'][c])
G = defaultdict(list)

def addEdge(a, b):
	G[a].append(b)
	G[b].append(a)
(n, m) = ilele()
for i in range(m):
	A = alele()
	if A[0] != 0:
		for j in range(1, len(A) - 1):
			addEdge(A[j], A[j + 1])
vis = [0] * (n + 1)

def dfs(node, Id):
	s = deque()
	count = 1
	s.append(node)
	vis[node] = Id
	while s:
		v = s.pop()
		for i in G.get(v, []):
			if not vis[i]:
				count += 1
				vis[i] = Id
				s.append(i)
	return count
Ans = {}
Id = 1
for i in range(1, n + 1):
	if not vis[i]:
		Ans[Id] = dfs(i, Id)
		Id += 1
for i in range(1, n + 1):
	print(Ans[vis[i]], end=' ')


def Find(x, par):
	if par[x] < 0:
		return x
	else:
		par[x] = Find(par[x], par)
		return par[x]

def Unite(x, y, par, rank):
	x = Find(x, par)
	y = Find(y, par)
	if x != y:
		if rank[x] < rank[y]:
			par[y] += par[x]
			par[x] = y
		else:
			par[x] += par[y]
			par[y] = x
			if rank[x] == rank[y]:
				rank[x] += 1

def Same(x, y, par):
	return Find(x, par) == Find(y, par)

def Size(x, par):
	return -par[Find(x, par)]
import sys
import io, os
input = io.BytesIO(os.read(0, os.fstat(0).st_size)).readline
(n, m) = map(int, input().split())
par = [-1] * n
rank = [0] * n
for i in range(m):
	temp = list(map(int, input().split()))
	k = temp[0]
	if k == 0:
		continue
	l = temp[1:]
	l = [a - 1 for a in l]
	for i in range(k):
		Unite(l[0], l[i], par, rank)
ans = [0] * n
for i in range(n):
	ans[i] = Size(i, par)
print(*ans)


import collections
from collections import defaultdict
import sys
p2D = lambda x: print(*x, sep='\n')

def II():
	return int(sys.stdin.buffer.readline())

def MI():
	return map(int, sys.stdin.buffer.readline().split())

def LI():
	return list(map(int, sys.stdin.buffer.readline().split()))

def LLI(rows_number):
	return [LI() for _ in range(rows_number)]

def BI():
	return sys.stdin.buffer.readline().rstrip()

def SI():
	return sys.stdin.buffer.readline().rstrip().decode()

def li():
	return [int(i) for i in input().split()]

def lli(rows):
	return [li() for _ in range(rows)]

def si():
	return input()

def ii():
	return int(input())

def ins():
	return input().split()

def findroot(x, parents):
	if parents[x] == x:
		return x
	else:
		result = findroot(parents[x], parents)
		parents[x] = result
		return result

def unionset(x, y, ranks, parents):
	x_root = findroot(x, parents)
	y_root = findroot(y, parents)
	if x_root == y_root:
		return
	if ranks[x_root] > ranks[y_root]:
		parents[y_root] = x_root
	elif ranks[y_root] > ranks[x_root]:
		parents[x_root] = y_root
	elif x_root < y_root:
		parents[y_root] = x_root
		ranks[x_root] += 1
	else:
		parents[x_root] = y_root
		ranks[y_root] += 1

def solve():
	(n, m) = LI()
	parents = list(range(n + 1))
	ranks = [0] * (n + 1)
	for i in range(m):
		tmp = LI()
		if tmp[0] > 1:
			for i in range(tmp[0] - 1):
				unionset(tmp[i + 1], tmp[i + 2], ranks, parents)
	for i in range(1, n + 1):
		findroot(i, parents)
	d = defaultdict(int)
	for j in parents[1:]:
		d[j] += 1
	ans = ''
	for i in range(1, n + 1):
		ans += str(d[parents[i]]) + ' '
	print(ans)

def main():
	solve()
main()


import os
import sys
from io import BytesIO, IOBase
import math
from decimal import *
from collections import defaultdict, deque
import heapq
getcontext().prec = 25
MOD = pow(10, 9) + 7
BUFSIZE = 8192

class FastIO(IOBase):
	newlines = 0

	def __init__(self, file):
		self._fd = file.fileno()
		self.buffer = BytesIO()
		self.writable = 'x' in file.mode or 'r' not in file.mode
		self.write = self.buffer.write if self.writable else None

	def read(self):
		while True:
			b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
			if not b:
				break
			ptr = self.buffer.tell()
			(self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
		self.newlines = 0
		return self.buffer.read()

	def readline(self):
		while self.newlines == 0:
			b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
			self.newlines = b.count(b'\n') + (not b)
			ptr = self.buffer.tell()
			(self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
		self.newlines -= 1
		return self.buffer.readline()

	def flush(self):
		if self.writable:
			os.write(self._fd, self.buffer.getvalue())
			(self.buffer.truncate(0), self.buffer.seek(0))

class IOWrapper(IOBase):

	def __init__(self, file):
		self.buffer = FastIO(file)
		self.flush = self.buffer.flush
		self.writable = self.buffer.writable
		self.write = lambda s: self.buffer.write(s.encode('ascii'))
		self.read = lambda : self.buffer.read().decode('ascii')
		self.readline = lambda : self.buffer.readline().decode('ascii')
(sys.stdin, sys.stdout) = (IOWrapper(sys.stdin), IOWrapper(sys.stdout))
input = lambda : sys.stdin.readline().rstrip('\r\n')

def bfs(z):
	c = 1
	l = [z + 1]
	q = deque(l)
	visted[z] = True
	while q:
		x = q.pop()
		for i in g[x]:
			if visted[i - 1]:
				continue
			visted[i - 1] = True
			c += 1
			q.append(i)
			l.append(i)
	for i in l:
		ans[i - 1] = c
g = {}
(n, k) = map(int, input().split(' '))
for i in range(n):
	g[i + 1] = []
visted = [False] * n
ans = [0] * n
for i in range(k):
	x = list(map(int, input().split(' ')))
	if x[0] > 1:
		for j in x[2:]:
			g[j].append(x[1])
			g[x[1]].append(j)
for i in range(n):
	if not visted[i]:
		bfs(i)
print(*ans)


import sys
I = lambda : sys.stdin.readline()
(n, m) = map(int, I().split())
parent = [i for i in range(1 + n)]
count = [0] * (n + 1)

def find(x):
	if x != parent[x]:
		parent[x] = find(parent[x])
	return parent[x]
for i in range(m):
	li = I().split()
	if int(li[0]) > 0:
		head = find(int(li[1]))
		for v in li[2:]:
			child = find(int(v))
			if head != child:
				parent[child] = head
for i in range(1, n + 1):
	count[find(i)] += 1
for i in range(1, n + 1):
	print(count[parent[i]], end=' ')


from sys import stdin
input = stdin.readline
IN = lambda : map(int, input().split())

def find(x):
	while x != p[x]:
		p[x] = p[p[x]]
		x = p[x]
	return x
(n, m) = IN()
p = [i for i in range(n + 1)]
sz = [0] * (n + 1)
for _ in range(m):
	a = [*IN()]
	for i in a[2:]:
		p[find(i)] = find(a[1])
for i in range(1, n + 1):
	sz[find(i)] += 1
print(*[sz[find(i)] for i in range(1, n + 1)])


from sys import stdin
input = stdin.readline
R = lambda : map(int, input().split())
(n, m) = R()
par = [i for i in range(n + 1)]
size = [0 for i in range(n + 1)]

def find(x):
	while x != par[x]:
		par[x] = par[par[x]]
		x = par[x]
	return x
for i in range(m):
	ki = list(R())
	if len(ki) > 1:
		ta = find(ki[1])
	for j in range(2, len(ki)):
		tb = find(ki[j])
		if ta != tb:
			par[tb] = ta
for i in range(1, n + 1):
	size[find(i)] = size[find(i)] + 1
ans = [0 for i in range(n)]
for i in range(1, n + 1):
	ans[i - 1] = size[find(i)]
print(*ans)


import sys
from typing import Any

def read_line():
	return sys.stdin.readline().split()

def read_int_iter():
	return map(int, read_line())

def read_int_array():
	return list(read_int_iter())

def init_array(n, default=0):
	return [default] * n

def iota(n, start=0):
	return list(range(start, n))

def print_any_iter(a):
	sys.stdout.write(' '.join(map(str, a)) + '\n')

def problem_c():

	class UF:

		def __init__(self, n: int) -> None:
			self.parent = list(range(n + 1))
			self.rank = [1] * (n + 1)
			self.count = n

		def find(self, p: Any):
			while p != self.parent[p]:
				p = self.parent[p]
			return p

		def connected(self, p: Any, q: Any):
			return self.find(p) == self.find(q)

		def union(self, p: Any, q: Any):
			root_p = self.find(p)
			root_q = self.find(q)
			if root_p == root_q:
				return
			if self.rank[root_p] > self.rank[root_q]:
				(root_p, root_q) = (root_q, root_p)
			self.parent[root_p] = root_q
			self.rank[root_q] += self.rank[root_p]
	(n, m) = read_int_iter()
	uf = UF(n)
	for i in range(m):
		a = read_int_array()
		for j in range(1, a[0]):
			uf.union(a[1], a[j + 1])
	print_any_iter((uf.rank[uf.find(i)] for i in range(1, n + 1)))
problem_c()


import sys

def find(i):
	if par[i] == i:
		return i
	par[i] = find(par[i])
	return par[i]
input = sys.stdin.readline
(n, m) = map(int, input().split())
par = [i for i in range(n + 1)]
cnt = [0] * (n + 1)
for _ in range(m):
	a = list(map(int, input().split()))[1:]
	if len(a) > 0:
		ta = find(a[0])
		for i in a[1:]:
			tb = find(i)
			if a != tb:
				par[tb] = ta
for i in range(n + 1):
	cnt[find(i)] += 1
for i in range(1, n + 1):
	print(cnt[par[i]], end=' ')
print()


import sys
sys.setrecursionlimit(10 ** 5)

def find(x):
	if x == parent[x]:
		return x
	parent[x] = find(parent[x])
	return parent[x]

def union(x, y):
	p_x = find(x)
	p_y = find(y)
	if p_x != p_y:
		if tamanho[p_x] > tamanho[p_y]:
			parent[p_y] = p_x
			tamanho[p_x] += tamanho[p_y]
		else:
			parent[p_x] = p_y
			tamanho[p_y] += tamanho[p_x]
(n, m) = list(map(int, input().split()))
parent = [i for i in range(n + 1)]
tamanho = [1 for i in range(n + 1)]
for entrada in sys.stdin.readlines():
	grupo = list(map(int, entrada.split()))
	i = 1
	j = 2
	while j < len(grupo):
		union(grupo[i], grupo[j])
		j += 1
for i in range(1, n + 1):
	print(tamanho[find(i)], end=' ')


import sys
input = sys.stdin.readline
(n, m) = map(int, input().split())
a = [i for i in range(n + 1)]

def find(a, i):
	if a[i] == i:
		return i
	else:
		a[i] = find(a, a[i])
		return a[i]
for i in range(m):
	p = [int(x) for x in input().split()]
	k = p[0]
	for ii in range(2, k + 1):
		a[find(a, p[ii])] = find(a, p[1])
s = [0] * (n + 1)
for j in range(1, n + 1):
	s[find(a, j)] += 1
for i in range(1, n + 1):
	print(s[find(a, i)], end=' ')


import sys
input = sys.stdin.readline
(n, m) = map(int, input().split())
gr = [set() for i in range(n + 1)]
tr = [[1, i] for i in range(n + 1)]
for i in range(m):
	a = list(map(int, input().split()))
	if a[0] in [0, 1]:
		continue
	for j in range(1, a[0]):
		gr[a[j]].add(a[j + 1])
		gr[a[j + 1]].add(a[j])
v = [False for i in range(n + 1)]
for i in range(1, n + 1):
	if v[i]:
		continue
	s = set([i])
	l = 0
	while s:
		x = s.pop()
		l += 1
		v[x] = True
		tr[x][1] = i
		for j in gr[x]:
			if v[j]:
				continue
			s.add(j)
	tr[i][1] = i
	tr[i][0] = l
for i in range(1, n + 1):
	print(tr[tr[i][1]][0], end=' ')


(n, m) = list(map(lambda x: int(x), input().split()))
from time import time
import sys
all_zeros = True

class DisjSet:

	def __init__(self, n):
		self.rank = [1] * n
		self.parent = [i for i in range(n)]
		self.sizes = [1 for i in range(n)]
		self.extra = []

	def find(self, x):
		if self.parent[x] != x:
			self.parent[x] = self.find(self.parent[x])
		return self.parent[x]

	def Union(self, x, y):
		xset = self.find(x)
		yset = self.find(y)
		if xset == yset:
			return
		if self.sizes[xset] < self.sizes[yset]:
			self.parent[xset] = yset
			self.sizes[yset] += self.sizes[xset]
		elif self.sizes[xset] > self.sizes[yset]:
			self.parent[yset] = xset
			self.sizes[xset] += self.sizes[yset]
		else:
			self.parent[yset] = xset
			self.sizes[xset] += self.sizes[yset]
from random import randint
obj = DisjSet(n)
from time import time
x = time()
for g in range(m):
	a = list(map(int, sys.stdin.readline().split()))
	for i in range(2, len(a)):
		obj.Union(a[1] - 1, a[i] - 1)
ans = []
hashmap = {}
for i in range(n):
	if obj.find(i) not in hashmap:
		hashmap[obj.find(i)] = 0
	hashmap[obj.find(i)] += 1
for i in range(n):
	ans.append(hashmap[obj.find(i)])
print(*ans)


import sys

class node:

	def __init__(self, value):
		self.parent = self
		self.size = 1

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

def uSet(u, v):
	up = find(u)
	vp = find(v)
	if up == vp:
		return
	if up.size >= vp.size:
		vp.parent = up
		up.size += vp.size
	else:
		up.parent = vp
		vp.size += up.size
(n, m) = map(int, input().split())
graph = [node(x) for x in range(n + 1)]
groups = [[int(i) for i in sys.stdin.readline().strip().split()] for _ in range(m)]
for i in range(m):
	group = groups[i]
	if group[0] == 0:
		continue
	for j in range(2, group[0] + 1):
		uSet(graph[group[j]], graph[group[j - 1]])
ans = [find(graph[x]).size for x in range(1, n + 1)]
for i in range(n):
	print(ans[i], end=' ')


from sys import stdin
input = stdin.readline

def find(r):
	if parent[r] == r:
		return r
	parent[r] = find(parent[r])
	return parent[r]
(n, m) = map(int, input().split())
parent = [0] * (1 + n)
count = [0] * (1 + n)
for i in range(1, 1 + n):
	parent[i] = i
for _ in range(m):
	a = list(map(int, input().split()))
	if a[0] == 0:
		continue
	u = find(a[1])
	for i in a[2:]:
		v = find(i)
		if u != v:
			parent[v] = u
for i in range(1, 1 + n):
	count[find(i)] += 1
for i in range(1, 1 + n):
	print(count[parent[i]], end=' ')


from sys import stdin, stdout
st = lambda : list(stdin.readline().strip())
li = lambda : list(map(int, stdin.readline().split()))
mp = lambda : map(int, stdin.readline().split())
inp = lambda : int(stdin.readline())
pr = lambda n: stdout.write(str(n) + '\n')

def solve():
	(n, m) = mp()
	d = {i: [] for i in range(1, n + 1)}
	for _ in range(m):
		l = li()
		x = l[0]
		if x > 1:
			for i in range(1, x):
				d[l[i]].append(l[i + 1])
				d[l[i + 1]].append(l[i])
	ans = [-1 for i in range(n + 1)]
	vi = [-1 for i in range(n + 1)]
	for i in range(1, n + 1):
		if vi[i] == -1:
			vi[i] = i
			stack = [i]
			ans[i] = 1
			while stack:
				a = stack.pop()
				for x in d[a]:
					if vi[x] == -1:
						ans[i] += 1
						vi[x] = i
						stack.append(x)
	print(' '.join((str(ans[vi[i]]) for i in range(1, n + 1))))
for _ in range(1):
	solve()


from sys import stdin
from sys import stdout

def find(x):
	while x != p[x]:
		p[x] = p[p[x]]
		x = p[x]
	return x
(n, m) = map(int, stdin.readline().split())
p = [0] * n
sz = [0] * n
for i in range(0, n):
	p[i] = i
for i in range(0, m):
	a = list(map(int, stdin.readline().split()))
	for el in a[2:]:
		p[find(el - 1)] = find(a[1] - 1)
ans = [0] * n
for i in range(0, n):
	sz[find(i)] += 1
for i in range(0, n):
	ans[i] = sz[find(i)]
stdout.write('%s' % ' '.join(map(str, ans)))


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):
	print(cnt[par[i]], end=' ')


import sys
readline = sys.stdin.readline
(N, M) = list(map(int, readline().split(' ')))
p = [x for x in range(N)]
counter = {x: 0 for x in range(N)}

def merge_groups(i, j):
	i = get_group(i)
	j = get_group(j)
	p[j] = i

def get_group(i):
	nodes = []
	while p[i] != i:
		nodes.append(i)
		i = p[i]
	for node in nodes:
		p[node] = i
	return i
for _ in range(M):
	group = list(map(int, readline().split(' ')))[1:]
	if len(group) < 2:
		continue
	boss = group[0] - 1
	for j in range(1, len(group)):
		slave = group[j] - 1
		merge_groups(boss, slave)
for node in range(N):
	group_id = get_group(node)
	counter[group_id] += 1
ans = [counter[get_group(node)] for node in range(N)]
sys.stdout.write(' '.join(map(str, ans)))


from collections import defaultdict
from collections import deque
(n, m) = map(int, input().split(' '))

def bfs(n, node, adj, vs, count):
	q = deque([node])
	reachable = []
	while len(q) > 0:
		node = q.popleft()
		if vs[node]:
			continue
		vs[node] = True
		reachable.append(node)
		for nei in adj[node]:
			if not vs[nei]:
				q.append(nei)
	for r in reachable:
		count[r] = len(reachable)

def solve(n, adj):
	count = [1] * (n + 1)
	vs = [False] * (n + 1)
	for j in range(1, n + 1):
		if not vs[j]:
			bfs(n, j, adj, vs, count)
	print(*count[1:])
import sys
adj = [[] for x in range(n + 1)]
for _ in range(m):
	a = list(map(int, sys.stdin.readline().split(' ')))
	if a[0] == 0:
		continue
	for i in range(2, len(a)):
		adj[a[1]].append(a[i])
		adj[a[i]].append(a[1])
solve(n, adj)


import sys
input = sys.stdin.readline
(n, m) = map(int, input().split())
parent = [[i, 1] for i in range(n + 1)]

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

def union(a, b):
	pa = find(a)
	pb = find(b)
	if pa != pb:
		parent[pa][0] = pb
		parent[pb][1] += parent[pa][1]
for i in range(m):
	l = list(map(int, input().split()))
	for i in range(1, l[0]):
		union(l[i], l[i + 1])
for i in range(1, n + 1):
	x = find(i)
	print(parent[x][1], end=' ')
print()


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)


(n, m) = map(int, input().split())
import sys
input = sys.stdin.readline
p = [i for i in range(n + 1)]
r = [0 for i in range(n + 1)]
k = 0

def get(x):
	while p[x] != x:
		x = p[x]
	return x

def union(x, y):
	x = get(x)
	y = get(y)
	if x == y:
		return 0
	if r[x] > r[y]:
		(x, y) = (y, x)
	p[x] = y
	if r[x] == r[y]:
		r[y] += 1
	return 1
for i in range(m):
	s = list(map(int, input().split()))
	for j in range(1, s[0]):
		union(s[j], s[j + 1])
h = [0 for i in range(n + 1)]
h2 = [0 for i in range(n + 1)]
for i in range(1, n + 1):
	h[i] = get(i)
	h2[h[i]] += 1
for i in range(1, n + 1):
	print(h2[h[i]], end=' ')


from sys import stdin
input = stdin.readline
(n, m) = map(int, input().split())
prt = [i for i in range(n + 1)]
cap = [1 for i in range(n + 1)]

def find_node(x):
	while x != prt[x]:
		prt[x] = prt[prt[x]]
		x = prt[x]
	return x

def union_nodes(u, v):
	pu = find_node(u)
	pv = find_node(v)
	if pu == pv:
		return
	if cap[pu] < cap[pv]:
		prt[pu] = prt[pv]
		cap[pv] += cap[pu]
	else:
		prt[pv] = prt[pu]
		cap[pu] += cap[pv]
for _ in range(m):
	arr = list(map(int, input().split()))[1:]
	for i in range(1, len(arr)):
		union_nodes(arr[0], arr[i])
(res, cnt) = ([0] * (n + 1), [0] * (n + 1))
for i in range(1, n + 1):
	cnt[find_node(i)] += 1
for i in range(1, n + 1):
	res[i] = cnt[find_node(i)]
print(*res[1:n + 1])


from sys import stdout, stdin, setrecursionlimit
from io import BytesIO, IOBase
from collections import *
from itertools import *
from bisect import *
from string import *
from queue import *
from heapq import *
from math import *
from re import *
from os import *

class FastIO(IOBase):
	newlines = 0

	def __init__(self, file):
		self._fd = file.fileno()
		self.buffer = BytesIO()
		self.writable = 'x' in file.mode or 'r' not in file.mode
		self.write = self.buffer.write if self.writable else None

	def read(self):
		while True:
			b = read(self._fd, max(fstat(self._fd).st_size, 8192))
			if not b:
				break
			ptr = self.buffer.tell()
			(self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
		self.newlines = 0
		return self.buffer.read()

	def readline(self):
		while self.newlines == 0:
			b = read(self._fd, max(fstat(self._fd).st_size, 8192))
			self.newlines = b.count(b'\n') + (not b)
			ptr = self.buffer.tell()
			(self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
		self.newlines -= 1
		return self.buffer.readline()

	def flush(self):
		if self.writable:
			write(self._fd, self.buffer.getvalue())
			(self.buffer.truncate(0), self.buffer.seek(0))

class IOWrapper(IOBase):

	def __init__(self, file):
		self.buffer = FastIO(file)
		self.flush = self.buffer.flush
		self.writable = self.buffer.writable
		self.write = lambda s: self.buffer.write(s.encode('ascii'))
		self.read = lambda : self.buffer.read().decode('ascii')
		self.readline = lambda : self.buffer.readline().decode('ascii')
(stdin, stdout) = (IOWrapper(stdin), IOWrapper(stdout))
(graph, mod, szzz) = ({}, 10 ** 9 + 7, lambda : sorted(zzz()))

def getStr():
	return input()

def getInt():
	return int(input())

def listStr():
	return list(input())

def getStrs():
	return input().split()

def isInt(s):
	return '0' <= s[0] <= '9'

def input():
	return stdin.readline().strip()

def zzz():
	return [int(i) for i in input().split()]

def output(answer, end='\n'):
	stdout.write(str(answer) + end)

def lcd(xnum1, xnum2):
	return xnum1 * xnum2 // gcd(xnum1, xnum2)
dx = [-1, 1, 0, 0, 1, -1, 1, -1]
dy = [0, 0, 1, -1, 1, -1, -1, 1]
daysInMounth = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
(n, m) = zzz()
for i in range(n):
	graph[i + 1] = []
for i in range(m):
	arr = zzz()
	if arr[0] == 0 or arr[0] == 1:
		continue
	for ii in arr[2:]:
		graph[arr[1]].append(ii)
		graph[ii].append(arr[1])

def bsf(start):
	cnt = 1
	lst = [start + 1]
	que = deque(lst)
	vis[start] = 1
	while que:
		x = que.pop()
		for i in graph[x]:
			if vis[i - 1]:
				continue
			vis[i - 1] = 1
			cnt += 1
			que.append(i)
			lst.append(i)
	for ll in lst:
		out[ll - 1] = cnt
out = [0] * n
vis = [0] * n
for i in range(n):
	if vis[i]:
		continue
	bsf(i)
for i in out:
	print(i)


from sys import *

def bfs(G, M, ind, n):
	met = set()
	ans = 0
	can = [ind]
	met.add(ind)
	M[ind] = 1
	while can:
		nextCan = []
		for c in can:
			if c <= n:
				ans += 1
				met.add(c)
			for nextCh in G[c]:
				if M[nextCh] == 0:
					nextCan.append(nextCh)
					M[nextCh] = 1
		can = nextCan
	return (ans, met)
(n, m) = map(int, input().split())
F = [[] for i in range(n + m + 1)]
M = [0] * (m + n + 1)
An = [0] * n
for i in range(m):
	A = list(map(int, stdin.readline().split()))
	for j in range(1, len(A)):
		F[1 + n + i].append(A[j])
		F[A[j]].append(1 + n + i)
for ind in range(n):
	if An[ind] == 0:
		(val, toCh) = bfs(F, M, ind + 1, n)
		for c in toCh:
			An[c - 1] = val
print(' '.join((str(a) for a in An)))


import os
from io import BytesIO, StringIO
input = BytesIO(os.read(0, os.fstat(0).st_size)).readline

def input_as_list():
	return list(map(int, input().split()))

def array_of(f, *dim):
	return [array_of(f, *dim[1:]) for _ in range(dim[0])] if dim else f()

def main():
	(n, m) = input_as_list()
	graph = array_of(set, n)
	for _ in range(m):
		x = input_as_list()
		if len(x) > 2:
			prev = x.pop()
			while len(x) > 1:
				this = x.pop()
				graph[prev - 1].add(this - 1)
				graph[this - 1].add(prev - 1)
				prev = this
	visited = array_of(bool, n)
	set_of = array_of(int, n)
	size_of = dict()
	for i in range(n):
		if not visited[i]:
			visited[i] = True
			size_cur = 0
			stack = [i]
			while stack:
				v = stack.pop()
				set_of[v] = i
				size_cur += 1
				for u in graph[v]:
					if not visited[u]:
						visited[u] = True
						stack.append(u)
			size_of[i] = size_cur
	for i in range(n):
		print(size_of[set_of[i]], end=' ')
main()


import sys
from collections import deque

def bfs(graph, start):
	q = [start]
	q = deque(q)
	traversed = [start]
	count = 0
	visited[start] = 1
	while len(q) != 0:
		element = q.popleft()
		for i in graph[element]:
			if visited[i] == 0:
				q.append(i)
				visited[i] = 1
				count += 1
				traversed.append(i)
	for i in traversed:
		countall[i] = count + 1
input = sys.stdin.readline
(n, m) = map(int, input().split())
if True:
	graph = [[] for i in range(n)]
	countall = [0] * n
	for i in range(m):
		l = list(map(int, input().split()))
		if len(l) > 2:
			for j in l[2:]:
				graph[l[1] - 1].append(j - 1)
				graph[j - 1].append(l[1] - 1)
	x = 0
	visited = [0] * len(graph)
	for i in range(n):
		if countall[i] == 0:
			bfs(graph, i)
			x += 1
	for i in countall:
		print(i, end=' ')


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, exit
from typing import List, Tuple, Set
from itertools import accumulate
(users_numb, groups_numb) = [int(v) for v in stdin.readline().rstrip().split()]
users: List[int] = [i for i in range(users_numb)]
_parent: List[int] = [-1] * users_numb
_size: List[int] = [0] * users_numb

def make_set(v: int):
	_parent[v] = v
	_size[v] = 1

def find_set(v: int) -> int:
	if v == _parent[v]:
		return v
	_parent[v] = find_set(_parent[v])
	return _parent[v]

def set_size(v: int) -> int:
	v = find_set(v)
	return _size[v]

def union_sets(v1: int, v2: int):
	v1 = find_set(v1)
	v2 = find_set(v2)
	if v1 != v2:
		if _size[v2] < _size[v1]:
			(v1, v2) = (v2, v1)
		_parent[v1] = v2
		_size[v2] += _size[v1]
for user in users:
	make_set(user)
for _ in range(groups_numb):
	last_user = None
	for user in stdin.readline().rstrip().split()[1:]:
		user = int(user) - 1
		if last_user is not None:
			union_sets(last_user, user)
		last_user = user
print(' '.join(map(str, [set_size(u) for u in users])))


import sys
from collections import defaultdict

def find_parent(u):
	if par[u] != u:
		par[u] = find_parent(par[u])
	return par[u]
(n, k) = map(int, input().split())
par = [0] + [i + 1 for i in range(n)]
for i in sys.stdin.readlines():
	l = list(map(int, i[:-1].split()))
	if len(l) >= 2:
		z = find_parent(l[1])
		for i in range(2, len(l)):
			a = l[i]
			z1 = find_parent(a)
			if z1 != z:
				par[z1] = z
final = [0] * (n + 1)
for i in range(1, n + 1):
	z = find_parent(i)
	final[z] += 1
for i in range(1, n + 1):
	print(final[par[i]], end=' ')


import os, sys
from io import BytesIO, IOBase

def inp():
	return int(input())

def inlist():
	return list(map(int, input().split()))

def instr():
	s = input()
	return list(s[:len(s)])

def inmap():
	return map(int, input().split())
BUFSIZE = 8192

class FastIO(IOBase):
	newlines = 0

	def __init__(self, file):
		self._fd = file.fileno()
		self.buffer = BytesIO()
		self.writable = 'x' in file.mode or 'r' not in file.mode
		self.write = self.buffer.write if self.writable else None

	def read(self):
		while True:
			b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
			if not b:
				break
			ptr = self.buffer.tell()
			(self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
		self.newlines = 0
		return self.buffer.read()

	def readline(self):
		while self.newlines == 0:
			b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
			self.newlines = b.count(b'\n') + (not b)
			ptr = self.buffer.tell()
			(self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
		self.newlines -= 1
		return self.buffer.readline()

	def flush(self):
		if self.writable:
			os.write(self._fd, self.buffer.getvalue())
			(self.buffer.truncate(0), self.buffer.seek(0))

class IOWrapper(IOBase):

	def __init__(self, file):
		self.buffer = FastIO(file)
		self.flush = self.buffer.flush
		self.writable = self.buffer.writable
		self.write = lambda s: self.buffer.write(s.encode('ascii'))
		self.read = lambda : self.buffer.read().decode('ascii')
		self.readline = lambda : self.buffer.readline().decode('ascii')
(sys.stdin, sys.stdout) = (IOWrapper(sys.stdin), IOWrapper(sys.stdout))

def input():
	return sys.stdin.readline().rstrip('\r\n')

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

def union(a, b):
	x = find(a)
	y = find(b)
	if x == y:
		return
	parent[x] += parent[y]
	parent[y] = x
(n, m) = inmap()
parent = [-1] * (n + 1)
for _ in range(m):
	arr = inlist()
	size = arr[0]
	for i in range(1, size):
		union(arr[i], arr[i + 1])
ans = []
for i in range(1, n + 1):
	ans.append(abs(parent[find(i)]))
print(*ans)


from sys import stdin
input = stdin.readline

def find(x):
	while x != p[x]:
		p[x] = p[p[x]]
		x = p[x]
	return x
R = lambda : map(int, input().split())
(n, m) = R()
p = [i for i in range(n)]
sz = [0] * n
for i in range(m):
	a = list(R())
	for el in a[2:]:
		p[find(el - 1)] = find(a[1] - 1)
for i in range(n):
	sz[find(i)] += 1
ans = [0] * n
for i in range(n):
	ans[i] = sz[find(i)]
print(*ans)


from collections import defaultdict
from sys import stdin

class UnionFind:

	def __init__(self, n):
		self.n = n
		self.parents = [-1] * n

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

	def union(self, x, y):
		x = self.find(x)
		y = self.find(y)
		if x == y:
			return
		if self.parents[x] > self.parents[y]:
			(x, y) = (y, x)
		self.parents[x] += self.parents[y]
		self.parents[y] = x

	def size(self, x):
		return -self.parents[self.find(x)]

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

	def members(self, x):
		root = self.find(x)
		return [i for i in range(self.n) if self.find(i) == root]

	def roots(self):
		return [i for (i, x) in enumerate(self.parents) if x < 0]

	def group_count(self):
		return len(self.roots())

	def all_group_members(self):
		group_members = defaultdict(list)
		for member in range(self.n):
			group_members[self.find(member)].append(member)
		return group_members
(n, m) = map(int, input().split())
uf = UnionFind(n)
arr = [[] for i in range(m)]
for i in range(m):
	(k, *l) = map(int, stdin.readline().split())
	for ll in l:
		arr[i].append(ll - 1)
for i in range(m):
	if len(arr[i]) <= 1:
		continue
	for j in range(len(arr[i]) - 1):
		uf.union(arr[i][j], arr[i][j + 1])
ans = [uf.size(i) for i in range(n)]
print(*ans)


import math, sys
from collections import defaultdict, deque
import bisect as bi

def yes():
	print('YES')

def no():
	print('NO')

def I():
	return int(sys.stdin.readline())

def In():
	return map(int, sys.stdin.readline().split())

def Sn():
	return sys.stdin.readline().strip()

def dict(a):
	d = {}
	for x in a:
		if d.get(x, -1) != -1:
			d[x] += 1
		else:
			d[x] = 1
	return d

def find_gt(a, x):
	i = bi.bisect_left(a, x)
	if i != len(a):
		return i
	else:
		return -1

class DSU:

	def __init__(self, n):
		self.parent = [i for i in range(n + 1)]
		self.rank = [0 for i in range(n + 1)]

	def find_set(self, v):
		if v == self.parent[v]:
			return v
		self.parent[v] = self.find_set(self.parent[v])
		return self.parent[v]

	def union(self, a, b):
		a = self.find_set(a)
		b = self.find_set(b)
		if a != b:
			if self.rank[a] < self.rank[b]:
				(a, b) = (b, a)
			self.parent[b] = a
			if self.rank[a] == self.rank[b]:
				self.rank[a] += 1

def main():
	try:
		(n, m) = In()
		dsu = DSU(n)
		for i in range(m):
			l = list(In())
			if l[0] <= 1:
				continue
			for j in range(2, l[0] + 1):
				dsu.union(l[1], l[j])
		an = [dsu.find_set(i) for i in range(1, n + 1)]
		d = dict(dsu.parent)
		ans = [d[dsu.parent[i]] for i in range(1, n + 1)]
		print(*ans)
	except:
		pass
M = 998244353
P = 1000000007
for _ in range(1):
	main()