Buggy python submission (verdict: Time Limit Exceeded):
N,K,L = map(int, input().split())

class UnionFind():
    def __init__(self, n):
        # size of n.
        self.n = n
        # n's parent. default is -1.
        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):
        # Root value's index has its size with negative.
        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 = map(int, input().split())
    p -= 1
    k -= 1
    road.union_merge(p, k)

for i in range(L):
    r, s = map(int, input().split())
    r -= 1
    s -= 1
    rail.union_merge(r, s)

result = []
for i in range(N):
    road_members = road.same_union_members(i)
    rail_members = rail.same_union_members(i)
    road_rail_both_members = set(road_members).intersection(set(rail_members))
    result.append(len(road_rail_both_members))

print(' '.join(map(str, result)))


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

class UnionFind():
    def __init__(self, n):
        # size of n.
        self.n = n
        # n's parent. default is -1.
        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

    # You shouldn't use these below for optimization.
    # Use only find_root to compare if you need.
    def union_size(self, x):
        # Root value's index has its size with negative.
        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 = map(int, input().split())
    road.union_merge(p-1, k-1)

for i in range(L):
    r, s = 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)

Buggy python submission (verdict: Time Limit Exceeded):
N,K,L = map(int, input().split())

class UnionFind():
    def __init__(self, n):
        # size of n.
        self.n = n
        # n's parent. default is -1.
        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):
        # Root value's index has its size with negative.
        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 = map(int, input().split())
    p -= 1
    k -= 1
    if not road.is_same_union(p, k):
        road.union_merge(p, k)

for i in range(L):
    r, s = map(int, input().split())
    r -= 1
    s -= 1
    if not rail.is_same_union(r, s):
        rail.union_merge(r, s)

result = []
for i in range(N):
    road_members = road.same_union_members(i)
    rail_members = rail.same_union_members(i)
    road_rail_both_members = set(road_members).intersection(set(rail_members))
    result.append(len(road_rail_both_members))

print(' '.join(map(str, result)))


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

class UnionFind():
    def __init__(self, n):
        # size of n.
        self.n = n
        # n's parent. default is -1.
        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

    # You shouldn't use these below for optimization.
    # Use only find_root to compare if you need.
    def union_size(self, x):
        # Root value's index has its size with negative.
        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 = map(int, input().split())
    road.union_merge(p-1, k-1)

for i in range(L):
    r, s = 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)