stablegradients/pie-gem5-pairs huggingface dataset:
// Slower C++ solution:
#include <bits/stdc++.h>

using namespace std;



long long f(long long a[],long long x)

{

    if(x==a[x]);

    else a[x]=f(a,a[x]);

    return a[x];

}

long long a[200010];

long long b[200010];

long long c[200010];

long long d[200010];

int e[200010];

int main()

{



    long long n,m,k;

    long long x,y,i;

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

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

    {

        a[i]=i;

        b[i]=i;

    }

    while(m--)

    {

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

        x=f(a,x);

        y=f(a,y);

        a[x]=y;

    }

    while(k--)

    {

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

        x=f(b,x);

        y=f(b,y);

        b[x]=y;

    }

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

    {

        c[i]=f(a,i)+(n+1)*f(b,i);

        d[i]=c[i];

    }

    sort(d+1,d+n+1);

    memset(e,0,sizeof(e));

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

    {

        y=lower_bound(d+1,d+n+1,c[i])-d;

        e[y]++;

    }

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

    {

        y=lower_bound(d+1,d+n+1,c[i])-d;

        if(i==n)printf("%d\n",e[y]);

        else printf("%d ",e[y]);

    }

    return 0;

}


// Faster C++ solution for the same problem (measured speedup: 1.776279207971851x):
#include<string>

#include<iostream>

#include<map>

using namespace std;

int head[200001],num_edge,n,l,p,fa[200001];

struct Edge

{

	int next,to;

}edge[200001];

int v[200001],ans[200001];

void add(int from,int to)

{

	edge[++num_edge].next=head[from];

	edge[num_edge].to=to;

	head[from]=num_edge;

}

int find(int x)

{

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

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

}

void get_together(int a,int b)

{

    fa[find(a)]=find(b);

}

void dfs1(int x,int tag,map<int,int>&num)

{

	if(v[x]==tag) return ;

	v[x]=tag;

	num[find(x)]++;

	for(int i=head[x];i;i=edge[i].next)

	  dfs1(edge[i].to,tag,num);

}

void dfs2(int x,int tag,map<int,int>&num)

{

	if(v[x]==tag) return ;

	v[x]=tag;

	ans[x]+=num[find(x)];

	for(int i=head[x];i;i=edge[i].next)

	  dfs2(edge[i].to,tag,num);

}

int main(){

	cin>>n>>p>>l;

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

	  fa[i]=i;

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

	{

		int a,b;

		cin>>a>>b;

		get_together(a,b);

	}

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

	{

		int a,b;

		cin>>a>>b;

		add(a,b);

		add(b,a);

	}

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

	  if(!v[i])

	  {

	  	map<int,int> num;

	  	dfs1(i,i,num);

	  	dfs2(i,-i,num);

	  }

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

	  cout<<ans[i]<<' ';

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

using namespace std;

#define INF 0x3f3f3f3f

#define maxn 212345

#define met(a, b) memset(a, b, sizeof(a))

class UMS

{

public:

    int f[maxn];

    UMS()

    {

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

        {

            f[i] = i;

        }

    }

    int getf(int u)

    {

        if(u == f[u])

            return f[u];

        else

        {

            f[u] = getf(f[u]);

            return f[u];

        }

    }

    void Merge(int u, int v)

    {

        int f1 = getf(u);

        int f2 = getf(v);

        if(f1 != f2)

        {

            f[f1] = f2;

        }

    }

};

vector<int> vec[maxn];

map<int, int> q;

int main()

{

    UMS u1, u2;

    int n, k, l, u, v;

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

    while(k--)

    {

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

        u1.Merge(u, v);

    }

    while(l--)

    {

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

        u2.Merge(u, v);

    }

    int vis[maxn];

    met(vis, 0);

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

    {

        int fa = u1.getf(i);

        vec[fa].push_back(i);

    }

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

    {

        q.clear();

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

        {

            q[u2.getf(vec[i][j])] ++;

        }

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

        {

            vis[vec[i][j]] += q[u2.getf(vec[i][j])];

        }



    }

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

    {

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

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

        else printf(" ");

    }

    return 0;

}


// Faster C++ solution for the same problem (measured speedup: 9.652436231091327x):
#include<string>

#include<iostream>

#include<map>

using namespace std;

int head[200001],num_edge,n,l,p,fa[200001];

struct Edge

{

	int next,to;

}edge[200001];

int v[200001],ans[200001];

void add(int from,int to)

{

	edge[++num_edge].next=head[from];

	edge[num_edge].to=to;

	head[from]=num_edge;

}

int find(int x)

{

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

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

}

void get_together(int a,int b)

{

    fa[find(a)]=find(b);

}

void dfs1(int x,int tag,map<int,int>&num)

{

	if(v[x]==tag) return ;

	v[x]=tag;

	num[find(x)]++;

	for(int i=head[x];i;i=edge[i].next)

	  dfs1(edge[i].to,tag,num);

}

void dfs2(int x,int tag,map<int,int>&num)

{

	if(v[x]==tag) return ;

	v[x]=tag;

	ans[x]+=num[find(x)];

	for(int i=head[x];i;i=edge[i].next)

	  dfs2(edge[i].to,tag,num);

}

int main(){

	cin>>n>>p>>l;

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

	  fa[i]=i;

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

	{

		int a,b;

		cin>>a>>b;

		get_together(a,b);

	}

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

	{

		int a,b;

		cin>>a>>b;

		add(a,b);

		add(b,a);

	}

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

	  if(!v[i])

	  {

	  	map<int,int> num;

	  	dfs1(i,i,num);

	  	dfs2(i,-i,num);

	  }

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

	  cout<<ans[i]<<' ';

}
// Slower C++ solution:
#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;

}


