import sys

sys.setrecursionlimit(10 ** 7)
f_inf = float('inf')
mod = 10 ** 9 + 7


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):
        """
        yをxの根に繋ぐ
        """
        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):
        """
        xとyが同じ連結成分か判別する
        """
        return self.find(x) == self.find(y)

    def size(self, x):
        """
        xの連結成分の大きさを返す
        """
        return -self.parents[self.find(x)]

    def kruskal(self, edge):
        """
        :param edge: edge = [(コスト, 頂点1, 頂点2),...]の形で重み付き隣接リストを渡して下さい
        :return: 最小全域木のコストの和
        """
        edge.sort()
        cost_sum = 0
        for cost, node1, node2 in edge:
            if not self.same(node1, node2):
                cost_sum += cost
                self.union(node1, node2)
        return cost_sum


def resolve():
    n, m = map(int, input().split())
    edge = [list(map(lambda x: int(x) - 1, input().split())) for _ in range(m)]
    uf = UnionFind(n)
    res = [(n - 1) * n // 2]
    for i in reversed(range(1, m)):
        a, b = edge[i]
        if not uf.same(a, b):
            res.append(res[-1] - uf.size(a) * uf.size(b))
            uf.union(a, b)
        else:
            res.append(res[-1])
    print(*res[::-1], sep="\n")


if __name__ == '__main__':
    resolve() import sys sys sys.setrecursionlimit(10 ** 7) sys.setrecursionlimit sys setrecursionlimit 10 ** 7 10 7 f_inf = float('inf') f_inf float('inf') float 'inf' mod = 10 ** 9 + 7 mod 10 ** 9 + 7 10 ** 9 10 9 7 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):
        """
        yをxの根に繋ぐ
        """
        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):
        """
        xとyが同じ連結成分か判別する
        """
        return self.find(x) == self.find(y)

    def size(self, x):
        """
        xの連結成分の大きさを返す
        """
        return -self.parents[self.find(x)]

    def kruskal(self, edge):
        """
        :param edge: edge = [(コスト, 頂点1, 頂点2),...]の形で重み付き隣接リストを渡して下さい
        :return: 最小全域木のコストの和
        """
        edge.sort()
        cost_sum = 0
        for cost, node1, node2 in edge:
            if not self.same(node1, node2):
                cost_sum += cost
                self.union(node1, node2)
        return cost_sum UnionFind def __init__(self, n):
        self.n = n
        self.parents = [-1] * n

     __init__ self.n = n self.n self n n self.parents = [-1] * n self.parents self parents [-1] * n [-1] -1 n self self n 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]

     find """
        親が同じか判別する
        """ if self.parents[x] < 0:
            return x
        else:
            self.parents[x] = self.find(self.parents[x])
            return self.parents[x]

     self.parents[x] < 0 self.parents[x] self.parents self parents x 0 return x x self.parents[x] = self.find(self.parents[x]) self.parents[x] self.parents self parents x self.find(self.parents[x]) self.find self find self.parents[x] self.parents self parents x return self.parents[x] self.parents[x] self.parents self parents x self self x x def union(self, x, y):
        """
        yをxの根に繋ぐ
        """
        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

     union """
        yをxの根に繋ぐ
        """ 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:
            return
         x == y x y return if self.parents[x] > self.parents[y]:
            x, y = y, x
         self.parents[x] > self.parents[y] self.parents[x] self.parents self parents x self.parents[y] self.parents self parents y x, y = y, x x y y x self.parents[x] += self.parents[y] self.parents[x] self.parents self parents x self.parents[y] self.parents self parents y self.parents[y] = x self.parents[y] self.parents self parents y x self self x x y y def same(self, x, y):
        """
        xとyが同じ連結成分か判別する
        """
        return self.find(x) == self.find(y)

     same """
        xとyが同じ連結成分か判別する
        """ 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 size(self, x):
        """
        xの連結成分の大きさを返す
        """
        return -self.parents[self.find(x)]

     size """
        xの連結成分の大きさを返す
        """ return -self.parents[self.find(x)] -self.parents[self.find(x)] self.parents[self.find(x)] self.parents self parents self.find(x) self.find self find x self self x x def kruskal(self, edge):
        """
        :param edge: edge = [(コスト, 頂点1, 頂点2),...]の形で重み付き隣接リストを渡して下さい
        :return: 最小全域木のコストの和
        """
        edge.sort()
        cost_sum = 0
        for cost, node1, node2 in edge:
            if not self.same(node1, node2):
                cost_sum += cost
                self.union(node1, node2)
        return cost_sum kruskal """
        :param edge: edge = [(コスト, 頂点1, 頂点2),...]の形で重み付き隣接リストを渡して下さい
        :return: 最小全域木のコストの和
        """ edge.sort() edge.sort edge sort cost_sum = 0 cost_sum 0 for cost, node1, node2 in edge:
            if not self.same(node1, node2):
                cost_sum += cost
                self.union(node1, node2)
         cost node1 node2 edge if not self.same(node1, node2):
                cost_sum += cost
                self.union(node1, node2)
         not self.same(node1, node2) self.same(node1, node2) self.same self same node1 node2 cost_sum += cost cost_sum cost self.union(node1, node2) self.union self union node1 node2 return cost_sum cost_sum self self edge edge def resolve():
    n, m = map(int, input().split())
    edge = [list(map(lambda x: int(x) - 1, input().split())) for _ in range(m)]
    uf = UnionFind(n)
    res = [(n - 1) * n // 2]
    for i in reversed(range(1, m)):
        a, b = edge[i]
        if not uf.same(a, b):
            res.append(res[-1] - uf.size(a) * uf.size(b))
            uf.union(a, b)
        else:
            res.append(res[-1])
    print(*res[::-1], sep="\n") resolve n, m = map(int, input().split()) n map(int, input().split()) map int input().split() ().split () input split m list(map(lambda x: int(x) - 1, input().split())) for _ in range(m) for _ in range(m) _ range(m) range m for _ in range(m) list(map(lambda x: int(x) - 1, input().split())) list map(lambda x: int(x) - 1, input().split()) map lambda x: int(x) - 1 int(x) - 1 int(x) int x 1 x input().split() ().split () input split edge = [list(map(lambda x: int(x) - 1, input().split())) for _ in range(m)] edge [list(map(lambda x: int(x) - 1, input().split())) for _ in range(m)] uf = UnionFind(n) uf UnionFind(n) UnionFind n res = [(n - 1) * n // 2] res [(n - 1) * n // 2] (n - 1) * n // 2 (n - 1) * n n - 1 n 1 n 2 for i in reversed(range(1, m)):
        a, b = edge[i]
        if not uf.same(a, b):
            res.append(res[-1] - uf.size(a) * uf.size(b))
            uf.union(a, b)
        else:
            res.append(res[-1])
     i reversed(range(1, m)) reversed range(1, m) range 1 m a, b = edge[i] a edge[i] edge i b if not uf.same(a, b):
            res.append(res[-1] - uf.size(a) * uf.size(b))
            uf.union(a, b)
        else:
            res.append(res[-1])
     not uf.same(a, b) uf.same(a, b) uf.same uf same a b res.append(res[-1] - uf.size(a) * uf.size(b)) res.append res append res[-1] - uf.size(a) * uf.size(b) res[-1] res -1 uf.size(a) * uf.size(b) uf.size(a) uf.size uf size a uf.size(b) uf.size uf size b uf.union(a, b) uf.union uf union a b res.append(res[-1]) res.append res append res[-1] res -1 print(*res[::-1], sep="\n") print *res[::-1] res[::-1] res ::-1 -1 sep="\n" sep "\n" if __name__ == '__main__':
    resolve() __name__ == '__main__' __name__ '__main__' resolve() resolve f_inf = float('inf') float('inf') f_inf mod = 10 ** 9 + 7 10 ** 9 + 7 mod def resolve():
    n, m = map(int, input().split())
    edge = [list(map(lambda x: int(x) - 1, input().split())) for _ in range(m)]
    uf = UnionFind(n)
    res = [(n - 1) * n // 2]
    for i in reversed(range(1, m)):
        a, b = edge[i]
        if not uf.same(a, b):
            res.append(res[-1] - uf.size(a) * uf.size(b))
            uf.union(a, b)
        else:
            res.append(res[-1])
    print(*res[::-1], sep="\n") def resolve():
    n, m = map(int, input().split())
    edge = [list(map(lambda x: int(x) - 1, input().split())) for _ in range(m)]
    uf = UnionFind(n)
    res = [(n - 1) * n // 2]
    for i in reversed(range(1, m)):
        a, b = edge[i]
        if not uf.same(a, b):
            res.append(res[-1] - uf.size(a) * uf.size(b))
            uf.union(a, b)
        else:
            res.append(res[-1])
    print(*res[::-1], sep="\n") resolve 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):
        """
        yをxの根に繋ぐ
        """
        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):
        """
        xとyが同じ連結成分か判別する
        """
        return self.find(x) == self.find(y)

    def size(self, x):
        """
        xの連結成分の大きさを返す
        """
        return -self.parents[self.find(x)]

    def kruskal(self, edge):
        """
        :param edge: edge = [(コスト, 頂点1, 頂点2),...]の形で重み付き隣接リストを渡して下さい
        :return: 最小全域木のコストの和
        """
        edge.sort()
        cost_sum = 0
        for cost, node1, node2 in edge:
            if not self.same(node1, node2):
                cost_sum += cost
                self.union(node1, node2)
        return cost_sum 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):
        """
        yをxの根に繋ぐ
        """
        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):
        """
        xとyが同じ連結成分か判別する
        """
        return self.find(x) == self.find(y)

    def size(self, x):
        """
        xの連結成分の大きさを返す
        """
        return -self.parents[self.find(x)]

    def kruskal(self, edge):
        """
        :param edge: edge = [(コスト, 頂点1, 頂点2),...]の形で重み付き隣接リストを渡して下さい
        :return: 最小全域木のコストの和
        """
        edge.sort()
        cost_sum = 0
        for cost, node1, node2 in edge:
            if not self.same(node1, node2):
                cost_sum += cost
                self.union(node1, node2)
        return cost_sum UnionFind
