Buggy python submission (verdict: Time Limit Exceeded):
class UnionFind:
    def __init__(self,N):
        self.parent = [i for i in range(N)]
        self.rank = [0] * N
        self.count = 0
        self._size = [1]*N
    def root(self,a):
        if self.parent[a] == a:
            return a
        else:
            self.parent[a] = self.root(self.parent[a])
            return self.parent[a]
    def is_sama(self,a,b):
        return self.root(a) == self.root(b)
    def unite(self,a,b):
        ra = self.root(a)
        rb = self.root(b)
        if ra == rb:
            return
        if self.rank[ra] < self.rank[rb]:
            self.parent[ra] = rb
            self._size[rb] += self._size[ra]
        else:
            self.parent[rb] = ra
            if self.rank[ra] == self.rank[rb]:
                self.rank[ra] += 1
            self._size[ra] += self._size[rb]
        self.count += 1
    def print_info(self):
        print("parent", self.parent)
        print("rank", self.rank)
        print("count", self.count)
        print("size", self._size)
    def size(self,a):
        return self._size[self.root(a)]

import sys
input = sys.stdin.readline
ans = 0
N,M = map(int,input().split())
UF = UnionFind(N)
for i in range(M):
    A,B = map(int,input().split())
    A -= 1
    B -= 1
    UF.unite(A,B)

for i in range(N):
    for j in range(i+1,N):
        if not UF.is_sama(i,j):
            ans += 1
            UF.unite(i,j)
print(ans)


Fixed submission:
import sys
from collections import deque
input = sys.stdin.readline

N,M = map(int,input().split())
table = [[] for i in range(N)]
Q = deque()
visited = [0]*N
ans = 0
for i in range(M):
    A,B = map(int,input().split())
    A -= 1
    B -= 1
    table[A].append(B)
    table[B].append(A)

for x in range(N):
    if visited[x] == 0:
        ans += 1
        Q.append(x)
        while Q:
            x = Q.popleft()
            for y in table[x]:
                if visited[y]==0:
                    Q.append(y)
                    visited[y] = 1

print(ans-1)

Buggy python submission (verdict: Time Limit Exceeded):
class UnionFind:
    def __init__(self,N):
        self.parent = [i for i in range(N)]
        self.rank = [0] * N
        self.count = 0
        self._size = [1]*N
    def root(self,a):
        if self.parent[a] == a:
            return a
        else:
            self.parent[a] = self.root(self.parent[a])
            return self.parent[a]
    def is_sama(self,a,b):
        return self.root(a) == self.root(b)
    def unite(self,a,b):
        ra = self.root(a)
        rb = self.root(b)
        if ra == rb:
            return
        if self.rank[ra] < self.rank[rb]:
            self.parent[ra] = rb
            self._size[rb] += self._size[ra]
        else:
            self.parent[rb] = ra
            if self.rank[ra] == self.rank[rb]:
                self.rank[ra] += 1
            self._size[ra] += self._size[rb]
        self.count += 1
    def print_info(self):
        print("parent", self.parent)
        print("rank", self.rank)
        print("count", self.count)
        print("size", self._size)
    def size(self,a):
        return self._size[self.root(a)]

import sys
input = sys.stdin.readline
ans = 0
N,M = map(int,input().split())
UF = UnionFind(N)
for i in range(M):
    A,B = map(int,input().split())
    A -= 1
    B -= 1
    UF.unite(A,B)

for i in range(N):
    for j in range(i+1,N):
        if not UF.is_sama(i,j):
            ans += 1
            UF.unite(i,j)
print(ans)

Fixed submission:
import sys
from collections import deque
input = sys.stdin.readline

N,M = map(int,input().split())
table = [[] for i in range(N)]
Q = deque()
visited = [0]*N
ans = 0
for i in range(M):
    A,B = map(int,input().split())
    A -= 1
    B -= 1
    table[A].append(B)
    table[B].append(A)

for x in range(N):
    if visited[x] == 0:
        ans += 1
        Q.append(x)
        while Q:
            x = Q.popleft()
            for y in table[x]:
                if visited[y]==0:
                    Q.append(y)
                    visited[y] = 1

print(ans-1)