stablegradients/pie-gem5-bysrc huggingface dataset:
// Original C++ solution (slower):
#include <algorithm>

#include <iostream>

#include <iomanip>

#include <cstring>

#include <string>

#include <vector>

#include <queue>

#include <cmath>

using namespace std;



const int MAXN = 200000 + 10;

const int MAXL = 100000 + 10;



struct DSU

{

    int fa[MAXN];



    int find(int x)

    {

        if(x == fa[x])

            return x;

        return fa[x] = find(fa[x]);

    }



    void merge(int x, int y)

    {

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

    }

}d1, d2;



int tmp[MAXN], ans[MAXN], cnt[MAXN];



void init(DSU & d)

{

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

        d.fa[i] = i;

}



int N, K, L;

int main()

{

    init(d1);

    init(d2);

    int u, v;

    cin >> N >> K >> L ;



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

        cin >> u >> v, d1.merge(u, v);

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

        cin >> u >> v, d2.merge(u, v);



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

        d1.fa[i] = d1.find(i),

        d2.fa[i] = d2.find(i);

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

        tmp[i] = i;

    sort(tmp+1, tmp+N+1, [](int x, int y)-> bool {return d1.fa[x] < d1.fa[y];});





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

    {

        int j = i;

        while(j < N && d1.fa[tmp[j]] == d1.fa[tmp[j+1]])

            j++;



        for(int t = i; t <= j; t++)

            cnt[d2.fa[tmp[t]]]++;

        for(int t = i; t <= j; t++)

            ans[tmp[t]] = cnt[d2.fa[tmp[t]]];

        for(int t = i; t <= j; t++)

            cnt[d2.fa[tmp[t]]]--;

        i = j ;

    }



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

        cout << ans[i] << " " ;



    return 0;

}


// Optimized solution to the same problem (faster):
#include<cstdio>

#include<map>

using namespace std;

int par1[200005],par2[200005];

int rank1[200005],rank2[200005];

typedef pair<int,int> P;

map<P,int>m;

int find(int *par,int x)

{

    if(x==par[x])

        return x;

    else

        return par[x]=find(par,par[x]);

}

void unite(int *par,int *rank,int x,int y)

{

    x=find(par,x);

    y=find(par,y);

    if(x==y)

        return ;

    else

    {

        if(rank[x]>rank[y])

            par[y]=x;

        else

        {

            par[x]=y;

            if(rank[x]==rank[y])

                rank[y]++;

        }

    }

}

int main()

{

    int n,k,l;

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

    int p,q;

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

    {

        par1[i]=par2[i]=i;

        rank1[i]=rank2[i]=0;

    }

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

    {

        scanf("%d%d",&p,&q);

        unite(par1,rank1,p,q);

    }

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

    {

        scanf("%d%d",&p,&q);

        unite(par2,rank2,p,q);

    }

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

    {

        find(par1,i);

        find(par2,i);

    }

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

    {

        m[P(par1[i],par2[i])]++;

    }

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

    {

        printf("%d ",m[P(par1[i],par2[i])]);

    }

    return 0;

}


// Fastest known solution for this problem:
// Original C++ solution (slower):
#include<cstdio>

#include<cstring>

#include<cmath>

#include<map>

#include<algorithm>



#define maxn 200005



using namespace std;



inline int getint()

{

	int num=0,flag=1;char c;

	while((c=getchar())<'0'||c>'9')if(c=='-')flag=-1;

	while(c>='0'&&c<='9')num=num*10+c-48,c=getchar();

	return num*flag;

}



map<long long,int>sz;

int n,k,l;

int fir[maxn],nxt[maxn],to[maxn],cnt;

int f1[maxn];

int f2[maxn];



inline void newnode(int u,int v)

{to[++cnt]=v,nxt[cnt]=fir[u],fir[u]=cnt;}



void dfs1(int u)

{

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

		if(!f1[to[i]])

		{

			f1[to[i]]=f1[u];

			dfs1(to[i]);

		}

}



