There are N cities. There are also K roads and L railways, extending between the cities.
The i-th road bidirectionally connects the p_i-th and q_i-th cities, and the i-th railway bidirectionally connects the r_i-th and s_i-th cities.
No two roads connect the same pair of cities. Similarly, no two railways connect the same pair of cities.
We will say city A and B are connected by roads if city B is reachable from city A by traversing some number of roads. Here, any city is considered to be connected to itself by roads.
We will also define connectivity by railways similarly.
For each city, find the number of the cities connected to that city by both roads and railways.

-----Constraints-----
 - 2 ≦ N ≦ 2*10^5
 - 1 ≦ K, L≦ 10^5
 - 1 ≦ p_i, q_i, r_i, s_i ≦ N
 - p_i < q_i
 - r_i < s_i
 - When i ≠ j, (p_i, q_i) ≠ (p_j, q_j)
 - When i ≠ j, (r_i, s_i) ≠ (r_j, s_j)

-----Input-----
The input is given from Standard Input in the following format:
N K L
p_1 q_1
:
p_K q_K
r_1 s_1
:
r_L s_L

-----Output-----
Print N integers. The i-th of them should represent the number of the cities connected to the i-th city by both roads and railways.

-----Sample Input-----
4 3 1
1 2
2 3
3 4
2 3

-----Sample Output-----
1 2 2 1

All the four cities are connected to each other by roads.
By railways, only the second and third cities are connected. Thus, the answers for the cities are 1, 2, 2 and 1, respectively.

Difficulty: MEDIUM_HARD

Starter code:

Solutions:
from collections import Counter

class Unionfind:

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

	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):
		return {r: self.members(r) for r in self.roots()}

	def __str__(self):
		return '\n'.join(('{}:{}'.format(r, self.members(r)) for r in self.roots()))
(N, K, L) = map(int, input().split())
uf = Unionfind(N)
uf1 = Unionfind(N)
for _ in range(K):
	(p, q) = map(int, input().split())
	uf.union(p - 1, q - 1)
for _ in range(L):
	(r, s) = map(int, input().split())
	uf1.union(r - 1, s - 1)
pairs = [(uf.find(i), uf1.find(i)) for i in range(N)]
c = Counter(pairs)
ans = [c[pairs[i]] for i in range(N)]
print(*ans)


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

def fp(x, parentList):
	if parentList[x] == x:
		return x
	else:
		parentList[x] = fp(parentList[x], parentList)
		return parentList[x]
road = [i for i in range(N)]
rail = [i for i in range(N)]
for _ in range(K):
	(p, q) = map(int, input().split())
	(par_p, par_q) = (fp(p - 1, road), fp(q - 1, road))
	if par_p < par_q:
		road[par_q] = par_p
	else:
		road[par_p] = par_q
for _ in range(L):
	(s, t) = map(int, input().split())
	(par_s, par_t) = (fp(s - 1, rail), fp(t - 1, rail))
	if par_s < par_t:
		rail[par_t] = par_s
	else:
		rail[par_s] = par_t
cnt = {}
for i in range(N):
	key = (fp(i, road), fp(i, rail))
	if key in cnt:
		cnt[key] += 1
	else:
		cnt[key] = 1
for i in range(N):
	key = (fp(i, road), fp(i, rail))
	ans = cnt[key]
	print(ans, end=' ')


from collections import Counter
(n, k, l) = map(int, input().split())
city1 = [i for i in range(n)]
city2 = [i for i in range(n)]

def root(c, x):
	if x == c[x]:
		return x
	else:
		c[x] = root(c, c[x])
		return c[x]

def union(c, x, y):
	rx = root(c, x)
	ry = root(c, y)
	if rx > ry:
		c[rx] = ry
	else:
		c[ry] = rx
for i in range(k):
	(a, b) = map(int, input().split())
	union(city1, a - 1, b - 1)
for i in range(l):
	(a, b) = map(int, input().split())
	union(city2, a - 1, b - 1)
r = []
for i in range(n):
	r.append((root(city1, i), root(city2, i)))
c = Counter(r)
for i in range(n):
	ans = c[r[i]]
	if i == n - 1:
		print(ans)
	else:
		print(ans, end=' ')


class UnionFind:

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

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

	def union(self, x, y):
		x = self.find(x)
		y = self.find(y)
		if x == y:
			return
		if self.par[x] > self.par[y]:
			(x, y) = (y, x)
		self.par[x] += self.par[y]
		self.par[y] = x
(N, K, L) = map(int, input().split())
Uni_1 = UnionFind(N)
Uni_2 = UnionFind(N)
D = {}
for _ in range(K):
	(p, q) = map(int, input().split())
	Uni_1.union(p - 1, q - 1)
for _ in range(L):
	(p, q) = map(int, input().split())
	Uni_2.union(p - 1, q - 1)
for i in range(N):
	k = (Uni_1.find(i), Uni_2.find(i))
	if k in D.keys():
		D[k] += 1
	else:
		D[k] = 1
for i in range(N):
	print(D[Uni_1.find(i), Uni_2.find(i)], end=' ')


from collections import Counter

class UnionFind:

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

	def find(self, x):
		if self.parents[x] < 0:
			return x
		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
(N, K, L) = map(int, input().split())
uf_road = UnionFind(N + 1)
uf_train = UnionFind(N + 1)
for _ in range(K):
	(p, q) = map(int, input().split())
	uf_road.union(p, q)
for _ in range(L):
	(s, t) = map(int, input().split())
	uf_train.union(s, t)
union_sets = [(uf_road.find(i), uf_train.find(i)) for i in range(1, N + 1)]
counts = Counter(union_sets)
ans = [counts[union_set] for union_set in union_sets]
print(' '.join((str(a) for a in ans)))


import sys
readline = sys.stdin.readline
from collections import Counter

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):
		return {r: self.members(r) for r in self.roots()}

	def __str__(self):
		return '\n'.join(('{}: {}'.format(r, self.members(r)) for r in self.roots()))

def main():
	(N, K, L) = map(int, readline().rstrip().split())
	uf_road = UnionFind(N)
	uf_train = UnionFind(N)
	for _ in range(K):
		(p, q) = map(int, readline().rstrip().split())
		uf_road.union(p - 1, q - 1)
	for _ in range(L):
		(r, s) = map(int, readline().rstrip().split())
		uf_train.union(r - 1, s - 1)
	pairs = []
	for i in range(N):
		pairs.append((uf_road.find(i), uf_train.find(i)))
	cnt = Counter(pairs)
	res = [cnt[pair] for pair in pairs]
	print(*res)

def __starting_point():
	main()
__starting_point()


from collections import Counter

class UnionFind:

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

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

	def unite(self, x, y):
		x = self.find(x)
		y = self.find(y)
		if x == y:
			return
		if self.rank[x] < self.rank[y]:
			self.par[x] = y
		else:
			self.par[y] = x
			if self.rank[x] == self.rank[y]:
				self.rank[x] += 1

	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]
(N, K, L) = map(int, input().split())
roads = [list(map(int, input().split())) for i in range(K)]
trains = [list(map(int, input().split())) for i in range(L)]
uf_road = UnionFind(N)
uf_train = UnionFind(N)
for road in roads:
	(x, y) = road
	uf_road.unite(x - 1, y - 1)
for train in trains:
	(x, y) = train
	uf_train.unite(x - 1, y - 1)
pairs = []
for i in range(N):
	pairs.append((uf_road.find(i), uf_train.find(i)))
cnt = Counter(pairs)
ans = [cnt[pair] for pair in pairs]
print(*ans)


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
import sys

def input():
	return sys.stdin.readline().strip()
(n, k, l) = map(int, input().split())
road = UnionFind(n)
rail = UnionFind(n)
for _ in range(k):
	(p, q) = map(int, input().split())
	road.union(p - 1, q - 1)
for _ in range(l):
	(r, s) = map(int, input().split())
	rail.union(r - 1, s - 1)
dic = {}
l = []
for i in range(n):
	tup = (road.find(i), rail.find(i))
	l.append(tup)
	if tup in dic:
		dic[tup] += 1
	else:
		dic[tup] = 1
ans = []
for i in l:
	ans.append(dic[i])
print(' '.join(map(str, ans)))


