#include <bits/stdc++.h>

#ifdef DEBUG
#define PRINT(x)\
    cout<<"func "<<__func__<<": line "<<__LINE__<<": "<<#x<<" = "<<(x)<<endl;
#define PRINTA(a,first,last)\
    cout<<"func "<<__func__<<": line "<<__LINE__<<": "<<#a<<"["<<(first)<<", "<<(last)<<")"<<endl;\
    for (int i=(first);i<(last);++i){cout<<#a<<"["<<i<<"] = "<<(a)[i]<<endl;}
#define PRINTP(p)\
    cout<<"func "<<__func__<<": line "<<__LINE__<<": "<<#p<<" = ("<<(p.first)<<", "<<(p.second)<<")"<<endl;
#define PRINTI(a,i)\
    cout<<"func "<<__func__<<": line "<<__LINE__<<": "<<#a<<"["<<#i<<"] = "<<#a<<"["<<(i)<<"] = "<<(a)[i]<<endl;
#else
#define PRINT(x)
#define PRINTA(a,first,last)
#define PRINTP(p)
#define PRINTI(a,i)
#endif

#define FOR(i,a,b) for (int i=(a);i<(b);++i)
#define RFOR(i,a,b) for (int i=(b)-1;i>=(a);--i)
#define REP(i,n) for (int i=0;i<(n);++i)
#define RREP(i,n) for (int i=(n)-1;i>=0;--i)
#define pb push_back
#define mp make_pair
#define all(a) (a).begin(),(a).end()
#define MOD 1000000007

using namespace std;

using ll = long long;
using ull = unsigned long long;
using pii = pair<int, int>;

template <class T, class U> void amax(T& x, U y) {if (x < y) x = y;}
template <class T, class U> void amin(T& x, U y) {if (x > y) x = y;}

const int dx[] = {1, 0, -1, 0, 1, -1, -1, 1};
const int dy[] = {0, 1, 0, -1, 1, 1, -1, -1};

class union_find_tree {
private:
    const size_t m_count_nodes;
    size_t *parent;
    size_t *rank;
    size_t m_count_components;
    size_t *m_component_size;
public:
    union_find_tree(size_t n);
    ~union_find_tree();
    size_t count_nodes() const;
    size_t count_components() const;
    size_t component_size(size_t x);
    size_t root(size_t x);
    void unite(size_t x, size_t y);
    bool same(size_t x, size_t y);
};

union_find_tree::union_find_tree(size_t n) : m_count_nodes(n) {
    parent = new size_t[n];
    rank = new size_t[n];
    m_count_components = n;
    m_component_size = new size_t[n];
    for (size_t i = 0; i < n; i++) {
        parent[i] = i;
        rank[i] = 0;
        m_component_size[i] = 1;
    }
}

union_find_tree::~union_find_tree() {
    delete [] parent;
    delete [] rank;
    delete [] m_component_size;
}

size_t union_find_tree::count_nodes() const {
    return m_count_nodes;
}

size_t union_find_tree::count_components() const {
    return m_count_components;
}

size_t union_find_tree::component_size(size_t x) {
    return m_component_size[root(x)];
}

size_t union_find_tree::root(size_t x) {
    if (parent[x] == x) {
        return x;
    } else {
        return parent[x] = root(parent[x]);
    }
}

void union_find_tree::unite(size_t x, size_t y) {
    x = root(x);
    y = root(y);
    if (x == y) {
        return;
    }
    if (rank[x] < rank[y]) {
        parent[x] = y;
        m_component_size[y] += m_component_size[x];
    } else {
        parent[y] = x;
        m_component_size[x] += m_component_size[y];
        if (rank[x] == rank[y]) {
            rank[x]++;
        }
    }
    m_count_components--;
}

bool union_find_tree::same(size_t x, size_t y) {
    return root(x) == root(y);
}

int main() {
    int N, M;
    cin >> N >> M;
    vector<int> A(M), B(M);
    REP(i, M) {
        cin >> A[i] >> B[i];
        A[i]--;
        B[i]--;
    }
    union_find_tree uft(N);
    ll inconvenience = (ll) N * (N - 1) / 2;
    vector<ll> inconveniences = {inconvenience};
    RREP(i, M) {
        if (!uft.same(A[i], B[i])) {
            //printf("%d and %d are disjoint\n", A[i], B[i]);
            //printf("%d's component size = %d\n", A[i], uft.component_size(A[i]));
            //printf("%d's component size = %d\n", B[i], uft.component_size(B[i]));
            inconvenience -= (ll) uft.component_size(A[i]) * uft.component_size(B[i]);
            uft.unite(A[i], B[i]);
        } else {
            //printf("%d and %d are connected\n", A[i], B[i]);
        }
        inconveniences.pb(inconvenience);
    }
    RREP(i, M) {
        cout << inconveniences[i] << endl;
    }
    return 0;
}

Measured memory_bytes: 5364