// Insteading breaking/damaging edges thinking of answering in reverse order helps
// in such problems , here merging in reverse order means making available edges at a particulartime
// If we dont think in reverse way this problem may take more time complexity to solve
#include <bits/stdc++.h>
using namespace std;
#define int long long
int par[100005];
int group_size[100005];
int answer;
// Disjoint set data structure
int find(int i)
{
if(par[i] == i)return i;
return par[i] = find(par[i]);
}
void merge(int a,int b)
{
a = find(a);
b = find(b);
if(a == b)
return;
// Retriving previously considered inconvinience pairs
answer += (group_size[a]*(group_size[a]-1)/2);
answer += (group_size[b]*(group_size[b]-1)/2);
par[b] = a;
group_size[a]+=group_size[b];
// adding new inconvinience pairs
answer -= (group_size[a]*(group_size[a]-1)/2);
}
signed main()
{
int n,m;
cin >> n >> m;
for(int i=1;i<=n;i++)
{
par[i] = i;
group_size[i] = 1;
}
vector<pair<int,int>> edges;
for(int i=0;i<m;i++)
{
int u,v;cin >> u >> v;
edges.push_back({u,v});
}
// Answering queries in reverse order
// before the first state there will be no merged points so answer will be n*(n-1)/3 [all are invonvient]
answer = n*(n-1)/2;
reverse(edges.begin(),edges.end());
vector<int> query_answers;
for(auto e:edges)
{
query_answers.push_back(answer);
int u = e.first;
int v = e.second;
// already part of same group
if(find(u) == find(v)) continue;
merge(u,v);
}
// reversing answers
reverse(query_answers.begin(),query_answers.end());
for(int ans:query_answers)
{
cout << ans << '\n';
}
}
Ly8gSW5zdGVhZGluZyBicmVha2luZy9kYW1hZ2luZyBlZGdlcyB0aGlua2luZyBvZiBhbnN3ZXJpbmcgaW4gcmV2ZXJzZSBvcmRlciBoZWxwcwovLyBpbiBzdWNoIHByb2JsZW1zICwgaGVyZSBtZXJnaW5nIGluIHJldmVyc2Ugb3JkZXIgbWVhbnMgbWFraW5nIGF2YWlsYWJsZSBlZGdlcyBhdCBhIHBhcnRpY3VsYXJ0aW1lCi8vIElmIHdlIGRvbnQgdGhpbmsgaW4gcmV2ZXJzZSB3YXkgdGhpcyBwcm9ibGVtIG1heSB0YWtlIG1vcmUgdGltZSBjb21wbGV4aXR5IHRvIHNvbHZlCiNpbmNsdWRlIDxiaXRzL3N0ZGMrKy5oPgp1c2luZyBuYW1lc3BhY2Ugc3RkOwojZGVmaW5lIGludCBsb25nIGxvbmcKaW50IHBhclsxMDAwMDVdOwppbnQgZ3JvdXBfc2l6ZVsxMDAwMDVdOwppbnQgYW5zd2VyOwoKLy8gRGlzam9pbnQgc2V0IGRhdGEgc3RydWN0dXJlCmludCBmaW5kKGludCBpKQp7CiAgICBpZihwYXJbaV0gPT0gaSlyZXR1cm4gaTsKICAgIHJldHVybiBwYXJbaV0gPSBmaW5kKHBhcltpXSk7Cn0Kdm9pZCBtZXJnZShpbnQgYSxpbnQgYikKewogICAgYSA9IGZpbmQoYSk7CiAgICBiID0gZmluZChiKTsKICAgIGlmKGEgPT0gYikKICAgICAgICByZXR1cm47CiAgICAvLyBSZXRyaXZpbmcgcHJldmlvdXNseSBjb25zaWRlcmVkIGluY29udmluaWVuY2UgcGFpcnMKICAgIGFuc3dlciArPSAoZ3JvdXBfc2l6ZVthXSooZ3JvdXBfc2l6ZVthXS0xKS8yKTsKICAgIGFuc3dlciArPSAoZ3JvdXBfc2l6ZVtiXSooZ3JvdXBfc2l6ZVtiXS0xKS8yKTsKCiAgICBwYXJbYl0gPSBhOwogICAgZ3JvdXBfc2l6ZVthXSs9Z3JvdXBfc2l6ZVtiXTsKCiAgICAvLyBhZGRpbmcgbmV3IGluY29udmluaWVuY2UgcGFpcnMKICAgIGFuc3dlciAtPSAoZ3JvdXBfc2l6ZVthXSooZ3JvdXBfc2l6ZVthXS0xKS8yKTsKfQoKc2lnbmVkIG1haW4oKQp7ICAgIAogICAKICAgIGludCBuLG07CiAgICBjaW4gPj4gbiA+PiBtOwogICAgZm9yKGludCBpPTE7aTw9bjtpKyspCiAgICB7CiAgICAgICAgcGFyW2ldID0gaTsKICAgICAgICBncm91cF9zaXplW2ldID0gMTsKICAgIH0KICAgIHZlY3RvcjxwYWlyPGludCxpbnQ+PiBlZGdlczsKICAgIGZvcihpbnQgaT0wO2k8bTtpKyspCiAgICB7CiAgICAgICAgaW50IHUsdjtjaW4gPj4gdSA+PiB2OwogICAgICAgIGVkZ2VzLnB1c2hfYmFjayh7dSx2fSk7CiAgICB9CgogICAgLy8gQW5zd2VyaW5nIHF1ZXJpZXMgaW4gcmV2ZXJzZSBvcmRlcgogICAgLy8gYmVmb3JlIHRoZSBmaXJzdCBzdGF0ZSB0aGVyZSB3aWxsIGJlIG5vIG1lcmdlZCBwb2ludHMgc28gYW5zd2VyIHdpbGwgYmUgbioobi0xKS8zIFthbGwgYXJlIGludm9udmllbnRdCiAgICBhbnN3ZXIgPSBuKihuLTEpLzI7CgogICAgcmV2ZXJzZShlZGdlcy5iZWdpbigpLGVkZ2VzLmVuZCgpKTsKCiAgICB2ZWN0b3I8aW50PiBxdWVyeV9hbnN3ZXJzOwoKICAgIGZvcihhdXRvIGU6ZWRnZXMpCiAgICB7CiAgICAgICAgcXVlcnlfYW5zd2Vycy5wdXNoX2JhY2soYW5zd2VyKTsKCiAgICAgICAgaW50IHUgPSBlLmZpcnN0OwogICAgICAgIGludCB2ID0gZS5zZWNvbmQ7CgogICAgICAgIC8vIGFscmVhZHkgcGFydCBvZiBzYW1lIGdyb3VwCiAgICAgICAgaWYoZmluZCh1KSA9PSBmaW5kKHYpKSBjb250aW51ZTsKCiAgICAgICAgbWVyZ2UodSx2KTsKICAgIH0KCgogICAgLy8gcmV2ZXJzaW5nIGFuc3dlcnMKICAgIHJldmVyc2UocXVlcnlfYW5zd2Vycy5iZWdpbigpLHF1ZXJ5X2Fuc3dlcnMuZW5kKCkpOwoKICAgIGZvcihpbnQgYW5zOnF1ZXJ5X2Fuc3dlcnMpCiAgICB7CiAgICAgICAgY291dCA8PCBhbnMgPDwgJ1xuJzsKICAgIH0KCn0K