void dfs2(int u)

{

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

		if(!f2[to[i]])

		{

			f2[to[i]]=f2[u];

			dfs2(to[i]);

		}

}





int main()

{

	n=getint(),k=getint(),l=getint();

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

	{

		int a=getint(),b=getint();

		newnode(a,b),newnode(b,a);

	}

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

		if(!f1[i])f1[i]=i,dfs1(i);

	memset(fir,0,sizeof fir);memset(nxt,0,sizeof nxt);

	memset(to,0,sizeof to);cnt=0;

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

	{

		int a=getint(),b=getint();

		newnode(a,b),newnode(b,a);

	}

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

		if(!f2[i])f2[i]=i,dfs2(i);

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

		sz[(long long)f1[i]*maxn+f2[i]]++;

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

		if(i==n)printf("%d\n",sz[(long long)f1[i]*maxn+f2[i]]);

		else printf("%d ",sz[(long long)f1[i]*maxn+f2[i]]);

}

// Optimized solution to the same problem (faster):
#include<cstdio>

#include<cstring>

#include<map>

#include<algorithm>

using namespace std;

#define N 200005

#define M 100005

struct node1{

	int to,nxt;

}e1[2*M];

int fir1[N],cnt1;

void adde1(int a,int b)

{

	e1[++cnt1].to=b;

	e1[cnt1].nxt=fir1[a];

	fir1[a]=cnt1;

	e1[++cnt1].to=a;

	e1[cnt1].nxt=fir1[b];

	fir1[b]=cnt1;

}

int vis1[N],tot1;

void dfs1(int u)

{

	int v,p;

	vis1[u]=tot1;

	for(p=fir1[u];p;p=e1[p].nxt){

		v=e1[p].to;

		if(!vis1[v])

			dfs1(v);

	}

}



struct node2{

	int to,nxt;

}e2[2*M];

int fir2[N],cnt2;

void adde2(int a,int b)

{

	e2[++cnt2].to=b;

	e2[cnt2].nxt=fir2[a];

	fir2[a]=cnt2;

	e2[++cnt2].to=a;

	e2[cnt2].nxt=fir2[b];

	fir2[b]=cnt2;

}

int vis2[N],tot2;

void dfs2(int u)

{

	int v,p;

	vis2[u]=tot2;

	for(p=fir2[u];p;p=e2[p].nxt){

		v=e2[p].to;

		if(!vis2[v])

			dfs2(v);

	}

}

map<long long,int >b;

int main()

{

	int n,m1,m2,u,v,i;

	scanf("%d%d%d",&n,&m1,&m2);

	for(i=1;i<=m1;i++){

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

		adde1(u,v);

	}

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

		if(!vis1[i]){tot1++;dfs1(i);}

	

	for(i=1;i<=m2;i++){

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

		adde2(u,v);

	}

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

		if(!vis2[i]){tot2++;dfs2(i);}

	

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

		b[1ll*vis1[i]*N+1ll*vis2[i]]++;

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

		printf("%d",b[1ll*vis1[i]*N+1ll*vis2[i]]);

		if(i!=n)printf(" ");

	}

}

// Fastest known solution for this problem:
// Original C++ solution (slower):
#include<cstdio>

#include<cstring>

#include<map>

#include<vector>

#include<algorithm>

#define MAXN 200006

using namespace std;

int n,K,L,fa[3][MAXN],u,v,sum[MAXN];

vector<int> road[MAXN];

map<int,int> ma;

int root(int x,int op)

{

	if(fa[op][x]==x) return x;

	fa[op][x]=root(fa[op][x],op);

	return fa[op][x];

}

int main()

{

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

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

	{

		fa[0][i]=i;

		fa[1][i]=i;

	}

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

	{

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

		fa[0][root(u,0)]=root(v,0);

	}

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

	{

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

		fa[1][root(u,1)]=root(v,1);

	}

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

		road[root(i,0)].push_back(i);

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

	{

		ma.clear();

		for(int j=0;j<(int)road[i].size();j++)

			ma[root(road[i][j],1)]++;

		for(int j=0;j<(int)road[i].size();j++)

			sum[road[i][j]]+=ma[root(road[i][j],1)];

	}

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

		printf("%d ",sum[i]);

}

