#include <bits/stdc++.h>
using namespace std;
using ll = long long; using pii = pair<ll,ll>;
const ll Nm = 1e5+5;
ll dsuf[Nm];
set<ll> iedg[Nm]; //edges going into group (ELEMENTS)
set<ll> grp[Nm]; //group members
set<ll> igrp[Nm]; //edges going into group (GROUPS)
set<ll> eloc[Nm]; //what groups does this element have an edge to
ll ans = 0;
ll getf(ll x) {
if (dsuf[x]==x) {
return x;
}
ll y = getf(dsuf[x]);
dsuf[x]=y;
return y;
}
void mrg(ll a, ll b) { //groups a,b
if ((grp[a].size())>(grp[b].size())) {
swap(a,b);
}
//merge a into b
ll ga = grp[a].size(); ll gb = grp[b].size();
ans += (ga+gb)*(ga+gb-1)-ga*(ga-1)-gb*(gb-1);
for (ll x: grp[a]) { //(x in a) -> b
if (iedg[b].find(x)!=iedg[b].end()) {
ans -= gb;
iedg[b].erase(x);
eloc[x].erase(b);
}
}
vector<ll> xdel;
for (ll x: iedg[a]) { //(x in b) -> a
if (grp[b].find(x)!=grp[b].end()) {
ans -= ga;
xdel.push_back(x);
}
}
for (ll x: xdel) {
iedg[a].erase(x);
eloc[x].erase(a);
}
for (ll x: grp[a]) { //x in a -> group y
for (ll y: eloc[x]) {
igrp[y].erase(a);
igrp[y].insert(b);
}
}
//merge all edges with a/b
//x -> b: +ga
ans += ga*iedg[b].size();
//x -> a: +gb, merge in
//and x -> a,b: +0 -> correct
for (ll x: iedg[a]) {
if (iedg[b].find(x)!=iedg[b].end()) {
ans -= ga;
} else {
iedg[b].insert(x);
ans += gb;
eloc[x].erase(a);
eloc[x].insert(b);
}
}
iedg[a].clear();
for (ll x: igrp[a]) {
igrp[b].insert(x);
}
igrp[a].clear();
for (ll x: grp[a]) {
grp[b].insert(x);
}
grp[a].clear();
dsuf[a]=b;
}
void add(ll a, ll b) {//add a->b
ll gb = getf(b);
ll ga = getf(a);
if (ga==gb) {
return;
}
if (iedg[gb].find(a)!=iedg[gb].end()) {
return;
}
if (igrp[ga].find(gb)!=igrp[ga].end()) {
//merge groups
mrg(ga,gb);
} else {
//add edge a->gb
iedg[gb].insert(a);
igrp[gb].insert(ga);
eloc[a].insert(gb);
ans += grp[gb].size();
}
}
int main() {
ios_base::sync_with_stdio(false); cin.tie(0);
ll N,M; cin >> N >> M;
for (ll i=0;i<N;i++) {
dsuf[i]=i;
grp[i].insert(i);
}
for (ll m=0;m<M;m++) {
ll a,b; cin >> a >> b;
a--; b--;
add(a,b);
cout << ans << "\n";
}
}