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

AB = [list(map(int,input().split())) for i in range(m)]

#入力

AB.reverse()

ans = [0]*(m+1)

ans[m] = n*(n-1)//2

class UnionFind:

    def __init__(self, n):

        self.par = [i for i in range(n+1)]

        self.rank = [0] * (n+1)

        self.count = [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)

        if self.rank[x] < self.rank[y]:

            self.par[x] = y

            self.count[y] += self.count[x]

            self.count[x] = 0

        else:

            self.par[y] = x

            self.count[x] += self.count[y]

            self.count[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)



    # 属している集合の要素数

    def search(self,x):

        q = UnionFind.find(self,x)

        return self.count[q]



uf = UnionFind(n)



for i in range(m):

    a = AB[i][0]

    b = AB[i][1]

    #print(a,b)

    if uf.same_check(a,b):

        ans[m-i-1] = ans[m-i]

        continue

    else:

        s = uf.search(a)

        t = uf.search(b)

        #print(s,t)

        uf.union(a,b)

        ans[m-i-1] = ans[m-i] + s*(s-1)//2 + t*(t-1)//2 - (s+t)*(s+t-1)//2

for i in range(1,m+1):

    print((ans[i]))
class UnionFind:

    def __init__(self, n):

        # 親要素のノード番号を格納　par[x] == x の時そのノードは根

        self.par = [i for i in range(n+1)]

        # 木の高さを格納する（初期状態では0)

        self.rank = [0] * (n+1)

        # 各々の集合の要素数（根が代表して値を持っておく）

        self.count = [1] * (n+1)



    # 検索

    def find(self, x):

        # 根ならその番号を返す

        root = x

        queue = [x]

        data = []

        while queue:

            now = queue.pop()

            if self.par[now] == now:

                root = now

            else:

                # 根でないなら親の要素で再検索

                data.append(now)

                queue.append(self.par[now])

        # 検索する過程で親を更新

        for y in data:

            self.par[y] = root

        return root



    # 併合

    def union(self, x, y):

        x = self.find(x)

        y = self.find(y)

        if x == y:

            return True

        if self.rank[x] < self.rank[y]:

            self.par[x] = y

            self.count[y] += self.count[x]

            self.count[x] = 0

        else:

            self.par[y] = x

            self.count[x] += self.count[y]

            self.count[y] = 0

            if self.rank[x] == self.rank[y]:

                self.rank[x] += 1

        return False



    # 同じ集合に属しているか判定

    def same_check(self, x, y):

        return self.find(x) == self.find(y)



    # 属している集合の要素数

    def size(self, x):

        q = UnionFind.find(self, x)

        return self.count[q]





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

data = [tuple([int(z) - 1 for z in input().split()]) for _ in range(m)][::-1]

u = UnionFind(n)

