#include<bits/stdc++.h>
#include<ext/pb_ds/assoc_container.hpp>
#include<ext/pb_ds/tree_policy.hpp>
#define rep(i, a, b) for(int i=(a); i<(b); i++)
#define repi(i, a, b) for(int i=(a); i>(b); i--)
#define db(x) (cerr << #x << ": " << (x) << '\n')
#define sync ios_base::sync_with_stdio(false), cin.tie(NULL)
#define tests(t) int t; cin >> t; while(t--)
#define iceil(n, x) (((n) + (x) - 1) / (x))
#define ll long long
#define gcd __gcd
#define pb push_back
#define pf push_front
#define pob pop_back
#define pof pop_front
#define sz size()
#define all(v) (v).begin(), (v).end()
#define uni(v) sort(all(v)); (v).erase(unique(all(v)), (v).end());
#define pii pair<int, int>
#define vi vector<int>
#define vpii vector<pii>
#define vvi vector<vi>
#define fi first
#define se second
#define umap unordered_map
#define uset unordered_set
#define pqueue priority_queue
#define si(a) scanf("%d", &a)
#define sll(a) scanf("%lld", &a)
#define bitcount(x) __builtin_popcount(x)
#define cps CLOCKS_PER_SEC
#define PI acos(-1.0)
#define EPS 1e-9
#define mod 1000000007
#define MOD 1000000007
#define N 100005
using namespace std;

#define trace(...) __f(#__VA_ARGS__, __VA_ARGS__)
template <typename Arg1>
void __f(const char* name, Arg1&& arg1){
    cerr << name << " : " << arg1 << '\n';
}
template <typename Arg1, typename... Args>
void __f(const char* names, Arg1&& arg1, Args&&... args){
    const char* comma = strchr(names + 1, ',');cerr.write(names, comma - names) << " : " << arg1<<" | ";__f(comma+1, args...);
}

template<typename T>
using minpq = priority_queue<T, vector<T>, greater<T>>;

template<typename T>
using maxpq = priority_queue<T>;

//All indexing is 0-based
using namespace __gnu_pbds;
typedef tree<int, null_type, less<int>, rb_tree_tag,
             tree_order_statistics_node_update> ordered_set;
//methods: find_by_order(k); & order_of_key(k);
//To make it an ordered_multiset, use pairs of (value, time_of_insertion)
//to distinguish values which are similar.

template<class key, class value, class cmp = std::less<key>>
using ordered_map = tree<key, value, cmp, rb_tree_tag, tree_order_statistics_node_update>;
//ordered_map<int, int> my_map;


//Returns no. of values x for which ceil(n / x) == y (y must be > 1).
inline ll CC(ll n, ll y) { return iceil(n, y-1) - iceil(n, y); }

//Returns no. of values x for which floor(n / x) == y
inline ll FF(ll n, ll y) { return n / y - n / (y+1); }

//a and b are assumed to be taken modulo p
inline int add(int a, int b, int p = mod){ int c = a + b; if(c >= p) c -= p; return c; }
inline int sub(int a, int b, int p = mod){ int c = a - b; if(c < 0) c += p; return c; }
inline int mul(int a, int b, int p = mod){ return (a * 1ll * b) % p; }

#define int ll
// #define trace(...) 42

int n, m;
pii edges[N];

//Vertices are assumed to be numbered starting from 0.

//SZ[i]: size of the set that the ith element is a root of
//Only valid for root elements
int par[N], Rank[N], SZ[N], ans[N];
int num_sets;
int cur;

//Rank[x] is an upper bound to the height 
//of the subtree roted at node x.
void make_set(int x)
{
    num_sets++;
    par[x]=x;
    Rank[x]=0;
    SZ[x] = 1;
}

void init() {
    num_sets = 0;
    for(int i = 0; i < n; i++) make_set(i);
}

//returns the representative of the set
//to which x belongs.
int find_set(int x)
{
    if(par[x]==x)
        return x;
    else
        return par[x]=find_set(par[x]); 
}

//Returns the size of set that the ith vertex is in
int sizeofSet(int i) {
    return SZ[find_set(i)];
}

void merge_sets(int x,int y)
{
    int rx=find_set(x),ry=find_set(y);
    if(rx==ry)
        return;
    else{
        num_sets--;
        int m, n;
        m = SZ[rx], n = SZ[ry];
        cur -= m * n;
        if(Rank[rx]==Rank[ry])// Anyone can be the others' parent
            par[ry]=rx,Rank[rx]++, SZ[rx]+= SZ[ry];
        else if(Rank[rx]<Rank[ry])
            par[rx]=ry, SZ[ry]+= SZ[rx];
        else
            par[ry]=rx, SZ[rx]+=SZ[ry];
    }
}

main()
{   
    #ifdef CP
        freopen("/home/tarun/Desktop/input.txt", "r", stdin);
     // freopen("/home/tarun/Desktop/output.txt", "w", stdout);
    #endif
    sync;
    clock_t clk = clock();
    cerr << "I will return...\n";

    cin >> n >> m;
    cur = n * (n-1) / 2;
    init();
    rep(i, 0, m) {
        cin >> edges[i].fi >> edges[i].se;
        --edges[i].fi, --edges[i].se;
    }

    repi(i, m-1, -1) {
        int u, v;
        tie(u, v) = edges[i];

        ans[i] = cur;
        merge_sets(u, v);
    }

    rep(i, 0, m) cout << ans[i] << '\n';

    cerr << "...don't you ever hang your head.\n";
    cerr << "Time (in ms): " << double(clock() - clk) * 1000.0 / cps << '\n';
}

//Compile using:
//g++ -o filename.exe --std=c++11 filename.cpp
//Use -D CP for defining a macro CP in the local environment







Measured memory_bytes: 6016