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

 

using namespace std;

 

typedef long long ll;

 

const int MAXN = 2e5+7;

const int Inf = 0x3f3f3f3f;

 

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++)

    {

        //cout<<pre1[i]<<" | "<<pre2[i]<<endl;

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

using namespace std;

int par1[200001],par2[200001];

vector<pair<int,int>> idx;

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

int rep1(int n)

{

    if(par1[n]==n)

        return n;

    return par1[n]=rep1(par1[n]);

}

int rep2(int n)

{

    if(par2[n]==n)

        return n;

    return par2[n]=rep2(par2[n]);

}

int main()

{

    int i,j;

    int n,k,l;

    int a,b,res=0;

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

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

        par1[i]=i;

        par2[i]=i;

    }

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

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

        swap(a,b);

        int r1=rep1(a);

        int r2=rep1(b);

        par1[r1]=r2;

    }

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

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

        int r1=rep2(a);

        int r2=rep2(b);

        par2[r2]=r1;

    }

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



        idx.push_back(make_pair(rep1(i),rep2(i)));

    }



    for(i=0;i<idx.size();i++){

            //assert(idx[i].first == idx[i].second);

        cnt[idx[i]]++;

       // printf("%d %d\n",idx[i].first,idx[i].second);

    }

    for(i=0;i<idx.size();i++)

        printf("%d ",cnt[idx[i]]);

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

using namespace std;

int par1[200001],par2[200001];

vector<pair<int,int>> idx;

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

int rep1(int n)

{

    if(par1[n]==n)

        return n;

    return par1[n]=rep1(par1[n]);

}

int rep2(int n)

{

    if(par2[n]==n)

        return n;

    return par2[n]=rep2(par2[n]);

}

int main()

{

    int i,j;

    int n,k,l;

    int a,b,res=0;

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

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

        par1[i]=i;

        par2[i]=i;

    }

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

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



        int r1=rep1(a);

        int r2=rep1(b);

        par1[r1]=r2;

    }

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

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

        int r1=rep2(a);

        int r2=rep2(b);

        par2[r2]=r1;

    }

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



        idx.push_back(make_pair(rep1(i),rep2(i)));

    }



    for(i=0;i<idx.size();i++){

            //assert(idx[i].first == idx[i].second);

        cnt[idx[i]]++;

       // printf("%d %d\n",idx[i].first,idx[i].second);

    }

    for(i=0;i<idx.size();i++)

        printf("%d ",cnt[idx[i]]);

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

#define f first

#define s second

using namespace std;



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

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



int root (int ind) {

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

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

}



void onion(int l, int r) {

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

}



int root2(int ind) {

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

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

}



void onion2(int l, int r) {

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

}



int main() {

	cin >> x >> y >> z;

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

		rail[i] = i;

		road[i] = i;

	}

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

		cin >> n >> m;

		onion(n,m);

	}

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

		cin >> n >> m;

		onion2(n,m);

	}

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

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

	}

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

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

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

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

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

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

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

			int tmp = st.size();

			while (!st.empty()) {

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

				st.pop(); 

			}

		} 

		b1 = a1, b2 = a2;

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

	}

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

		cout << connect[i]+1 << " ";

	}

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

#include <string.h>

#include <stdio.h>

#include <queue>

#include <vector>

#include <map>

#include <algorithm>

using namespace std;

const int Max=3e5+100;

int get_root(int *f, int root){

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

}

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

    int i=get_root(f, x);

    int j=get_root(f, y);

    f[i]=j;

}

int f[Max], g[Max];

void init(int n){

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

}

int vis[Max], num[Max];

vector<int> vec[Max];

map<int, int>ma;

int main(){

    int n, m, k, u, v;

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

    init(n);

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

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

        merge(f, u, v);

    }

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

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

        merge(g, u, v);

    }

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

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

        ma.clear();

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

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

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

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

        }

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

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

        }

    }

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

    return  0;

}

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

using namespace std;

typedef long long ll;

struct hi{

	ll a;int b;

} cnt[200005];

int id[200005],id2[200005],p[200005]

,n,k,l,i,j,m;



int find(int x){

	while (x!=id[x]){

		id[x]=id[id[x]];

		x=id[x];

	}

	return x;

}



int find2(int x){

	while (x!=id2[x]){

		id2[x]=id2[id2[x]];

		x=id2[x];

	}

	return x;

}



void connect(int x,int y){

	x=find(x);y=find(y);

	if (x!=y) id[x]=y;

}



void connect2(int x,int y){

	x=find2(x);y=find2(y);

	if (x!=y) id2[x]=y;

}



bool cmp(hi a,hi b){

	return a.a<b.a;

}



int main(){

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

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

		id[i]=i;id2[i]=i;

	}

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

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

		connect(j,m);

	}

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

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

		connect2(j,m);

	}

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

		id[i]=find(id[i]);id2[i]=find2(id2[i]);

		cnt[i].a=ll(id[i])*200001+ll(id2[i]);cnt[i].b=i;

	}

	sort(cnt+1,cnt+n+1,cmp);

	j=0;k=0;

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

		if (cnt[i].a!=cnt[i-1].a) j++;

		p[j]++;

		id[cnt[i].b]=j;

	}

	for (i=1;i<n;i++) printf("%d ",p[id[i]]);

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

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

#include <string.h>

#include <stdio.h>

#include <queue>

#include <vector>

#include <map>

#include <algorithm>

using namespace std;

const int Max=3e5+100;

int get_root(int *f, int root){

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

}

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

    int i=get_root(f, x);

    int j=get_root(f, y);

    f[i]=j;

}

int f[Max], g[Max];

void init(int n){

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

}

int vis[Max], num[Max];

vector<int> vec[Max];

map<int, int>ma;

int main(){

    int n, m, k, u, v;

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

    init(n);

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

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

        merge(f, u, v);

    }

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

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

        merge(g, u, v);

    }

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

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

        ma.clear();

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

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

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

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

        }

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

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

        }

    }

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

    return  0;

}

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

using namespace std;



typedef long long ll;

typedef pair<int, int> pii;

typedef pair<int, pii> pipii;

typedef pair<pii, int> piipi;

typedef pair<pii, pii> piipii;



#define mp make_pair

#define fi first

#define se second

#define all(a) (a).begin(), (a).end()

#define sz(a) (int)(a).size()

#define eb emplace_back



struct p{

    int p[200005];

    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) p[a] = b;

    }

}p1,p2;



map<pii, int> dp;

int main(){

    int n, k, l;

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

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

        p1.p[i] = i;

        p2.p[i] = i;

    }

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

        int p, q;

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

        p1.merge(p, q);

    }

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

        int p, q;

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

        p2.merge(p, q);

    }

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

        int r1 = p1.root(i);

        int r2 = p2.root(i);

        dp[mp(r1, r2)]++;

    }

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

        int r1 = p1.root(i);

        int r2 = p2.root(i);

        printf("%lld ", dp[mp(r1, r2)]);

    }

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

using namespace std;

#define ll long long

#define ull unsigned long long

#define pb push_back

const int maxn=2e5+10;

const int mod=998244353;

int f1[maxn];

int f2[maxn];



int find1(int x)

{

    if(f1[x]==x)

        return x;

    return f1[x]=find1(f1[x]);

}

int find2(int x)

{

    if(f2[x]==x)

        return x;

    return f2[x]=find2(f2[x]);

}



void add1(int x,int y)

{

    int t1=find1(x),t2=find1(y);

    f1[t1]=t2;

}

void add2(int x,int y)

{

    int t1=find2(x),t2=find2(y);

    f2[t1]=t2;

}



int main()

{

    ios::sync_with_stdio(false);

    cin.tie(0);

    int n,k,l;

    cin>>n>>k>>l;

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

        f1[i]=f2[i]=i;

    while(k--)

    {

        int p,q;

        cin>>p>>q;

        add1(p,q);

    }

    while(l--)

    {

        int r,s;

        cin>>r>>s;

        add2(r,s);

    }

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

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

    {

        mp[{find1(i),find2(i)}]++;

    }

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

    {

        cout<<mp[{f1[i],f2[i]}]<<" ";

    }





}
// 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.425061261137587x):
// ====================================

