import sys

def LI(): return list(map(int,sys.stdin.readline().rstrip().split()))  #空白あり

N,M = LI()
AB = [LI() for i in range(M)]
del AB[0]

AB.reverse()

# 逆に橋がない状態から1本ずつ橋を加えた時に、不便さがどのくらい減少するかを考える

class UnionFind:
    def __init__(self,n):
        self.par = [i for i in range(n+1)]  # 親のノード番号
        self.rank = [0]*(n+1)
    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 same_check(self,x,y):  # x,yが同じグループか否か
        return self.find(x) == self.find(y)
    def unite(self,x,y):  # x,yの属するグループの併合
        x = self.find(x)
        y = self.find(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

G = UnionFind(N)
C = [1]*(N+1)  # 連結成分の大きさ(根となっている頂点だけ正しい)

ANS = [N*(N-1)//2]
for a,b in AB:
    if not G.same_check(a,b):
        x = C[G.find(a)]
        y = C[G.find(b)]
        ANS.append(ANS[-1]-x*y)  # 連結成分の積だけ不便さが減少
        G.unite(a,b)
        C[G.find(a)] = x+y  # 連結成分の大きさを変える
    else:
        ANS.append(ANS[-1])

ANS.reverse()

print(*ANS,sep='\n') import sys sys def LI(): return list(map(int,sys.stdin.readline().rstrip().split()))  #空白あり LI N,M = LI() N LI() LI M LI() for i in range(M) for i in range(M) i range(M) range M for i in range(M) LI() LI AB = [LI() for i in range(M)] AB [LI() for i in range(M)] del AB[0] AB[0] AB 0 AB.reverse() AB.reverse AB reverse class UnionFind:
    def __init__(self,n):
        self.par = [i for i in range(n+1)]  # 親のノード番号
        self.rank = [0]*(n+1)
    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 same_check(self,x,y):  # x,yが同じグループか否か
        return self.find(x) == self.find(y)
    def unite(self,x,y):  # x,yの属するグループの併合
        x = self.find(x)
        y = self.find(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 UnionFind def __init__(self,n):
        self.par = [i for i in range(n+1)]  # 親のノード番号
        self.rank = [0]*(n+1)
     __init__ i for i in range(n+1) for i in range(n+1) i range(n+1) range n+1 n 1 for i in range(n+1) i self.par = [i for i in range(n+1)] self.par self par [i for i in range(n+1)] self.rank = [0]*(n+1) self.rank self rank [0]*(n+1) [0] 0 n+1 n 1 self self n 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]
     find if self.par[x] == x:
            return x
        else:
            self.par[x] = self.find(self.par[x])
            return self.par[x]
     self.par[x] == x self.par[x] self.par self par x x return x x self.par[x] = self.find(self.par[x]) self.par[x] self.par self par x self.find(self.par[x]) self.find self find self.par[x] self.par self par x return self.par[x] self.par[x] self.par self par x self self x x def same_check(self,x,y):  # x,yが同じグループか否か
        return self.find(x) == self.find(y)
     same_check return self.find(x) == self.find(y) self.find(x) == self.find(y) self.find(x) self.find self find x self.find(y) self.find self find y self self x x y y def unite(self,x,y):  # x,yの属するグループの併合
        x = self.find(x)
        y = self.find(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 unite x = self.find(x) x self.find(x) self.find self find x y = self.find(y) y self.find(y) self.find self find y if self.rank[x] < self.rank[y]:
            x,y = y,x
         self.rank[x] < self.rank[y] self.rank[x] self.rank self rank x self.rank[y] self.rank self rank y x,y = y,x x y y x if self.rank[x] == self.rank[y]:
            self.rank[x] += 1
         self.rank[x] == self.rank[y] self.rank[x] self.rank self rank x self.rank[y] self.rank self rank y self.rank[x] += 1 self.rank[x] self.rank self rank x 1 self.par[y] = x self.par[y] self.par self par y x self self x x y y G = UnionFind(N) G UnionFind(N) UnionFind N C = [1]*(N+1) C [1]*(N+1) [1] 1 N+1 N 1 ANS = [N*(N-1)//2] ANS [N*(N-1)//2] N*(N-1)//2 N*(N-1) N N-1 N 1 2 for a,b in AB:
    if not G.same_check(a,b):
        x = C[G.find(a)]
        y = C[G.find(b)]
        ANS.append(ANS[-1]-x*y)  # 連結成分の積だけ不便さが減少
        G.unite(a,b)
        C[G.find(a)] = x+y  # 連結成分の大きさを変える
    else:
        ANS.append(ANS[-1]) a b AB if not G.same_check(a,b):
        x = C[G.find(a)]
        y = C[G.find(b)]
        ANS.append(ANS[-1]-x*y)  # 連結成分の積だけ不便さが減少
        G.unite(a,b)
        C[G.find(a)] = x+y  # 連結成分の大きさを変える
    else:
        ANS.append(ANS[-1]) not G.same_check(a,b) G.same_check(a,b) G.same_check G same_check a b x = C[G.find(a)] x C[G.find(a)] C G.find(a) G.find G find a y = C[G.find(b)] y C[G.find(b)] C G.find(b) G.find G find b ANS.append(ANS[-1]-x*y) ANS.append ANS append ANS[-1]-x*y ANS[-1] ANS -1 x*y x y G.unite(a,b) G.unite G unite a b C[G.find(a)] = x+y C[G.find(a)] C G.find(a) G.find G find a x+y x y ANS.append(ANS[-1]) ANS.append ANS append ANS[-1] ANS -1 ANS.reverse() ANS.reverse ANS reverse print(*ANS,sep='\n') print *ANS ANS sep='\n' sep '\n' M = LI() LI() M G = UnionFind(N) UnionFind(N) G AB = [LI() for i in range(M)] [LI() for i in range(M)] AB N,M = LI() LI() N C = [1]*(N+1) [1]*(N+1) C def LI(): return list(map(int,sys.stdin.readline().rstrip().split()))  #空白あり def LI(): return list(map(int,sys.stdin.readline().rstrip().split()))  #空白あり LI ANS = [N*(N-1)//2] [N*(N-1)//2] ANS x = C[G.find(a)] C[G.find(a)] x class UnionFind:
    def __init__(self,n):
        self.par = [i for i in range(n+1)]  # 親のノード番号
        self.rank = [0]*(n+1)
    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 same_check(self,x,y):  # x,yが同じグループか否か
        return self.find(x) == self.find(y)
    def unite(self,x,y):  # x,yの属するグループの併合
        x = self.find(x)
        y = self.find(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 class UnionFind:
    def __init__(self,n):
        self.par = [i for i in range(n+1)]  # 親のノード番号
        self.rank = [0]*(n+1)
    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 same_check(self,x,y):  # x,yが同じグループか否か
        return self.find(x) == self.find(y)
    def unite(self,x,y):  # x,yの属するグループの併合
        x = self.find(x)
        y = self.find(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 UnionFind y = C[G.find(b)] C[G.find(b)] y
import sys

def LI(): return list(map(int,sys.stdin.readline().rstrip().split()))  #空白あり

N,M = LI()
AB = [LI() for i in range(M)]
del AB[0]

AB.reverse()

# 逆に橋がない状態から1本ずつ橋を加えた時に、不便さがどのくらい減少するかを考える

class UnionFind:
    def __init__(self,n):
        self.par = [i for i in range(n+1)]  # 親のノード番号
        self.rank = [0]*(n+1)
    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 same_check(self,x,y):  # x,yが同じグループか否か
        return self.find(x) == self.find(y)
    def unite(self,x,y):  # x,yの属するグループの併合
        x = self.find(x)
        y = self.find(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

G = UnionFind(N)
C = [1]*(N+1)  # 連結成分の大きさ(根となっている頂点だけ正しい)

ANS = [N*(N-1)//2]
for a,b in AB:
    if not G.same_check(a,b):
        x = C[G.find(a)]
        y = C[G.find(b)]
        ANS.append(ANS[-1]-x*y)  # 連結成分の積だけ不便さが減少
        G.unite(a,b)
        C[G.find(a)] = x+y  # 連結成分の大きさを変える
    else:
        ANS.append(ANS[-1])

ANS.reverse()

print(*ANS,sep='\n')
