Buggy python submission (verdict: Time Limit Exceeded):
# -*- coding utf-8 -*-
###########################
## TLE
###########################

N, M = map(int, input().split())
bridge_m = [set(map(int, input().split())) for _ in range(M)]
bridge_m.append(set())
# print(bridge_m)

def conb2(x):
    return int(x * (x - 1)/2) if x > 1 else 0

sets = []
ans = conb2(N)
ans_list = []
for i in range(M, 0, -1):
    bi = bridge_m[i]
    joint_set = set()
    joint_set = joint_set.union(bi)

    next_sets = []
    for s in sets:
        if not s.isdisjoint(joint_set):
            joint_set = joint_set.union(s)
        else:
            next_sets.append(s)
    next_sets.append(joint_set)

    sets = next_sets

    # calc ans
    ans = conb2(N)
    for s in sets:
        ans -= conb2(len(s))
    # print(ans)
    ans_list.append(ans)


for i in range(M - 1, -1, -1):
    print(ans_list[i])

    

Fixed submission:
# -*- coding utf-8 -*-

N, M = map(int, input().split())
bridge_m = [list(map(int, input().split())) for _ in range(M)]
# print(bridge_m)

class UnionFind():
    def __init__(self, n):
        self.node = [-1] * n
    
    def is_root(self, nid):
        return self.node[nid] < 0

    def find(self, nid):
        # find group id
        if self.is_root(nid):
            return nid
        else:
            self.node[nid] = self.find(self.node[nid])
            return self.node[nid]

    def is_same_group(self, nid1, nid2):
        return self.find(nid1) == self.find(nid2)

    def size(self, nid):
        return - self.node[self.find(nid)]

    def union(self, nid1, nid2):
        if self.is_same_group(nid1, nid2):
            return

        g1 = self.find(nid1)
        g2 = self.find(nid2)
        if self.size(g1) < self.size(g2):
            self.node[g2] -= self.size(g1)
            self.node[g1] = g2
        else:
            self.node[g1] -= self.size(g2)
            self.node[g2] = g1

uf = UnionFind(N + 1)
ans = [0] * M
ans[M - 1] = int(N * (N - 1) / 2)
g_num = 0
for i in range(M - 1, 0, -1):
    a = bridge_m[i][0]
    b = bridge_m[i][1]

    if uf.is_same_group(a, b):
        ans[i - 1] = ans[i]
    else:
        ans[i - 1] = ans[i] - uf.size(a) * uf.size(b)
        uf.union(a, b)

for i in range(M):
    print(ans[i])

Buggy python submission (verdict: Time Limit Exceeded):
# -*- coding utf-8 -*-

N, M = map(int, input().split())
bridge_m = [set(map(int, input().split())) for _ in range(M)]
bridge_m.append(set())
# print(bridge_m)

def conb2(x):
    return int(x * (x - 1)/2) if x > 1 else 0

sets = []
ans = conb2(N)
ans_list = []
for i in range(M, 0, -1):
    joint_sets = []
    bi = bridge_m[i]
    for s in sets:
        if not s.isdisjoint(bi):
            joint_sets.append(s)

    if len(joint_sets) == 0:
        sets.append(bi)
    else:
        new_set = set()
        new_set = new_set.union(bi)
        for js in joint_sets:
            new_set = new_set.union(js)
            sets.remove(js)
        sets.append(new_set)
    # print('joint_sets', joint_sets)
    # print('sets', sets)

    # calc ans
    ans = conb2(N)
    for s in sets:
        ans -= conb2(len(s))
    # print(ans)
    ans_list.append(ans)
for i in range(M - 1, -1, -1):
    print(ans_list[i])

    

Fixed submission:
# -*- coding utf-8 -*-

N, M = map(int, input().split())
bridge_m = [list(map(int, input().split())) for _ in range(M)]
# print(bridge_m)

class UnionFind():
    def __init__(self, n):
        self.node = [-1] * n
    
    def is_root(self, nid):
        return self.node[nid] < 0

    def find(self, nid):
        # find group id
        if self.is_root(nid):
            return nid
        else:
            self.node[nid] = self.find(self.node[nid])
            return self.node[nid]

    def is_same_group(self, nid1, nid2):
        return self.find(nid1) == self.find(nid2)

    def size(self, nid):
        return - self.node[self.find(nid)]

    def union(self, nid1, nid2):
        if self.is_same_group(nid1, nid2):
            return

        g1 = self.find(nid1)
        g2 = self.find(nid2)
        if self.size(g1) < self.size(g2):
            self.node[g2] -= self.size(g1)
            self.node[g1] = g2
        else:
            self.node[g1] -= self.size(g2)
            self.node[g2] = g1

uf = UnionFind(N + 1)
ans = [0] * M
ans[M - 1] = int(N * (N - 1) / 2)
g_num = 0
for i in range(M - 1, 0, -1):
    a = bridge_m[i][0]
    b = bridge_m[i][1]

    if uf.is_same_group(a, b):
        ans[i - 1] = ans[i]
    else:
        ans[i - 1] = ans[i] - uf.size(a) * uf.size(b)
        uf.union(a, b)

for i in range(M):
    print(ans[i])