//   author: M_sea

//   website: https://m-sea-blog.com/

// ====================================

#include <bits/stdc++.h>

#define file(x) freopen(#x".in","r",stdin); freopen(#x".out","w",stdout)

#define debug(...) fprintf(stderr,__VA_ARGS__)

#define mp make_pair

using namespace std;

typedef long long ll;



int read() {

	int X=0,w=1; char c=getchar();

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

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

	return X*w;

}



const int N=200000+10;



int n,k,l;

struct DSU {

	int f[N];

	int find(int x) { return x==f[x]?x:f[x]=find(f[x]); }

	void merge(int x,int y) {

		x=find(x),y=find(y);

		if (x!=y) f[x]=y;

	}

} A,B;

map<pair<int,int>,int> M;



int main() {

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

	for (int i=1;i<=n;++i) A.f[i]=B.f[i]=i;

	for (int i=1;i<=k;++i) A.merge(read(),read());

	for (int i=1;i<=l;++i) B.merge(read(),read());

	for (int i=1;i<=n;++i) ++M[mp(A.find(i),B.find(i))];

	for (int i=1;i<=n;++i) printf("%d ",M[mp(A.find(i),B.find(i))]);

	return 0;

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

using namespace std;

#define ll long long

#define ull unsigned long long

#define pb push_back

const int maxn=2e5+10;

const int mod=998244353;

int f1[maxn];

int f2[maxn];



int find1(int x)

{

    if(f1[x]==x)

        return x;

    return f1[x]=find1(f1[x]);

}

int find2(int x)

{

    if(f2[x]==x)

        return x;

    return f2[x]=find2(f2[x]);

}



void add1(int x,int y)

{

    int t1=find1(x),t2=find1(y);

    f1[t1]=t2;

}

void add2(int x,int y)

{

    int t1=find2(x),t2=find2(y);

    f2[t1]=t2;

}



int main()

{

    ios::sync_with_stdio(false);

    cin.tie(0);

    int n,k,l;

    cin>>n>>k>>l;

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

        f1[i]=f2[i]=i;

    while(k--)

    {

        int p,q;

        cin>>p>>q;

        add1(p,q);

    }

    while(l--)

    {

        int r,s;

        cin>>r>>s;

        add2(r,s);

    }

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

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

    {

        mp[{find1(i),find2(i)}]++;

    }

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

    {

        cout<<mp[{f1[i],f2[i]}]<<" ";

    }





}


// Faster C++ solution for the same problem (measured speedup: 2.640789806678568x):
// ====================================

//   author: M_sea

//   website: https://m-sea-blog.com/

// ====================================

#include <bits/stdc++.h>

#define file(x) freopen(#x".in","r",stdin); freopen(#x".out","w",stdout)

#define debug(...) fprintf(stderr,__VA_ARGS__)

#define mp make_pair

using namespace std;

typedef long long ll;



int read() {

	int X=0,w=1; char c=getchar();

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

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

	return X*w;

}



const int N=200000+10;



int n,k,l;

struct DSU {

	int f[N];

	int find(int x) { return x==f[x]?x:f[x]=find(f[x]); }

	void merge(int x,int y) {

		x=find(x),y=find(y);

		if (x!=y) f[x]=y;

	}

} A,B;

map<pair<int,int>,int> M;



int main() {

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

	for (int i=1;i<=n;++i) A.f[i]=B.f[i]=i;

	for (int i=1;i<=k;++i) A.merge(read(),read());

	for (int i=1;i<=l;++i) B.merge(read(),read());

	for (int i=1;i<=n;++i) ++M[mp(A.find(i),B.find(i))];

	for (int i=1;i<=n;++i) printf("%d ",M[mp(A.find(i),B.find(i))]);

	return 0;

}