Buggy python submission (verdict: Time Limit Exceeded):
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)]


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

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

    # 併合
    def union(self, x, y):
        x = self.find(x)
        y = self.find(y)

        if self.rank[x] < self.rank[y]:
            self.par[x] = y
            gx = list(self.group[x])
            gy = list(self.group[y])
            gx.extend(gy)
            gy.extend(gx)
            self.group[x] = set(gx)
            self.group[y] = set(gy)
        else:
            self.par[y] = x
            gx = list(self.group[x])
            gy = list(self.group[y])
            gx.extend(gy)
            gy.extend(gx)
            self.group[x] = set(gx)
            self.group[y] = set(gy)
            if self.rank[x] == self.rank[y]:
                self.rank[x] += 1

    # 同じ集合に属するか判定
    def same_check(self, x, y):
        return self.find(x) == self.find(y)


road_uf = UnionFind(N)
train_uf = UnionFind(N)

for p, q in roads:
    road_uf.union(p, q)

for r, s in trains:
    train_uf.union(r, s)

road_link = road_uf.group
road_par = road_uf.par
train_link = train_uf.group
train_par = train_uf.par

for i in range(1, N+1):
    road_link[i] = road_link[road_par[i]]
    train_link[i] = train_link[train_par[i]]

ans = []
for n in range(1, N+1):
    ans.append(str(len(road_link[n] & train_link[n])))

print(" ".join(ans))

Fixed submission:
from collections import defaultdict
N, K, L = map(int, input().split())


class UnionFind:
    def __init__(self, n):
        self.par = [i for i in range(n)]
        self.rank = [0] * n
        self.size = [1] * 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:
            return

        if self.rank[x] < self.rank[y]:
            self.par[x] = y
            self.size[y] += self.size[x]
            self.size[x] = 0
        else:
            self.par[y] = x
            self.size[x] += self.size[y]
            self.size[y] = 0
            if self.rank[x] == self.rank[y]:
                self.rank[x] += 1

    # 同じ集合に属するか判定
    def same(self, x, y):
        return self.find(x) == self.find(y)

    # すべての頂点に対して親を検索する
    def all_find(self):
        for n in range(len(self.par)):
            self.find(n)


UF_road = UnionFind(N)
for k in range(K):
    p, q = map(int, input().split())
    p, q = p - 1, q - 1
    UF_road.union(p, q)
UF_road.all_find()

UF_train = UnionFind(N)
for l in range(L):
    r, s = map(int, input().split())
    r, s = r - 1, s - 1
    UF_train.union(r, s)
UF_train.all_find()

D = defaultdict(int)
for r, t in zip(UF_road.par, UF_train.par):
    D[(r, t)] += 1

ans = [D[(r, t)] for r, t in zip(UF_road.par, UF_train.par)]
print(*ans, sep=' ')

Buggy python submission (verdict: Time Limit Exceeded):
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)]


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

    # 検索
    def find(self, x):
        if self.par[x] == x:
            self.group[x].add(self.par[x])
            gx = list(self.group[x])
            gp = list(self.group[self.par[x]])
            gx.extend(gp)
            gp.extend(gx)
            self.group[x] = set(gx)
            self.group[self.par[x]] = set(gp)
            return x
        else:
            self.par[x] = self.find(self.par[x])
            gx = list(self.group[x])
            gp = list(self.group[self.par[x]])
            gx.extend(gp)
            gp.extend(gx)
            self.group[x] = set(gx)
            self.group[self.par[x]] = set(gp)
            return self.par[x]

    # 併合
    def union(self, x, y):
        self.group[y].add(x)
        self.group[x].add(y)
        x = self.find(x)
        y = self.find(y)

        if self.rank[x] < self.rank[y]:
            self.par[x] = y
            gx = list(self.group[x])
            gy = list(self.group[y])
            gx.extend(gy)
            gy.extend(gx)
            self.group[x] = set(gx)
            self.group[y] = set(gy)
        else:
            self.par[y] = x
            gx = list(self.group[x])
            gy = list(self.group[y])
            gx.extend(gy)
            gy.extend(gx)
            self.group[x] = set(gx)
            self.group[y] = set(gy)
            if self.rank[x] == self.rank[y]:
                self.rank[x] += 1

    # 同じ集合に属するか判定
    def same_check(self, x, y):
        return self.find(x) == self.find(y)


