'''
satoooh
時間経過を逆転させて考えてみます。つまり、橋が崩壊していくのではなく、 
橋が復旧していくときの答えの変化を順に考えます。橋 i+1 が復旧すると、
group_size(A_{i+1}) * group_size(B_{i+1}) 分だけ答えが減る
'''

class UnionFind:
    def __init__(self, n):
        self.n = n
        self.parent = [i for i in range(n)]  # 親
        self.rank = [1] * n  # 木の高さ
        self.size = [1] * n  # size[i] は i を根とするグループのサイズ

    def find(self, x):  # x の根を返す
        if self.parent[x] == x:
            return x
        else:
            self.parent[x] = self.find(self.parent[x])  # 経路圧縮
            return self.parent[x]

    def unite(self, x, y):  # x, y の属する集合を併合する
        x = self.find(x)
        y = self.find(y)
        if x != y:
            if self.rank[x] < self.rank[y]:
                self.parent[x] = y
                self.size[y] += self.size[x]
            else:
                self.parent[y] = x
                self.size[x] += self.size[y]
                if self.rank[x] == self.rank[y]:
                    self.rank[x] += 1

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

    def group_size(self, x):  # x が属する集合の大きさを返す
        return self.size[self.find(x)]

    #def __str__(self):  # print 表示用
        #return '\n'.join('{}: {}'.format(r, self.group_members(r)) for r in self.roots())


N, M = map(int, input().split())
bridge = [list(map(int, input().split())) for _ in range(M)]
ans = [0]*M
uf = UnionFind(N)

# うしろからつないでいく
ans[M-1] = N*(N-1)//2
for i in range(M-2, -1, -1):
    A, B = bridge[i+1]
    if uf.is_same(A-1, B-1):
        ans[i] = ans[i+1]
    else:
        ans[i] = ans[i+1] - uf.group_size(A-1) * uf.group_size(B-1)
    uf.unite(A-1, B-1)

