Buggy python submission (verdict: Runtime Error):
from collections import defaultdict

def main():
    N, M = map(int, input().split())
    g = defaultdict(set)

    for _ in range(M):
        a, b = map(int, input().split())
        a -= 1
        b -= 1 
        g[a].add(b)
        g[b].add(a)

    from functools import lru_cache
    def dfs(u, visited: set):
        visited.add(u)
        for v in g[u]:
            if v not in visited:
                dfs(v, visited)

    count = dict()       
    for u in range(N):
        if u in count:
            continue
        visited = set()
        dfs(u, visited)
        # print(visited)
        count[u] = len(visited)
        for v in visited:
            count[v] = len(visited)

    print(max(count.values()))


if __name__ == '__main__':
    import sys
    sys.setrecursionlimit(10000)
    main()

Fixed submission:
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]


def main():
    N, M = map(int, input().split())

    uf = UnionFind(N)
    for _ in range(M):
        a, b = map(int, input().split())
        uf.union(a-1, b-1)

    ans = max(uf.get_size(i) for i in range(N))
    print(ans)


if __name__ == '__main__':
    main()

Buggy python submission (verdict: Runtime Error):
from collections import defaultdict

def main():
    N, M = map(int, input().split())
    g = defaultdict(set)

    for _ in range(M):
        a, b = map(int, input().split())
        a -= 1
        b -= 1 
        g[a].add(b)
        g[b].add(a)

    from functools import lru_cache
    def dfs(u, visited: set):
        visited.add(u)
        for v in g[u]:
            if v not in visited:
                dfs(v, visited)

    count = dict()       
    for u in range(N):
        if u in count:
            continue
        visited = set()
        dfs(u, visited)
        # print(visited)
        count[u] = len(visited)
        for v in visited:
            count[v] = len(visited)

    print(max(count.values()))


if __name__ == '__main__':
    main()

Fixed submission:
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]


def main():
    N, M = map(int, input().split())

    uf = UnionFind(N)
    for _ in range(M):
        a, b = map(int, input().split())
        uf.union(a-1, b-1)

    ans = max(uf.get_size(i) for i in range(N))
    print(ans)


if __name__ == '__main__':
    main()