// Optimized solution to the same problem (faster):
#include <bits/stdc++.h>

using namespace std;

typedef pair<int, int> pii;

struct dsu{

    int p[200002], sz[200002];

    void init(int n){

        for(int i=1;i<=n;i++) p[i] = i, sz[i] = 1;

    }

    int root(int a){

        return p[a] == a?a:(p[a]=root(p[a]));

    }

    void merge(int a, int b){

        a = root(a), b = root(b);

        if(a != b){

            sz[b] += sz[a];

            p[a] = b;

        }

    }

}d1, d2;

map<pii, int> dp;



int main(){

    int n, k, l;

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

    d1.init(n), d2.init(n);

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

        int a, b;

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

        d1.merge(a, b);

    }

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

        int a, b;

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

        d2.merge(a, b);

    }

    for(int i=1;i<=n;i++) dp[make_pair(d1.root(i), d2.root(i))]++;

    for(int i=1;i<=n;i++) printf("%d ", dp[make_pair(d1.root(i), d2.root(i))]);

}

// Fastest known solution for this problem:
// Original C++ solution (slower):
#include <bits/stdc++.h>

using namespace std;



const int N = 220000;



vector<int> con[N];



int root[N];

inline int find_root(int u) {

	if (u == root[u]) return root[u];

	return root[u] = find_root(root[u]);

}



int vis[N];

vector<int> cur;

void dfs(int u) {

	vis[u] = 1;

	cur.push_back(u);

	for (int v : con[u]) if (!vis[v]) dfs(v);

}



int cnt[N];

int ans[N];



int main() {

	

	ios::sync_with_stdio(0);

	cin.tie(0), cout.tie(0);

	

	int n, m, k; cin >> n >> m >> k;

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

	while (m--) {

		int u, v; cin >> u >> v;

		int a = find_root(u), b = find_root(v);

		if (a == b) continue;

		root[a] = b;

	}

	while (k--) {

		int u, v; cin >> u >> v;

		con[u].push_back(v), con[v].push_back(u);

	}

	for (int i = 1; i <= n; i++) if (!vis[i]) {

		cur.clear();

		dfs(i);

		for (auto u : cur) cnt[find_root(u)] = 0;

		for (auto u : cur) cnt[find_root(u)]++;

		for (auto u : cur) ans[u] = cnt[find_root(u)];

	}

	for (int i = 1; i <= n; i++) cout << ans[i] << " \n"[i == n];

	

	return 0;

}


// Optimized solution to the same problem (faster):
#include <iostream>

#include <cstdio>

#include <algorithm>

#include <vector>

#include <map>

using namespace std;

const int N = 200005;

int n,x,y,ans[N];

// road

int k, knm[N],kfa[N];



int kfind(int t){

	if(t == kfa[t]) return t;

	return kfa[t] = kfind(kfa[t]);

}

// raiway

int l, lnm[N],lfa[N];

int lfind(int t){

	if(t == lfa[t]) return t;

	return lfa[t] = lfind(lfa[t]);

}



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



int main(){

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

	// k

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

		kfa[i] = i;

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

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

		int tx = kfind(x), ty = kfind(y);

		if(tx != ty)

			kfa[ty] = tx;

	}

	

	// l

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

		lfa[i] = i;	

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

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

		int tx = lfind(x), ty = lfind(y);

		if(tx != ty)

			lfa[ty] = tx;

	}

	

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

//		cout<<lfa[i]<<" ";

//	cout<<endl;

	//cout<<kfa[3]<<" "<<lfa[3]<<endl;

	//cout<<kfa[5]<<" "<<lfa[5]<<endl;

	

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

		++ mp[make_pair(kfind(i), lfind(i))];

	}

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

		ans[i] = mp[make_pair(kfind(i), lfind(i))];

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

		printf("%d ", ans[i]);

	printf("%d\n", ans[n]); 

}

