Buggy python submission (verdict: Time Limit Exceeded):
N, M = map(int, input().split(" "))
bridges = [list(map(int, input().split(" "))) for _ in range(M)]

def search_tree(trees, n):
    while type(trees[n]) == int:
        n = trees[n]
    return trees[n], n

all_ptn = N * (N-1) // 2
ans = [all_ptn]
trees = [{i} for i in range(N)]
for i in range(M-1, 0, -1):
    tree1, num1 = search_tree(trees, bridges[i][0]-1)
    tree2, num2 = search_tree(trees, bridges[i][1]-1)
    if tree1 != tree2:
        tmp = tree1.union(tree2)
        trees[num1] = tmp
        trees[num2] = num1
        ans.append(ans[-1] - len(tree1) * len(tree2))
        
    else:
        ans.append(ans[-1])
for i in range(M-1, -1, -1):
    print(ans[i])

Fixed submission:
N, M = map(int, input().split(" "))
bridges = [list(map(int, input().split(" "))) for _ in range(M)]

class UnionFind:
    def __init__(self, n):
        self.n = n
        self.par = [-1] * n
        self.rank = [0] * n
        
    def root(self, x):
        if self.par[x] < 0:
            return x
        else:
            self.par[x] = self.root(self.par[x])
            return self.par[x]
        
    def unite(self, x, y):
        rx = self.root(x)
        ry = self.root(y)
        
        if rx == ry:
            return
        elif self.rank[rx] > self.rank[ry]:
            self.par[rx] += self.par[ry]
            self.par[ry] = rx
            
        else:
            self.par[ry] += self.par[rx]
            self.par[rx] = ry
            if self.rank[rx] == self.rank[ry]:
                self.rank[ry] += 1
                
    def same(self, x, y):
        return self.root(x) == self.root(y)
    
    def count(self, x):
        return -self.par[self.root(x)]

all_ptn = N * (N-1) // 2
ans = [all_ptn]
uf = UnionFind(N)
for i in range(M-1, 0, -1):
    x = bridges[i][0] - 1
    y = bridges[i][1] - 1
    if uf.same(x, y):
        ans.append(ans[-1])
    else:
        ans.append(ans[-1] - uf.count(x) * uf.count(y))
        uf.unite(x, y)
        
for i in range(M-1, -1, -1):
    print(ans[i])

Buggy python submission (verdict: Time Limit Exceeded):
N, M = map(int, input().split(" "))
bridges = [list(map(int, input().split(" "))) for _ in range(M)]

all_ptn = N * (N-1) // 2
ans = [all_ptn]
trees = [{i} for i in range(N)]
for i in range(M-1, 0, -1):
    tree1 = trees[bridges[i][0]-1]
    tree2 = trees[bridges[i][1]-1]
    if tree1 != tree2:
        tmp = tree1.union(tree2)
        for node in tmp:
            trees[node] = tmp
        ans.append(ans[-1] - len(tree1) * len(tree2))
    else:
        ans.append(ans[-1])
for i in range(M-1, -1, -1):
    print(ans[i])

Fixed submission:
N, M = map(int, input().split(" "))
bridges = [list(map(int, input().split(" "))) for _ in range(M)]

class UnionFind:
    def __init__(self, n):
        self.n = n
        self.par = [-1] * n
        self.rank = [0] * n
        
    def root(self, x):
        if self.par[x] < 0:
            return x
        else:
            self.par[x] = self.root(self.par[x])
            return self.par[x]
        
    def unite(self, x, y):
        rx = self.root(x)
        ry = self.root(y)
        
        if rx == ry:
            return
        elif self.rank[rx] > self.rank[ry]:
            self.par[rx] += self.par[ry]
            self.par[ry] = rx
            
        else:
            self.par[ry] += self.par[rx]
            self.par[rx] = ry
            if self.rank[rx] == self.rank[ry]:
                self.rank[ry] += 1
                
    def same(self, x, y):
        return self.root(x) == self.root(y)
    
    def count(self, x):
        return -self.par[self.root(x)]

all_ptn = N * (N-1) // 2
ans = [all_ptn]
uf = UnionFind(N)
for i in range(M-1, 0, -1):
    x = bridges[i][0] - 1
    y = bridges[i][1] - 1
    if uf.same(x, y):
        ans.append(ans[-1])
    else:
        ans.append(ans[-1] - uf.count(x) * uf.count(y))
        uf.unite(x, y)
        
for i in range(M-1, -1, -1):
    print(ans[i])