Buggy python submission (verdict: Time Limit Exceeded):
#D問題再チャレンジ
#Union Find

class UnionFind:
    def __init__(self, n):
        self.par = [i for i in range(n+1)]
        self.rank = [0] * (n+1)
        self.size = [1] * (n+1)

    # 検索
    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)
        #print([x,y])
        if self.rank[x] < self.rank[y]:
            self.par[x] = y
            self.size[y] = self.size[x] + self.size[y]
            self.size[x] = 0
        else:
            self.par[y] = x
            if x != y:
                self.size[x] = self.size[x] + self.size[y]
                self.size[y] = 0
            if self.rank[x] == self.rank[y]:
                self.rank[x] += 1

    # 同じ集合に属するか判定
    def same_check(self, x, y):
        return self.find(x) == self.find(y)

n, m = map(int, input().split())

uf = UnionFind(n)

con = [0] * (m+1)#convenience
x = [0] * (m+1)
y = [0] * (m+1)

con[m] = 0

for i in range(1,m+1):
    x[i], y[i] = map(int, input().split())
    #print([x,y])
    
for j in range(m-1,0,-1):
    #print([x[j+1],y[j+1]])
    uf.union(x[j+1],y[j+1])
    
    for k in range(1,n+1):
        s = uf.size[k]
        con[j] = con[j] + int(s*(s-1) / 2)
    
    #print(uf.size)

N = int(n * (n-1) / 2)

for i in range(1,m+1):
    print(N-con[i])

Fixed submission:
class UnionFind:
    def __init__(self, n):
        self.par = [i for i in range(n+1)]
        self.rank = [0] * (n+1)
        self.size = [1] * (n+1)
        self.con = [0] * (m+1)#convenience

    # 検索
    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, j):
        x = self.find(x)
        y = self.find(y)
        if x != y:
            self.con[j] = self.con[j+1] + self.size[x] * self.size[y]
        else:
            self.con[j] = self.con[j+1]
        #print([x,y])
        if self.rank[x] < self.rank[y]:
            self.par[x] = y
            self.size[y] = self.size[x] + self.size[y]
            self.size[x] = 0
        else:
            self.par[y] = x
            if x != y:
                self.size[x] = self.size[x] + self.size[y]
                self.size[y] = 0
            if self.rank[x] == self.rank[y]:
                self.rank[x] += 1

    # 同じ集合に属するか判定
    def same_check(self, x, y):
        return self.find(x) == self.find(y)

n, m = map(int, input().split())

uf = UnionFind(n)

x = [0] * (m+1)
y = [0] * (m+1)


for i in range(1,m+1):
    x[i], y[i] = map(int, input().split())
    #print([x,y])
    
for j in range(m-1,0,-1):
    #print([x[j+1],y[j+1]])
    uf.union(x[j+1],y[j+1],j)
    
    #print(uf.size)
    #print(uf.con)

N = int(n * (n-1) / 2)

for i in range(1,m+1):
    print(N-uf.con[i])

Buggy python submission (verdict: Time Limit Exceeded):
class UnionFind:
    def __init__(self, n):
        self.par = [i for i in range(n+1)]
        self.rank = [0] * (n+1)

    # 検索
    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 self.rank[x] < self.rank[y]:
            self.par[x] = y
        else:
            self.par[y] = x
            if self.rank[x] == self.rank[y]:
                self.rank[x] += 1

    # 同じ集合に属するか判定
    def same_check(self, x, y):
        return self.find(x) == self.find(y)

n, m = map(int, input().split())

uf = UnionFind(n)

con = [0] * (m+1)#convenience
x = [0] * (m+1)
y = [0] * (m+1)

con[m] = 0

for i in range(1,m+1):
    x[i], y[i] = map(int, input().split())
    
for j in range(m-1,0,-1):
    uf.union(x[j+1],y[j+1])
    
    for k in range(1,n+1):
        for l in range(1,n+1):
            if uf.same_check(k,l):
                con[j] = con[j] + 1
    
    con[j] = int((con[j] - n) / 2)

N = int(n * (n-1) / 2)

for i in range(1,m+1):
    print(N-con[i])
        

Fixed submission:
class UnionFind:
    def __init__(self, n):
        self.par = [i for i in range(n+1)]
        self.rank = [0] * (n+1)
        self.size = [1] * (n+1)
        self.con = [0] * (m+1)#convenience

    # 検索
    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, j):
        x = self.find(x)
        y = self.find(y)
        if x != y:
            self.con[j] = self.con[j+1] + self.size[x] * self.size[y]
        else:
            self.con[j] = self.con[j+1]
        #print([x,y])
        if self.rank[x] < self.rank[y]:
            self.par[x] = y
            self.size[y] = self.size[x] + self.size[y]
            self.size[x] = 0
        else:
            self.par[y] = x
            if x != y:
                self.size[x] = self.size[x] + self.size[y]
                self.size[y] = 0
            if self.rank[x] == self.rank[y]:
                self.rank[x] += 1

    # 同じ集合に属するか判定
    def same_check(self, x, y):
        return self.find(x) == self.find(y)

n, m = map(int, input().split())

uf = UnionFind(n)

x = [0] * (m+1)
y = [0] * (m+1)


for i in range(1,m+1):
    x[i], y[i] = map(int, input().split())
    #print([x,y])
    
for j in range(m-1,0,-1):
    #print([x[j+1],y[j+1]])
    uf.union(x[j+1],y[j+1],j)
    
    #print(uf.size)
    #print(uf.con)

N = int(n * (n-1) / 2)

for i in range(1,m+1):
    print(N-uf.con[i])