def main():

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

	def unite(x, y):
		x = find(x)
		y = find(y)
		if x == y:
			return False
		else:
			if par[x] > par[y]:
				(x, y) = (y, x)
			par[x] += par[y]
			par[y] = x
			return True

	def find2(x):
		if pa[x] < 0:
			return x
		else:
			pa[x] = find2(pa[x])
			return pa[x]
	import sys
	input = sys.stdin.readline
	(n, k, l) = [int(i) for i in input().split()]
	par = [-1] * n
	pa = [-1] * n
	ans = [0] * n
	for i in range(k):
		(p, q) = [int(i) for i in input().split()]
		unite(p - 1, q - 1)

	def unite2(x, y):
		x = find2(x)
		y = find2(y)
		if x == y:
			return False
		else:
			if pa[x] > pa[y]:
				(x, y) = (y, x)
			pa[x] += pa[y]
			pa[y] = x
			return True
	for i in range(l):
		(r, s) = [int(i) for i in input().split()]
		unite2(r - 1, s - 1)
	dic = {}
	chk = []
	for i in range(n):
		p1 = find(i)
		p2 = find2(i)
		chk.append((p1, p2))
		if (p1, p2) in dic:
			dic[p1, p2] += 1
		else:
			dic[p1, p2] = 1
	print(' '.join([str(dic[chk[i]]) for i in range(n)]))

def __starting_point():
	main()
__starting_point()


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):
		return {r: self.members(r) for r in self.roots()}

	def __str__(self):
		return '\n'.join(('{}: {}'.format(r, self.members(r)) for r in self.roots()))
(N, K, L) = list(map(int, input().split()))
pq = [list(map(int, input().split())) for i in range(K)]
rs = [list(map(int, input().split())) for i in range(L)]
uf_road = UnionFind(N)
uf_train = UnionFind(N)
for i in range(K):
	uf_road.union(pq[i][0] - 1, pq[i][1] - 1)
for i in range(L):
	uf_train.union(rs[i][0] - 1, rs[i][1] - 1)
from collections import Counter
pair = [(uf_road.find(i), uf_train.find(i)) for i in range(N)]
ans = Counter(pair)
print(*[ans[i] for i in pair])


from collections import defaultdict

class UnionFind:

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

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

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

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

def main():
	(n, k, l) = map(int, input().split())
	road = UnionFind(n)
	train = UnionFind(n)
	for _ in range(k):
		(p, q) = map(int, input().split())
		road.unite(p - 1, q - 1)
	for _ in range(l):
		(r, s) = map(int, input().split())
		train.unite(r - 1, s - 1)
	d = defaultdict(int)
	for i in range(n):
		d[road.find(i), train.find(i)] += 1
	ans = []
	for i in range(n):
		ans.append(d[road.find(i), train.find(i)])
	print(*ans)

def __starting_point():
	main()
__starting_point()


import sys
from collections import defaultdict
sys.setrecursionlimit(10 ** 6)
int1 = lambda x: int(x) - 1
p2D = lambda x: print(*x, sep='\n')

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

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

def MI1():
	return map(int1, sys.stdin.readline().split())

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

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

def SI():
	return sys.stdin.readline()[:-1]

class UnionFind:

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

	def root(self, u):
		v = self.state[u]
		if v < 0:
			return u
		self.state[u] = res = self.root(v)
		return res

	def merge(self, u, v):
		ru = self.root(u)
		rv = self.root(v)
		if ru == rv:
			return
		du = self.state[ru]
		dv = self.state[rv]
		if du > dv:
			(ru, rv) = (rv, ru)
		if du == dv:
			self.state[ru] -= 1
		self.state[rv] = ru
		return

def main():
	(n, k, l) = MI()
	road = UnionFind(n)
	train = UnionFind(n)
	for _ in range(k):
		(u, v) = MI1()
		road.merge(u, v)
	for _ in range(l):
		(u, v) = MI1()
		train.merge(u, v)
	cnt = defaultdict(int)
	for u in range(n):
		cnt[road.root(u), train.root(u)] += 1
	ans = [cnt[road.root(u), train.root(u)] for u in range(n)]
	print(*ans)
main()


(N, M, L) = [int(s) for s in input().split()]
parent_road = list(range(N))
parent_train = list(range(N))
rank_road = [0] * N
rank_train = [0] * N

class UnionFind:

	def __init__(self, n):
		self.parent = list(range(n))
		self.rank = [0] * N

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

	def union(self, x, y):
		x = self.find(x)
		y = self.find(y)
		if self.rank[x] < self.rank[y]:
			self.parent[x] = y
		else:
			self.parent[y] = x
			if self.rank[x] == self.rank[y]:
				self.rank[x] += 1
edge_road = [[int(s) - 1 for s in input().split()] for _ in range(M)]
edge_train = [[int(s) - 1 for s in input().split()] for _ in range(L)]
group_road = UnionFind(N)
group_train = UnionFind(N)
for (x, y) in edge_road:
	group_road.union(x, y)
for (x, y) in edge_train:
	group_train.union(x, y)
group_count = {}
group_list = []
for i in range(N):
	gr = group_road.find(i)
	gt = group_train.find(i)
	group_list.append((gr, gt))
	if (gr, gt) in list(group_count.keys()):
		group_count[gr, gt] += 1
	else:
		group_count[gr, gt] = 1
print(' '.join([str(group_count[g]) for g in group_list]))


import io
import math
import string

def col(n, m):
	X = [[] for _ in range(n)]
	for _ in range(m):
		(a, b) = map(int, input().split())
		X[a - 1].append(b - 1)
		X[b - 1].append(a - 1)
	C = [-1] * n
	c = 0
	for i in range(N):
		if C[i] >= 0:
			continue
		Q = [i]
		C[i] = c
		while Q:
			x = Q.pop()
			for y in X[x]:
				if C[y] == -1:
					C[y] = C[x]
					Q.append(y)
		c += 1
	return C
(N, K, L) = map(int, input().split())
A = col(N, K)
B = col(N, L)
D = {}
for (a, b) in zip(A, B):
	t = (a << 18) + b
	if t in D:
		D[t] += 1
	else:
		D[t] = 1
print(*[D[(a << 18) + b] for (a, b) in zip(A, B)])


from collections import Counter

class UnionFind:

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

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

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

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

	def get_size(self, x):
		return -self.parent[self.find(x)]

	def members(self, x, is_set=False):
		root = self.find(x)
		res = [i for i in range(self.node) if self.find(i) == root]
		if is_set:
			return set(res)
		return res

	def all_root(self):
		return [idx for (idx, val) in enumerate(self.parent) if val < 0]

def main():
	(cities, roads, railroads) = list(map(int, input().split()))
	uf_road = UnionFind(cities)
	uf_train = UnionFind(cities)
	for _ in range(roads):
		(p, q) = [int(x) - 1 for x in input().split()]
		uf_road.union(p, q)
	for _ in range(railroads):
		(r, s) = [int(x) - 1 for x in input().split()]
		uf_train.union(r, s)
	each_pair = []
	for i in range(cities):
		each_pair.append(tuple([uf_road.find(i), uf_train.find(i)]))
	pair_count = dict(Counter(each_pair))
	answer = [pair_count[each_pair[i]] for i in range(cities)]
	print(' '.join(map(str, answer)))

def __starting_point():
	main()
__starting_point()


import numpy as np
from collections import Counter
from scipy.sparse.csgraph import connected_components
from scipy.sparse import csr_matrix
int1 = lambda x: int(x) - 1
(N, K, L) = map(int, input().split())
roads = np.array([tuple(map(int1, input().split())) for _ in range(K)]).T
railways = np.array([tuple(map(int1, input().split())) for _ in range(L)]).T

def connected(G, M):
	matr = csr_matrix((np.ones(M, dtype=int), G), shape=(N, N))
	(_, labels) = connected_components(matr)
	return labels
roads_connection = connected(roads, K).tolist()
railways_connection = connected(railways, L).tolist()
ct = Counter(((roads_connection[i], railways_connection[i]) for i in range(N)))
ans = [ct[roads_connection[i], railways_connection[i]] for i in range(N)]
print(*ans)


from collections import Counter
(n, k, l) = map(int, input().split())

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):
	p = find(x, par)
	q = find(y, par)
	if p == q:
		return None
	if p > q:
		(p, q) = (q, p)
	par[p] += par[q]
	par[q] = p

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

def size(x):
	return -par[find(x)]
road_par = [-1 for i in range(n + 1)]
train_par = [-1 for i in range(n + 1)]
for i in range(k):
	(p, q) = map(int, input().split())
	unite(p, q, road_par)
for i in range(l):
	(r, s) = map(int, input().split())
	unite(r, s, train_par)
