Buggy python submission (verdict: Runtime Error):
N, M = map(int, input().split())

AB = []

for _ in range(M):
    A_i, B_i = map(int, input().split())
    AB.append([A_i, B_i])
    
class UnionFind():
    def __init__(self, n):
        self.parent = [-1 for _ in range(n)] # 親なら -1 * サイズ
        
    def root(self, x):
        if self.parent[x] < 0:
            return x
        else:
            self.parent[x] = self.root(self.parent[x])
            return self.parent[x]
    def size(self, x):
        x = self.root(x)
        return -1 * self.parent[x]
    
    def union(self, x, y):
        x = self.root(x)
        y = self.root(y)
        if x == y:
            return False
        x_size = self.parent[x]
        y_size = self.parent[y]
        if x_size < y_size:
            x, y = y, x
        self.parent[x] += self.parent[y]
        self.parent[y] = x
        return True
        
max_inconvenience = N * (N - 1) // 2 
ans = [max_inconvenience]
uf = UnionFind(N)
for bridge in reversed(AB):
    x = uf.root(bridge[0] - 1)
    y = uf.root(bridge[1] - 1)

    if x != y:
        x_size = uf.size(x)
        y_size = uf.size(y)
        ans_tmp = max_inconvenience - x_size * y_size
        max_inconvenience = ans_tmp
        uf.union(x, y)
    else:
        ans_tmp = max_inconvenience
    ans.append(ans_tmp)
    
for a in reversed(ans[:-1]):
    print(a)

Fixed submission:
N, M = map(int, input().split())

AB = []

for _ in range(M):
    A_i, B_i = map(int, input().split())
    AB.append([A_i, B_i])

class UnionFind():
    def __init__(self, n):
        self.parent = [-1 for _ in range(n)] # 親なら -1 * サイズ
        
    def root(self, x):
        if self.parent[x] < 0:
            return x
        else:
            self.parent[x] = self.root(self.parent[x])
            return self.parent[x]
    def size(self, x):
        x = self.root(x)
        return -1 * self.parent[x]
    
    def union(self, x, y):
        x = self.root(x)
        y = self.root(y)
        if x == y:
            return False
        x_size = self.size(x)
        y_size = self.size(y)
        if x_size < y_size:
            x, y = y, x
        self.parent[x] += self.parent[y]
        self.parent[y] = x
        return True
        
max_inconvenience = N * (N - 1) // 2 
ans = [max_inconvenience]
uf = UnionFind(N)
for bridge in reversed(AB):
    x = uf.root(bridge[0] - 1)
    y = uf.root(bridge[1] - 1)

    if x != y:
        x_size = uf.size(x)
        y_size = uf.size(y)
        ans_tmp = max_inconvenience - x_size * y_size
        max_inconvenience = ans_tmp
        uf.union(x, y)
    else:
        ans_tmp = max_inconvenience
    ans.append(ans_tmp)
    
for a in reversed(ans[:-1]):
    print(a)

Buggy python submission (verdict: Time Limit Exceeded):
N, M = map(int, input().split())

AB = []

for _ in range(M):
    A_i, B_i = map(int, input().split())
    AB.append([A_i, B_i])
    