for a in ans:
    print(a) '''
satoooh
時間経過を逆転させて考えてみます。つまり、橋が崩壊していくのではなく、 
橋が復旧していくときの答えの変化を順に考えます。橋 i+1 が復旧すると、
group_size(A_{i+1}) * group_size(B_{i+1}) 分だけ答えが減る
''' class UnionFind:
    def __init__(self, n):
        self.n = n
        self.parent = [i for i in range(n)]  # 親
        self.rank = [1] * n  # 木の高さ
        self.size = [1] * n  # size[i] は i を根とするグループのサイズ

    def find(self, x):  # x の根を返す
        if self.parent[x] == x:
            return x
        else:
            self.parent[x] = self.find(self.parent[x])  # 経路圧縮
            return self.parent[x]

    def unite(self, x, y):  # x, y の属する集合を併合する
        x = self.find(x)
        y = self.find(y)
        if x != y:
            if self.rank[x] < self.rank[y]:
                self.parent[x] = y
                self.size[y] += self.size[x]
            else:
                self.parent[y] = x
                self.size[x] += self.size[y]
                if self.rank[x] == self.rank[y]:
                    self.rank[x] += 1

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

    def group_size(self, x):  # x が属する集合の大きさを返す
        return self.size[self.find(x)]

    #def __str__(self):  # print 表示用
        #return '\n'.join('{}: {}'.format(r, self.group_members(r)) for r in self.roots()) UnionFind def __init__(self, n):
        self.n = n
        self.parent = [i for i in range(n)]  # 親
        self.rank = [1] * n  # 木の高さ
        self.size = [1] * n  # size[i] は i を根とするグループのサイズ

     __init__ self.n = n self.n self n n i for i in range(n) for i in range(n) i range(n) range n for i in range(n) i self.parent = [i for i in range(n)] self.parent self parent [i for i in range(n)] self.rank = [1] * n self.rank self rank [1] * n [1] 1 n self.size = [1] * n self.size self size [1] * n [1] 1 n self self n n def find(self, x):  # x の根を返す
        if self.parent[x] == x:
            return x
        else:
            self.parent[x] = self.find(self.parent[x])  # 経路圧縮
            return self.parent[x]

     find if self.parent[x] == x:
            return x
        else:
            self.parent[x] = self.find(self.parent[x])  # 経路圧縮
            return self.parent[x]

     self.parent[x] == x self.parent[x] self.parent self parent x x return x x self.parent[x] = self.find(self.parent[x]) self.parent[x] self.parent self parent x self.find(self.parent[x]) self.find self find self.parent[x] self.parent self parent x return self.parent[x] self.parent[x] self.parent self parent x self self x x def unite(self, x, y):  # x, y の属する集合を併合する
        x = self.find(x)
        y = self.find(y)
        if x != y:
            if self.rank[x] < self.rank[y]:
                self.parent[x] = y
                self.size[y] += self.size[x]
            else:
                self.parent[y] = x
                self.size[x] += self.size[y]
                if self.rank[x] == self.rank[y]:
                    self.rank[x] += 1

     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 x != y:
            if self.rank[x] < self.rank[y]:
                self.parent[x] = y
                self.size[y] += self.size[x]
            else:
                self.parent[y] = x
                self.size[x] += self.size[y]
                if self.rank[x] == self.rank[y]:
                    self.rank[x] += 1

     x != y x y if self.rank[x] < self.rank[y]:
                self.parent[x] = y
                self.size[y] += self.size[x]
            else:
                self.parent[y] = x
                self.size[x] += self.size[y]
                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.parent[x] = y self.parent[x] self.parent self parent x y self.size[y] += self.size[x] self.size[y] self.size self size y self.size[x] self.size self size x self.parent[y] = x self.parent[y] self.parent self parent y x self.size[x] += self.size[y] self.size[x] self.size self size x self.size[y] self.size self size y 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 self x x y y def is_same(self, x, y):  # x, y が同じ集合に属するか判定する
        return self.find(x) == self.find(y)

     is_same 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 group_size(self, x):  # x が属する集合の大きさを返す
        return self.size[self.find(x)]

    #def __str__(self):  # print 表示用
        #return '\n'.join('{}: {}'.format(r, self.group_members(r)) for r in self.roots()) group_size return self.size[self.find(x)] self.size[self.find(x)] self.size self size self.find(x) self.find self find x self self x x N, M = map(int, input().split()) N map(int, input().split()) map int input().split() ().split () input split M list(map(int, input().split())) for _ in range(M) for _ in range(M) _ range(M) range M for _ in range(M) list(map(int, input().split())) list map(int, input().split()) map int input().split() ().split () input split bridge = [list(map(int, input().split())) for _ in range(M)] bridge [list(map(int, input().split())) for _ in range(M)] ans = [0]*M ans [0]*M [0] 0 M uf = UnionFind(N) uf UnionFind(N) UnionFind N ans[M-1] = N*(N-1)//2 ans[M-1] ans M-1 M 1 N*(N-1)//2 N*(N-1) N N-1 N 1 2 for i in range(M-2, -1, -1):
    A, B = bridge[i+1]
    if uf.is_same(A-1, B-1):
        ans[i] = ans[i+1]
    else:
        ans[i] = ans[i+1] - uf.group_size(A-1) * uf.group_size(B-1)
    uf.unite(A-1, B-1) i range(M-2, -1, -1) range M-2 M 2 -1 -1 A, B = bridge[i+1] A bridge[i+1] bridge i+1 i 1 B if uf.is_same(A-1, B-1):
        ans[i] = ans[i+1]
    else:
        ans[i] = ans[i+1] - uf.group_size(A-1) * uf.group_size(B-1)
     uf.is_same(A-1, B-1) uf.is_same uf is_same A-1 A 1 B-1 B 1 ans[i] = ans[i+1] ans[i] ans i ans[i+1] ans i+1 i 1 ans[i] = ans[i+1] - uf.group_size(A-1) * uf.group_size(B-1) ans[i] ans i ans[i+1] - uf.group_size(A-1) * uf.group_size(B-1) ans[i+1] ans i+1 i 1 uf.group_size(A-1) * uf.group_size(B-1) uf.group_size(A-1) uf.group_size uf group_size A-1 A 1 uf.group_size(B-1) uf.group_size uf group_size B-1 B 1 uf.unite(A-1, B-1) uf.unite uf unite A-1 A 1 B-1 B 1 for a in ans:
    print(a) a ans print(a) print a B = bridge[i+1] bridge[i+1] B N, M = map(int, input().split()) map(int, input().split()) N bridge = [list(map(int, input().split())) for _ in range(M)] [list(map(int, input().split())) for _ in range(M)] bridge uf = UnionFind(N) UnionFind(N) uf M = map(int, input().split()) map(int, input().split()) M A, B = bridge[i+1] bridge[i+1] A ans = [0]*M [0]*M ans class UnionFind:
    def __init__(self, n):
        self.n = n
        self.parent = [i for i in range(n)]  # 親
        self.rank = [1] * n  # 木の高さ
        self.size = [1] * n  # size[i] は i を根とするグループのサイズ

    def find(self, x):  # x の根を返す
        if self.parent[x] == x:
            return x
        else:
            self.parent[x] = self.find(self.parent[x])  # 経路圧縮
            return self.parent[x]

    def unite(self, x, y):  # x, y の属する集合を併合する
        x = self.find(x)
        y = self.find(y)
        if x != y:
            if self.rank[x] < self.rank[y]:
                self.parent[x] = y
                self.size[y] += self.size[x]
            else:
                self.parent[y] = x
                self.size[x] += self.size[y]
                if self.rank[x] == self.rank[y]:
                    self.rank[x] += 1

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

    def group_size(self, x):  # x が属する集合の大きさを返す
        return self.size[self.find(x)]

    #def __str__(self):  # print 表示用
        #return '\n'.join('{}: {}'.format(r, self.group_members(r)) for r in self.roots()) class UnionFind:
    def __init__(self, n):
        self.n = n
        self.parent = [i for i in range(n)]  # 親
        self.rank = [1] * n  # 木の高さ
        self.size = [1] * n  # size[i] は i を根とするグループのサイズ

    def find(self, x):  # x の根を返す
        if self.parent[x] == x:
            return x
        else:
            self.parent[x] = self.find(self.parent[x])  # 経路圧縮
            return self.parent[x]

    def unite(self, x, y):  # x, y の属する集合を併合する
        x = self.find(x)
        y = self.find(y)
        if x != y:
            if self.rank[x] < self.rank[y]:
                self.parent[x] = y
                self.size[y] += self.size[x]
            else:
                self.parent[y] = x
                self.size[x] += self.size[y]
                if self.rank[x] == self.rank[y]:
                    self.rank[x] += 1

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

    def group_size(self, x):  # x が属する集合の大きさを返す
        return self.size[self.find(x)]

    #def __str__(self):  # print 表示用
        #return '\n'.join('{}: {}'.format(r, self.group_members(r)) for r in self.roots()) UnionFind
