class UnionFind():

    def __init__(self, n):

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

        # 正==子: 根の頂点番号 / 負==根: 連結頂点数



    def find(self, x):

        if self.parent[x] < 0:

            return x

        else:

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

            return self.parent[x]



    def unite(self, x, y):

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

        if x == y:

            return False

        else:

            if self.size(x) < self.size(y):

                x, y = y, x

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

            self.parent[y] = x



    def same(self, x, y):

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



    def size(self, x):

        x = self.find(x)

        return -self.parent[x]





def main():

    import sys



    input = sys.stdin.readline



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



    g = tuple(reversed(tuple((int(x) - 1 for x in input().split()) for _ in range(m))))

    t = n * (n - 1) // 2



    ret = [t]  # 最後反転

    uf = UnionFind(n)

    for a, b in g[:-1]:

        if not uf.same(a, b):

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

        ret.append(t)

        uf.unite(a, b)

    ret.reverse()

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





if __name__ == '__main__':

    main()

class UnionFind:

    def __init__(self, n):

        self.v = [-1] * n



    def find(self, x):

        if self.v[x] < 0:

            return x

        else:

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

            return self.v[x]



    def unite(self, x, y):

        x = self.find(x)

        y = self.find(y)



        if x == y:

            return False

        else:

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

                x, y = y, x

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

            self.v[y] = x

            return True



    def same(self, x, y):

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



    def size(self, x):

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





def main():

    import sys

    input = sys.stdin.readline



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



    collapse_schedule = []

    for _ in range(M):

        A, B = (int(x) - 1 for x in input().split())

        collapse_schedule.append((A, B))

    collapse_schedule.reverse()



    uf = UnionFind(N)



    def evaluate(size):

        return size * (size - 1) // 2



    all_dropped = evaluate(N)

    curr = all_dropped



    ret = [-1] * M

    ret[-1] = all_dropped



    for i, (a, b) in zip(reversed(range(M - 1)), collapse_schedule):

        if not uf.same(a, b):

            sa, sb = uf.size(a), uf.size(b)

            ea, eb = evaluate(sa), evaluate(sb)



            curr += ea + eb



            uf.unite(a, b)



            sa = uf.size(a)

            ea = evaluate(sa)



            curr -= ea



        ret[i] = curr



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





if __name__ == '__main__':

    main()

class UnionFind:
    def __init__(self, n):
        self.parent = [-1 for _ in range(n)]
        # 正==子: 根の頂点番号 / 負==根: 連結頂点数

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

    def unite(self, x, y):
        x, y = self.find(x), self.find(y)
        if x == y:
            return False
        else:
            if self.size(x) < self.size(y):
                x, y = y, x
            self.parent[x] += self.parent[y]
            self.parent[y] = x

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

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


def main():
    import sys

    input = sys.stdin.readline
    n, m = map(int, input().split())
    g = tuple(reversed(tuple((int(x) - 1 for x in input().split()) for _ in range(m))))
    t = n * (n - 1) // 2
    ret = [t]  # 最後反転
    uf = UnionFind(n)
    for a, b in g[:-1]:
        if not uf.same(a, b):
            t -= uf.size(a) * uf.size(b)
        ret.append(t)
        uf.unite(a, b)
    ret.reverse()
    print(*ret, sep="\n")


if __name__ == "__main__":
    main()

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

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

    def unite(self, x, y):
        x = self.find(x)
        y = self.find(y)
        if x == y:
            return False
        else:
            if self.v[x] > self.v[y]:
                x, y = y, x
            self.v[x] += self.v[y]
            self.v[y] = x
            return True

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

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


def main():
    import sys

    input = sys.stdin.readline
    N, M = map(int, input().split())
    collapse_schedule = []
    for _ in range(M):
        A, B = (int(x) - 1 for x in input().split())
        collapse_schedule.append((A, B))
    collapse_schedule.reverse()
    uf = UnionFind(N)

    def evaluate(size):
        return size * (size - 1) // 2

    all_dropped = evaluate(N)
    curr = all_dropped
    ret = [-1] * M
    ret[-1] = all_dropped
    for i, (a, b) in zip(reversed(range(M - 1)), collapse_schedule):
        if not uf.same(a, b):
            sa, sb = uf.size(a), uf.size(b)
            ea, eb = evaluate(sa), evaluate(sb)
            curr += ea + eb
            uf.unite(a, b)
            sa = uf.size(a)
            ea = evaluate(sa)
            curr -= ea
        ret[i] = curr
    print(*ret, sep="\n")


if __name__ == "__main__":
    main()

-        self.parent = [-1 for _ in range(n)] -        # 正==子: 根の頂点番号 / 負==根: 連結頂点数 +        self.v = [-1] * n -        if self.parent[x] < 0: +        if self.v[x] < 0: -            self.parent[x] = self.find(self.parent[x]) -            return self.parent[x] +            self.v[x] = self.find(self.v[x]) +            return self.v[x] -        x, y = self.find(x), self.find(y) +        x = self.find(x) +        y = self.find(y) -            if self.size(x) < self.size(y): +            if self.v[x] > self.v[y]: -            self.parent[x] += self.parent[y] -            self.parent[y] = x +            self.v[x] += self.v[y] +            self.v[y] = x +            return True -        x = self.find(x) -        return -self.parent[x] +        return -self.v[self.find(x)] -    n, m = map(int, input().split()) -    g = tuple(reversed(tuple((int(x) - 1 for x in input().split()) for _ in range(m)))) -    t = n * (n - 1) // 2 -    ret = [t]  # 最後反転 -    uf = UnionFind(n) -    for a, b in g[:-1]: +    N, M = map(int, input().split()) +    collapse_schedule = [] +    for _ in range(M): +        A, B = (int(x) - 1 for x in input().split()) +        collapse_schedule.append((A, B)) +    collapse_schedule.reverse() +    uf = UnionFind(N) + +    def evaluate(size): +        return size * (size - 1) // 2 + +    all_dropped = evaluate(N) +    curr = all_dropped +    ret = [-1] * M +    ret[-1] = all_dropped +    for i, (a, b) in zip(reversed(range(M - 1)), collapse_schedule): -            t -= uf.size(a) * uf.size(b) -        ret.append(t) -        uf.unite(a, b) -    ret.reverse() +            sa, sb = uf.size(a), uf.size(b) +            ea, eb = evaluate(sa), evaluate(sb) +            curr += ea + eb +            uf.unite(a, b) +            sa = uf.size(a) +            ea = evaluate(sa) +            curr -= ea +        ret[i] = curr