class UnionFind:

    def __init__(self, nodes):

        self._parents = {k: k for k in nodes}

        self._ranks = {k: 0 for k in nodes}

        self._sizes = {k: 1 for k in nodes}



    def union(self, x, y):

        """

        x が属する木と y が属する木を併合

        :param x:

        :param y:

        :return:

        """

        x = self.find(x)

        y = self.find(y)

        if x != y:

            # rank が小さい方が下

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

                self._parents[y] = x

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

            else:

                self._parents[x] = y

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

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

                    self._ranks[y] += 1



    def find(self, x):

        """

        x が属する木の root

        :param x:

        :return:

        """

        if self._parents[x] == x:

            return x

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

        return self._parents[x]



    def size(self, x):

        """

        x が属する木のノード数

        :param x:

        :return:

        """

        return self._sizes[self.find(x)]





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



bridges = []

for _ in range(m):

    bridges.append(list(map(int, input().split())))





def c2(n):

    # n から2個選ぶ組み合わせ nC2

    return int(n * (n - 1) / 2)





bridges.reverse()

uf = UnionFind(nodes=[i + 1 for i in range(n)])

# 便利さ; つながってる島の組み合わせの数

useful = 0

useful_history = []



for bridge in bridges:

    useful_history.append(useful)



    if uf.find(bridge[0]) != uf.find(bridge[1]):

        # 新しくつながったので便利さを更新

        size0 = uf.size(bridge[0])

        size1 = uf.size(bridge[1])

        useful += c2(size0 + size1) - c2(size0) - c2(size1)

        uf.union(bridge[0], bridge[1])



for u in reversed(useful_history):

    print((useful - u))

import bisect

import cmath

import heapq

import itertools

import math

import operator

import os

import re

import string

import sys

from collections import Counter, deque, defaultdict

from copy import deepcopy

from decimal import Decimal

from fractions import gcd

from functools import lru_cache, reduce

from operator import itemgetter, mul, add, xor



import numpy as np



if os.getenv("LOCAL"):

    sys.stdin = open("_in.txt", "r")



sys.setrecursionlimit(10 ** 9)

INF = float("inf")

IINF = 10 ** 18

MOD = 10 ** 9 + 7





# MOD = 998244353

class UnionFind:

    def __init__(self, size=None, nodes=None):

        """

        size か nodes どっちか指定。

        nodes は set、size は list を使う。

        set の最悪計算量は O(N) なので size 指定のほうが若干速い

        :param int size:

        :param collections.Iterable nodes:

        """

        assert size is not None or nodes is not None

        if size is not None:

            self._parents = [i for i in range(size)]

            self._ranks = [0 for _ in range(size)]

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

        else:

            self._parents = {k: k for k in nodes}

            self._ranks = {k: 0 for k in nodes}

            self._sizes = {k: 1 for k in nodes}



    def unite(self, x, y):

        """

        x が属する木と y が属する木を併合

        :param x:

        :param y:

        :return:

        """

        x = self.root(x)

        y = self.root(y)

        if x == y:

            return



        # rank が小さい方が下

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

            # x が root

            self._parents[y] = x

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

        else:

            # y が root

            self._parents[x] = y

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

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

                self._ranks[y] += 1



    def root(self, x):

        """

        x が属する木の root

        :param x:

        :return:

        """

        if self._parents[x] == x:

            return x

        self._parents[x] = self.root(self._parents[x])

        return self._parents[x]



    def size(self, x):

        """

        x が属する木のノード数

        :param x:

        :return:

        """

        return self._sizes[self.root(x)]





N, M = list(map(int, sys.stdin.buffer.readline().split()))

AB = [list(map(int, sys.stdin.buffer.readline().split())) for _ in range(M)]



AB.reverse()

uf = UnionFind(size=N)

ans = (N - 1) * N // 2

hist = []

for a, b in AB:

    a -= 1

    b -= 1

    hist.append(ans)



    if uf.root(a) != uf.root(b):

        ans -= uf.size(a) * uf.size(b)

        uf.unite(a, b)

hist.reverse()



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