// Fastest known solution for this problem:
// Original C++ solution (slower):
#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;

}

// Optimized solution to the same problem (faster):
#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;

}

// Fastest known solution for this problem:
// Original C++ solution (slower):
#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]]);

}

// Optimized solution to the same problem (faster):
#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;

}

// Fastest known solution for this problem:
// Original C++ solution (slower):
#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;

}


// Optimized solution to the same problem (faster):
#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;

}

// Fastest known solution for this problem:
// Original C++ solution (slower):
#include <iostream>

#include <cstdio>

#include <cstring>

#include <cmath>

#include <algorithm>

#include <vector>

#include <map>

#define ms(x) memset(x, 0, sizeof(x))

#define inf 0x3f3f3f3f

using namespace std;

const int N = 200005;

vector<int >book[N];

int faf[N], fag[N];

int vis[N];

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

void init() {

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

        faf[i] = fag[i] = i;

    }

}

int Find(int *f, int x){

    if(f[x] == x) return x;

    else{

        f[x] = Find(f, f[x]);

        return f[x];

    }

}

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

    int a = Find(f, x) , b = Find(f, y);

    if(a!=b){

        f[b] = a;

    }

}

int main() {

    int n, k, l;

    while(cin>>n>>k>>l) {

        int u, v;

        init();

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

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

            Merge(faf, u, v);

        }

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

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

            Merge(fag, u, v);

        }

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

            ++mp[{Find(faf, i), Find(fag, i)}];        //将同一个连通块中的点 集合起来

        }

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

            printf("%d%c", mp[{Find(faf, i), Find(fag, i)}],i==n?'\n':' ');

        }

    }

    return 0;

}


// Optimized solution to the same problem (faster):
/*Lucky_Glass*/

#include<cstdio>

#include<cstring>

#include<algorithm>

#include<vector>

#include<queue>

#include<map>

using namespace std;

const int MAXN=int(2e5);

int n,p,q;

int fa[2][MAXN+5];

map< pair<int,int> ,int> cnt;

int Find(int x,int y)

{

	if(fa[y][x]==x) return x;

	return fa[y][x]=Find(fa[y][x],y);

}

int main()

{

	scanf("%d%d%d",&n,&p,&q);

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

		fa[0][i]=fa[1][i]=i;

	for(int i=0,u,v;i<p;i++)

	{

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

		if(Find(u,0)!=Find(v,0))

			fa[0][fa[0][u]]=fa[0][v];

	}

	for(int i=0,u,v;i<q;i++)

	{

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

		if(Find(u,1)!=Find(v,1))

			fa[1][fa[1][u]]=fa[1][v];

	}

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

		cnt[make_pair(Find(i,0),Find(i,1))]++;

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

	{

		if(i!=1) printf(" ");

		printf("%d",cnt[make_pair(fa[0][i],fa[1][i])]);

	}

	printf("\n");

	return 0;

}


// Fastest known solution for this problem:
// Original C++ solution (slower):
#include <map>

#include <cmath>

#include <queue>

#include <stack>

#include <vector>

#include <cstdio>

#include <string>

#include <cstring>

#include <sstream>

#include <algorithm>



using namespace std;



int ro[200005], ra[200005], n, k, l;



int Find(int *r, int x) {

    return r[x]==x ? x : r[x]=Find(r, r[x]);

}



void init() {

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

        ra[i]=ro[i]=i;

    }

}



vector <int> ve[200005];

map <int, int> ma;

int ans[200005];



