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.348133837913931x):
#include<bits/stdc++.h>

using namespace std;

int f1[200000+10],f2[200000+10],n,k,l,x,y;

map<pair<int,int>,int > m;

int find(int x,int p[]){

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

}

void un(int x,int y,int p[]){

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

		p[find(x,p)]=find(y,p);

	}

}

void init(int p[]){

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

		p[i]=i;

	}	

}

int main(){

	cin>>n>>k>>l;

	init(f1);init(f2);

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

		cin>>x>>y;

		un(x,y,f1);

	}

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

		cin>>x>>y;

		un(x,y,f2);

	}

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

		find(i,f1);find(i,f2);

	}

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

		m[make_pair(f1[i],f2[i])]++;

	}

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

		cout<<m[make_pair(f1[i],f2[i])]<<" ";

	}

	return 0;

}
// 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.72005024159734x):
#include<bits/stdc++.h>

using namespace std;

int f1[200000+10],f2[200000+10],n,k,l,x,y;

map<pair<int,int>,int > m;

int find(int x,int p[]){

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

}

void un(int x,int y,int p[]){

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

		p[find(x,p)]=find(y,p);

	}

}

void init(int p[]){

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

		p[i]=i;

	}	

}

int main(){

	cin>>n>>k>>l;

	init(f1);init(f2);

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

		cin>>x>>y;

		un(x,y,f1);

	}

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

		cin>>x>>y;

		un(x,y,f2);

	}

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

		find(i,f1);find(i,f2);

	}

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

		m[make_pair(f1[i],f2[i])]++;

	}

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

		cout<<m[make_pair(f1[i],f2[i])]<<" ";

	}

	return 0;

}
// 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.859630239819369x):
#include<bits/stdc++.h>

using namespace std;

int f1[200000+10],f2[200000+10],n,k,l,x,y;

map<pair<int,int>,int > m;

int find(int x,int p[]){

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

}

void un(int x,int y,int p[]){

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

		p[find(x,p)]=find(y,p);

	}

}

void init(int p[]){

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

		p[i]=i;

	}	

}

int main(){

	cin>>n>>k>>l;

	init(f1);init(f2);

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

		cin>>x>>y;

		un(x,y,f1);

	}

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

		cin>>x>>y;

		un(x,y,f2);

	}

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

		find(i,f1);find(i,f2);

	}

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

		m[make_pair(f1[i],f2[i])]++;

	}

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

		cout<<m[make_pair(f1[i],f2[i])]<<" ";

	}

	return 0;

}
// 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: 10.106239925103127x):
#include<cstdio>

#include<map>

using namespace std;

int n,k,l;

int fg[200000],ft[200000];

map<pair<int,int>,int> s;

int findg(int x)

{

	if(fg[x]!=x) fg[x]=findg(fg[x]);

	return fg[x];

}

void ug(int r1,int r2)

{

	fg[r2]=r1;

}

int findt(int x)

{

	if(ft[x]!=x) ft[x]=findt(ft[x]);

	return ft[x];

}

void ut(int r1,int r2)

{

	ft[r2]=r1;

}

int main()

{

	int r1,r2;

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

	for(int i=1;i<=n;i++) fg[i]=ft[i]=i;

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

	{

		scanf("%d%d",&r1,&r2);

		r1=findg(r1);

		r2=findg(r2);

		if(r1!=r2) ug(r1,r2);

	}

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

	{

		scanf("%d%d",&r1,&r2);

		r1=findt(r1);

		r2=findt(r2);

		if(r1!=r2) ut(r1,r2);

	}

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

	{

		findg(i);

		findt(i);

	}

	

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

	{

		s[{fg[i],ft[i]}]++;

	}

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

	{

		printf("%d ",s[{fg[i],ft[i]}]);

	}

	return 0;

}
// 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.8595412438696373x):
#include<cstdio>

#include<map>

using namespace std;

int n,k,l;

int fg[200000],ft[200000];

map<pair<int,int>,int> s;

int findg(int x)

{

	if(fg[x]!=x) fg[x]=findg(fg[x]);

	return fg[x];

}

void ug(int r1,int r2)

{

	fg[r2]=r1;

}

int findt(int x)

{

	if(ft[x]!=x) ft[x]=findt(ft[x]);

	return ft[x];

}

void ut(int r1,int r2)

{

	ft[r2]=r1;

}

int main()

{

	int r1,r2;

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

	for(int i=1;i<=n;i++) fg[i]=ft[i]=i;

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

	{

		scanf("%d%d",&r1,&r2);

		r1=findg(r1);

		r2=findg(r2);

		if(r1!=r2) ug(r1,r2);

	}

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

	{

		scanf("%d%d",&r1,&r2);

		r1=findt(r1);

		r2=findt(r2);

		if(r1!=r2) ut(r1,r2);

	}

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

	{

		findg(i);

		findt(i);

	}

	

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

	{

		s[{fg[i],ft[i]}]++;

	}

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

	{

		printf("%d ",s[{fg[i],ft[i]}]);

	}

	return 0;

}
// 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: 12.821411278956317x):
#include<cstdio>

#include<map>

using namespace std;

int n,k,l;

int fg[200000],ft[200000];

map<pair<int,int>,int> s;

int findg(int x)

{

	if(fg[x]!=x) fg[x]=findg(fg[x]);

	return fg[x];

}

void ug(int r1,int r2)

{

	fg[r2]=r1;

}

int findt(int x)

{

	if(ft[x]!=x) ft[x]=findt(ft[x]);

	return ft[x];

}

void ut(int r1,int r2)

{

	ft[r2]=r1;

}

int main()

{

	int r1,r2;

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

	for(int i=1;i<=n;i++) fg[i]=ft[i]=i;

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

	{

		scanf("%d%d",&r1,&r2);

		r1=findg(r1);

		r2=findg(r2);

		if(r1!=r2) ug(r1,r2);

	}

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

	{

		scanf("%d%d",&r1,&r2);

		r1=findt(r1);

		r2=findt(r2);

		if(r1!=r2) ut(r1,r2);

	}

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

	{

		findg(i);

		findt(i);

	}

	

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

	{

		s[{fg[i],ft[i]}]++;

	}

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

	{

		printf("%d ",s[{fg[i],ft[i]}]);

	}

	return 0;

}
// 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.26782913942796x):
#include <bits/stdc++.h>

using namespace std;

const int MAXN = 2e5+2;

int pre1[MAXN],pre2[MAXN];

int finds(int x,int *pre)

{

    return pre[x] == x? pre[x]:pre[x] = finds(pre[x],pre);

}

void join(int x,int y,int *pre)

{

    int px = finds(x,pre);

    int py = finds(y,pre);

    if( px!=py)

    {

        pre[px] = py;

    }

}

int main()

{

    int n,k,l;

    cin>>n>>k>>l;

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

        pre1[i] = i,pre2[i] = i;

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

    {

        int x,y;

        cin>>x>>y;

        join(x,y,pre1);

    }

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

    {

        int x,y;

        cin>>x>>y;

        join(x,y,pre2);

    }

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

    {

        finds(i,pre1);

        finds(i,pre2);

    }

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

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

    {

        mp[make_pair(pre1[i],pre2[i])] ++;

    }

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

    {

        cout<<mp[make_pair(pre1[i],pre2[i])]<<" ";

    }

    cout<<endl;

}
// 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.7052742319223417x):
#include <bits/stdc++.h>

using namespace std;

const int MAXN = 2e5+2;

int pre1[MAXN],pre2[MAXN];

int finds(int x,int *pre)

{

    return pre[x] == x? pre[x]:pre[x] = finds(pre[x],pre);

}

void join(int x,int y,int *pre)

{

    int px = finds(x,pre);

    int py = finds(y,pre);

    if( px!=py)

    {

        pre[px] = py;

    }

}

int main()

{

    int n,k,l;

    cin>>n>>k>>l;

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

        pre1[i] = i,pre2[i] = i;

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

    {

        int x,y;

        cin>>x>>y;

        join(x,y,pre1);

    }

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

    {

        int x,y;

        cin>>x>>y;

        join(x,y,pre2);

    }

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

    {

        finds(i,pre1);

        finds(i,pre2);

    }

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

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

    {

        mp[make_pair(pre1[i],pre2[i])] ++;

    }

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

    {

        cout<<mp[make_pair(pre1[i],pre2[i])]<<" ";

    }

    cout<<endl;

}
// 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.7577506511146x):
#include <bits/stdc++.h>

using namespace std;

const int MAXN = 2e5+2;

int pre1[MAXN],pre2[MAXN];

int finds(int x,int *pre)

{

    return pre[x] == x? pre[x]:pre[x] = finds(pre[x],pre);

}

void join(int x,int y,int *pre)

{

    int px = finds(x,pre);

    int py = finds(y,pre);

    if( px!=py)

    {

        pre[px] = py;

    }

}

int main()

{

    int n,k,l;

    cin>>n>>k>>l;

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

        pre1[i] = i,pre2[i] = i;

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

    {

        int x,y;

        cin>>x>>y;

        join(x,y,pre1);

    }

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

    {

        int x,y;

        cin>>x>>y;

        join(x,y,pre2);

    }

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

    {

        finds(i,pre1);

        finds(i,pre2);

    }

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

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

    {

        mp[make_pair(pre1[i],pre2[i])] ++;

    }

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

    {

        cout<<mp[make_pair(pre1[i],pre2[i])]<<" ";

    }

    cout<<endl;

}
// 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: 10.106239925103127x):
#include<cstdio>

#include<map>

using namespace std;

int n,k,l;

int fg[200000],ft[200000];

map<pair<int,int>,int> s;

int findg(int x)

{

    if(fg[x]!=x) fg[x]=findg(fg[x]);

    return fg[x];

}

void ug(int r1,int r2)

{

    fg[r2]=r1;

}

int findt(int x)

{

    if(ft[x]!=x) ft[x]=findt(ft[x]);

    return ft[x];

}

void ut(int r1,int r2)

{

    ft[r2]=r1;

}

int main()

{

    int r1,r2;

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

    for(int i=1;i<=n;i++) fg[i]=ft[i]=i;

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

    {

        scanf("%d%d",&r1,&r2);

        r1=findg(r1);

        r2=findg(r2);

        if(r1!=r2) ug(r1,r2);

    }

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

    {

        scanf("%d%d",&r1,&r2);

        r1=findt(r1);

        r2=findt(r2);

        if(r1!=r2) ut(r1,r2);

    }

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

    {

        findg(i);

        findt(i);

    }

    //首先把问题数据用并查集处理为一个个联通块，

    //要 求既通过公路连通又通过铁路连通的城市数 就转化为了 求各fg与ft的交集元素数 

    //所以只需用map统计每个交集中点的数量即可

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

    {

        s[{fg[i],ft[i]}]++;

        //如果两个点之间既能走公路到达，又能走铁路到达，他们肯定属于同一个交集，那么fg[i]与ft[i]的交集元素数+1 

    }

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

    {

        printf("%d ",s[{fg[i],ft[i]}]);

    }

    return 0;

}
// 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.8595412438696373x):
#include<cstdio>

#include<map>

using namespace std;

int n,k,l;

int fg[200000],ft[200000];

map<pair<int,int>,int> s;

int findg(int x)

{

    if(fg[x]!=x) fg[x]=findg(fg[x]);

    return fg[x];

}

void ug(int r1,int r2)

{

    fg[r2]=r1;

}

int findt(int x)

{

    if(ft[x]!=x) ft[x]=findt(ft[x]);

    return ft[x];

}

void ut(int r1,int r2)

{

    ft[r2]=r1;

}

int main()

{

    int r1,r2;

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

    for(int i=1;i<=n;i++) fg[i]=ft[i]=i;

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

    {

        scanf("%d%d",&r1,&r2);

        r1=findg(r1);

        r2=findg(r2);

        if(r1!=r2) ug(r1,r2);

    }

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

    {

        scanf("%d%d",&r1,&r2);

        r1=findt(r1);

        r2=findt(r2);

        if(r1!=r2) ut(r1,r2);

    }

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

    {

        findg(i);

        findt(i);

    }

    //首先把问题数据用并查集处理为一个个联通块，

    //要 求既通过公路连通又通过铁路连通的城市数 就转化为了 求各fg与ft的交集元素数 

    //所以只需用map统计每个交集中点的数量即可

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

    {

        s[{fg[i],ft[i]}]++;

        //如果两个点之间既能走公路到达，又能走铁路到达，他们肯定属于同一个交集，那么fg[i]与ft[i]的交集元素数+1 

    }

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

    {

        printf("%d ",s[{fg[i],ft[i]}]);

    }

    return 0;

}