#include <bits/stdc++.h>
using namespace std;
#define int long long 
#define ld long double
#define show(x,y) cout << y << " " << #x << endl;
#define show2(x,y,i,j) cout << y << " " << #x << "  " << j << " " << #i << endl;
#define show3(x,y,i,j,p,q) cout << y << " " << #x << "  " << j << " " << #i << "  " << q << " " << #p << endl;
#define show4(x,y) for(auto it:y) cout << it << " "; cout << #x << endl;
typedef pair<int,int>pii;
mt19937_64 rng(chrono::system_clock::now().time_since_epoch().count());
set<pii>in[100005];
set<pii>out[100005];
int counter=0;
bool connect(int a, int b){
	//out[a].find(b)!=out[a].end()&&out[b].find(a)!=out[b].end()
	auto it=out[a].lower_bound({b,0});
	auto it2=out[b].lower_bound({a,0});
	if(it!=out[a].end()&&it2!=out[b].end()&&it->first==b&&it2->first==a) return true;
	return false;
}
int f(int a){
	return a*(a-1);
}
struct DSU{
	vector<int>e;
	void init(int n){
		e=vector<int>(n,-1);
	}
	
	int get(int x){
		return e[x]<0?x:e[x]=get(e[x]);
	}
	
	int sz(int x){
		return -e[get(x)];
	}
	
	bool sameSet(int x, int y){
		return get(x)==get(y);
	}
	
	bool unite(int x, int y){
		x=get(x); y=get(y);
		if(x==y) return 1;
		if(e[x]>e[y]){
			swap(x,y);
			//swap(in[x],in[y]);
			//swap(out[x],out[y]);
		}
		
		//show2(x,x,y,y);
		
		counter-=(-e[x])*(in[x].size());
		counter-=(-e[y])*(in[y].size());
		counter-=f(-e[x]);
		counter-=f(-e[y]);
		//show(done,1);
		
		//check if they have edge pointing to each other
		vector<pii>dlt;
		for(auto it:out[y]){
			//show(it,it);
			if(sameSet(it.first,x)) dlt.push_back(it);
		}
		for(auto it:dlt){
			out[y].erase(it);
			in[it.first].erase({y,it.second});
		}
		//show4(dlt,dlt);
		dlt.clear();
		for(auto it:in[y]){
			if(sameSet(it.first,x)) dlt.push_back(it);
		}
		
		for(auto it:dlt){
			in[y].erase(it);
			out[it.first].erase({y,it.second});
		}
		//show4(dlt,dlt);
		
		//show(done,2);
		
		//y something x 
		vector<int>merge;
		for(auto it:in[y]){
			auto ite=out[x].lower_bound({it.first,0});
			if(ite!=out[x].end()&&ite->first==it.first){
				merge.push_back(it.first);
			}
			//if(out[x].find(it)!=out[x].end()){
				//merge.push_back(it.first);
			//}
		}
		
		for(auto it:out[y]){
			auto ite=in[x].lower_bound({it.first,0});
			if(ite!=in[x].end()&&ite->first==it.first){
				merge.push_back(it.first);
			}
			//if(in[x].find(it)!=in[x].end()){
				//merge.push_back(it.first);
			//}
		}
		
		//show(done,3);
		
		//for(int i=1;i<=4;i++){
			//show(i,i);
			//show4(in[i],in[i]);
			//show4(out[i],out[i]);
		//}
		
		//show(y,y);
		
		//upd all the nodes pointing to y
		dlt.clear();
		for(auto it:out[y]){
			//cout << it << endl;
			in[it.first].erase({y,it.second});
			//out[y].erase(it);
			in[it.first].insert({x,it.second});
			out[x].insert(it);
			//dlt.push_back(it);
		}
		//for(auto it:dlt) out[y].erase(it);
		//show(done,5);
		
		for(auto it:in[y]){
			//cout << it << " *" << endl;
			out[it.first].erase({y,it.second});
			//in[y].erase(it);
			out[it.first].insert({x,it.second});
			in[x].insert(it);
		}
		
		in[y].clear();
		out[y].clear();
		
		//show(done,4);
		
		e[x]+=e[y];
		e[y]=x;
		
		counter+=f(-e[x]);
		counter+=(-e[x])*(in[x].size());
		
		for(auto it:merge) unite(x,it);
		return 0;
	}
};
void solve(){
	int n,m;
	cin >> n >> m;
	
	int a,b;
	DSU dsu;
	dsu.init(n+5);
	
	for(int x=0;x<m;x++){
		cin >> a >> b;
		int og=a;
		a=dsu.get(a);
		b=dsu.get(b);
		if(a!=b&&out[a].find({b,og})==out[a].end()){
			//show(sz,in[b].size());
			//counter-=in[b].size()*dsu.sz(b);
			in[b].insert({a,og});
			out[a].insert({b,og});
			//counter+=in[b].size()*dsu.sz(b);
			//show2(x,x,sz,dsu.sz(b));
			counter+=dsu.sz(b);
			//check (a,b)
			//show(counter,counter);
			//cout << counter << " " << x << " counter\n";
			
			if(connect(a,b)){
				dsu.unite(a,b);
			}
		}
		//for(int y=1;y<=n;y++){
			////show(y,y);
			//show4(in[y],in[y]);
			//show4(out[y],out[y]);
		//}
		cout << counter << "\n";
	}
}
																   
int32_t main(){
	ios::sync_with_stdio(0);
	cin.tie(0);
	int t=1;
	//cin >> t;
	while(t--){
		solve();
	}
}
| # | Verdict | Execution time | Memory | Grader output | 
|---|
| Fetching results... | 
| # | Verdict | Execution time | Memory | Grader output | 
|---|
| Fetching results... | 
| # | Verdict | Execution time | Memory | Grader output | 
|---|
| Fetching results... |