#include <bits/stdc++.h>
#include <regex>
#ifdef _DEBUG
#include "debug.h"
#endif
#define int ll
#define FOR(i, s, e) for (int i = int(s); i < int(e); ++i)
#define REP(i, e) FOR(i, 0, e)
#define all(v) (v).begin(),(v).end()
#define mkpr make_pair
#define mktp make_tuple
#define tv(tp, i) get<(i)>(tp)
#define CLEAR(obj) obj = decltype(obj)()
#define var auto
#define OUT(type) type &
#define IN(type) const type &
#define self (*this)
#define in :
#define True true
#define False false
using namespace std; using int32 = int32_t; using str = string; using cstr = const str;
using ll = long long; using ull = unsigned long long; using cint = const int; using cll = const ll;
using vi = vector<int>; using vvi = vector<vi>; using vl = vector<ll>; using vvl = vector<vl>;
using vb = vector<bool>; using vvb = vector<vb>; using vd = vector<double>; using vvd = vector<vd>;
using vc = vector<char>; using vvc = vector<vc>; using vs = vector<string>;
using pii = pair<int, int>; using pll = pair<ll, ll>; using pdd = pair<double, double>; using psl = pair<string, ll>;
using tiii = tuple<int, int, int>; using tlll = tuple<ll, ll, ll>;
static const int MGN = 10; static const int ARYSZ_MAX = (int)1e7;
static const ll LINF = LLONG_MAX/2;
#ifdef int
static const int INF = LINF;
#else
static const int INF = INT_MAX/2;
#endif
static double EPS = 1e-9;
#define FASTCIN() cin.tie(0);ios::sync_with_stdio(false);
#ifdef IMPORT_SAMPLE
#define DEBUG_IMPORT(file) vs args(argv, argv+argc);str sample = make_sample(args, file);ifstream ifs(sample); cin.rdbuf(ifs.rdbuf());
#else
#define DEBUG_IMPORT(file)
#endif
static inline bool DBLEQ(double a, double b) {return abs(a - b) < EPS;}
static inline void EPR(str msg) {cerr << msg << endl;}
static inline void AST(bool exp, str msg) {if(!exp){EPR(msg);} assert(exp);}
static inline void TAST(bool exp, str msg) {if(!exp){EPR(msg);} while(!exp){}}


struct UnionFind {
    vi dt;
    UnionFind(const int N) {
        self.dt = vi(N+1, -1);
    }
    int root(int key){
        if (self.dt[key] < 0)
            return key;
        else {
            self.dt[key] = self.root(self.dt[key]);
            return self.dt[key];
        }
    }
    bool unite(int kx, int ky) {
        kx = self.root(kx); ky = self.root(ky);
        if (kx == ky)
            return False;
        if (self.size(kx) < self.size(ky))
            swap(kx, ky);
        self.dt[kx] += self.dt[ky];
        self.dt[ky] = kx;
        return True;
    }
    int size(int key) {
        int rk = self.root(key);
        return -self.dt[rk];
    }
    bool is_connect(int kx, int ky) {
        return self.root(kx) == self.root(ky);
    }
};


int32 main(int32 argc, char* argv[]) {
    FASTCIN();
    DEBUG_IMPORT("sample-1");


    int N,M; cin>>N>>M;
    vi A(M),B(M);
    REP(i,M) {
        cin>>A[i]>>B[i];
        A[i]-=1; B[i]-=1;
    }

    UnionFind uf(N);
    vi ans(M+1);  // ans[i] := i 本目の橋が崩壊した後の不便さ
    ans[M] = N*(N-1)/2; // 全崩壊時の不便さ
    for (int i = M-1; i >= 0; i--) {
        if (uf.is_connect(A[i], B[i])) {
            ans[i] = ans[i+1];
            continue;
        } else {
            int gaSz = uf.size(A[i]);
            int gbSz = uf.size(B[i]);
            ans[i] = ans[i+1] - gaSz * gbSz;  // 不便さが減る、便利さは増える
            uf.unite(A[i], B[i]);
        }
    }

    FOR(i, 1, M+1)
        cout << ans[i] << endl;


    return 0;
}


Measured memory_bytes: 4480