N,M=map(int, input().split())
L=[]
for i in range(M):
    a,b=map(int, input().split())
    L.append((a-1,b-1))



class UnionFind():
    # 作りたい要素数nで初期化
    # 使用するインスタンス変数の初期化
    def __init__(self, n):
        self.n = n
        # root[x]<0ならそのノードが根かつその値が木の要素数
        # rootノードでその木の要素数を記録する
        self.root = [-1]*(n+1)
        # 木をくっつける時にアンバランスにならないように調整する
        self.rnk = [0]*(n+1)

    # ノードxのrootノードを見つける
    def Find_Root(self, x):
        if(self.root[x] < 0):
            return x
        else:
            # ここで代入しておくことで、後の繰り返しを避ける
            self.root[x] = self.Find_Root(self.root[x])
        return self.root[x]

    # 木の併合、入力は併合したい各ノード
    def Unite(self, x, y):
        # 入力ノードのrootノードを見つける
        x = self.Find_Root(x)
        y = self.Find_Root(y)
        # すでに同じ木に属していた場合
        if (x == y):
            return 
        # 違う木に属していた場合rnkを見てくっつける方を決める
        #rnkが大きい方に結合
        elif (self.rnk[x] > self.rnk[y]):
            self.root[x] += self.root[y]
            self.root[y] = x

        else:
            self.root[y] += self.root[x]
            self.root[x] = y
        # rnkが同じ（深さに差がない場合）は1増やす
        if(self.rnk[x] == self.rnk[y]):
            self.rnk[y] += 1

    # xとyが同じグループに属するか判断
    def isSameGroup(self, x, y):
        return self.Find_Root(x) == self.Find_Root(y)

    # ノードxが属する木のサイズを返す
    def Count(self, x):
        return -self.root[self.Find_Root(x)]


