#define __mode_debug__
/*   ξ
     ll
   ＿ll＿
 ／  ∞  ＼
│*  Ａ  *│
│*  Ｃ  *│
│*  祈  *│
│*  願  *│
│*      *│
 ￣￣￣￣￣    */
//C++14 (GCC 5.4.1)
#include <bits/stdc++.h>
using namespace std;
#ifdef __mode_debug__
    #define DBG
#else
    #define DBG if(false)
#endif

#define LLINF (1LL<<60)
typedef long long ll;
#define mod 1000000007

#define repd(i,a,b) for (int i=(a);i<(b);i++)
#define rep(i,n) repd(i,0,n)
#define rrepd(i,a,b) for(int i=(a);i>=(b);i--)
#define repi(itr,ds) for(auto itr=ds.begin();itr!=ds.end();itr++)

template<typename T> inline bool chmax(T& a, T b) { if (a < b) { a = b; return 1; } return 0; }
template<typename T> inline bool chmin(T& a, T b) { if (a > b) { a = b; return 1; } return 0; }

template < typename T > inline string toString( const T &a ) { ostringstream oss; oss << a; return oss.str(); }

//DUMP
//  ostream vector<T> , vector<vector<T>> , set<T> ,queue<T> , priority_queue<T> , pair<T,U> , map<T,U>
template<class T> ostream& operator<<(ostream&os,vector<T>&vec){os<<"{ ";rep(i,vec.size()) os<<((i==0)?"":", ")<<i<<":"<<vec[i];os<<" }";return os;}
template<class T> ostream& operator<<(ostream&os,vector<vector<T>>&vec){os<<"{"<<endl;rep(i,vec.size())os<<"\t   "<<i<<":"<<vec[i]<<((i==vec.size()-1)? "":",")<<endl;os<<"\t }";return os;}
template<class T> ostream& operator<<(ostream&os,set<T>&p){os<<"{ ";repi(itr,p)  os<<((itr==p.begin())?"":", ")<<*itr;os<<" }";return os;}
template<class T> ostream& operator<<(ostream&os,queue<T>&p){queue<T> q(p);os<<"[< "<<(q.empty()?" <]":"");while(!q.empty()){os<<q.front();q.pop();os<< (q.empty() ? " <]" : ", ");}return os;}
template<class T> ostream& operator<<(ostream&os,priority_queue<T>&p){priority_queue<T> q(p);os<<"[< "<<(q.empty()?" <]":"");while(!q.empty()){os<<q.top();q.pop();os<< (q.empty() ? " <]" : ", ");}return os;}
template<class T,class U> ostream& operator<<(ostream&os,pair<T,U>&p){os<<"("<<p.first<<","<<p.second<<")";return os;}
template<class T,class U> ostream& operator<<(ostream&os,map<T,U>&p){os<<"{ ";repi(itr,p)os<<((itr==p.begin())?"":", ")<<itr->first<<":"<<itr->second;os<<" }";return os;}
void dump_f(string &nm){cerr<<endl;}
template<class T,class... Ts> void dump_f(string &nm,T &&x,Ts&&... ts){int l=nm.find_first_of(',');string name(nm,0,l),nx(nm,l+1,-1);cerr<<"  "<<name<<"\t:"<<x<<endl;dump_f(nx,forward<Ts>(ts)...);}
template<class... Ts> void dump_m(int &&ln,string &&nm,Ts&&... ts){cerr<<"[ln:"<<ln<<"]"<<endl;dump_f(nm,forward<Ts>(ts)...);}
#define dump(...) DBG dump_m(__LINE__,#__VA_ARGS__,__VA_ARGS__)

#define lower_bound_idx(V,c) distance(V.begin(),lower_bound(V.begin(),V.end(),c))

// Union-Find木
template<class Abel>//加減可能のアーベル群
class UnionFind{
protected:
    vector<int> par;//親ノード
    vector<Abel> pod;//ポテンシャル
    Abel O=0;
public:
    UnionFind(int n,Abel zero=0) : par(n,-1),pod(n,zero){
        O=zero;
    }

    //根を求める（同時に経路圧縮）
    int root(int x){
        if(par[x]<0) return x;
        int r = root(par[x]);
        pod[x] +=pod[par[x]];
        return par[x]=r;
    }

    //根が等しいか判定
    bool issame(int x,int y){
        return root(x)==root(y);
    }

    //マージ
    bool unite(int base,int x){
        return unite(base,x,O);
    }
    bool unite(int base,int x,Abel pd){
        pd -=p(x) - p(base);
        base=root(base);x=root(x);
        if(base==x)return false;
        if(par[base]>par[x]) std::swap(base,x),pd=-pd;
        //baseがxの親になる
        par[base] +=par[x];//根は-(size)
        par[x]=base;
        pod[x]=pd;
        return true;
    }

    //属す根のサイズ
    int size(int x){
        return -par[root(x)];
    }
    //要素のポテンシャル
    Abel p(int x){
        root(x);//経路圧縮
        return pod[x];
    }
    //要素の相対ポテンシャル
    Abel diff(int base,int x){
        if(issame(base,x)) return pod[x]-pod[base];
        return 0;//同箇所にない場合は未定義
    }
};

int main() {
    ios::sync_with_stdio(false);//stdoutとcoutの同期解除
    cin.tie(nullptr);//cinとcoutの同期解除
    
    ll N,M;
    cin >>N>>M;
    UnionFind<ll> X(N);

    vector<ll> A(M),B(M);
    rep(i,M){
        cin >> A[i]>>B[i];
        A[i]--;
        B[i]--;
    }
    ll ans=N*(N-1)/2;
    vector<ll> as(M);
    rrepd(i,M-1,0){
        as[i]=ans;
        if(!X.issame(A[i],B[i])){
            ans-=X.size(A[i])*X.size(B[i]);
            X.unite(A[i],B[i]);
        }
    }
    rep(i,M)cout<<as[i]<<endl;
    return (0);
}

Measured memory_bytes: 4864