ans = []
for i in range(n):
	ans.append((find(i + 1, road_par), find(i + 1, train_par)))
c = Counter(ans)
for i in ans:
	print(c[i], end=' ')


from sys import stdin
import sys
import math
from functools import reduce
import functools
import itertools
from collections import deque, Counter
from operator import mul
import copy
(n, k, l) = list(map(int, input().split()))
road = [[] for i in range(n + 1)]
rail = [[] for i in range(n + 1)]
for i in range(k):
	(p, q) = list(map(int, input().split()))
	road[p].append(q)
	road[q].append(p)
for i in range(l):
	(r, s) = list(map(int, input().split()))
	rail[r].append(s)
	rail[s].append(r)
seen = [0 for i in range(n + 1)]

def dfs_stack(u, al, al_c, d):
	stack = deque([u])
	seen[u] = 1
	while len(stack) > 0:
		v = stack.pop()
		al_c[v] = d
		for w in al[v]:
			if seen[w] == 0:
				stack.append(w)
				seen[w] = 1
		if stack == []:
			break
road_c = [-1 for i in range(n + 1)]
rail_c = [-1 for i in range(n + 1)]
d = 0
for i in range(1, n + 1):
	if seen[i] == 0:
		dfs_stack(i, road, road_c, d)
		d += 1
seen = [0 for i in range(n + 1)]
d = 0
for i in range(1, n + 1):
	if seen[i] == 0:
		dfs_stack(i, rail, rail_c, d)
		d += 1
dict = {}
for i in range(1, n + 1):
	if (road_c[i], rail_c[i]) not in dict:
		dict[road_c[i], rail_c[i]] = [i]
	else:
		dict[road_c[i], rail_c[i]].append(i)
ans = [0 for i in range(n + 1)]
for dd in list(dict.items()):
	for j in dd[1]:
		ans[j] = str(len(dd[1]))
print(' '.join(ans[1:]))


class UnionFind:

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

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

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

	def union(self, x, y):
		r1 = self._root(x)
		r2 = self._root(y)
		if r1 == r2:
			return
		d1 = self.table[r1]
		d2 = self.table[r2]
		if d1 <= d2:
			self.table[r2] = r1
			if d1 == d2:
				self.table[r1] -= 1
		else:
			self.table[r1] = r2

def __starting_point():
	(n, k, l) = map(int, input().split())
	pq = UnionFind(n + 1)
	rs = UnionFind(n + 1)
	for i in range(k):
		(p, q) = map(int, input().split())
		pq.union(p, q)
	for i in range(l):
		(r, s) = map(int, input().split())
		rs.union(r, s)
	sameroot = []
	for i in range(1, n + 1):
		sameroot.append([pq._root(i), rs._root(i), i])
	sameroot.sort()
	sameroot.append([0, 0, n + 1])
	cnt = [0] * (n + 1)
	(bx, by) = (0, 0)
	samelist = []
	for (x, y, i) in sameroot:
		if bx == x and by == y:
			samelist.append(i)
		else:
			k = len(samelist)
			if k > 0:
				for j in samelist:
					cnt[j] = k
			samelist = [i]
			(bx, by) = (x, y)
	print(' '.join(map(str, cnt[1:])))
__starting_point()


import sys
import heapq, math
from itertools import zip_longest, permutations, combinations, combinations_with_replacement
from itertools import accumulate, dropwhile, takewhile, groupby
from functools import lru_cache
from copy import deepcopy

class UnionFind:

	def __init__(self, n: int):
		self._n = n
		self._parents = [i for i in range(n)]
		self._size = [1 for _ in range(n)]

	def unite(self, x: int, y: int) -> None:
		px = self.find(x)
		py = self.find(y)
		if px != py:
			self._link(px, py)

	def _link(self, x: int, y: int):
		if self._size[x] < self._size[y]:
			self._parents[x] = y
			self._size[y] += self._size[x]
		else:
			self._parents[y] = x
			self._size[x] += self._size[y]

	def same(self, x: int, y: int) -> bool:
		px = self.find(x)
		py = self.find(y)
		return px == py

	def find(self, x: int) -> int:
		if self._parents[x] == x:
			return x
		self._parents[x] = self.find(self._parents[x])
		return self._parents[x]

	def size(self, x: int):
		return self._size[self.find(self._parents[x])]
(N, K, L) = map(int, input().split())
road = UnionFind(N + 1)
rail = UnionFind(N + 1)
share = UnionFind(N + 1)
roads = [list(map(int, input().split())) for _ in range(K)]
rails = [list(map(int, input().split())) for _ in range(L)]
for i in range(K):
	(p, q) = roads[i]
	road.unite(p, q)
for i in range(L):
	(r, s) = rails[i]
	rail.unite(r, s)
m = {}
for i in range(1, N + 1):
	cnt = m.get((road.find(i), rail.find(i)), 0)
	m[road.find(i), rail.find(i)] = cnt + 1
ans = [0] * N
for i in range(N):
	ans[i] = m[road.find(i + 1), rail.find(i + 1)]
print(*ans)


import collections

class UnionFind:

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

	def root(self, x):
		if self.par[x] == -1:
			return x
		else:
			self.par[x] = self.root(self.par[x])
			return self.par[x]

	def unite(self, x, y):
		x_r = self.root(x)
		y_r = self.root(y)
		if self.rank[x_r] > self.rank[y_r]:
			self.par[y_r] = x_r
		elif self.rank[x_r] < self.rank[y_r]:
			self.par[x_r] = y_r
		elif x_r != y_r:
			self.par[y_r] = x_r
			self.rank[x_r] += 1
		if x_r != y_r:
			size = self.tsize[x_r] + self.tsize[y_r]
			self.tsize[x_r] = size
			self.tsize[y_r] = size

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

	def size(self, x):
		return self.tsize[self.root(x)]

def main():
	(n, k, l) = tuple([int(t) for t in input().split()])
	uf_k = UnionFind(n)
	uf_l = UnionFind(n)
	pq = [[int(t) - 1 for t in input().split()] for _ in [0] * k]
	for (p, q) in pq:
		uf_k.unite(p, q)
	rs = [[int(t) - 1 for t in input().split()] for _ in [0] * l]
	for (r, s) in rs:
		uf_l.unite(r, s)
	pair = []
	for i in range(n):
		pair.append((uf_k.root(i), uf_l.root(i)))
	counter = collections.Counter(pair)
	ans = []
	for a in pair:
		ans.append(counter[a])
	print(*ans)

def __starting_point():
	main()
__starting_point()


class UnionFind(object):

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

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

	def union(self, x, y):
		x = self.find(x)
		y = self.find(y)
		if x != y:
			if self.rank[x] < self.rank[y]:
				(x, y) = (y, x)
			if self.rank[x] == self.rank[y]:
				self.rank[x] += 1
			self.par[y] = x
			self.size[x] += self.size[y]

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

	def get_size(self, x):
		x = self.find(x)
		return self.size[x]
import collections
(N, K, L) = map(int, input().split())
uf1 = UnionFind(N)
for i in range(K):
	(p, q) = map(int, input().split())
	uf1.union(p - 1, q - 1)
uf2 = UnionFind(N)
for j in range(L):
	(r, s) = map(int, input().split())
	uf2.union(r - 1, s - 1)
list = []
for i in range(N):
	list.append((uf1.find(i), uf2.find(i)))
count = collections.Counter(list)
for i in range(N):
	ans = count[list[i]]
	if i == N - 1:
		print(ans)
	else:
		print(ans, end=' ')


import sys
sys.setrecursionlimit(10 ** 6)
INF = float('inf')
MOD = 10 ** 9 + 7

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

