stablegradients/pie-gem5-pairs huggingface dataset:
// 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);

    }

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

    //要 求既通过公路连通又通过铁路连通的城市数 就转化为了 求各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 <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.234348134154024x):
#include<iostream>

#include<map>

using namespace std;

const int maxn=200005;

int root1[maxn],root2[maxn];

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

int ufind(int x,int *root)

{

    if(root[x]==x)

    {

        return x;

    }else

        return root[x]=ufind(root[x],root);

}

void umerge(int p,int q,int*root)

{

    int rp=ufind(p,root);

    int rq=ufind(q,root);

    if(rp!=rq)

    {

        root[rq]=rp;

    }

}

int main()

{

    ios::sync_with_stdio(false);

    int n,k,l,x,y;

    cin>>n>>k>>l;

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

    {

        root1[i]=i;

        root2[i]=i;

    }

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

    {

        cin>>x>>y;

        umerge(x,y,root1);

    }

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

    {

        cin>>x>>y;

        umerge(x,y,root2);

    }

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

    {

        ufind(i,root1);

        ufind(i,root2);

    }

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

    {

        mp[make_pair(root1[i],root2[i])]++;

    }

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

    {

        cout<<mp[make_pair(root1[i],root2[i])]<<" ";

    }cout<<endl;

    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.6991137498187598x):
#include<iostream>

#include<map>

using namespace std;

const int maxn=200005;

int root1[maxn],root2[maxn];

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

int ufind(int x,int *root)

{

    if(root[x]==x)

    {

        return x;

    }else

        return root[x]=ufind(root[x],root);

}

void umerge(int p,int q,int*root)

{

    int rp=ufind(p,root);

    int rq=ufind(q,root);

    if(rp!=rq)

    {

        root[rq]=rp;

    }

}

int main()

{

    ios::sync_with_stdio(false);

    int n,k,l,x,y;

    cin>>n>>k>>l;

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

    {

        root1[i]=i;

        root2[i]=i;

    }

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

    {

        cin>>x>>y;

        umerge(x,y,root1);

    }

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

    {

        cin>>x>>y;

        umerge(x,y,root2);

    }

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

    {

        ufind(i,root1);

        ufind(i,root2);

    }

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

    {

        mp[make_pair(root1[i],root2[i])]++;

    }

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

    {

        cout<<mp[make_pair(root1[i],root2[i])]<<" ";

    }cout<<endl;

    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.715274543102979x):
#include<iostream>

#include<map>

using namespace std;

const int maxn=200005;

int root1[maxn],root2[maxn];

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

int ufind(int x,int *root)

{

    if(root[x]==x)

    {

        return x;

    }else

        return root[x]=ufind(root[x],root);

}

void umerge(int p,int q,int*root)

{

    int rp=ufind(p,root);

    int rq=ufind(q,root);

    if(rp!=rq)

    {

        root[rq]=rp;

    }

}

int main()

{

    ios::sync_with_stdio(false);

    int n,k,l,x,y;

    cin>>n>>k>>l;

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

    {

        root1[i]=i;

        root2[i]=i;

    }

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

    {

        cin>>x>>y;

        umerge(x,y,root1);

    }

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

    {

        cin>>x>>y;

        umerge(x,y,root2);

    }

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

    {

        ufind(i,root1);

        ufind(i,root2);

    }

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

    {

        mp[make_pair(root1[i],root2[i])]++;

    }

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

    {

        cout<<mp[make_pair(root1[i],root2[i])]<<" ";

    }cout<<endl;

    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: 1.446516232464794x):
#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;

}
// 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.835141425056585x):
#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;

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

using namespace std;

#define ll long long

#define x first

#define y second

#define mp make_pair

#define pb push_back

#define kk 1000000007

int l,n,m,k,a,b,c,tmp,cc[300005],u,v,gp1[300005],gp2[300005],an1[300005],an2[300005],an3[300005];

vector<int > ee;

map<pair<int ,int > ,int > mm;

int find1(int x){

	return gp1[x] == x? x : gp1[x] = find1(gp1[x]); 

}

int find2(int x){

	return gp2[x] == x? x : gp2[x] = find2(gp2[x]); 

}

char g;

int main(){

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

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

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

	

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

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

		gp1[find1(gp1[u])] = find1(gp1[v]);

	}

	

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

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

		gp2[find2(gp2[u])] = find2(gp2[v]);

	}

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

		if (!an1[find1(gp1[i])]) an1[find1(gp1[i])] = ++tmp;

		if (!an2[find2(gp2[i])]) an2[find2(gp2[i])] = ++tmp;		

	}

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

		u = find1(gp1[i]);

		v = find2(gp2[i]);

		mm[mp(an1[u],an2[v])] ++;

	}

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

		u = find1(gp1[i]);

		v = find2(gp2[i]);	

		an3[i] = mm[mp(an1[u],an2[v])];	

	}	

	for (int i=1;i<=n;i++) printf(i==n?"%d\n":"%d ",an3[i]);

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

using namespace std;

#define ll long long

#define x first

#define y second

#define mp make_pair

#define pb push_back

#define kk 1000000007

int l,n,m,k,a,b,c,tmp,cc[300005],u,v,gp1[300005],gp2[300005],an1[300005],an2[300005],an3[300005];

vector<int > ee;

map<pair<int ,int > ,int > mm;

int find1(int x){

	return gp1[x] == x? x : gp1[x] = find1(gp1[x]); 

}

int find2(int x){

	return gp2[x] == x? x : gp2[x] = find2(gp2[x]); 

}

char g;

int main(){

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

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

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

	

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

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

		gp1[find1(gp1[u])] = find1(gp1[v]);

	}

	

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

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

		gp2[find2(gp2[u])] = find2(gp2[v]);

	}

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

		if (!an1[find1(gp1[i])]) an1[find1(gp1[i])] = ++tmp;

		if (!an2[find2(gp2[i])]) an2[find2(gp2[i])] = ++tmp;		

	}

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

		u = find1(gp1[i]);

		v = find2(gp2[i]);

		mm[mp(an1[u],an2[v])] ++;

	}

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

		u = find1(gp1[i]);

		v = find2(gp2[i]);	

		an3[i] = mm[mp(an1[u],an2[v])];	

	}	

	for (int i=1;i<=n;i++) printf(i==n?"%d\n":"%d ",an3[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: 11.906460256733972x):
#include<bits/stdc++.h>

using namespace std;

#define ll long long

#define x first

#define y second

#define mp make_pair

#define pb push_back

#define kk 1000000007

int l,n,m,k,a,b,c,tmp,cc[300005],u,v,gp1[300005],gp2[300005],an1[300005],an2[300005],an3[300005];

vector<int > ee;

map<pair<int ,int > ,int > mm;

int find1(int x){

	return gp1[x] == x? x : gp1[x] = find1(gp1[x]); 

}

int find2(int x){

	return gp2[x] == x? x : gp2[x] = find2(gp2[x]); 

}

char g;

int main(){

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

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

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

	

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

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

		gp1[find1(gp1[u])] = find1(gp1[v]);

	}

	

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

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

		gp2[find2(gp2[u])] = find2(gp2[v]);

	}

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

		if (!an1[find1(gp1[i])]) an1[find1(gp1[i])] = ++tmp;

		if (!an2[find2(gp2[i])]) an2[find2(gp2[i])] = ++tmp;		

	}

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

		u = find1(gp1[i]);

		v = find2(gp2[i]);

		mm[mp(an1[u],an2[v])] ++;

	}

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

		u = find1(gp1[i]);

		v = find2(gp2[i]);	

		an3[i] = mm[mp(an1[u],an2[v])];	

	}	

	for (int i=1;i<=n;i++) printf(i==n?"%d\n":"%d ",an3[i]);

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

using namespace std;

#define ll long long

#define x first

#define y second

#define mp make_pair

#define pb push_back

#define kk 1000000007

int l,n,m,k,a,b,c,tmp,cc[300005],u,v,gp1[300005],gp2[300005],an1[300005],an2[300005],an3[300005];

vector<int > ee;

map<pair<int ,int > ,int > mm;

int find1(int x){

	return gp1[x] == x? x : gp1[x] = find1(gp1[x]); 

}

int find2(int x){

	return gp2[x] == x? x : gp2[x] = find2(gp2[x]); 

}

char g;

int main(){

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

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

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

	

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

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

		gp1[find1(gp1[u])] = find1(gp1[v]);

	}

	

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

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

		gp2[find2(gp2[u])] = find2(gp2[v]);

	}

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

		if (!an1[find1(gp1[i])]) an1[find1(gp1[i])] = ++tmp;

		if (!an2[find2(gp2[i])]) an2[find2(gp2[i])] = ++tmp;		

	}

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

		u = find1(gp1[i]);

		v = find2(gp2[i]);

		mm[mp(an1[u],an2[v])] ++;

	}

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

		u = find1(gp1[i]);

		v = find2(gp2[i]);	

		an3[i] = mm[mp(an1[u],an2[v])];	

	}	

	for (int i=1;i<=n;i++) printf(i==n?"%d\n":"%d ",an3[i]);

}