uni=UnionFind(N)
L=L[::-1]
ans=[N*(N-1)//2]

for i in range(0,M):
    a,b=L[i]
    size_a=uni.Count(a)
    size_b=uni.Count(b)
    if i!=M-1:
        if not uni.isSameGroup(a,b):
            ans.append(ans[-1]-size_a*size_b)
        else:
            ans.append(ans[-1])
    uni.Unite(a,b)

ans=ans[::-1]
for a in ans:
    print(a) N,M=map(int, input().split()) N map(int, input().split()) map int input().split() ().split () input split M L=[] L [] for i in range(M):
    a,b=map(int, input().split())
    L.append((a-1,b-1)) i range(M) range M a,b=map(int, input().split()) a map(int, input().split()) map int input().split() ().split () input split b L.append((a-1,b-1)) L.append L append (a-1,b-1) a-1 a 1 b-1 b 1 class UnionFind():
    # 作りたい要素数nで初期化
    # 使用するインスタンス変数の初期化
    def __init__(self, n):
        self.n = n
        # root[x]<0ならそのノードが根かつその値が木の要素数
        # rootノードでその木の要素数を記録する
        self.root = [-1]*(n+1)
        # 木をくっつける時にアンバランスにならないように調整する
        self.rnk = [0]*(n+1)

    # ノードxのrootノードを見つける
    def Find_Root(self, x):
        if(self.root[x] < 0):
            return x
        else:
            # ここで代入しておくことで、後の繰り返しを避ける
            self.root[x] = self.Find_Root(self.root[x])
        return self.root[x]

    # 木の併合、入力は併合したい各ノード
    def Unite(self, x, y):
        # 入力ノードのrootノードを見つける
        x = self.Find_Root(x)
        y = self.Find_Root(y)
        # すでに同じ木に属していた場合
        if (x == y):
            return 
        # 違う木に属していた場合rnkを見てくっつける方を決める
        #rnkが大きい方に結合
        elif (self.rnk[x] > self.rnk[y]):
            self.root[x] += self.root[y]
            self.root[y] = x

        else:
            self.root[y] += self.root[x]
            self.root[x] = y
        # rnkが同じ（深さに差がない場合）は1増やす
        if(self.rnk[x] == self.rnk[y]):
            self.rnk[y] += 1

    # xとyが同じグループに属するか判断
    def isSameGroup(self, x, y):
        return self.Find_Root(x) == self.Find_Root(y)

    # ノードxが属する木のサイズを返す
    def Count(self, x):
        return -self.root[self.Find_Root(x)] UnionFind def __init__(self, n):
        self.n = n
        # root[x]<0ならそのノードが根かつその値が木の要素数
        # rootノードでその木の要素数を記録する
        self.root = [-1]*(n+1)
        # 木をくっつける時にアンバランスにならないように調整する
        self.rnk = [0]*(n+1)

    # ノードxのrootノードを見つける
     __init__ self.n = n self.n self n n self.root = [-1]*(n+1) self.root self root [-1]*(n+1) [-1] -1 n+1 n 1 self.rnk = [0]*(n+1) self.rnk self rnk [0]*(n+1) [0] 0 n+1 n 1 self self n n def Find_Root(self, x):
        if(self.root[x] < 0):
            return x
        else:
            # ここで代入しておくことで、後の繰り返しを避ける
            self.root[x] = self.Find_Root(self.root[x])
        return self.root[x]

    # 木の併合、入力は併合したい各ノード
     Find_Root if(self.root[x] < 0):
            return x
        else:
            # ここで代入しておくことで、後の繰り返しを避ける
            self.root[x] = self.Find_Root(self.root[x])
         self.root[x] < 0 self.root[x] self.root self root x 0 return x x self.root[x] = self.Find_Root(self.root[x]) self.root[x] self.root self root x self.Find_Root(self.root[x]) self.Find_Root self Find_Root self.root[x] self.root self root x return self.root[x] self.root[x] self.root self root x self self x x def Unite(self, x, y):
        # 入力ノードのrootノードを見つける
        x = self.Find_Root(x)
        y = self.Find_Root(y)
        # すでに同じ木に属していた場合
        if (x == y):
            return 
        # 違う木に属していた場合rnkを見てくっつける方を決める
        #rnkが大きい方に結合
        elif (self.rnk[x] > self.rnk[y]):
            self.root[x] += self.root[y]
            self.root[y] = x

        else:
            self.root[y] += self.root[x]
            self.root[x] = y
        # rnkが同じ（深さに差がない場合）は1増やす
        if(self.rnk[x] == self.rnk[y]):
            self.rnk[y] += 1

    # xとyが同じグループに属するか判断
     Unite x = self.Find_Root(x) x self.Find_Root(x) self.Find_Root self Find_Root x y = self.Find_Root(y) y self.Find_Root(y) self.Find_Root self Find_Root y if (x == y):
            return 
        # 違う木に属していた場合rnkを見てくっつける方を決める
        #rnkが大きい方に結合
        elif (self.rnk[x] > self.rnk[y]):
            self.root[x] += self.root[y]
            self.root[y] = x

        else:
            self.root[y] += self.root[x]
            self.root[x] = y
        # rnkが同じ（深さに差がない場合）は1増やす
         x == y x y return elif (self.rnk[x] > self.rnk[y]):
            self.root[x] += self.root[y]
            self.root[y] = x

         self.rnk[x] > self.rnk[y] self.rnk[x] self.rnk self rnk x self.rnk[y] self.rnk self rnk y self.root[x] += self.root[y] self.root[x] self.root self root x self.root[y] self.root self root y self.root[y] = x self.root[y] self.root self root y x self.root[y] += self.root[x] self.root[y] self.root self root y self.root[x] self.root self root x self.root[x] = y self.root[x] self.root self root x y if(self.rnk[x] == self.rnk[y]):
            self.rnk[y] += 1

    # xとyが同じグループに属するか判断
     self.rnk[x] == self.rnk[y] self.rnk[x] self.rnk self rnk x self.rnk[y] self.rnk self rnk y self.rnk[y] += 1 self.rnk[y] self.rnk self rnk y 1 self self x x y y def isSameGroup(self, x, y):
        return self.Find_Root(x) == self.Find_Root(y)

    # ノードxが属する木のサイズを返す
     isSameGroup return self.Find_Root(x) == self.Find_Root(y) self.Find_Root(x) == self.Find_Root(y) self.Find_Root(x) self.Find_Root self Find_Root x self.Find_Root(y) self.Find_Root self Find_Root y self self x x y y def Count(self, x):
        return -self.root[self.Find_Root(x)] Count return -self.root[self.Find_Root(x)] -self.root[self.Find_Root(x)] self.root[self.Find_Root(x)] self.root self root self.Find_Root(x) self.Find_Root self Find_Root x self self x x uni=UnionFind(N) uni UnionFind(N) UnionFind N L=L[::-1] L L[::-1] L ::-1 -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 i in range(0,M):
    a,b=L[i]
    size_a=uni.Count(a)
    size_b=uni.Count(b)
    if i!=M-1:
        if not uni.isSameGroup(a,b):
            ans.append(ans[-1]-size_a*size_b)
        else:
            ans.append(ans[-1])
    uni.Unite(a,b) i range(0,M) range 0 M a,b=L[i] a L[i] L i b size_a=uni.Count(a) size_a uni.Count(a) uni.Count uni Count a size_b=uni.Count(b) size_b uni.Count(b) uni.Count uni Count b if i!=M-1:
        if not uni.isSameGroup(a,b):
            ans.append(ans[-1]-size_a*size_b)
        else:
            ans.append(ans[-1])
     i!=M-1 i M-1 M 1 if not uni.isSameGroup(a,b):
            ans.append(ans[-1]-size_a*size_b)
        else:
            ans.append(ans[-1])
     not uni.isSameGroup(a,b) uni.isSameGroup(a,b) uni.isSameGroup uni isSameGroup a b ans.append(ans[-1]-size_a*size_b) ans.append ans append ans[-1]-size_a*size_b ans[-1] ans -1 size_a*size_b size_a size_b ans.append(ans[-1]) ans.append ans append ans[-1] ans -1 uni.Unite(a,b) uni.Unite uni Unite a b ans=ans[::-1] ans ans[::-1] ans ::-1 -1 for a in ans:
    print(a) a ans print(a) print a a,b=L[i] L[i] a a,b=map(int, input().split()) map(int, input().split()) a N,M=map(int, input().split()) map(int, input().split()) N b=L[i] L[i] b L=[] [] L class UnionFind():
    # 作りたい要素数nで初期化
    # 使用するインスタンス変数の初期化
    def __init__(self, n):
        self.n = n
        # root[x]<0ならそのノードが根かつその値が木の要素数
        # rootノードでその木の要素数を記録する
        self.root = [-1]*(n+1)
        # 木をくっつける時にアンバランスにならないように調整する
        self.rnk = [0]*(n+1)

    # ノードxのrootノードを見つける
    def Find_Root(self, x):
        if(self.root[x] < 0):
            return x
        else:
            # ここで代入しておくことで、後の繰り返しを避ける
            self.root[x] = self.Find_Root(self.root[x])
        return self.root[x]

    # 木の併合、入力は併合したい各ノード
    def Unite(self, x, y):
        # 入力ノードのrootノードを見つける
        x = self.Find_Root(x)
        y = self.Find_Root(y)
        # すでに同じ木に属していた場合
        if (x == y):
            return 
        # 違う木に属していた場合rnkを見てくっつける方を決める
        #rnkが大きい方に結合
        elif (self.rnk[x] > self.rnk[y]):
            self.root[x] += self.root[y]
            self.root[y] = x

        else:
            self.root[y] += self.root[x]
            self.root[x] = y
        # rnkが同じ（深さに差がない場合）は1増やす
        if(self.rnk[x] == self.rnk[y]):
            self.rnk[y] += 1

    # xとyが同じグループに属するか判断
    def isSameGroup(self, x, y):
        return self.Find_Root(x) == self.Find_Root(y)

    # ノードxが属する木のサイズを返す
    def Count(self, x):
        return -self.root[self.Find_Root(x)] class UnionFind():
    # 作りたい要素数nで初期化
    # 使用するインスタンス変数の初期化
    def __init__(self, n):
        self.n = n
        # root[x]<0ならそのノードが根かつその値が木の要素数
        # rootノードでその木の要素数を記録する
        self.root = [-1]*(n+1)
        # 木をくっつける時にアンバランスにならないように調整する
        self.rnk = [0]*(n+1)

    # ノードxのrootノードを見つける
    def Find_Root(self, x):
        if(self.root[x] < 0):
            return x
        else:
            # ここで代入しておくことで、後の繰り返しを避ける
            self.root[x] = self.Find_Root(self.root[x])
        return self.root[x]

    # 木の併合、入力は併合したい各ノード
    def Unite(self, x, y):
        # 入力ノードのrootノードを見つける
        x = self.Find_Root(x)
        y = self.Find_Root(y)
        # すでに同じ木に属していた場合
        if (x == y):
            return 
        # 違う木に属していた場合rnkを見てくっつける方を決める
        #rnkが大きい方に結合
        elif (self.rnk[x] > self.rnk[y]):
            self.root[x] += self.root[y]
            self.root[y] = x

        else:
            self.root[y] += self.root[x]
            self.root[x] = y
        # rnkが同じ（深さに差がない場合）は1増やす
        if(self.rnk[x] == self.rnk[y]):
            self.rnk[y] += 1

    # xとyが同じグループに属するか判断
    def isSameGroup(self, x, y):
        return self.Find_Root(x) == self.Find_Root(y)

    # ノードxが属する木のサイズを返す
    def Count(self, x):
        return -self.root[self.Find_Root(x)] UnionFind size_b=uni.Count(b) uni.Count(b) size_b b=map(int, input().split()) map(int, input().split()) b L=L[::-1] L[::-1] L ans=ans[::-1] ans[::-1] ans ans=[N*(N-1)//2] [N*(N-1)//2] ans M=map(int, input().split()) map(int, input().split()) M uni=UnionFind(N) UnionFind(N) uni size_a=uni.Count(a) uni.Count(a) size_a
N,M=map(int, input().split())
L=[]
for i in range(M):
    a,b=map(int, input().split())
    L.append((a-1,b-1))



class UnionFind():
    # 作りたい要素数nで初期化
    # 使用するインスタンス変数の初期化
    def __init__(self, n):
        self.n = n
        # root[x]<0ならそのノードが根かつその値が木の要素数
        # rootノードでその木の要素数を記録する
        self.root = [-1]*(n+1)
        # 木をくっつける時にアンバランスにならないように調整する
        self.rnk = [0]*(n+1)

    # ノードxのrootノードを見つける
    def Find_Root(self, x):
        if(self.root[x] < 0):
            return x
        else:
            # ここで代入しておくことで、後の繰り返しを避ける
            self.root[x] = self.Find_Root(self.root[x])
        return self.root[x]

    # 木の併合、入力は併合したい各ノード
    def Unite(self, x, y):
        # 入力ノードのrootノードを見つける
        x = self.Find_Root(x)
        y = self.Find_Root(y)
        # すでに同じ木に属していた場合
        if (x == y):
            return 
        # 違う木に属していた場合rnkを見てくっつける方を決める
        #rnkが大きい方に結合
        elif (self.rnk[x] > self.rnk[y]):
            self.root[x] += self.root[y]
            self.root[y] = x

        else:
            self.root[y] += self.root[x]
            self.root[x] = y
        # rnkが同じ（深さに差がない場合）は1増やす
        if(self.rnk[x] == self.rnk[y]):
            self.rnk[y] += 1

    # xとyが同じグループに属するか判断
    def isSameGroup(self, x, y):
        return self.Find_Root(x) == self.Find_Root(y)

    # ノードxが属する木のサイズを返す
    def Count(self, x):
        return -self.root[self.Find_Root(x)]


uni=UnionFind(N)
L=L[::-1]
ans=[N*(N-1)//2]

for i in range(0,M):
    a,b=L[i]
    size_a=uni.Count(a)
    size_b=uni.Count(b)
    if i!=M-1:
        if not uni.isSameGroup(a,b):
            ans.append(ans[-1]-size_a*size_b)
        else:
            ans.append(ans[-1])
    uni.Unite(a,b)

ans=ans[::-1]
for a in ans:
    print(a)