class UnionFind:

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

	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 unite(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 get_size(self, x):
		return -self.parents[self.find(x)]

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

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

	def get_members(self, x):
		parent = self.find(x)
		return [i for i in range(self.n_nodes) if self.find(i) == parent]

	def get_members_dict(self):
		return {par: self.get_members(par) for par in self.get_parent_list()}

def main():
	(N, K, L) = map(int, input().split())
	tree_road = UnionFind(N)
	tree_subway = UnionFind(N)
	for _ in range(K):
		(p, q) = map(int, input().split())
		p -= 1
		q -= 1
		tree_road.unite(p, q)
	for _ in range(L):
		(r, s) = map(int, input().split())
		r -= 1
		s -= 1
		tree_subway.unite(r, s)
	d = {}
	for i in range(N):
		p1 = tree_road.find(i)
		p2 = tree_subway.find(i)
		if (p1, p2) not in d:
			d[p1, p2] = 1
		else:
			d[p1, p2] += 1
	for i in range(N):
		p1 = tree_road.find(i)
		p2 = tree_subway.find(i)
		print(d[p1, p2], end=' ')

def __starting_point():
	main()
__starting_point()


from collections import Counter

class UnionFind:

	def __init__(self, n: int) -> None:
		self.parent = [i for i in range(n)]
		self.rank = [0 for _ in range(n)]

	def find(self, i: int) -> None:
		if self.parent[i] == i:
			return i
		else:
			return self.find(self.parent[i])

	def unite(self, i: int, j: int) -> None:
		root_i = self.find(i)
		root_j = self.find(j)
		if root_i == root_j:
			return
		if self.rank[root_i] < self.rank[root_j]:
			self.parent[root_i] = root_j
		else:
			self.parent[root_j] = root_i
			if self.rank[root_i] == self.rank[root_j]:
				self.rank[root_i] += 1
(N, K, L) = map(int, input().split())
uf1 = UnionFind(N)
for _ in range(K):
	(i, j) = map(int, input().split())
	uf1.unite(i - 1, j - 1)
uf2 = UnionFind(N)
for _ in range(L):
	(i, j) = map(int, input().split())
	uf2.unite(i - 1, j - 1)
set_id_pairs = [(uf1.find(i), uf2.find(i)) for i in range(N)]
counter = Counter(set_id_pairs)
counts = [counter[set_id_pairs[i]] for i in range(N)]
print(' '.join((str(c) for c in counts)))


def makeTree(a):
	aT = list(range(N + 1))
	for (p, q) in a:
		rootp = getRoot(aT, p)
		rootq = getRoot(aT, q)
		thisRoot = max(rootp, rootq, q)
		aT[p] = thisRoot
		aT[q] = thisRoot
		aT[rootp] = thisRoot
		aT[rootq] = thisRoot
	return aT

def getRoot(a, i):
	if a[i] == i:
		return i
	else:
		a[i] = getRoot(a, a[i])
		return a[i]
(N, K, L) = list(map(int, input().split()))
pqrs = []
for idx1 in range(K + L):
	(temp0, temp1) = list(map(int, input().split()))
	pqrs.append([temp0, temp1])
MTree = makeTree(pqrs[0:K])
TTree = makeTree(pqrs[K:])
aRet = []
dRet = {}
for idx1 in range(1, N + 1):
	Comb = (getRoot(MTree, idx1), getRoot(TTree, idx1))
	aRet.append(Comb)
	if Comb in dRet:
		dRet[Comb] += 1
	else:
		dRet[Comb] = 1
print(' '.join([str(dRet[_]) for _ in aRet]))


from collections import deque
(n, k, l) = map(int, input().split())
ep = [[] for i in range(n)]
er = [[] for i in range(n)]
gp = [-1] * n
gr = [-1] * n
for i in range(k):
	(a, b) = map(int, input().split())
	a -= 1
	b -= 1
	ep[a].append(b)
	ep[b].append(a)
for i in range(l):
	(a, b) = map(int, input().split())
	a -= 1
	b -= 1
	er[a].append(b)
	er[b].append(a)

def dfs(e, g):
	count = 0
	for i in range(n):
		if g[i] == -1:
			g[i] = count
			q = deque([])
			q.append(i)
			while q:
				now = q.pop()
				for nex in e[now]:
					if g[nex] == -1:
						g[nex] = g[now]
						q.append(nex)
			count += 1
	return g
gp = dfs(ep, gp)
gr = dfs(er, gr)
l = []
dic = {}
for i in range(n):
	s = (gp[i], gr[i])
	l.append(s)
	if s in dic:
		dic[s] += 1
	else:
		dic[s] = 1
ans = [0] * n
for i in range(n):
	ans[i] = dic[l[i]]
print(*ans)


(n, k, l) = map(int, input().split())

class UnionFind:
	__slots__ = ['_size', '_first_idx', '_parents']

	def __init__(self, size: int, first_index: int=0) -> None:
		self._size = size
		self._first_idx = first_index
		self._parents = [-1] * (size + first_index)

	def find(self, x: int) -> int:
		if self._parents[x] < 0:
			return x
		news = []
		p = self._parents
		y = p[x]
		while y >= 0:
			news.append(x)
			(x, y) = (y, p[y])
		if len(news) != 1:
			for P in news:
				p[P] = x
		return x

	def same(self, x: int, y: int) -> bool:
		return self.find(x) == self.find(y)

	def unite(self, x: int, y: int) -> bool:
		(x, y) = (self.find(x), self.find(y))
		if x == y:
			return False
		if self._parents[x] > self._parents[y]:
			(x, y) = (y, x)
		self._parents[x] += self._parents[y]
		self._parents[y] = x
		return True

	def size(self, x: int) -> int:
		return -self._parents[self.find(x)]

	def group_count(self) -> int:
		return sum((1 for i in self._parents if i < 0)) - self._first_idx

	def connected(self) -> bool:
		return self._parents[self.find(self._first_idx)] == -self._size
road = UnionFind(1, n)
rail = UnionFind(1, n)
for i in range(k):
	road.unite(*map(int, input().split()))
for i in range(l):
	rail.unite(*map(int, input().split()))
from collections import defaultdict
d = defaultdict(int)
for i in range(1, n + 1):
	(ap, op) = (rail.find(i), road.find(i))
	d[ap * (n + 1) + op] += 1
print(*[d[road.find(i) + rail.find(i) * (n + 1)] for i in range(1, n + 1)])


import sys

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):
		return {r: self.members(r) for r in self.roots()}

	def __str__(self):
		return '\n'.join(('{}: {}'.format(r, self.members(r)) for r in self.roots()))
(N, K, L) = map(int, input().split())
uf_road = UnionFind(N)
uf_train = UnionFind(N)
for i in range(K):
	(p, q) = map(int, input().split())
	p -= 1
	q -= 1
	uf_road.union(p, q)
for i in range(L):
	(p, q) = map(int, input().split())
	p -= 1
	q -= 1
	uf_train.union(p, q)
pair_list = []
for i in range(N):
	pair_list.append((uf_road.find(i), uf_train.find(i), i))
pair_list.sort()
ans = [0] * N
pair = (pair_list[0][0], pair_list[0][1])
countup_list = [pair_list[0][2]]
for i in range(1, N):
	if pair == (pair_list[i][0], pair_list[i][1]):
		countup_list.append(pair_list[i][2])
	else:
		for c in countup_list:
			ans[c] += len(countup_list)
		pair = (pair_list[i][0], pair_list[i][1])
		countup_list = [pair_list[i][2]]
for c in countup_list:
	ans[c] += len(countup_list)
for i in range(N):
	print(ans[i], end=' ')


import sys
sys.setrecursionlimit(10 ** 7)
from collections import Counter

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):
		return {r: self.members(r) for r in self.roots()}

	def __str__(self):
		return '\n'.join(('{}: {}'.format(r, self.members(r)) for r in self.roots()))
(n, k, l) = map(int, input().split())
load = UnionFind(n + 1)
tetsu = UnionFind(n + 1)
for _ in range(k):
	(p, q) = map(int, input().split())
	load.union(p, q)
for _ in range(l):
	(r, s) = map(int, input().split())
	tetsu.union(r, s)
count = [(load.find(i), tetsu.find(i)) for i in range(1, n + 1)]
C = Counter(count)
ans = []
for i in range(n):
	if count[i][0] < 0 or count[i][1] < 0:
		ans.append(0)
	else:
		ans.append(C[count[i]])
print(*ans)


(n, k, l) = map(int, input().split())
load = [[] for _ in range(n)]
train = [[] for _ in range(n)]
for _ in range(k):
	(a, b) = map(int, input().split())
	a -= 1
	b -= 1
	load[a].append(b)
	load[b].append(a)
for _ in range(l):
	(a, b) = map(int, input().split())
	a -= 1
	b -= 1
	train[a].append(b)
	train[b].append(a)
load_grp_id = [-1] * n
not_grp = set(range(n))
while not_grp:
	t0 = not_grp.pop()
	todo = [t0]
	load_grp_id[t0] = t0
	while todo:
		t = todo.pop()
		l = load[t]
		for li in l:
			if load_grp_id[li] == -1:
				load_grp_id[li] = t0
				not_grp.discard(li)
				todo.append(li)