int main () {

    int u, v;

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

    init();

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

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

        u=Find(ro, u), v=Find(ro, v);

        if(u!=v) {

            ro[u]=v;

        }

    }



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

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

        u=Find(ra, u), v=Find(ra, v);

        if(u!=v) {

            ra[u]=v;

        }

    }



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

        ve[Find(ro, i)].push_back(i);

    }



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

        ma.clear();

        for(int j=0;j<(int)ve[i].size();j++) {

            ma[Find(ra, ve[i][j])]++;

        }



        for(int j=0;j<(int)ve[i].size();j++) {

            ans[ve[i][j]]+=ma[Find(ra, ve[i][j])];

        }

    }



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

        printf("%d%c", ans[i], i==n ? '\n' : ' ');

    }

    return 0;

}

// Optimized solution to the same problem (faster):
/*Lucky_Glass*/

#include<cstdio>

#include<cstring>

#include<algorithm>

#include<vector>

#include<queue>

#include<map>

using namespace std;

const int MAXN=int(2e5);

int n,p,q;

int fa[2][MAXN+5];

map< pair<int,int> ,int> cnt;

int Find(int x,int y)

{

	if(fa[y][x]==x) return x;

	return fa[y][x]=Find(fa[y][x],y);

}

int main()

{

	scanf("%d%d%d",&n,&p,&q);

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

		fa[0][i]=fa[1][i]=i;

	for(int i=0,u,v;i<p;i++)

	{

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

		if(Find(u,0)!=Find(v,0))

			fa[0][fa[0][u]]=fa[0][v];

	}

	for(int i=0,u,v;i<q;i++)

	{

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

		if(Find(u,1)!=Find(v,1))

			fa[1][fa[1][u]]=fa[1][v];

	}

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

		cnt[make_pair(Find(i,0),Find(i,1))]++;

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

	{

		if(i!=1) printf(" ");

		printf("%d",cnt[make_pair(fa[0][i],fa[1][i])]);

	}

	printf("\n");

	return 0;

}


// Fastest known solution for this problem:
// Original C++ solution (slower):
#include<cstdio>

#include<cstring>

#include<algorithm>

#include<set>

#include<map>

#define MAXN 200000

using namespace std;

typedef pair<int,int> PII;

map<PII,int> mp;

int setfa[2][MAXN+5];

void Init()

{

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

		setfa[0][i]=setfa[1][i]=i;

}

int Findfa(int x,int typ)

{

	if(setfa[typ][x]==x)

		return x;

	return setfa[typ][x]=Findfa(setfa[typ][x],typ);

}

void Union(int x,int y,int typ)

{

	int fx=Findfa(x,typ),fy=Findfa(y,typ);

	if(fx==fy)

		return;

	setfa[typ][fx]=fy;

}

int main()

{

	Init();

	int N,K,L;

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

	int x,y;

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

	{

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

		Union(x,y,0);

	}

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

	{

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

		Union(x,y,1);

	}

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

	{

		int a=Findfa(i,0),b=Findfa(i,1);

		mp[PII(a,b)]++;

	}

	int Ans;

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

	{

		int a=Findfa(i,0),b=Findfa(i,1);

		Ans=mp[PII(a,b)];

		if(i==1)

			printf("%d",Ans);

		else

			printf(" %d",Ans);

	}

	printf("\n");

	return 0;

}

// Optimized solution to the same problem (faster):
#include <bits/stdc++.h>

using namespace std;

const int N=200000+10;

const int INF=10000000;

int p1[N],p2[N];

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 cha(int x,int y,int *p)

{

    int px=find(x,p);

    int py=find(y,p);

    if(px!=py)

    {

        p[px]=py;

    }

}

int main()

{

    int n,k,l;

    cin>>n>>k>>l;

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

        p1[i]=i,p2[i]=i;

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

    {

        int x,y;

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

        cha(x,y,p1);

    }

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

    {

        int x,y;

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

        cha(x,y,p2);

    }

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

    {

        find(i,p1);

        find(i,p2);

    }

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

        m[make_pair(p1[i],p2[i])]++;

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

        printf("%d ",m[make_pair(p1[i],p2[i])]);

    putchar('\n');

    return 0;

}

// Fastest known solution for this problem: