stablegradients/pie-gem5-pairs huggingface dataset:
// Slower C++ solution:
#include <iostream>

#include <string.h>

#include <stdio.h>

#include <queue>

#include <vector>

#include <map>

#include <algorithm>

using namespace std;

const int Max=3e5+100;

int get_root(int *f, int root){

    return f[root]==root?root:f[root]=get_root(f, f[root]);

}

void merge(int *f, int x,int y){

    int i=get_root(f, x);

    int j=get_root(f, y);

    f[i]=j;

}

int f[Max], g[Max];

void init(int n){

    for(int a=0; a<=n; a++)f[a]=a, g[a]=a;

}

int vis[Max], num[Max];

vector<int> vec[Max];

map<int, int>ma;

int main(){

    int n, m, k, u, v;

    scanf("%d%d%d", &n, &m, &k);

    init(n);

    for(int a=0; a<m; a++){

        scanf("%d%d", &u, &v);

        merge(f, u, v);

    }

    for(int a=0; a<k; a++){

        scanf("%d%d", &u, &v);

        merge(g, u, v);

    }

    for(int a=1; a<=n; a++)vec[get_root(f, a)].push_back(a);

    for(int a=0; a<=n; a++){

        ma.clear();

       // memset(num, 0, sizeof(num));

        for(int b=0; b<vec[a].size(); b++){

            ma[get_root(g, vec[a][b])]++;

            //num[get_root(g, vec[a][b])]++;

        }

        for(int b=0; b<vec[a].size(); b++){

            vis[vec[a][b]]+=ma[get_root(g, vec[a][b])];

        }

    }

    for(int a=1; a<=n; a++)printf("%d%c", vis[a], a==n?'\n':' ');

    return  0;

}

// Faster C++ solution for the same problem (measured speedup: 9.339803245995338x):
//hate penalty



#include <bits/stdc++.h>

using namespace std;



int dsu[200001], dsu2[200001];

map <pair<int, int> ,int> mp;



int find(int x){

	if (dsu[x]) return dsu[x]=find(dsu[x]);

	return x;

}



int find2(int x){

	if (dsu2[x]) return dsu2[x]=find2(dsu2[x]);

	return x;

}



int main(){

	int n, k, l;

	cin >> n >> k >> l;

	int x, y;

	for (int i=1; i<=k; i++){

		cin >> x >> y;

		if (find(x)!=find(y)){

			dsu[find(x)]=find(y);

		}

	}

	for (int i=1; i<=l; i++){

		cin >> x >> y;

		if (find2(x)!=find2(y)){

			dsu2[find2(x)]=find2(y);

		}

	}

	for (int i=1; i<=n; i++){

		mp[make_pair(find(i),find2(i))]++;

	}

	for (int i=1; i<n; i++){

		cout << mp[make_pair(find(i), find2(i))] << " ";

	}

	cout << mp[make_pair(find(n), find2(n))] << "\n";

}
// Slower C++ solution:
#include<cstdio>

#include<algorithm>

#include<cstring>

#include<vector>

#include<queue>

#include<map>

using namespace std;

#define LL long long

#define MAXN 200010

map<LL,int>G;

LL col[MAXN];

int vis[MAXN],n,a,b;

int Adj[MAXN],V[MAXN],nxt[MAXN],c;

void AddEdge(int u,int v)

{

	c++;V[c]=v,nxt[c]=Adj[u];

	Adj[u]=c;

}

void dfs1(int u)

{

	vis[u]=1;

	col[u]=col[0];

	for(int i=Adj[u];i;i=nxt[i])

		if(!vis[V[i]])

			dfs1(V[i]);

}

void dfs2(int u)

{

	vis[u]=0;

	col[u]=(col[u]<<20)+col[0];

	G[col[u]]++;

	for(int i=Adj[u];i;i=nxt[i])

		if(vis[V[i]])

			dfs2(V[i]);

}

int main()

{

	int u,v;

	scanf("%d%d%d",&n,&a,&b);

	for(int i=0;i<a;i++)

	{

		scanf("%d%d",&u,&v);

		AddEdge(u,v);

		AddEdge(v,u);

	}

	for(int i=1;i<=n;i++)

		if(!vis[i])

		{

			col[0]++;

			dfs1(i);

		}

	memset(Adj,0,sizeof Adj);

	col[0]=0,c=0;

	for(int i=0;i<b;i++)

	{

		scanf("%d%d",&u,&v);

		AddEdge(u,v);

		AddEdge(v,u);

	}

	for(int i=1;i<=n;i++)

		if(vis[i])

		{

			col[0]++;

			dfs2(i);

		}

	for(int i=1;i<=n;i++)

		printf("%d ",G[col[i]]);

}

// Faster C++ solution for the same problem (measured speedup: 1.718517418373938x):
//hate penalty



#include <bits/stdc++.h>

using namespace std;



int dsu[200001], dsu2[200001];

map <pair<int, int> ,int> mp;



int find(int x){

	if (dsu[x]) return dsu[x]=find(dsu[x]);

	return x;

}



int find2(int x){

	if (dsu2[x]) return dsu2[x]=find2(dsu2[x]);

	return x;

}



int main(){

	int n, k, l;

	cin >> n >> k >> l;

	int x, y;

	for (int i=1; i<=k; i++){

		cin >> x >> y;

		if (find(x)!=find(y)){

			dsu[find(x)]=find(y);

		}

	}

	for (int i=1; i<=l; i++){

		cin >> x >> y;

		if (find2(x)!=find2(y)){

			dsu2[find2(x)]=find2(y);

		}

	}

	for (int i=1; i<=n; i++){

		mp[make_pair(find(i),find2(i))]++;

	}

	for (int i=1; i<n; i++){

		cout << mp[make_pair(find(i), find2(i))] << " ";

	}

	cout << mp[make_pair(find(n), find2(n))] << "\n";

}
// Slower C++ solution:
#include<cstdio>

#include<map>

using namespace std;

const int MAXN=200005;



struct DSU

{

	int fa[MAXN];

	int Root(int x)

	{return fa[x]==0?x:fa[x]=Root(fa[x]);}

	void Union(int x,int y)

	{

		int r1=Root(x),r2=Root(y);

		if(r1==r2)

			return;

		fa[r1]=r2;

	}

};



DSU s1,s2;

map<int,int> cnt[MAXN];



int main()

{

	int N,K,L;

	scanf("%d%d%d",&N,&K,&L);

	for(int i=1,x,y;i<=K;i++)

	{

		scanf("%d%d",&x,&y);

		s1.Union(x,y);

	}

	for(int i=1,x,y;i<=L;i++)

	{

		scanf("%d%d",&x,&y);

		s2.Union(x,y);

	}

	for(int i=1;i<=N;i++)

		cnt[s1.Root(i)][s2.Root(i)]++;

	for(int i=1;i<=N;i++)

		printf("%d ",cnt[s1.Root(i)][s2.Root(i)]);

	puts("");

	

	return 0;

}


// Faster C++ solution for the same problem (measured speedup: 11.84906152722428x):
//hate penalty



#include <bits/stdc++.h>

using namespace std;



int dsu[200001], dsu2[200001];

map <pair<int, int> ,int> mp;



int find(int x){

	if (dsu[x]) return dsu[x]=find(dsu[x]);

	return x;

}



int find2(int x){

	if (dsu2[x]) return dsu2[x]=find2(dsu2[x]);

	return x;

}



int main(){

	int n, k, l;

	cin >> n >> k >> l;

	int x, y;

	for (int i=1; i<=k; i++){

		cin >> x >> y;

		if (find(x)!=find(y)){

			dsu[find(x)]=find(y);

		}

	}

	for (int i=1; i<=l; i++){

		cin >> x >> y;

		if (find2(x)!=find2(y)){

			dsu2[find2(x)]=find2(y);

		}

	}

	for (int i=1; i<=n; i++){

		mp[make_pair(find(i),find2(i))]++;

	}

	for (int i=1; i<n; i++){

		cout << mp[make_pair(find(i), find2(i))] << " ";

	}

	cout << mp[make_pair(find(n), find2(n))] << "\n";

}
// Slower C++ solution:
#include <bits/stdc++.h>

using namespace std;



#define fr(i,n) _back

#define pb	push_back

#define eb	emplace_back

#define mk	make_pair

#define fi	first

#define se	second

#define endl	'\n'



typedef long long ll;

typedef pair<int,int> ii;

typedef vector<ii> vii;

const int INF = 0x3f3f3f3f;

const double PI = acos(-1.0);

const int T = 2e5 + 3;



int pai[3][T];

int peso[3][T];

vii g[T];

int n,k,l;



void init() {

    for(int i = 0; i < 3; i++)

        for(int j = 0; j <= n; j++) {

            pai[i][j] = j;

            peso[i][j] = 1;

        }

}



int find(int op, int x) {

    return (pai[op][x] == x? x : pai[op][x] = find(op,pai[op][x]));

}



void join(int op, int x, int y) {

    x = find(op,x);

    y = find(op,y);

    if(x == y) return;

    if(peso[op][x] < peso[op][y]) swap(x,y);

    pai[op][y] = x;

    peso[op][x] += peso[op][y];

}



int main() {

    ios_base::sync_with_stdio(false);

    cin >> n >> k >> l;

    init();



    while(k--) {

        int a,b; cin >> a >> b;

        if(find(0,a) != find(0,b)) join(0,a,b);

    }



    while(l--) {

        int a,b; cin >> a >> b;

        if(find(1,a) != find(1,b)) join(1,a,b);

    }



    for(int i = 1; i <= n; i++)

        g[find(0,i)].eb(find(1,i),i);



    for(int i = 1; i <= n; i++) {

        sort(g[i].begin(), g[i].end());

        for(int j = 1; j < g[i].size(); j++)

            if(g[i][j].fi == g[i][j-1].fi)

                join(2,g[i][j].se,g[i][j-1].se);

    }



    for(int i = 1; i <= n; i++) cout << peso[2][find(2,i)] << " ";

    cout << endl;



    return 0;

}


// Faster C++ solution for the same problem (measured speedup: 6.456756610384359x):
//hate penalty



#include <bits/stdc++.h>

using namespace std;



int dsu[200001], dsu2[200001];

map <pair<int, int> ,int> mp;



int find(int x){

	if (dsu[x]) return dsu[x]=find(dsu[x]);

	return x;

}



int find2(int x){

	if (dsu2[x]) return dsu2[x]=find2(dsu2[x]);

	return x;

}



int main(){

	int n, k, l;

	cin >> n >> k >> l;

	int x, y;

	for (int i=1; i<=k; i++){

		cin >> x >> y;

		if (find(x)!=find(y)){

			dsu[find(x)]=find(y);

		}

	}

	for (int i=1; i<=l; i++){

		cin >> x >> y;

		if (find2(x)!=find2(y)){

			dsu2[find2(x)]=find2(y);

		}

	}

	for (int i=1; i<=n; i++){

		mp[make_pair(find(i),find2(i))]++;

	}

	for (int i=1; i<n; i++){

		cout << mp[make_pair(find(i), find2(i))] << " ";

	}

	cout << mp[make_pair(find(n), find2(n))] << "\n";

}
// Slower C++ solution:
#include <iostream>

#include <string.h>

#include <stdio.h>

#include <queue>

#include <vector>

#include <map>

#include <algorithm>

using namespace std;

const int Max=3e5+100;

int get_root(int *f, int root){

    return f[root]==root?root:f[root]=get_root(f, f[root]);

}

void merge(int *f, int x,int y){

    int i=get_root(f, x);

    int j=get_root(f, y);

    f[i]=j;

}

int f[Max], g[Max];

void init(int n){

    for(int a=0; a<=n; a++)f[a]=a, g[a]=a;

}

int vis[Max], num[Max];

vector<int> vec[Max];

map<int, int>ma;

int main(){

    int n, m, k, u, v;

    scanf("%d%d%d", &n, &m, &k);

    init(n);

    for(int a=0; a<m; a++){

        scanf("%d%d", &u, &v);

        merge(f, u, v);

    }

    for(int a=0; a<k; a++){

        scanf("%d%d", &u, &v);

        merge(g, u, v);

    }

    for(int a=1; a<=n; a++)vec[get_root(f, a)].push_back(a);

    for(int a=0; a<=n; a++){

        ma.clear();

       // memset(num, 0, sizeof(num));

        for(int b=0; b<vec[a].size(); b++){

            ma[get_root(g, vec[a][b])]++;

            //num[get_root(g, vec[a][b])]++;

        }

        for(int b=0; b<vec[a].size(); b++){

            vis[vec[a][b]]+=ma[get_root(g, vec[a][b])];

        }

    }

    for(int a=1; a<=n; a++)printf("%d%c", vis[a], a==n?'\n':' ');

    return  0;

}

// Faster C++ solution for the same problem (measured speedup: 9.405803587780097x):
//used C i/o for faster peformance



#include<bits/stdc++.h>

#define f first

#define s second

using namespace std;



int x,y,z,n,m,road[200005],rail[200005],connect[200005];

pair<pair<int,int>,int> total[200005];



int root (int ind) {

	if (road[ind] == ind) return ind; else 

	return road[ind] = root(road[ind]);

}



void onion(int l, int r) {

	if (root(l) != root(r)) road[root(l)] = root(r);

}



int root2(int ind) {

	if (rail[ind] == ind) return ind; else 

	return rail[ind] = root2(rail[ind]);

}



void onion2(int l, int r) {

	if (root2(l) != root2(r)) rail[root2(l)] = root2(r);

}



int main() {

	scanf("%d%d%d",&x,&y,&z);

	for (int i = 0; i <= x; i++) {

		rail[i] = i;

		road[i] = i;

	}

	for (int i = 0; i < y; i++) {

		scanf("%d%d",&n,&m);

		onion(n,m);

	}

	for (int i = 0; i < z; i++) {

		scanf("%d%d",&n,&m);

		onion2(n,m);

	}

	for (int i = 1; i <= x; i++) {

		total[i] = make_pair(make_pair(root(i),root2(i)),i);

	}

	sort(total+1,total+1+x);

	total[x+1].f.f = total[x+1].f.s = -31415;

	stack<int> st; while (!st.empty()) st.pop();

	int a1 = 0,a2 = 0,b1 = 0,b2 = 0;

	for (int i = 1; i <= x+1; i++) {

		a1 = total[i].f.f, a2 = total[i].f.s;

		if (!(st.empty() || (a1 == b1 && a2 == b2))) {

			int tmp = st.size();

			while (!st.empty()) {

				connect[st.top()] += tmp-1;

				st.pop(); 

			}

		} 

		b1 = a1, b2 = a2;

		st.push(total[i].second);

	}

	for (int i = 1; i <= x; i++) {

		printf("%d ",connect[i]+1);

	}

}
// Slower C++ solution:
#include<cstdio>

#include<algorithm>

#include<cstring>

#include<vector>

#include<queue>

#include<map>

using namespace std;

#define LL long long

#define MAXN 200010

map<LL,int>G;

LL col[MAXN];

int vis[MAXN],n,a,b;

int Adj[MAXN],V[MAXN],nxt[MAXN],c;

void AddEdge(int u,int v)

{

	c++;V[c]=v,nxt[c]=Adj[u];

	Adj[u]=c;

}

void dfs1(int u)

{

	vis[u]=1;

	col[u]=col[0];

	for(int i=Adj[u];i;i=nxt[i])

		if(!vis[V[i]])

			dfs1(V[i]);

}

void dfs2(int u)

{

	vis[u]=0;

	col[u]=(col[u]<<20)+col[0];

	G[col[u]]++;

	for(int i=Adj[u];i;i=nxt[i])

		if(vis[V[i]])

			dfs2(V[i]);

}

int main()

{

	int u,v;

	scanf("%d%d%d",&n,&a,&b);

	for(int i=0;i<a;i++)

	{

		scanf("%d%d",&u,&v);

		AddEdge(u,v);

		AddEdge(v,u);

	}

	for(int i=1;i<=n;i++)

		if(!vis[i])

		{

			col[0]++;

			dfs1(i);

		}

	memset(Adj,0,sizeof Adj);

	col[0]=0,c=0;

	for(int i=0;i<b;i++)

	{

		scanf("%d%d",&u,&v);

		AddEdge(u,v);

		AddEdge(v,u);

	}

	for(int i=1;i<=n;i++)

		if(vis[i])

		{

			col[0]++;

			dfs2(i);

		}

	for(int i=1;i<=n;i++)

		printf("%d ",G[col[i]]);

}

// Faster C++ solution for the same problem (measured speedup: 1.7306614361854884x):
//used C i/o for faster peformance



#include<bits/stdc++.h>

#define f first

#define s second

using namespace std;



int x,y,z,n,m,road[200005],rail[200005],connect[200005];

pair<pair<int,int>,int> total[200005];



int root (int ind) {

	if (road[ind] == ind) return ind; else 

	return road[ind] = root(road[ind]);

}



void onion(int l, int r) {

	if (root(l) != root(r)) road[root(l)] = root(r);

}



int root2(int ind) {

	if (rail[ind] == ind) return ind; else 

	return rail[ind] = root2(rail[ind]);

}



void onion2(int l, int r) {

	if (root2(l) != root2(r)) rail[root2(l)] = root2(r);

}



int main() {

	scanf("%d%d%d",&x,&y,&z);

	for (int i = 0; i <= x; i++) {

		rail[i] = i;

		road[i] = i;

	}

	for (int i = 0; i < y; i++) {

		scanf("%d%d",&n,&m);

		onion(n,m);

	}

	for (int i = 0; i < z; i++) {

		scanf("%d%d",&n,&m);

		onion2(n,m);

	}

	for (int i = 1; i <= x; i++) {

		total[i] = make_pair(make_pair(root(i),root2(i)),i);

	}

	sort(total+1,total+1+x);

	total[x+1].f.f = total[x+1].f.s = -31415;

	stack<int> st; while (!st.empty()) st.pop();

	int a1 = 0,a2 = 0,b1 = 0,b2 = 0;

	for (int i = 1; i <= x+1; i++) {

		a1 = total[i].f.f, a2 = total[i].f.s;

		if (!(st.empty() || (a1 == b1 && a2 == b2))) {

			int tmp = st.size();

			while (!st.empty()) {

				connect[st.top()] += tmp-1;

				st.pop(); 

			}

		} 

		b1 = a1, b2 = a2;

		st.push(total[i].second);

	}

	for (int i = 1; i <= x; i++) {

		printf("%d ",connect[i]+1);

	}

}
// Slower C++ solution:
#include<cstdio>

#include<map>

using namespace std;

const int MAXN=200005;



struct DSU

{

	int fa[MAXN];

	int Root(int x)

	{return fa[x]==0?x:fa[x]=Root(fa[x]);}

	void Union(int x,int y)

	{

		int r1=Root(x),r2=Root(y);

		if(r1==r2)

			return;

		fa[r1]=r2;

	}

};



DSU s1,s2;

map<int,int> cnt[MAXN];



int main()

{

	int N,K,L;

	scanf("%d%d%d",&N,&K,&L);

	for(int i=1,x,y;i<=K;i++)

	{

		scanf("%d%d",&x,&y);

		s1.Union(x,y);

	}

	for(int i=1,x,y;i<=L;i++)

	{

		scanf("%d%d",&x,&y);

		s2.Union(x,y);

	}

	for(int i=1;i<=N;i++)

		cnt[s1.Root(i)][s2.Root(i)]++;

	for(int i=1;i<=N;i++)

		printf("%d ",cnt[s1.Root(i)][s2.Root(i)]);

	puts("");

	

	return 0;

}


// Faster C++ solution for the same problem (measured speedup: 11.93279370980112x):
//used C i/o for faster peformance



#include<bits/stdc++.h>

#define f first

#define s second

using namespace std;



int x,y,z,n,m,road[200005],rail[200005],connect[200005];

pair<pair<int,int>,int> total[200005];



int root (int ind) {

	if (road[ind] == ind) return ind; else 

	return road[ind] = root(road[ind]);

}



void onion(int l, int r) {

	if (root(l) != root(r)) road[root(l)] = root(r);

}



int root2(int ind) {

	if (rail[ind] == ind) return ind; else 

	return rail[ind] = root2(rail[ind]);

}



void onion2(int l, int r) {

	if (root2(l) != root2(r)) rail[root2(l)] = root2(r);

}



int main() {

	scanf("%d%d%d",&x,&y,&z);

	for (int i = 0; i <= x; i++) {

		rail[i] = i;

		road[i] = i;

	}

	for (int i = 0; i < y; i++) {

		scanf("%d%d",&n,&m);

		onion(n,m);

	}

	for (int i = 0; i < z; i++) {

		scanf("%d%d",&n,&m);

		onion2(n,m);

	}

	for (int i = 1; i <= x; i++) {

		total[i] = make_pair(make_pair(root(i),root2(i)),i);

	}

	sort(total+1,total+1+x);

	total[x+1].f.f = total[x+1].f.s = -31415;

	stack<int> st; while (!st.empty()) st.pop();

	int a1 = 0,a2 = 0,b1 = 0,b2 = 0;

	for (int i = 1; i <= x+1; i++) {

		a1 = total[i].f.f, a2 = total[i].f.s;

		if (!(st.empty() || (a1 == b1 && a2 == b2))) {

			int tmp = st.size();

			while (!st.empty()) {

				connect[st.top()] += tmp-1;

				st.pop(); 

			}

		} 

		b1 = a1, b2 = a2;

		st.push(total[i].second);

	}

	for (int i = 1; i <= x; i++) {

		printf("%d ",connect[i]+1);

	}

}
// Slower C++ solution:
#include <bits/stdc++.h>

using namespace std;



#define fr(i,n) _back

#define pb	push_back

#define eb	emplace_back

#define mk	make_pair

#define fi	first

#define se	second

#define endl	'\n'



typedef long long ll;

typedef pair<int,int> ii;

typedef vector<ii> vii;

const int INF = 0x3f3f3f3f;

const double PI = acos(-1.0);

const int T = 2e5 + 3;



int pai[3][T];

int peso[3][T];

vii g[T];

int n,k,l;



void init() {

    for(int i = 0; i < 3; i++)

        for(int j = 0; j <= n; j++) {

            pai[i][j] = j;

            peso[i][j] = 1;

        }

}



int find(int op, int x) {

    return (pai[op][x] == x? x : pai[op][x] = find(op,pai[op][x]));

}



void join(int op, int x, int y) {

    x = find(op,x);

    y = find(op,y);

    if(x == y) return;

    if(peso[op][x] < peso[op][y]) swap(x,y);

    pai[op][y] = x;

    peso[op][x] += peso[op][y];

}



int main() {

    ios_base::sync_with_stdio(false);

    cin >> n >> k >> l;

    init();



    while(k--) {

        int a,b; cin >> a >> b;

        if(find(0,a) != find(0,b)) join(0,a,b);

    }



    while(l--) {

        int a,b; cin >> a >> b;

        if(find(1,a) != find(1,b)) join(1,a,b);

    }



    for(int i = 1; i <= n; i++)

        g[find(0,i)].eb(find(1,i),i);



    for(int i = 1; i <= n; i++) {

        sort(g[i].begin(), g[i].end());

        for(int j = 1; j < g[i].size(); j++)

            if(g[i][j].fi == g[i][j-1].fi)

                join(2,g[i][j].se,g[i][j-1].se);

    }



    for(int i = 1; i <= n; i++) cout << peso[2][find(2,i)] << " ";

    cout << endl;



    return 0;

}


// Faster C++ solution for the same problem (measured speedup: 6.502383711071849x):
//used C i/o for faster peformance



#include<bits/stdc++.h>

#define f first

#define s second

using namespace std;



int x,y,z,n,m,road[200005],rail[200005],connect[200005];

pair<pair<int,int>,int> total[200005];



int root (int ind) {

	if (road[ind] == ind) return ind; else 

	return road[ind] = root(road[ind]);

}



void onion(int l, int r) {

	if (root(l) != root(r)) road[root(l)] = root(r);

}



int root2(int ind) {

	if (rail[ind] == ind) return ind; else 

	return rail[ind] = root2(rail[ind]);

}



void onion2(int l, int r) {

	if (root2(l) != root2(r)) rail[root2(l)] = root2(r);

}



int main() {

	scanf("%d%d%d",&x,&y,&z);

	for (int i = 0; i <= x; i++) {

		rail[i] = i;

		road[i] = i;

	}

	for (int i = 0; i < y; i++) {

		scanf("%d%d",&n,&m);

		onion(n,m);

	}

	for (int i = 0; i < z; i++) {

		scanf("%d%d",&n,&m);

		onion2(n,m);

	}

	for (int i = 1; i <= x; i++) {

		total[i] = make_pair(make_pair(root(i),root2(i)),i);

	}

	sort(total+1,total+1+x);

	total[x+1].f.f = total[x+1].f.s = -31415;

	stack<int> st; while (!st.empty()) st.pop();

	int a1 = 0,a2 = 0,b1 = 0,b2 = 0;

	for (int i = 1; i <= x+1; i++) {

		a1 = total[i].f.f, a2 = total[i].f.s;

		if (!(st.empty() || (a1 == b1 && a2 == b2))) {

			int tmp = st.size();

			while (!st.empty()) {

				connect[st.top()] += tmp-1;

				st.pop(); 

			}

		} 

		b1 = a1, b2 = a2;

		st.push(total[i].second);

	}

	for (int i = 1; i <= x; i++) {

		printf("%d ",connect[i]+1);

	}

}
// Slower C++ solution:
#include <iostream>

#include <string.h>

#include <stdio.h>

#include <queue>

#include <vector>

#include <map>

#include <algorithm>

using namespace std;

const int Max=3e5+100;

int get_root(int *f, int root){

    return f[root]==root?root:f[root]=get_root(f, f[root]);

}

void merge(int *f, int x,int y){

    int i=get_root(f, x);

    int j=get_root(f, y);

    f[i]=j;

}

int f[Max], g[Max];

void init(int n){

    for(int a=0; a<=n; a++)f[a]=a, g[a]=a;

}

int vis[Max], num[Max];

vector<int> vec[Max];

map<int, int>ma;

int main(){

    int n, m, k, u, v;

    scanf("%d%d%d", &n, &m, &k);

    init(n);

    for(int a=0; a<m; a++){

        scanf("%d%d", &u, &v);

        merge(f, u, v);

    }

    for(int a=0; a<k; a++){

        scanf("%d%d", &u, &v);

        merge(g, u, v);

    }

    for(int a=1; a<=n; a++)vec[get_root(f, a)].push_back(a);

    for(int a=0; a<=n; a++){

        ma.clear();

       // memset(num, 0, sizeof(num));

        for(int b=0; b<vec[a].size(); b++){

            ma[get_root(g, vec[a][b])]++;

            //num[get_root(g, vec[a][b])]++;

        }

        for(int b=0; b<vec[a].size(); b++){

            vis[vec[a][b]]+=ma[get_root(g, vec[a][b])];

        }

    }

    for(int a=1; a<=n; a++)printf("%d%c", vis[a], a==n?'\n':' ');

    return  0;

}

// Faster C++ solution for the same problem (measured speedup: 1.4516578176611832x):
#include<bits/stdc++.h>

#define YY "YES\n"

#define NN "NO\n"

#define LL long long

#define mp make_pair

using namespace std;



int n,m,tt,tar,k,tmp,l,ans[200001],dsua[200001],dsub[200001];

vector<int> ar[200001];



int finda(int now){

	if (dsua[now]==now) return now;	

	return dsua[now]=finda(dsua[now]); 

}

int findb(int now){

	if (dsub[now]==now) return now;	

	return dsub[now]=findb(dsub[now]); 

}



int main(){

	int x,y;

	cin>>n>>k>>l;

	for (int i=1;i<=n;i++){

		dsua[i]=i;

		dsub[i]=i;

	}

	for (int i=1;i<=k;i++){

		cin>>x>>y;

		int a=finda(x);

		int b=finda(y);

		if (a!=b){

			dsua[a]=dsua[b];

		}

	}

	for (int i=1;i<=l;i++){

		cin>>x>>y;

		int a=findb(x);

		int b=findb(y);

		if (a!=b){

			dsub[a]=dsub[b];

		}

	}

	for (int i=1;i<=n;i++){

		finda(i);

		findb(i);

	}

	map<pair<int,int>,int> mpp;

	for (int i=1;i<=n;i++){

		mpp[mp(dsua[i],dsub[i])]++;

	}

	for (int i=1;i<=n;i++){

		cout<<mpp[mp(dsua[i],dsub[i])]<<" ";

	}

}
// Slower C++ solution:
#include<cstdio>

#include<map>

using namespace std;

const int MAXN=200005;



struct DSU

{

	int fa[MAXN];

	int Root(int x)

	{return fa[x]==0?x:fa[x]=Root(fa[x]);}

	void Union(int x,int y)

	{

		int r1=Root(x),r2=Root(y);

		if(r1==r2)

			return;

		fa[r1]=r2;

	}

};



DSU s1,s2;

map<int,int> cnt[MAXN];



int main()

{

	int N,K,L;

	scanf("%d%d%d",&N,&K,&L);

	for(int i=1,x,y;i<=K;i++)

	{

		scanf("%d%d",&x,&y);

		s1.Union(x,y);

	}

	for(int i=1,x,y;i<=L;i++)

	{

		scanf("%d%d",&x,&y);

		s2.Union(x,y);

	}

	for(int i=1;i<=N;i++)

		cnt[s1.Root(i)][s2.Root(i)]++;

	for(int i=1;i<=N;i++)

		printf("%d ",cnt[s1.Root(i)][s2.Root(i)]);

	puts("");

	

	return 0;

}


// Faster C++ solution for the same problem (measured speedup: 1.841664363252912x):
#include<bits/stdc++.h>

#define YY "YES\n"

#define NN "NO\n"

#define LL long long

#define mp make_pair

using namespace std;



int n,m,tt,tar,k,tmp,l,ans[200001],dsua[200001],dsub[200001];

vector<int> ar[200001];



int finda(int now){

	if (dsua[now]==now) return now;	

	return dsua[now]=finda(dsua[now]); 

}

int findb(int now){

	if (dsub[now]==now) return now;	

	return dsub[now]=findb(dsub[now]); 

}



int main(){

	int x,y;

	cin>>n>>k>>l;

	for (int i=1;i<=n;i++){

		dsua[i]=i;

		dsub[i]=i;

	}

	for (int i=1;i<=k;i++){

		cin>>x>>y;

		int a=finda(x);

		int b=finda(y);

		if (a!=b){

			dsua[a]=dsua[b];

		}

	}

	for (int i=1;i<=l;i++){

		cin>>x>>y;

		int a=findb(x);

		int b=findb(y);

		if (a!=b){

			dsub[a]=dsub[b];

		}

	}

	for (int i=1;i<=n;i++){

		finda(i);

		findb(i);

	}

	map<pair<int,int>,int> mpp;

	for (int i=1;i<=n;i++){

		mpp[mp(dsua[i],dsub[i])]++;

	}

	for (int i=1;i<=n;i++){

		cout<<mpp[mp(dsua[i],dsub[i])]<<" ";

	}

}