train_grp_id = [-1] * n
not_grp = set(range(n))
while not_grp:
	t0 = not_grp.pop()
	todo = [t0]
	train_grp_id[t0] = t0
	while todo:
		t = todo.pop()
		l = train[t]
		for li in l:
			if train_grp_id[li] == -1:
				train_grp_id[li] = t0
				not_grp.discard(li)
				todo.append(li)
d = {}
for i in range(n):
	lid = load_grp_id[i]
	tid = train_grp_id[i]
	if (lid, tid) in d:
		d[lid, tid] += 1
	else:
		d[lid, tid] = 1
ans = []
for i in range(n):
	lid = load_grp_id[i]
	tid = train_grp_id[i]
	ans.append(str(d[lid, tid]))
print(' '.join(ans))


from collections import defaultdict

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 unite(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 -size.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):
		return {r: self.members(r) for r in self.roots()}
(n, k, l) = map(int, input().split())
uf1 = UnionFind(n)
for _ in range(k):
	(u, v) = map(int, input().split())
	uf1.unite(u - 1, v - 1)
uf2 = UnionFind(n)
for _ in range(l):
	(u, v) = map(int, input().split())
	uf2.unite(u - 1, v - 1)
d = defaultdict(int)
for i in range(n):
	d[uf1.find(i), uf2.find(i)] += 1
ans = [d[uf1.find(i), uf2.find(i)] for i in range(n)]
print(*ans)


import sys
from collections import deque
from collections import defaultdict
from collections import Counter

def conn(n, m, e):
	d = dict(list(zip(list(range(1, n + 1)), list(range(-1, -1 * n - 1, -1)))))
	td = defaultdict(lambda : deque([]))
	c = 1
	for edge in e:
		a = edge[0]
		b = edge[1]
		da = d[a]
		db = d[b]
		if da < 0 and db < 0:
			d[a] = c
			d[b] = c
			td[c].append(a)
			td[c].append(b)
			c += 1
		elif da > 0 and db < 0:
			d[b] = da
			td[d[a]].append(b)
		elif da < 0 and db > 0:
			d[a] = db
			td[d[b]].append(a)
		elif da > 0 and db > 0 and (da != db):
			for x in td[db]:
				d[x] = da
				td[da].append(x)
	return list(d.values())

def components(n, k, e):
	ed = defaultdict(lambda : deque())
	for edge in e:
		ed[edge[0]].append(edge[1])
	c = 0
	s = [0] * n
	label = [0] * n
	for i in range(1, n + 1):
		if s[i - 1] == 0:
			c += 1
			label[c - 1] = c
			stack = deque([i])
			while stack:
				w = stack.pop()
				s[w - 1] = c
				while ed[w]:
					wn = ed[w].pop()
					if s[wn - 1] == 0:
						s[wn - 1] = c
						if ed[wn]:
							stack.append(w)
							w = wn
					elif s[wn - 1] < c:
						label[s[wn - 1] - 1] = c
	return [label[s[i] - 1] for i in range(n)]

def components2(n, k, e):
	ed = defaultdict(lambda : deque())
	for edge in e:
		ed[edge[0]].append(edge[1])
		ed[edge[1]].append(edge[0])
	c = 0
	s = [0] * n
	for i in range(1, n + 1):
		if s[i - 1] == 0:
			c += 1
			stack = deque([i])
			while stack:
				w = stack.pop()
				s[w - 1] = c
				while ed[w]:
					wn = ed[w].pop()
					if s[wn - 1] == 0:
						s[wn - 1] = c
						if ed[wn]:
							stack.append(w)
							w = wn
	return [s[i] for i in range(n)]

def main(n, k, l, e1, e2):
	d1 = components2(n, k, e1)
	d2 = components2(n, l, e2)
	p = tuple(zip(iter(d1), iter(d2)))
	d = Counter(p)
	print(' '.join([str(d[x]) for x in p]))

def __starting_point():
	ssr = sys.stdin.readline
	(n, k, l) = list(map(int, ssr().strip().split()))
	e1 = []
	e2 = []
	for _ in range(k):
		e1.append(tuple(map(int, ssr().strip().split())))
	for _ in range(l):
		e2.append(tuple(map(int, ssr().strip().split())))
	main(n, k, l, e1, e2)
__starting_point()


from collections import defaultdict

class UnionFind:

	def __init__(self, n):
		self.parents = [i for i in range(n + 1)]
		self.ranks = [0 for _ in range(n + 1)]

	def find_root(self, node):
		parent_node = self.parents[node]
		if parent_node == node:
			return node
		else:
			root_node = self.find_root(parent_node)
			self.parents[node] = root_node
			return root_node

	def union(self, one, other):
		one_root = self.find_root(one)
		other_root = self.find_root(other)
		if one_root == other_root:
			return
		if self.ranks[one_root] < self.ranks[other_root]:
			self.parents[one_root] = other_root
		else:
			self.parents[other_root] = one_root
			if self.ranks[one_root] == self.ranks[other_root]:
				self.ranks[one_root] += 1

	def is_same_group(self, one, other):
		one_root = self.find_root(one)
		other_root = self.find_root(other)
		return one_root == other_root

def main():
	(N, K, L) = list(map(int, input().split(' ')))
	road_tree = UnionFind(N)
	for _ in range(K):
		(p, q) = list(map(int, input().split(' ')))
		road_tree.union(p, q)
	train_tree = UnionFind(N)
	for _ in range(L):
		(r, s) = list(map(int, input().split(' ')))
		train_tree.union(r, s)
	group_count = defaultdict(int)
	group_list = list()
	for node in range(1, N + 1):
		group = (road_tree.find_root(node), train_tree.find_root(node))
		group_count[group] += 1
		group_list.append(group)
	answer = ' '.join(list(map(lambda g: str(group_count[g]), group_list)))
	print(answer)

def __starting_point():
	main()
__starting_point()


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):
		return {r: self.members(r) for r in self.roots()}

	def __str__(self):
		return '\n'.join(('{}: {}'.format(r, self.members(r)) for r in self.roots()))

def main():
	(n, k, l) = map(int, input().split())
	p = [list(map(int, input().split())) for _ in range(k)]
	r = [list(map(int, input().split())) for _ in range(l)]
	uf1 = UnionFind(n)
	for (a, b) in p:
		uf1.union(a - 1, b - 1)
	uf2 = UnionFind(n)
	for (a, b) in r:
		uf2.union(a - 1, b - 1)
	dic = {}
	for i in range(n):
		(rt1, rt2) = (uf1.find(i), uf2.find(i))
		if (rt1, rt2) in dic:
			dic[rt1, rt2] += 1
		else:
			dic[rt1, rt2] = 1
	for i in range(n):
		(rt1, rt2) = (uf1.find(i), uf2.find(i))
		print(dic[rt1, rt2], end=' ')

def __starting_point():
	main()
__starting_point()


from collections import Counter

class UnionFind:

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

	def find(self, x):
		if self.parents[x] < 0:
			return x
		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 abs(self.parents[self.find(x)])
(N, K, L) = list(map(int, input().split()))
uf_road = UnionFind(N + 1)
uf_train = UnionFind(N + 1)
road_dict = dict()
train_dict = dict()
for _ in range(K):
	(p, q) = list(map(int, input().split()))
	uf_road.union(p, q)
for _ in range(L):
	(r, s) = list(map(int, input().split()))
	uf_train.union(r, s)
set_id_pairs = [(uf_road.find(i), uf_train.find(i)) for i in range(1, N + 1)]
counter = Counter(set_id_pairs)
counts = [counter[set_id_pairs[i]] for i in range(N)]
print(' '.join((str(c) for c in counts)))


import sys
mod = 10 ** 9 + 7
inf = float('inf')
from math import sqrt, ceil
from collections import deque, Counter, defaultdict
input = lambda : sys.stdin.readline().strip()
sys.setrecursionlimit(11451419)
from decimal import ROUND_HALF_UP, Decimal
from functools import lru_cache
from bisect import bisect_left as bileft, bisect_right as biright