// Faster C++ solution for the same problem (measured speedup: 2.5808652798291147x):
#include<string>

#include<iostream>

#include<map>

using namespace std;

int head[200001],num_edge,n,l,p,fa[200001];

struct Edge

{

	int next,to;

}edge[200001];

int v[200001],ans[200001];

void add(int from,int to)

{

	edge[++num_edge].next=head[from];

	edge[num_edge].to=to;

	head[from]=num_edge;

}

int find(int x)

{

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

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

}

void get_together(int a,int b)

{

    fa[find(a)]=find(b);

}

void dfs1(int x,int tag,map<int,int>&num)

{

	if(v[x]==tag) return ;

	v[x]=tag;

	num[find(x)]++;

	for(int i=head[x];i;i=edge[i].next)

	  dfs1(edge[i].to,tag,num);

}

void dfs2(int x,int tag,map<int,int>&num)

{

	if(v[x]==tag) return ;

	v[x]=tag;

	ans[x]+=num[find(x)];

	for(int i=head[x];i;i=edge[i].next)

	  dfs2(edge[i].to,tag,num);

}

int main(){

	cin>>n>>p>>l;

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

	  fa[i]=i;

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

	{

		int a,b;

		cin>>a>>b;

		get_together(a,b);

	}

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

	{

		int a,b;

		cin>>a>>b;

		add(a,b);

		add(b,a);

	}

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

	  if(!v[i])

	  {

	  	map<int,int> num;

	  	dfs1(i,i,num);

	  	dfs2(i,-i,num);

	  }

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

	  cout<<ans[i]<<' ';

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

using namespace std;



long long f(long long a[],long long x)

{

    if(x==a[x]);

    else a[x]=f(a,a[x]);

    return a[x];

}

long long a[200010];

long long b[200010];

long long c[200010];

long long d[200010];

int e[200010];

int main()

{



    long long n,m,k;

    long long x,y,i;

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

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

    {

        a[i]=i;

        b[i]=i;

    }

    while(m--)

    {

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

        x=f(a,x);

        y=f(a,y);

        a[x]=y;

    }

    while(k--)

    {

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

        x=f(b,x);

        y=f(b,y);

        b[x]=y;

    }

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

    {

        c[i]=f(a,i)+(n+1)*f(b,i);

        d[i]=c[i];

    }

    sort(d+1,d+n+1);

    memset(e,0,sizeof(e));

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

    {

        y=lower_bound(d+1,d+n+1,c[i])-d;

        e[y]++;

    }

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

    {

        y=lower_bound(d+1,d+n+1,c[i])-d;

        if(i==n)printf("%d\n",e[y]);

        else printf("%d ",e[y]);

    }

    return 0;

}


// Faster C++ solution for the same problem (measured speedup: 1.7887447954996052x):
#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])]);

    return 0;

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

using namespace std;

#define INF 0x3f3f3f3f

#define maxn 212345

#define met(a, b) memset(a, b, sizeof(a))

class UMS

{

public:

    int f[maxn];

    UMS()

    {

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

        {

            f[i] = i;

        }

    }

    int getf(int u)

    {

        if(u == f[u])

            return f[u];

        else

        {

            f[u] = getf(f[u]);

            return f[u];

        }

    }

    void Merge(int u, int v)

    {

        int f1 = getf(u);

        int f2 = getf(v);

        if(f1 != f2)

        {

            f[f1] = f2;

        }

    }

};

vector<int> vec[maxn];

map<int, int> q;

int main()

{

    UMS u1, u2;

    int n, k, l, u, v;

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

    while(k--)

    {

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

        u1.Merge(u, v);

    }

    while(l--)

    {

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

        u2.Merge(u, v);

    }

    int vis[maxn];

    met(vis, 0);

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

    {

        int fa = u1.getf(i);

        vec[fa].push_back(i);

    }

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

    {

        q.clear();

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

        {

            q[u2.getf(vec[i][j])] ++;

        }

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

        {

            vis[vec[i][j]] += q[u2.getf(vec[i][j])];

        }



    }

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

    {

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

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

        else printf(" ");

    }

    return 0;

}


// Faster C++ solution for the same problem (measured speedup: 9.720175181226379x):
#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])]);

    return 0;

}
// Slower C++ solution:
#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;

}