import sys

sys.setrecursionlimit(10 ** 7)
f_inf = float('inf')
mod = 10 ** 9 + 7


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):
        """
        yをxの根に繋ぐ
        """
        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):
        """
        xとyが同じ連結成分か判別する
        """
        return self.find(x) == self.find(y)

    def size(self, x):
        """
        xの連結成分の大きさを返す
        """
        return -self.parents[self.find(x)]

    def kruskal(self, edge):
        """
        :param edge: edge = [(コスト, 頂点1, 頂点2),...]の形で重み付き隣接リストを渡して下さい
        :return: 最小全域木のコストの和
        """
        edge.sort()
        cost_sum = 0
        for cost, node1, node2 in edge:
            if not self.same(node1, node2):
                cost_sum += cost
                self.union(node1, node2)
        return cost_sum


def resolve():
    n, m = map(int, input().split())
    edge = [list(map(lambda x: int(x) - 1, input().split())) for _ in range(m)]
    uf = UnionFind(n)
    res = [(n - 1) * n // 2]
    for i in reversed(range(1, m)):
        a, b = edge[i]
        if not uf.same(a, b):
            res.append(res[-1] - uf.size(a) * uf.size(b))
            uf.union(a, b)
        else:
            res.append(res[-1])
    print(*res[::-1], sep="\n")


if __name__ == '__main__':
    resolve()