class UnionFind:

	def __init__(self, num):
		self.n = num
		self.parents = [-1 for i in range(self.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):
		xx = self.find(x)
		yy = self.find(y)
		if xx == yy:
			return
		else:
			size_xx = abs(self.parents[xx])
			size_yy = abs(self.parents[yy])
			if size_xx > size_yy:
				(xx, yy) = (yy, xx)
			self.parents[yy] += self.parents[xx]
			self.parents[xx] = yy

	def size(self, x):
		xx = self.find(x)
		return abs(self.parents[xx])

	def same(self, x, y):
		return 1 if self.find(x) == self.find(y) else 0

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

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

	def all_group_members(self):
		return {r: self.members(r) for r in self.roots()}

	def state_grouping(self):
		return list(self.all_group_members().values())
(n, k, l) = map(int, input().split())
uf = UnionFind(n)
uf2 = UnionFind(n)
for i in range(k):
	(p, q) = map(int, input().split())
	p -= 1
	q -= 1
	uf.union(p, q)
for i in range(l):
	(p, q) = map(int, input().split())
	p -= 1
	q -= 1
	if 1:
		uf2.union(p, q)
C = Counter([(uf.find(i), uf2.find(i)) for i in range(n)])
ANS = [0] * n
for i in range(n):
	ANS[i] = C[uf.find(i), uf2.find(i)]
print(*ANS)


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):
		return {r: self.members(r) for r in self.roots()}

	def __str__(self):
		return '\n'.join(('{}: {}'.format(r, self.members(r)) for r in self.roots()))
from collections import Counter
(n, k, l) = map(int, input().split())
a = [list(map(int, input().split())) for i in range(k)]
b = [list(map(int, input().split())) for i in range(l)]
uf1 = UnionFind(n)
uf2 = UnionFind(n)
for i in a:
	uf1.union(i[0] - 1, i[1] - 1)
for i in b:
	uf2.union(i[0] - 1, i[1] - 1)
l = [[0, 0] for i in range(n)]
for i in range(n):
	l[i][0] = uf1.find(i)
	l[i][1] = uf2.find(i)
	l[i] = tuple([l[i][0], l[i][1]])
c = Counter(l)
for i in range(n):
	print(c[l[i]], end=' ')


from collections import defaultdict

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):
		return {r: self.members(r) for r in self.roots()}

	def __str__(self):
		return '\n'.join(('{}: {}'.format(r, self.members(r)) for r in self.roots()))
(n, k, l) = map(int, input().split())
uf = UnionFind(n)
(p, q) = ([0] * k, [0] * k)
for i in range(k):
	(pp, qq) = map(int, input().split())
	p[i] = pp - 1
	q[i] = qq - 1
	uf.union(pp - 1, qq - 1)
uuff = UnionFind(n)
(r, s) = ([0] * l, [0] * l)
for i in range(l):
	(rr, ss) = map(int, input().split())
	r[i] = rr - 1
	s[i] = ss - 1
	uuff.union(rr - 1, ss - 1)
dic = defaultdict(int)
for i in range(n):
	dic[uf.find(i), uuff.find(i)] += 1
ans = []
for i in range(n):
	ans.append(dic[uf.find(i), uuff.find(i)])
for i in ans:
	print(i, end=' ')


import sys
from collections import defaultdict

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

class UnionFind:

	def __init__(self, n_nodes):
		self.n_nodes = n_nodes
		self.parent = [i for i in range(n_nodes)]
		self.rank = [1] * n_nodes
		self.size = [1] * n_nodes

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

	def unite(self, x, y):
		x = self.find(x)
		y = self.find(y)
		if x == y:
			return
		if self.rank[x] > self.rank[y]:
			self.parent[y] = x
			self.size[x] += self.size[y]
		else:
			self.parent[x] = y
			self.size[y] += self.size[x]
			if self.rank[x] == self.rank[y]:
				self.rank[y] += 1

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

	def get_parent_list(self):
		return [i for i in range(self.n_nodes) if self.find(i) == i]

	def get_n_groups(self):
		return len(self.get_parent_list())

	def get_members(self, x):
		parent = self.find(x)
		return [i for i in range(self.n_nodes) if self.find(i) == parent]

	def get_members_dict(self):
		return {par: self.get_members(par) for par in self.get_parent_list()}

def main():
	(N, K, L) = map(int, input().split())
	Tree_road = UnionFind(N)
	Tree_train = UnionFind(N)
	for _ in range(K):
		(p, q) = map(int, input().split())
		Tree_road.unite(p - 1, q - 1)
	for _ in range(L):
		(p, q) = map(int, input().split())
		Tree_train.unite(p - 1, q - 1)
	DD = defaultdict(int)
	for i in range(N):
		DD[Tree_road.find(i), Tree_train.find(i)] += 1
	answer = []
	for i in range(N):
		answer.append(DD[Tree_road.find(i), Tree_train.find(i)])
	print(*answer, sep=' ')

def __starting_point():
	main()
__starting_point()


import sys
input = sys.stdin.readline
import numpy as np

class UnionFind:

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

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

	def unite(self, x, y):
		x = self.find(x)
		y = self.find(y)
		if self.rank[x] < self.rank[y]:
			self.par[x] = y
		else:
			self.par[y] = x
			if self.rank[x] == self.rank[y]:
				self.rank[x] += 1

	def check(self, x, y):
		return self.find(x) == self.find(y)
(N, K, L) = map(int, input().split())
PQ = [tuple(map(int, input().split())) for _ in range(K)]
RS = [tuple(map(int, input().split())) for _ in range(L)]
A = UnionFind(N)
for (p, q) in PQ:
	A.unite(p - 1, q - 1)
B = UnionFind(N)
for (r, s) in RS:
	B.unite(r - 1, s - 1)
from collections import defaultdict
dic = defaultdict(int)
for i in range(N):
	dic[A.find(i), B.find(i)] += 1
Ans = list((dic[A.find(i), B.find(i)] for i in range(N)))
print(' '.join(map(str, Ans)))


class UnionFind:

	def __init__(self, N):
		self.N = N
		self.parent = [-1] * N

	def root(self, i):
		if self.parent[i] < 0:
			return i
		r = self.root(self.parent[i])
		self.parent[i] = r
		return r

	def unite(self, i, j):
		i = self.root(i)
		j = self.root(j)
		if i == j:
			return
		if i > j:
			(i, j) = (j, i)
		self.parent[i] += self.parent[j]
		self.parent[j] = i

	def same(self, i, j):
		return self.root(i) == self.root(j)

	def size(self, i):
		return -self.parent[self.root(i)]

	def roots(self):
		return [self.root(i) for i in range(self.N)]
(N, K, L) = map(int, input().split())
road = UnionFind(N)
rail = UnionFind(N)
for _ in range(K):
	(p, q) = map(int, input().split())
	p += -1
	q += -1
	road.unite(p, q)
for _ in range(L):
	(r, s) = map(int, input().split())
	r += -1
	s += -1
	rail.unite(r, s)
pair = {}
for (i, j) in zip(road.roots(), rail.roots()):
	t = (i, j)
	if t in pair:
		pair[t] += 1
	else:
		pair[t] = 1
ans = ' '.join([str(pair[i, j]) for (i, j) in zip(road.roots(), rail.roots())])
print(ans)


from collections import defaultdict
import sys
sys.setrecursionlimit(10 ** 9)
input = sys.stdin.readline
(N, K, L) = map(int, input().split())

def get_par(x):
	if x == par_list[x]:
		return x
	else:
		par_list[x] = get_par(par_list[x])
		return par_list[x]

def merge(x, y):
	par_x = get_par(x)
	par_y = get_par(y)
	if par_x != par_y:
		par_list[par_y] = par_x

def is_same(x, y):
	return get_par(x) == get_par(y)
par_list = list(range(N + 1))
for _ in range(K):
	(p, q) = map(int, input().split())
	merge(p, q)
for i in range(1, N + 1):
	par_list[i] = get_par(i)
par_list_road = par_list[:]
par_list = list(range(N + 1))
for _ in range(L):
	(r, s) = map(int, input().split())
	merge(r, s)
for i in range(1, N + 1):
	par_list[i] = get_par(i)
par_list_rail = par_list[:]
answer_dic = defaultdict(int)
for i in range(1, N + 1):
	road_i = par_list_road[i]
	rail_i = par_list_rail[i]
	answer_dic[road_i, rail_i] += 1
answer_list = []
for i in range(1, N + 1):
	road_i = par_list_road[i]
	rail_i = par_list_rail[i]
	answer_list.append(answer_dic[road_i, rail_i])
print(*answer_list)


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