class UnionFind:
    def __init__(self, nodes):
        self._parents = {k: k for k in nodes}
        self._ranks = {k: 0 for k in nodes}
        self._sizes = {k: 1 for k in nodes}

    def union(self, x, y):
        """
        x が属する木と y が属する木を併合
        :param x:
        :param y:
        :return:
        """
        x = self.find(x)
        y = self.find(y)
        if x != y:
            # rank が小さい方が下
            if self._ranks[x] > self._ranks[y]:
                self._parents[y] = x
                self._sizes[x] += self._sizes[y]
            else:
                self._parents[x] = y
                self._sizes[y] += self._sizes[x]
                if self._ranks[x] == self._ranks[y]:
                    self._ranks[y] += 1

    def find(self, x):
        """
        x が属する木の root
        :param x:
        :return:
        """
        if self._parents[x] == x:
            return x
        self._parents[x] = self.find(self._parents[x])
        return self._parents[x]

    def size(self, x):
        """
        x が属する木のノード数
        :param x:
        :return:
        """
        return self._sizes[self.find(x)]


n, m = list(map(int, input().split()))
bridges = []
for _ in range(m):
    bridges.append(list(map(int, input().split())))


def c2(n):
    # n から2個選ぶ組み合わせ nC2
    return int(n * (n - 1) / 2)


bridges.reverse()
uf = UnionFind(nodes=[i + 1 for i in range(n)])
# 便利さ; つながってる島の組み合わせの数
useful = 0
useful_history = []
for bridge in bridges:
    useful_history.append(useful)
    if uf.find(bridge[0]) != uf.find(bridge[1]):
        # 新しくつながったので便利さを更新
        size0 = uf.size(bridge[0])
        size1 = uf.size(bridge[1])
        useful += c2(size0 + size1) - c2(size0) - c2(size1)
        uf.union(bridge[0], bridge[1])
for u in reversed(useful_history):
    print((useful - u))

import bisect
import cmath
import heapq
import itertools
import math
import operator
import os
import re
import string
import sys
from collections import Counter, deque, defaultdict
from copy import deepcopy
from decimal import Decimal
from fractions import gcd
from functools import lru_cache, reduce
from operator import itemgetter, mul, add, xor
import numpy as np

if os.getenv("LOCAL"):
    sys.stdin = open("_in.txt", "r")
sys.setrecursionlimit(10**9)
INF = float("inf")
IINF = 10**18
MOD = 10**9 + 7
# MOD = 998244353
class UnionFind:
    def __init__(self, size=None, nodes=None):
        """
        size か nodes どっちか指定。
        nodes は set、size は list を使う。
        set の最悪計算量は O(N) なので size 指定のほうが若干速い
        :param int size:
        :param collections.Iterable nodes:
        """
        assert size is not None or nodes is not None
        if size is not None:
            self._parents = [i for i in range(size)]
            self._ranks = [0 for _ in range(size)]
            self._sizes = [1 for _ in range(size)]
        else:
            self._parents = {k: k for k in nodes}
            self._ranks = {k: 0 for k in nodes}
            self._sizes = {k: 1 for k in nodes}

    def unite(self, x, y):
        """
        x が属する木と y が属する木を併合
        :param x:
        :param y:
        :return:
        """
        x = self.root(x)
        y = self.root(y)
        if x == y:
            return
        # rank が小さい方が下
        if self._ranks[x] > self._ranks[y]:
            # x が root
            self._parents[y] = x
            self._sizes[x] += self._sizes[y]
        else:
            # y が root
            self._parents[x] = y
            self._sizes[y] += self._sizes[x]
            if self._ranks[x] == self._ranks[y]:
                self._ranks[y] += 1

    def root(self, x):
        """
        x が属する木の root
        :param x:
        :return:
        """
        if self._parents[x] == x:
            return x
        self._parents[x] = self.root(self._parents[x])
        return self._parents[x]

    def size(self, x):
        """
        x が属する木のノード数
        :param x:
        :return:
        """
        return self._sizes[self.root(x)]


N, M = list(map(int, sys.stdin.buffer.readline().split()))
AB = [list(map(int, sys.stdin.buffer.readline().split())) for _ in range(M)]
AB.reverse()
uf = UnionFind(size=N)
ans = (N - 1) * N // 2
hist = []
for a, b in AB:
    a -= 1
    b -= 1
    hist.append(ans)
    if uf.root(a) != uf.root(b):
        ans -= uf.size(a) * uf.size(b)
        uf.unite(a, b)