// Faster C++ solution for the same problem (measured speedup: 2.5989772984231876x):
#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])]);

    return 0;

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

using namespace std;



long long f(long long a[],long long x)

{

    if(x==a[x]);

    else a[x]=f(a,a[x]);

    return a[x];

}

long long a[200010];

long long b[200010];

long long c[200010];

long long d[200010];

int e[200010];

int main()

{



    long long n,m,k;

    long long x,y,i;

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

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

    {

        a[i]=i;

        b[i]=i;

    }

    while(m--)

    {

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

        x=f(a,x);

        y=f(a,y);

        a[x]=y;

    }

    while(k--)

    {

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

        x=f(b,x);

        y=f(b,y);

        b[x]=y;

    }

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

    {

        c[i]=f(a,i)+(n+1)*f(b,i);

        d[i]=c[i];

    }

    sort(d+1,d+n+1);

    memset(e,0,sizeof(e));

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

    {

        y=lower_bound(d+1,d+n+1,c[i])-d;

        e[y]++;

    }

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

    {

        y=lower_bound(d+1,d+n+1,c[i])-d;

        if(i==n)printf("%d\n",e[y]);

        else printf("%d ",e[y]);

    }

    return 0;

}


// Faster C++ solution for the same problem (measured speedup: 1.9325349620267744x):
#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;

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

using namespace std;

#define INF 0x3f3f3f3f

#define maxn 212345

#define met(a, b) memset(a, b, sizeof(a))

class UMS

{

public:

    int f[maxn];

    UMS()

    {

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

        {

            f[i] = i;

        }

    }

    int getf(int u)

    {

        if(u == f[u])

            return f[u];

        else

        {

            f[u] = getf(f[u]);

            return f[u];

        }

    }

    void Merge(int u, int v)

    {

        int f1 = getf(u);

        int f2 = getf(v);

        if(f1 != f2)

        {

            f[f1] = f2;

        }

    }

};

vector<int> vec[maxn];

map<int, int> q;

int main()

{

    UMS u1, u2;

    int n, k, l, u, v;

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

    while(k--)

    {

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

        u1.Merge(u, v);

    }

    while(l--)

    {

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

        u2.Merge(u, v);

    }

    int vis[maxn];

    met(vis, 0);

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

    {

        int fa = u1.getf(i);

        vec[fa].push_back(i);

    }

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

    {

        q.clear();

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

        {

            q[u2.getf(vec[i][j])] ++;

        }

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

        {

            vis[vec[i][j]] += q[u2.getf(vec[i][j])];

        }



    }

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

    {

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

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

        else printf(" ");

    }

    return 0;

}


// Faster C++ solution for the same problem (measured speedup: 10.50154187562474x):
#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;

}
// Slower C++ solution:
#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;

}


// Faster C++ solution for the same problem (measured speedup: 2.807898872635916x):
#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;

}