class UnionFind:

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

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

	def union_merge(self, x, y):
		x = self.find_root(x)
		y = self.find_root(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 union_size(self, x):
		return -self.parents[self.find_root(x)]

	def is_same_union(self, x, y):
		return self.find_root(x) == self.find_root(y)

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

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

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

	def all_unions(self):
		return [self.same_union_members(r) for r in self.roots()]
road = UnionFind(N)
rail = UnionFind(N)
for i in range(K):
	(p, k) = list(map(int, input().split()))
	road.union_merge(p - 1, k - 1)
for i in range(L):
	(r, s) = list(map(int, input().split()))
	rail.union_merge(r - 1, s - 1)
root_combinations = []
for i in range(N):
	root_combinations.append((road.find_root(i), rail.find_root(i)))
from collections import Counter
same_combinations = Counter(root_combinations)
result = [same_combinations[root_combination] for root_combination in root_combinations]
ans = ' '.join(map(str, result))
print(ans)


class UnionFind:

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

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

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

	def union(self, x, y):
		x = self.find(x)
		y = self.find(y)
		if self.rank[x] < self.rank[y]:
			self.par[x] = y
		elif self.rank[x] > self.rank[y]:
			self.par[y] = x
		else:
			self.par[y] = x
			self.rank[x] += 1
(N, K, L) = map(int, input().split())
A = [list(map(int, input().split())) for i in range(K)]
B = [list(map(int, input().split())) for i in range(L)]
road = UnionFind(N)
train = UnionFind(N)
for i in range(K):
	road.union(A[i][0], A[i][1])
for i in range(L):
	train.union(B[i][0], B[i][1])
pair = [(road.find(i), train.find(i)) for i in range(1, N + 1)]
from collections import Counter
c = Counter(pair)
print(*[c[i] for i in pair])


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 unite(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):
		return {r: self.members(r) for r in self.roots()}

	def __str__(self):
		return '\n'.join(('{}: {}'.format(r, self.members(r)) for r in self.roots()))

def renketu(n, k, l, pqli, rsli):
	from collections import defaultdict
	ans = []
	pquf = UnionFind(n)
	rsuf = UnionFind(n)
	[pquf.unite(p - 1, q - 1) for (q, p) in pqli]
	[rsuf.unite(r - 1, s - 1) for (r, s) in rsli]
	ansdict = defaultdict(int)
	for i in range(n):
		ansdict[pquf.find(i), rsuf.find(i)] += 1
	for i in range(n):
		ans.append(ansdict[pquf.find(i), rsuf.find(i)])
	return ans

def main():
	(n, k, l) = map(int, input().split())
	pqli = [list(map(int, input().split())) for i in range(k)]
	rsli = [list(map(int, input().split())) for i in range(l)]
	ans = renketu(n, k, l, pqli, rsli)
	print(*ans)

def __starting_point():
	main()
__starting_point()


from collections import Counter

class UnionFind:

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

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

	def unite(self, x, y):
		x = self.find(x)
		y = self.find(y)
		if x == y:
			return
		if self.rank[x] < self.rank[y]:
			self.par[x] = y
		else:
			self.par[y] = x
			if self.rank[x] == self.rank[y]:
				self.rank[x] += 1

	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]
(n, k, l) = map(int, input().split())
pq = [list(map(int, input().split())) for i in range(k)]
rs = [list(map(int, input().split())) for i in range(l)]
uf_pq = UnionFind(n)
uf_rs = UnionFind(n)
for p in pq:
	(x, y) = p
	uf_pq.unite(x - 1, y - 1)
for r in rs:
	(x, y) = r
	uf_rs.unite(x - 1, y - 1)
pairs = []
for i in range(n):
	pairs.append((uf_pq.find(i), uf_rs.find(i)))
count = Counter(pairs)
ans = [count[pair] for pair in pairs]
print(*ans)


(n, k, l) = map(int, input().split())

class UnionFind(object):

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

	def root(self, v):
		if self._par[v] == v:
			return v
		self._par[v] = self.root(self._par[v])
		return self._par[v]

	def unite(self, u, v):
		(u, v) = (self.root(u), self.root(v))
		if u == v:
			return False
		if self.size[u] > self.size[v]:
			(u, v) = (v, u)
		self.size[v] += self.size[u]
		self._par[u] = v

	def is_connected(self, u, v):
		return self.root(u) == self.root(v)
rood = UnionFind(n)
train = UnionFind(n)
for _ in range(k):
	(p, q) = map(int, input().split())
	rood.unite(p - 1, q - 1)
for _ in range(l):
	(r, s) = map(int, input().split())
	train.unite(r - 1, s - 1)
from collections import Counter
cnt = Counter()
for i in range(n):
	(root_r, root_t) = (rood.root(i), train.root(i))
	cnt[root_r, root_t] += 1
ans = []
for i in range(n):
	(root_r, root_t) = (rood.root(i), train.root(i))
	ans.append(cnt[root_r, root_t])
print(*ans)


(N, K, L) = map(int, input().split())
road = [i for i in range(N)]
rail = [i for i in range(N)]

def fp(x, P):
	if x == P[x]:
		return x
	else:
		P[x] = fp(P[x], P)
		return P[x]
for i in range(K + L):
	PL = (lambda x: road if x < K else rail)(i)
	(p, q) = map(lambda x: int(x) - 1, input().split())
	(p, q) = (fp(p, PL), fp(q, PL))
	PL[p] = PL[q] = min(p, q)
from collections import defaultdict as dd
Wconnected = dd(lambda : 0)
for i in range(N):
	Wconnected[fp(i, road), fp(i, rail)] += 1
print(*[Wconnected[fp(i, road), fp(i, rail)] for i in range(N)])


from collections import deque

def bfs():
	q = deque()
	color1 = [-1] * (n + 1)
	color2 = [-1] * (n + 1)
	for i in range(1, n + 1):
		if color1[i] == -1:
			color1[i] = i
			q.append(i)
			while q:
				p = q.popleft()
				for j in G[p]:
					if color1[j] == -1:
						color1[j] = color1[p]
						q.append(j)
		if color2[i] == -1:
			color2[i] = i
			q.append(i)
			while q:
				p = q.popleft()
				for j in H[p]:
					if color2[j] == -1:
						color2[j] = color2[p]
						q.append(j)
	group = [color1[i] + 200000 * color2[i] for i in range(n + 1)]
	return group
(n, k, l) = map(int, input().split())
G = [[] for _ in range(n + 1)]
H = [[] for _ in range(n + 1)]
for _ in range(k):
	(p, q) = map(int, input().split())
	G[p].append(q)
	G[q].append(p)
for _ in range(l):
	(r, s) = map(int, input().split())
	H[r].append(s)
	H[s].append(r)
group = bfs()
d = {}
for i in range(1, n + 1):
	if group[i] in d:
		d[group[i]] += 1
	else:
		d[group[i]] = 1
ans = [0] * n
for i in range(1, n + 1):
	ans[i - 1] = d[group[i]]
print(' '.join(map(str, ans)))


from collections import Counter
(N, K, L) = list(map(int, input().split()))

def get_root(par, node):
	if par[node] == node:
		return node
	root = get_root(par, par[node])
	par[node] = root
	return root

def union(par, rank, a, b):
	(root_a, root_b) = (get_root(par, a), get_root(par, b))
	if root_a == root_b:
		return
	(rank_a, rank_b) = (rank[root_a], rank[root_b])
	if rank_a < rank_b:
		par[root_a] = root_b
	else:
		par[root_b] = root_a
		if rank_a == rank_b:
			rank[root_a] += 1
par1 = [i for i in range(N)]
rank1 = [1] * N
for _ in range(K):
	(a, b) = list(map(int, input().split()))
	union(par1, rank1, a - 1, b - 1)
par2 = [i for i in range(N)]
rank2 = [1] * N
for _ in range(L):
	(a, b) = list(map(int, input().split()))
	union(par2, rank2, a - 1, b - 1)
ct = Counter()
for i in range(N):
	a = get_root(par1, i)
	b = get_root(par2, i)
	ct[a, b] += 1
print(' '.join([str(ct[par1[i], par2[i]]) for i in range(N)]))


import sys
from collections import deque
from collections import defaultdict
from collections import Counter

def conn(n, m, e):
	d = dict(list(zip(list(range(1, n + 1)), list(range(-1, -1 * n - 1, -1)))))
	td = defaultdict(lambda : deque([]))
	c = 1
	for edge in e:
		a = edge[0]
		b = edge[1]
		da = d[a]
		db = d[b]
		if da < 0 and db < 0:
			d[a] = c
			d[b] = c
			td[c].append(a)
			td[c].append(b)
			c += 1
		elif da > 0 and db < 0:
			d[b] = da
			td[d[a]].append(b)
		elif da < 0 and db > 0:
			d[a] = db
			td[d[b]].append(a)
		elif da > 0 and db > 0 and (da != db):
			for x in td[db]:
				d[x] = da
				td[da].append(x)
	return list(d.values())

