class UnionFind(object):

    def __init__(self, n=1):

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

        self.rank = [0 for _ in range(n)]

        self.size = [1 for _ in range(n)]



    def find(self, x):

        """

        x が属するグループを探索

        """

        # xが根だったら自分自身をreturnする

        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 と y のグループを結合

        """

        x = self.find(x)

        y = self.find(y)

        if x != 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

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



    def is_same(self, x, y):

        """

        x と y が同じグループかどうか

        """

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



    def get_size(self, x):

        """

        x が属するグループの要素数

        """

        x = self.find(x)

        return self.size[x]





def main():

    N, M = list(map(int, input().split()))



    A = [None] * M

    B = [None] * M



    for i in range(M):

        A[i], B[i] = list(map(int, input().split()))



    uni = UnionFind(N)

    ans = [None] * M

    ans[M-1] = N * (N - 1) // 2

    for i in range(M - 1, 0, -1):

        x = A[i] - 1

        y = B[i] - 1

        # 辺でつなげても元々同じグループに属していた場合、変化はしない

        if uni.is_same(x, y):

            ans[i - 1] = ans[i]

        else:

            ans[i - 1] = ans[i] - (uni.get_size(x) * uni.get_size(y))

        uni.union(x, y)





    for a in ans:

        print(a)



main()
class UnionFind():

    def __init__(self, n):

        self.n = n

        self.parents = [-1] * n



    def find(self, x):

        if self.parents[x] < 0:

            return x

        else:

            self.parents[x] = self.find(self.parents[x])

            return self.parents[x]



    def union(self, x, y):

        x = self.find(x)

        y = self.find(y)



        if x == y:

            return

        

        if self.parents[x] > self.parents[y]:

            x, y = y, x



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

        self.parents[y] = x



    def same(self, x, y):

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



    def size(self, x):

        return -self.parents[self.find(x)]



def main():

    N, M = list(map(int, input().split()))

    bridges = []

    for _ in range(M):

        A, B = list(map(int, input().split()))

        A -= 1

        B -= 1

        bridges.append((A,B))



    ans = [0] * M

    ans[M-1] = N * (N - 1) // 2

    uni = UnionFind(N)

    for i in range(M-1,0,-1):

        a, b = bridges[i]

        if not uni.same(a, b):

            ans[i-1] = ans[i] - (uni.size(a) * uni.size(b))           

            uni.union(a,b)

        else:

            ans[i-1] = ans[i]

    for a in ans:

        print(a)



if __name__ == "__main__":

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

    def find(self, x):
        """
        x が属するグループを探索
        """
        # xが根だったら自分自身をreturnする
        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 と y のグループを結合
        """
        x = self.find(x)
        y = self.find(y)
        if x != 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
            self.size[x] += self.size[y]

    def is_same(self, x, y):
        """
        x と y が同じグループかどうか
        """
        return self.find(x) == self.find(y)

    def get_size(self, x):
        """
        x が属するグループの要素数
        """
        x = self.find(x)
        return self.size[x]


def main():
    N, M = list(map(int, input().split()))
    A = [None] * M
    B = [None] * M
    for i in range(M):
        A[i], B[i] = list(map(int, input().split()))
    uni = UnionFind(N)
    ans = [None] * M
    ans[M - 1] = N * (N - 1) // 2
    for i in range(M - 1, 0, -1):
        x = A[i] - 1
        y = B[i] - 1
        # 辺でつなげても元々同じグループに属していた場合、変化はしない
        if uni.is_same(x, y):
            ans[i - 1] = ans[i]
        else:
            ans[i - 1] = ans[i] - (uni.get_size(x) * uni.get_size(y))
        uni.union(x, y)
    for a in ans:
        print(a)


main()

class UnionFind:
    def __init__(self, n):
        self.n = n
        self.parents = [-1] * n

    def find(self, x):
        if self.parents[x] < 0:
            return x
        else:
            self.parents[x] = self.find(self.parents[x])
            return self.parents[x]

    def union(self, x, y):
        x = self.find(x)
        y = self.find(y)
        if x == y:
            return
        if self.parents[x] > self.parents[y]:
            x, y = y, x
        self.parents[x] += self.parents[y]
        self.parents[y] = x

    def same(self, x, y):
        return self.find(x) == self.find(y)

    def size(self, x):
        return -self.parents[self.find(x)]


def main():
    N, M = list(map(int, input().split()))
    bridges = []
    for _ in range(M):
        A, B = list(map(int, input().split()))
        A -= 1
        B -= 1
        bridges.append((A, B))
    ans = [0] * M
    ans[M - 1] = N * (N - 1) // 2
    uni = UnionFind(N)
    for i in range(M - 1, 0, -1):
        a, b = bridges[i]
        if not uni.same(a, b):
            ans[i - 1] = ans[i] - (uni.size(a) * uni.size(b))
            uni.union(a, b)
        else:
            ans[i - 1] = ans[i]
    for a in ans:
        print(a)


if __name__ == "__main__":
    main()

-class UnionFind(object): -    def __init__(self, n=1): -        self.par = [i for i in range(n)] -        self.rank = [0 for _ in range(n)] -        self.size = [1 for _ in range(n)] +class UnionFind: +    def __init__(self, n): +        self.n = n +        self.parents = [-1] * n -        """ -        x が属するグループを探索 -        """ -        # xが根だったら自分自身をreturnする -        if self.par[x] == x: +        if self.parents[x] < 0: -            self.par[x] = self.find(self.par[x]) -            return self.par[x] +            self.parents[x] = self.find(self.parents[x]) +            return self.parents[x] -        """ -        x と y のグループを結合 -        """ -        if x != 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 -            self.size[x] += self.size[y] +        if x == y: +            return +        if self.parents[x] > self.parents[y]: +            x, y = y, x +        self.parents[x] += self.parents[y] +        self.parents[y] = x -    def is_same(self, x, y): -        """ -        x と y が同じグループかどうか -        """ +    def same(self, x, y): -    def get_size(self, x): -        """ -        x が属するグループの要素数 -        """ -        x = self.find(x) -        return self.size[x] +    def size(self, x): +        return -self.parents[self.find(x)] -    A = [None] * M -    B = [None] * M -    for i in range(M): -        A[i], B[i] = list(map(int, input().split())) +    bridges = [] +    for _ in range(M): +        A, B = list(map(int, input().split())) +        A -= 1 +        B -= 1 +        bridges.append((A, B)) +    ans = [0] * M +    ans[M - 1] = N * (N - 1) // 2 -    ans = [None] * M -    ans[M - 1] = N * (N - 1) // 2 -        x = A[i] - 1 -        y = B[i] - 1 -        # 辺でつなげても元々同じグループに属していた場合、変化はしない -        if uni.is_same(x, y): +        a, b = bridges[i] +        if not uni.same(a, b): +            ans[i - 1] = ans[i] - (uni.size(a) * uni.size(b)) +            uni.union(a, b) +        else: -        else: -            ans[i - 1] = ans[i] - (uni.get_size(x) * uni.get_size(y)) -        uni.union(x, y) -main() +if __name__ == "__main__": +    main()