import std.algorithm;
import std.bigint;
import std.concurrency;
import std.container;
import std.conv;
import std.functional;
import std.format;
import std.math;
import std.meta;
import std.numeric;
import std.random;
import std.range;
import std.stdio;
import std.string;
import std.traits;
import std.typecons;


auto solve(long N, long M, long[] A, long[] B) {
    auto uf = UnionFind(N + 1);
    long inc = N * (N - 1) / 2;
    auto ans = new long[](M);

    foreach_reverse (i; 0 .. M) {
        ans[i] = inc;
        if (!uf.haveSameRoot(A[i], B[i]))
            inc -= uf.getSize(A[i]) * uf.getSize(B[i]);
        uf.unite(A[i], B[i]);
    }

    ans.map!(to!string).each!writeln;
}


struct UnionFind {
private:
    long[] rank;
    long[] size;
    long[] par;

public:
    this(long n) {
        rank = repeat(0L).take(n).array;
        size = repeat(1L).take(n).array;
        par = iota(n).array;
    }

    long getRoot(long n) {
        return par[n] = (par[n] == n ? n : getRoot(par[n]));
    }

    long getSize(long n) {
        return size[getRoot(n)];
    }

    bool unite(long n1, long n2) {
        n1 = getRoot(n1);
        n2 = getRoot(n2);
        if (n1 == n2)
            return false;

        long subTreeRoot = rank[n1] < rank[n2] ? n1 : n2;
        long newRoot = rank[n1] < rank[n2] ? n2 : n1;

        par[subTreeRoot] = newRoot;
        size[newRoot] = size[n1] + size[n2];

        if (rank[n1] == rank[n2])
            rank[n1]++;
        return true;
    }

    bool haveSameRoot(long n1, long n2) {
        return getRoot(n1) == getRoot(n2);
    }

    long countRoots() {
        long roots;
        foreach (i, v; par)
            if (getRoot(v) == i)
                roots++;
        return roots;
    }
}



void main() {
    auto input = stdin.byLine.map!split.joiner;

    long N;
    N = input.front.to!long;
    input.popFront;

    long M;
    M = input.front.to!long;
    input.popFront;

    long[] A = new long[](cast(size_t) (M));
    long[] B = new long[](cast(size_t) (M));
    foreach (i; 0 .. cast(size_t) (M)) {
        A[i] = input.front.to!long;
        input.popFront;
        B[i] = input.front.to!long;
        input.popFront;
    }

    static if (is(ReturnType!solve == void))
        solve(N, M, A, B);
    else
        solve(N, M, A, B).writeln;
}
