Problem p03855 (python)

Fixed submission:
from collections import defaultdict


class UnionFind:

    def __init__(self, n):
        # * Access m-th node by index `m`, not `m - 1`.
        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  # reduction
            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)
    # Calculate groups
    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)


if __name__ == '__main__':
    main()

Buggy submission (verdict: Runtime Error):
import sys
sys.setrecursionlimit(10**12)


class UnionFind:

    def __init__(self, n):
        self.n = n
        # access m-th node by index `m`, not `m - 1`
        self.roots = [i for i in range(n + 1)]
        self.ranks = [0 for _ in range(n + 1)]
        self.group_sizes = [1 for _ in range(n + 1)]

    def find_root(self, node):
        root_node = self.roots[node]
        if node == root_node:
            return root_node
        else:
            new_root_node = self.find_root(root_node)
            self.roots[node] = new_root_node  # reduction
            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.roots[one_root] = other_root
            self.group_sizes[other_root] += self.group_sizes[one_root]
        else:
            self.roots[other_root] = one_root
            self.group_sizes[one_root] += self.group_sizes[other_root]
            if self.ranks[one_root] == self.ranks[other_root]:
                self.ranks[other_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 group_size(self, node):
        root_node = self.find_root(node)
        return self.group_sizes[root_node]


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)
    road_train_tree = UnionFind(N)
    for _ in range(L):
        r, s = list(map(int, input().split(' ')))
        if not road_tree.is_same_group(r, s):
            continue
        road_train_tree.union(r, s)
    answer = ' '.join([str(road_train_tree.group_size(node)) for node in range(1, N + 1)])
    print(answer)


if __name__ == '__main__':
    main()

Buggy submission (verdict: Runtime Error):
import sys
sys.setrecursionlimit(10**7)


class UnionFind:

    def __init__(self, n):
        self.n = n
        # access m-th node by index `m`, not `m - 1`
        self.roots = [i for i in range(n + 1)]
        self.ranks = [0 for _ in range(n + 1)]
        self.group_sizes = [1 for _ in range(n + 1)]

    def find_root(self, node):
        root_node = self.roots[node]
        if node == root_node:
            return root_node
        else:
            new_root_node = self.find_root(root_node)
            self.roots[node] = new_root_node  # reduction
            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.roots[one_root] = other_root
            self.group_sizes[other_root] += self.group_sizes[one_root]
        else:
            self.roots[other_root] = one_root
            self.group_sizes[one_root] += self.group_sizes[other_root]
            if self.ranks[one_root] == self.ranks[other_root]:
                self.ranks[other_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 group_size(self, node):
        root_node = self.find_root(node)
        return self.group_sizes[root_node]


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)
    road_train_tree = UnionFind(N)
    for _ in range(L):
        r, s = list(map(int, input().split(' ')))
        if not road_tree.is_same_group(r, s):
            continue
        road_train_tree.union(r, s)
    answer = ' '.join([str(road_train_tree.group_size(node)) for node in range(1, N + 1)])
    print(answer)


if __name__ == '__main__':
    main()

Buggy submission (verdict: Runtime Error):
class UnionFind:

    def __init__(self, n):
        self.n = n
        # access m-th node by index `m`, not `m - 1`
        self.roots = [i for i in range(n + 1)]
        self.ranks = [0 for _ in range(n + 1)]
        self.group_sizes = [1 for _ in range(n + 1)]

    def find_root(self, node):
        root_node = self.roots[node]
        if node == root_node:
            return root_node
        else:
            new_root_node = self.find_root(root_node)
            self.roots[node] = new_root_node  # reduction
            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.roots[one_root] = other_root
            self.group_sizes[other_root] += self.group_sizes[one_root]
        else:
            self.roots[other_root] = one_root
            self.group_sizes[one_root] += self.group_sizes[other_root]
            if self.ranks[one_root] == self.ranks[other_root]:
                self.ranks[other_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 group_size(self, node):
        root_node = self.find_root(node)
        return self.group_sizes[root_node]


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)
    road_train_tree = UnionFind(N)
    for _ in range(L):
        r, s = list(map(int, input().split(' ')))
        if not road_tree.is_same_group(r, s):
            continue
        road_train_tree.union(r, s)
    answer = ' '.join([str(road_train_tree.group_size(node)) for node in range(1, N + 1)])
    print(answer)


if __name__ == '__main__':
    main()