hist.reverse()
print(*hist, sep="\n")

+import bisect +import cmath +import heapq +import itertools +import math +import operator +import os +import re +import string +import sys +from collections import Counter, deque, defaultdict +from copy import deepcopy +from decimal import Decimal +from fractions import gcd +from functools import lru_cache, reduce +from operator import itemgetter, mul, add, xor +import numpy as np + +if os.getenv("LOCAL"): +    sys.stdin = open("_in.txt", "r") +sys.setrecursionlimit(10**9) +INF = float("inf") +IINF = 10**18 +MOD = 10**9 + 7 +# MOD = 998244353 -    def __init__(self, nodes): -        self._parents = {k: k for k in nodes} -        self._ranks = {k: 0 for k in nodes} -        self._sizes = {k: 1 for k in nodes} +    def __init__(self, size=None, nodes=None): +        """ +        size か nodes どっちか指定。 +        nodes は set、size は list を使う。 +        set の最悪計算量は O(N) なので size 指定のほうが若干速い +        :param int size: +        :param collections.Iterable nodes: +        """ +        assert size is not None or nodes is not None +        if size is not None: +            self._parents = [i for i in range(size)] +            self._ranks = [0 for _ in range(size)] +            self._sizes = [1 for _ in range(size)] +        else: +            self._parents = {k: k for k in nodes} +            self._ranks = {k: 0 for k in nodes} +            self._sizes = {k: 1 for k in nodes} -    def union(self, x, y): +    def unite(self, x, y): -        x = self.find(x) -        y = self.find(y) -        if x != y: -            # rank が小さい方が下 -            if self._ranks[x] > self._ranks[y]: -                self._parents[y] = x -                self._sizes[x] += self._sizes[y] -            else: -                self._parents[x] = y -                self._sizes[y] += self._sizes[x] -                if self._ranks[x] == self._ranks[y]: -                    self._ranks[y] += 1 +        x = self.root(x) +        y = self.root(y) +        if x == y: +            return +        # rank が小さい方が下 +        if self._ranks[x] > self._ranks[y]: +            # x が root +            self._parents[y] = x +            self._sizes[x] += self._sizes[y] +        else: +            # y が root +            self._parents[x] = y +            self._sizes[y] += self._sizes[x] +            if self._ranks[x] == self._ranks[y]: +                self._ranks[y] += 1 -    def find(self, x): +    def root(self, x): -        self._parents[x] = self.find(self._parents[x]) +        self._parents[x] = self.root(self._parents[x]) -        return self._sizes[self.find(x)] +        return self._sizes[self.root(x)] -n, m = list(map(int, input().split())) -bridges = [] -for _ in range(m): -    bridges.append(list(map(int, input().split()))) - - -def c2(n): -    # n から2個選ぶ組み合わせ nC2 -    return int(n * (n - 1) / 2) - - -bridges.reverse() -uf = UnionFind(nodes=[i + 1 for i in range(n)]) -# 便利さ; つながってる島の組み合わせの数 -useful = 0 -useful_history = [] -for bridge in bridges: -    useful_history.append(useful) -    if uf.find(bridge[0]) != uf.find(bridge[1]): -        # 新しくつながったので便利さを更新 -        size0 = uf.size(bridge[0]) -        size1 = uf.size(bridge[1]) -        useful += c2(size0 + size1) - c2(size0) - c2(size1) -        uf.union(bridge[0], bridge[1]) -for u in reversed(useful_history): -    print((useful - u)) +N, M = list(map(int, sys.stdin.buffer.readline().split())) +AB = [list(map(int, sys.stdin.buffer.readline().split())) for _ in range(M)] +AB.reverse() +uf = UnionFind(size=N) +ans = (N - 1) * N // 2 +hist = [] +for a, b in AB: +    a -= 1 +    b -= 1 +    hist.append(ans) +    if uf.root(a) != uf.root(b): +        ans -= uf.size(a) * uf.size(b) +        uf.unite(a, b) +hist.reverse() +print(*hist, sep="\n")