class UnionFind(object):
    def __init__(self, n=1):
        self.par = [i for i in range(n)]
        self.rank = [0 for _ in range(n)]

    def find(self, x):
        """
        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 と 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

    def is_same(self, x, y):
        """
        x と y が同じグループか否か
        """
        return self.find(x) == self.find(y)
      
uf = UnionFind(N+1)
max_inconvenience = N * (N-1) // 2
ans_list = []
for bridge in reversed(AB):
    #print("====")
    #print(bridge)
    uf.union(bridge[0], bridge[1])

    #print(uf.par)
    #print(uf.rank)
    #print(uf.find(1),uf.find(2),uf.find(3),uf.find(4))
    
    count = {}
    for i in range(1, N+1):
        x = uf.find(i)
        if x in count:
            count[x] += 1
        else:
            count[x] = 1
    #print(count)
    ans = 0
    for c in count.values():
        ans += c * (c - 1) // 2
    ans_list.append(ans)

for ans in reversed(ans_list[:-1]):
    print(max_inconvenience - ans)
print(max_inconvenience)
    



Fixed submission:
N, M = map(int, input().split())

AB = []

for _ in range(M):
    A_i, B_i = map(int, input().split())
    AB.append([A_i, B_i])

class UnionFind():
    def __init__(self, n):
        self.parent = [-1 for _ in range(n)] # 親なら -1 * サイズ
        
    def root(self, x):
        if self.parent[x] < 0:
            return x
        else:
            self.parent[x] = self.root(self.parent[x])
            return self.parent[x]
    def size(self, x):
        x = self.root(x)
        return -1 * self.parent[x]
    
    def union(self, x, y):
        x = self.root(x)
        y = self.root(y)
        if x == y:
            return False
        x_size = self.size(x)
        y_size = self.size(y)
        if x_size < y_size:
            x, y = y, x
        self.parent[x] += self.parent[y]
        self.parent[y] = x
        return True
        
max_inconvenience = N * (N - 1) // 2 
ans = [max_inconvenience]
uf = UnionFind(N)
for bridge in reversed(AB):
    x = uf.root(bridge[0] - 1)
    y = uf.root(bridge[1] - 1)

    if x != y:
        x_size = uf.size(x)
        y_size = uf.size(y)
        ans_tmp = max_inconvenience - x_size * y_size
        max_inconvenience = ans_tmp
        uf.union(x, y)
    else:
        ans_tmp = max_inconvenience
    ans.append(ans_tmp)
    
for a in reversed(ans[:-1]):
    print(a)

Buggy python submission (verdict: Time Limit Exceeded):
N, M = map(int, input().split())

AB = []

for _ in range(M):
    A_i, B_i = map(int, input().split())
    AB.append([A_i, B_i])
    
can_move = {}

MAX_COMBINATION = N * (N-1) // (2 * 1)
ans = [MAX_COMBINATION]
#print(AB)
for i in range(1, N+1):
    can_move[i] = set([i])


#print(can_move)
#print("-----")
for bridge in reversed(AB):
    merge_island = can_move[bridge[0]] | can_move[bridge[1]] 
    import copy
    tmp = copy.deepcopy(can_move[bridge[0]])
    for island in tmp:
        can_move[island] = merge_island
    tmp = copy.deepcopy(can_move[bridge[1]])
    for island in tmp:
        can_move[island] = merge_island
    
    
    #print(bridge)
    #print(can_move)
    
    can_move_count = 0
    for i in range(1, N+1):
        for j in range(i+1, N+1):
            if j in can_move[i]:
                can_move_count += 1
    #print(can_move_count)
    ans.append(MAX_COMBINATION - can_move_count)



#print("--")
for a in reversed(ans[:-1]):
    print(a)

Fixed submission:
N, M = map(int, input().split())

AB = []

for _ in range(M):
    A_i, B_i = map(int, input().split())
    AB.append([A_i, B_i])

class UnionFind():
    def __init__(self, n):
        self.parent = [-1 for _ in range(n)] # 親なら -1 * サイズ
        
    def root(self, x):
        if self.parent[x] < 0:
            return x
        else:
            self.parent[x] = self.root(self.parent[x])
            return self.parent[x]
    def size(self, x):
        x = self.root(x)
        return -1 * self.parent[x]
    
    def union(self, x, y):
        x = self.root(x)
        y = self.root(y)
        if x == y:
            return False
        x_size = self.size(x)
        y_size = self.size(y)
        if x_size < y_size:
            x, y = y, x
        self.parent[x] += self.parent[y]
        self.parent[y] = x
        return True
        
max_inconvenience = N * (N - 1) // 2 
ans = [max_inconvenience]
uf = UnionFind(N)
for bridge in reversed(AB):
    x = uf.root(bridge[0] - 1)
    y = uf.root(bridge[1] - 1)

    if x != y:
        x_size = uf.size(x)
        y_size = uf.size(y)
        ans_tmp = max_inconvenience - x_size * y_size
        max_inconvenience = ans_tmp
        uf.union(x, y)
    else:
        ans_tmp = max_inconvenience
    ans.append(ans_tmp)
    
for a in reversed(ans[:-1]):
    print(a)