'''
satoooh
時間経過を逆転させて考えてみます。つまり、橋が崩壊していくのではなく、 
橋が復旧していくときの答えの変化を順に考えます。橋 i+1 が復旧すると、
group_size(A_{i+1}) * group_size(B_{i+1}) 分だけ答えが減る
'''

class UnionFind:
    def __init__(self, n):
        self.n = n
        self.parent = [i for i in range(n)]  # 親
        self.rank = [1] * n  # 木の高さ
        self.size = [1] * n  # size[i] は i を根とするグループのサイズ

    def find(self, x):  # x の根を返す
        if self.parent[x] == x:
            return x
        else:
            self.parent[x] = self.find(self.parent[x])  # 経路圧縮
            return self.parent[x]

    def unite(self, x, y):  # x, y の属する集合を併合する
        x = self.find(x)
        y = self.find(y)
        if x != y:
            if self.rank[x] < self.rank[y]:
                self.parent[x] = y
                self.size[y] += self.size[x]
            else:
                self.parent[y] = x
                self.size[x] += self.size[y]
                if self.rank[x] == self.rank[y]:
                    self.rank[x] += 1

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

    def group_size(self, x):  # x が属する集合の大きさを返す
        return self.size[self.find(x)]

    #def __str__(self):  # print 表示用
        #return '\n'.join('{}: {}'.format(r, self.group_members(r)) for r in self.roots())


N, M = map(int, input().split())
bridge = [list(map(int, input().split())) for _ in range(M)]
ans = [0]*M
uf = UnionFind(N)

# うしろからつないでいく
ans[M-1] = N*(N-1)//2
for i in range(M-2, -1, -1):
    A, B = bridge[i+1]
    if uf.is_same(A-1, B-1):
        ans[i] = ans[i+1]
    else:
        ans[i] = ans[i+1] - uf.group_size(A-1) * uf.group_size(B-1)
    uf.unite(A-1, B-1)

for a in ans:
    print(a)