def main(n, k, l, e1, e2):
	d1 = conn(n, k, e1)
	d2 = conn(n, l, e2)
	p = tuple(zip(iter(d1), iter(d2)))
	d = Counter(p)
	d[k, l] = 1
	print(' '.join([str(d[x]) for x in p]))

def __starting_point():
	ssr = sys.stdin.readline
	(n, k, l) = list(map(int, ssr().strip().split()))
	e1 = []
	e2 = []
	for _ in range(k):
		e1.append(tuple(map(int, ssr().strip().split())))
	for _ in range(l):
		e2.append(tuple(map(int, ssr().strip().split())))
	main(n, k, l, e1, e2)
__starting_point()


(N, K, L) = map(int, input().split())
par = [i for i in range(N)]

def find(x, P):
	if P[x] == x:
		return x
	else:
		b = find(P[x], P)
		P[x] = b
		return b

def unite(x, y, P):
	root_x = find(x, P)
	root_y = find(y, P)
	if root_y > root_x:
		P[root_x] = root_y
	else:
		P[root_y] = root_x
par2 = [i for i in range(N)]
for _ in range(K):
	(p, q) = map(int, input().split())
	unite(p - 1, q - 1, par)
for _ in range(L):
	(p, q) = map(int, input().split())
	unite(p - 1, q - 1, par2)
r = []
for i in range(N):
	r.append((find(i, par), find(i, par2)))
import collections
count = collections.Counter(r)
for i in range(N):
	ans = count[r[i]]
	if i == N - 1:
		print(ans)
	else:
		print(ans, end=' ')


import math
import sys
sys.setrecursionlimit(200000)

class UnionFind:

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

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

	def union(self, x, y):
		self.parents[self.find(y)] = self.find(x)
(N, K, L) = list(map(int, input().split()))
A = UnionFind(N)
B = UnionFind(N)
for i in range(K):
	(p, q) = list(map(int, input().split()))
	A.union(p, q)
for i in range(L):
	(r, s) = list(map(int, input().split()))
	B.union(r, s)
group = {}
for i in range(1, N + 1):
	roadRoot = A.find(i)
	if roadRoot not in group:
		group[roadRoot] = {}
	railRoot = B.find(i)
	if railRoot not in group[roadRoot]:
		group[roadRoot][railRoot] = []
	group[roadRoot][railRoot].append(i)
ans = [[] for _ in range(N)]
for i in list(group.items()):
	for j in list(i[1].values()):
		for k in j:
			ans[k - 1] = str(len(j))
ans = ' '.join(ans)
print(ans)


from collections import Counter

class UnionFind:

	def __init__(self, n):
		self.n = n
		self.root = [-1] * (n + 1)
		self.rnk = [0] * (n + 1)

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

	def unite(self, x, y):
		x = self.find_root(x)
		y = self.find_root(y)
		if x == y:
			return
		elif self.rnk[x] > self.rnk[y]:
			self.root[x] += self.root[y]
			self.root[y] = x
		else:
			self.root[y] += self.root[x]
			self.root[x] = y
			if self.rnk[x] == self.rnk[y]:
				self.rnk[y] += 1

	def isSame(self, x, y):
		return self.find_root(x) == self.find_root(y)

	def size(self, x):
		return -self.root[self.find_root(x)]
(n, k, l) = map(int, input().split())
fe = UnionFind(n)
bus = UnionFind(n)
for _ in range(k):
	(p, q) = map(int, input().split())
	fe.unite(p, q)
for _ in range(l):
	(r, s) = map(int, input().split())
	bus.unite(r, s)
cnt = Counter()
for i in range(1, n + 1):
	cnt[fe.find_root(i), bus.find_root(i)] += 1
print(*[cnt[fe.find_root(i), bus.find_root(i)] for i in range(1, n + 1)])


from collections import Counter

class Union_Find:

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

	def root(self, x):
		if self.par[x] == -1:
			return x
		else:
			self.par[x] = self.root(self.par[x])
			return self.par[x]

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

	def unite(self, x, y):
		x = self.root(x)
		y = self.root(y)
		if x == y:
			return False
		if self.siz[x] < self.siz[y]:
			tmp = x
			x = y
			y = tmp
		self.par[y] = x
		self.siz[x] += self.siz[y]
		return True

	def size(self, x):
		return self.siz[self.root(x)]
(N, K, L) = map(int, input().split())
road_uf = Union_Find(N)
train_uf = Union_Find(N)
for _ in range(K):
	(p, q) = map(int, input().split())
	p -= 1
	q -= 1
	road_uf.unite(p, q)
for _ in range(L):
	(r, s) = map(int, input().split())
	r -= 1
	s -= 1
	train_uf.unite(r, s)
roots = [''] * N
for i in range(N):
	r = str(road_uf.root(i)) + '-' + str(train_uf.root(i))
	roots[i] = r
counts = Counter(roots)
ans = [1] * N
for i in range(N):
	r = roots[i]
	ans[i] = counts[r]
print(*ans)


class UnionFind:

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

	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 find(self, x):
		if self.parents[x] < 0:
			return x
		else:
			self.parents[x] = self.find(self.parents[x])
			return self.parents[x]

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

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

	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):
		return {r: self.members(r) for r in self.roots()}

	def __str__(self):
		return '\n'.join(('{}: {}'.format(r, self.members(r)) for r in self.roots()))
from collections import Counter

def main():
	(N, K, L) = map(int, input().split())
	ufK = UnionFind(N)
	ufL = UnionFind(N)
	for i in range(K):
		(a, b) = map(int, input().split())
		ufK.union(a - 1, b - 1)
	for i in range(L):
		(a, b) = map(int, input().split())
		ufL.union(a - 1, b - 1)
	ps = [(ufK.find(i), ufL.find(i)) for i in range(N)]
	cps = Counter(ps)
	ret = [0] * N
	for i in range(N):
		ret[i] = cps[ps[i]]
	print(*ret)

def __starting_point():
	main()
__starting_point()


from collections import Counter
(N, K, L) = map(int, input().split())
drive = [-1] * N
train = [-1] * N

def find(List, x):
	if List[x] < 0:
		return x
	List[x] = find(List, List[x])
	return List[x]

def unite(List, x, y):
	if find(List, x) != find(List, y):
		List[find(List, y)] = find(List, x)
for i in range(K + L):
	(a, b) = map(int, input().split())
	unite(drive if i < K else train, a - 1, b - 1)
pair = [(find(drive, i), find(train, i)) for i in range(N)]
c = Counter(pair)
print(*[c[pair[i]] for i in range(N)])


from collections import deque, Counter
(N, K, L) = [int(s) for s in input().split()]
edge_road = [[int(s) - 1 for s in input().split()] for _ in range(K)]
edge_train = [[int(s) - 1 for s in input().split()] for _ in range(L)]
graph_road = [[] for _ in range(N)]
graph_train = [[] for _ in range(N)]
for (i, j) in edge_road:
	graph_road[i].append(j)
	graph_road[j].append(i)
for (i, j) in edge_train:
	graph_train[i].append(j)
	graph_train[j].append(i)
group_road = [0] * N
group_num = 0
visited = [False] * N
for i in range(N):
	if visited[i]:
		continue
	dq = deque([i])
	group_road[i] = group_num
	visited[i] = True
	while dq:
		search_obj = dq.pop()
		for candidate_obj in graph_road[search_obj]:
			if not visited[candidate_obj]:
				group_road[candidate_obj] = group_num
				dq.appendleft(candidate_obj)
				visited[candidate_obj] = True
	group_num += 1
group_train = [0] * N
group_num = 0
visited = [False] * N
for i in range(N):
	if visited[i]:
		continue
	dq = deque([i])
	group_train[i] = group_num
	visited[i] = True
	while dq:
		search_obj = dq.pop()
		for candidate_obj in graph_train[search_obj]:
			if not visited[candidate_obj]:
				group_train[candidate_obj] = group_num
				dq.appendleft(candidate_obj)
				visited[candidate_obj] = True
	group_num += 1
group_count = Counter(zip(group_road, group_train))
for (gr, gt) in zip(group_road, group_train):
	print(group_count[gr, gt], end=' ')