road_uf = UnionFind(N)
train_uf = UnionFind(N)

for p, q in roads:
    road_uf.union(p, q)

for r, s in trains:
    train_uf.union(r, s)

road_link = road_uf.group
train_link = train_uf.group

for i in range(1, N+1):
    road_link[i] = road_link[road_uf.par[i]]
    train_link[i] = train_link[train_uf.par[i]]

ans = []
for n in range(1, N+1):
    ans.append(str(len(road_link[n] & train_link[n])))

print(" ".join(ans))

Fixed submission:
from collections import defaultdict
N, K, L = map(int, input().split())


class UnionFind:
    def __init__(self, n):
        self.par = [i for i in range(n)]
        self.rank = [0] * n
        self.size = [1] * 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:
            return

        if self.rank[x] < self.rank[y]:
            self.par[x] = y
            self.size[y] += self.size[x]
            self.size[x] = 0
        else:
            self.par[y] = x
            self.size[x] += self.size[y]
            self.size[y] = 0
            if self.rank[x] == self.rank[y]:
                self.rank[x] += 1

    # 同じ集合に属するか判定
    def same(self, x, y):
        return self.find(x) == self.find(y)

    # すべての頂点に対して親を検索する
    def all_find(self):
        for n in range(len(self.par)):
            self.find(n)


UF_road = UnionFind(N)
for k in range(K):
    p, q = map(int, input().split())
    p, q = p - 1, q - 1
    UF_road.union(p, q)
UF_road.all_find()

UF_train = UnionFind(N)
for l in range(L):
    r, s = map(int, input().split())
    r, s = r - 1, s - 1
    UF_train.union(r, s)
UF_train.all_find()

D = defaultdict(int)
for r, t in zip(UF_road.par, UF_train.par):
    D[(r, t)] += 1

ans = [D[(r, t)] for r, t in zip(UF_road.par, UF_train.par)]
print(*ans, sep=' ')

Buggy python submission (verdict: Time Limit Exceeded):
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)]


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 union(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 same_check(self, x, y):
        return self.find(x) == self.find(y)


road_uf = UnionFind(N)
train_uf = UnionFind(N)

for p, q in roads:
    road_uf.union(p, q)
for r, s in trains:
    train_uf.union(r, s)

road_link = road_uf.par
train_link = train_uf.par

ans = []
for n in range(1, N+1):
    road_set = set()
    train_set = set()
    for i in range(1, N+1):
        if road_link[i] == road_link[n]:
            road_set.add(i)
        if train_link[i] == train_link[n]:
            train_set.add(i)
    ans.append(str(len(road_set & train_set)))

print(" ".join(ans))

Fixed submission:
from collections import defaultdict
N, K, L = map(int, input().split())


class UnionFind:
    def __init__(self, n):
        self.par = [i for i in range(n)]
        self.rank = [0] * n
        self.size = [1] * 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:
            return

        if self.rank[x] < self.rank[y]:
            self.par[x] = y
            self.size[y] += self.size[x]
            self.size[x] = 0
        else:
            self.par[y] = x
            self.size[x] += self.size[y]
            self.size[y] = 0
            if self.rank[x] == self.rank[y]:
                self.rank[x] += 1

    # 同じ集合に属するか判定
    def same(self, x, y):
        return self.find(x) == self.find(y)

    # すべての頂点に対して親を検索する
    def all_find(self):
        for n in range(len(self.par)):
            self.find(n)


UF_road = UnionFind(N)
for k in range(K):
    p, q = map(int, input().split())
    p, q = p - 1, q - 1
    UF_road.union(p, q)
UF_road.all_find()

UF_train = UnionFind(N)
for l in range(L):
    r, s = map(int, input().split())
    r, s = r - 1, s - 1
    UF_train.union(r, s)
UF_train.all_find()

D = defaultdict(int)
for r, t in zip(UF_road.par, UF_train.par):
    D[(r, t)] += 1

ans = [D[(r, t)] for r, t in zip(UF_road.par, UF_train.par)]
print(*ans, sep=' ')