ans = [n*(n-1)//2]

for i in range(m):

    if u.same_check(data[i][0], data[i][1]):

        ans.append(ans[-1])

    else:

        ans.append(ans[-1] - u.size(data[i][0])*u.size(data[i][1]))

        u.union(data[i][0], data[i][1])



for x in ans[::-1][1:]:

    print(x)

n, m = list(map(int, input().split()))
AB = [list(map(int, input().split())) for i in range(m)]
# 入力
AB.reverse()
ans = [0] * (m + 1)
ans[m] = n * (n - 1) // 2


class UnionFind:
    def __init__(self, n):
        self.par = [i for i in range(n + 1)]
        self.rank = [0] * (n + 1)
        self.count = [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)
        if self.rank[x] < self.rank[y]:
            self.par[x] = y
            self.count[y] += self.count[x]
            self.count[x] = 0
        else:
            self.par[y] = x
            self.count[x] += self.count[y]
            self.count[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)

    # 属している集合の要素数
    def search(self, x):
        q = UnionFind.find(self, x)
        return self.count[q]


uf = UnionFind(n)
for i in range(m):
    a = AB[i][0]
    b = AB[i][1]
    # print(a,b)
    if uf.same_check(a, b):
        ans[m - i - 1] = ans[m - i]
        continue
    else:
        s = uf.search(a)
        t = uf.search(b)
        # print(s,t)
        uf.union(a, b)
        ans[m - i - 1] = (
            ans[m - i]
            + s * (s - 1) // 2
            + t * (t - 1) // 2
            - (s + t) * (s + t - 1) // 2
        )
for i in range(1, m + 1):
    print((ans[i]))

class UnionFind:
    def __init__(self, n):
        # 親要素のノード番号を格納　par[x] == x の時そのノードは根
        self.par = [i for i in range(n + 1)]
        # 木の高さを格納する（初期状態では0)
        self.rank = [0] * (n + 1)
        # 各々の集合の要素数（根が代表して値を持っておく）
        self.count = [1] * (n + 1)

    # 検索
    def find(self, x):
        # 根ならその番号を返す
        root = x
        queue = [x]
        data = []
        while queue:
            now = queue.pop()
            if self.par[now] == now:
                root = now
            else:
                # 根でないなら親の要素で再検索
                data.append(now)
                queue.append(self.par[now])
        # 検索する過程で親を更新
        for y in data:
            self.par[y] = root
        return root

    # 併合
    def union(self, x, y):
        x = self.find(x)
        y = self.find(y)
        if x == y:
            return True
        if self.rank[x] < self.rank[y]:
            self.par[x] = y
            self.count[y] += self.count[x]
            self.count[x] = 0
        else:
            self.par[y] = x
            self.count[x] += self.count[y]
            self.count[y] = 0
            if self.rank[x] == self.rank[y]:
                self.rank[x] += 1
        return False

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

    # 属している集合の要素数
    def size(self, x):
        q = UnionFind.find(self, x)
        return self.count[q]


n, m = list(map(int, input().split()))
data = [tuple([int(z) - 1 for z in input().split()]) for _ in range(m)][::-1]
u = UnionFind(n)
ans = [n * (n - 1) // 2]
for i in range(m):
    if u.same_check(data[i][0], data[i][1]):
        ans.append(ans[-1])
    else:
        ans.append(ans[-1] - u.size(data[i][0]) * u.size(data[i][1]))
        u.union(data[i][0], data[i][1])
for x in ans[::-1][1:]:
    print(x)

-n, m = list(map(int, input().split())) -AB = [list(map(int, input().split())) for i in range(m)] -# 入力 -AB.reverse() -ans = [0] * (m + 1) -ans[m] = n * (n - 1) // 2 - - +        # 親要素のノード番号を格納　par[x] == x の時そのノードは根 +        # 木の高さを格納する（初期状態では0) +        # 各々の集合の要素数（根が代表して値を持っておく） -        if self.par[x] == x: -            return x -        else: -            self.par[x] = self.find(self.par[x]) -            return self.par[x] +        # 根ならその番号を返す +        root = x +        queue = [x] +        data = [] +        while queue: +            now = queue.pop() +            if self.par[now] == now: +                root = now +            else: +                # 根でないなら親の要素で再検索 +                data.append(now) +                queue.append(self.par[now]) +        # 検索する過程で親を更新 +        for y in data: +            self.par[y] = root +        return root +        if x == y: +            return True +        return False -    # 同じ集合に属するか判定 +    # 同じ集合に属しているか判定 -    def search(self, x): +    def size(self, x): -uf = UnionFind(n) +n, m = list(map(int, input().split())) +data = [tuple([int(z) - 1 for z in input().split()]) for _ in range(m)][::-1] +u = UnionFind(n) +ans = [n * (n - 1) // 2] -    a = AB[i][0] -    b = AB[i][1] -    # print(a,b) -    if uf.same_check(a, b): -        ans[m - i - 1] = ans[m - i] -        continue +    if u.same_check(data[i][0], data[i][1]): +        ans.append(ans[-1]) -        s = uf.search(a) -        t = uf.search(b) -        # print(s,t) -        uf.union(a, b) -        ans[m - i - 1] = ( -            ans[m - i] -            + s * (s - 1) // 2 -            + t * (t - 1) // 2 -            - (s + t) * (s + t - 1) // 2 -        ) -for i in range(1, m + 1): -    print((ans[i])) +        ans.append(ans[-1] - u.size(data[i][0]) * u.size(data[i][1])) +        u.union(data[i][0], data[i][1]) +for x in ans[::-1][1:]: +    print(x)