stablegradients/pie-gem5-pairs huggingface dataset:
// Slower C++ solution:
#include <cstdio>

#include <map>

#include <vector>

using namespace std;



const int N = 2e5 + 5;

int pa1[N], pa2[N];

int find(int* p, int v) { return v == p[v] ? v : p[v] = find(p, p[v]); }

void unite(int* p, int a, int b) { p[find(p, b)] = find(p, a); }



typedef long long LL;

int n, k, l;

// vector<int> e1[N], e2[N];



map<LL, int> mp;



int main() {

#ifdef D

    freopen("a.in", "r", stdin);

#endif

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

        pa1[i] = pa2[i] = i;

    }

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

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

        int a, b;

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

        unite(pa1, a, b);

        // e1[a].push_back(b);

        // e1[b].push_back(a);

    }

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

        int a, b;

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

        unite(pa2, a, b);

        // e2[a].push_back(b);

        // e2[b].push_back(a);

    }



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

        mp[find(pa1, i) * (LL)(n + 1) + find(pa2, i)] += 1;

    }



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

        printf("%d ", mp[find(pa1, i) * (LL)(n + 1) + find(pa2, i)]);

    }

    puts("");



    return 0;

}


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

#include<iostream>

#include<algorithm>

#include<cstdio>

#include<cstdlib>

#include<cmath> 

#include<cstring> 

#include<cassert>

#include<string>

#include<sstream>

#include<fstream>

#include<deque>

#include<queue>

#include<vector>

#include<map>

#include<list>

#include<stack>

#include<set>

#include<bitset>

#include<iomanip>

#include<utility>

#include<functional>

#include<cctype>

#include<cerrno>

#include<cfloat>

#include<ciso646>

#include<climits>

#include<clocale>

#include<complex>

#include<csetjmp>

#include<csignal>

#include<cstdarg>

#include<cstddef>

#include<cwchar>

#include<cwctype>

#include<exception>

#include<locale>

#include<numeric>

#include<new>

#include<stdexcept>

#include<limits>

using namespace std;



#define ll long long

#define INF 1e9

#define rep(i,n) for(int (i)=0;(i)<n;i++)

#define REP(i,n) for(int (i)=1;(i)<=n;i++)

#define mk(a,b) make_pair(a,b)

#define fi first

#define se second

#define pii pair<int,int>

#define sz(s) s.size()

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



const int maxn=200005;

int n,k,l;

int f1[maxn],f2[maxn],ans[maxn];

map<pii,vector<int> >mp;





int Find(int f[],int x){

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

}



void Union(int f[],int x,int y){

	x=Find(f,x);y=Find(f,y);

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

}



int main(){

	ios::sync_with_stdio(false);

	cin>>n>>k>>l;

	REP(i,n)f1[i]=f2[i]=i;

	while(k--){

		int u,v;

		cin>>u>>v;

		Union(f1,u,v);

	}

	while(l--){

		int u,v;

		cin>>u>>v;

		Union(f2,u,v);

	}

	REP(i,n)mp[mk(Find(f1,i),Find(f2,i))].push_back(i);

	for(map<pii,vector<int> >::iterator it=mp.begin();it!=mp.end();it++){

		rep(j,it->se.size())ans[it->se[j]]=it->se.size();

	}

	REP(i,n)cout<<ans[i]<<" ";

	return 0;

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

#include <cstring>

#include <algorithm>

#include <vector>

#define ll long long

using namespace std;



const int maxn = 200010;

int n, m1, m2, u, v;

int f1[maxn], f2[maxn], vis[maxn], cnt[maxn], res[maxn];

vector <int> G[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]);

}



int main () {

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

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

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

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

        f1[Find1(u)] = Find1(v);

	}

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

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

        f2[Find2(u)] = Find2(v);

	}

    for (int i = 1; i <= n; i++) G[Find1(i)].push_back(i);

    for (int i = 1; i <= n; i++) if(G[i].size()) {

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

            int t = Find2(G[i][j]);

            if (vis[t] != i) {

                vis[t] = i;

                cnt[t] = 0;

            }

            cnt[t]++;

        }

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

            int t = Find2(G[i][j]);

            res[G[i][j]] = cnt[t];

        }

    }

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

	return 0;

}


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

#include<iostream>

#include<algorithm>

#include<cstdio>

#include<cstdlib>

#include<cmath> 

#include<cstring> 

#include<cassert>

#include<string>

#include<sstream>

#include<fstream>

#include<deque>

#include<queue>

#include<vector>

#include<map>

#include<list>

#include<stack>

#include<set>

#include<bitset>

#include<iomanip>

#include<utility>

#include<functional>

#include<cctype>

#include<cerrno>

#include<cfloat>

#include<ciso646>

#include<climits>

#include<clocale>

#include<complex>

#include<csetjmp>

#include<csignal>

#include<cstdarg>

#include<cstddef>

#include<cwchar>

#include<cwctype>

#include<exception>

#include<locale>

#include<numeric>

#include<new>

#include<stdexcept>

#include<limits>

using namespace std;



#define ll long long

#define INF 1e9

#define rep(i,n) for(int (i)=0;(i)<n;i++)

#define REP(i,n) for(int (i)=1;(i)<=n;i++)

#define mk(a,b) make_pair(a,b)

#define fi first

#define se second

#define pii pair<int,int>

#define sz(s) s.size()

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



const int maxn=200005;

int n,k,l;

int f1[maxn],f2[maxn],ans[maxn];

map<pii,vector<int> >mp;





int Find(int f[],int x){

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

}



void Union(int f[],int x,int y){

	x=Find(f,x);y=Find(f,y);

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

}



int main(){

	ios::sync_with_stdio(false);

	cin>>n>>k>>l;

	REP(i,n)f1[i]=f2[i]=i;

	while(k--){

		int u,v;

		cin>>u>>v;

		Union(f1,u,v);

	}

	while(l--){

		int u,v;

		cin>>u>>v;

		Union(f2,u,v);

	}

	REP(i,n)mp[mk(Find(f1,i),Find(f2,i))].push_back(i);

	for(map<pii,vector<int> >::iterator it=mp.begin();it!=mp.end();it++){

		rep(j,it->se.size())ans[it->se[j]]=it->se.size();

	}

	REP(i,n)cout<<ans[i]<<" ";

	return 0;

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

using namespace std;



const int maxn = 200010;



int fa1[maxn], fa2[maxn], r1[maxn], r2[maxn];



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



void kexin_init() {

	for (int i=1; i<=maxn; ++i) {fa1[i] = i; fa2[i] = i;}

	memset(r1, 0, sizeof r1);

	memset(r2, 0, sizeof r2);

}



int kexin_find_road(int x) {

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

	return fa1[x] = kexin_find_road(fa1[x]);

}

void kexin_Union_road(int x, int y) {

	x = kexin_find_road(x);

	y = kexin_find_road(y);

	if (x == y) return ;

	if (r1[x] < r1[y]) swap(x, y);

	fa1[y] = x;

	if (r1[x] == r1[y]) r1[x]++;

}



int kexin_find_railway(int x) {

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

	return fa2[x] = kexin_find_railway(fa2[x]);

}

void kexin_Union_railway(int x, int y) {

	x = kexin_find_railway(x);

	y = kexin_find_railway(y);

	if (x == y) return ;

	if (r2[x] < r2[y]) swap(x, y);

	fa2[y] = x;

	if (r2[x] == r2[y]) r2[x]++;

}

int main() {

	int n, k, l;

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

	

	kexin_init();

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

		int x, y;

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

		kexin_Union_road(x, y);

	}

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

		int x, y;

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

		kexin_Union_railway(x, y);

	}

	

	mp.clear();



	for (int i=1; i<=n; ++i) mp[make_pair(kexin_find_road(i), kexin_find_railway(i))]++;

	for (int i=1; i<n; ++i) printf("%d ", mp[make_pair(kexin_find_road(i), kexin_find_railway(i))]);

	printf("%d\n", mp[make_pair(kexin_find_road(n), kexin_find_railway(n))]);



	return 0;

}

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

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

#define rep(i,a,b) for (int i=(a); i<(b); i++)

#define per(i,a,b) for (int i=(b-1); i>=(a); i--)

#define debug(x) cout << #x << " => " << x << endl

using namespace std;



#define fi first

#define se second

#define mp make_pair

typedef pair<int,int> pii;



#define pb push_back

typedef vector<int> vi;



typedef long long ll;

typedef long double ld;



const int MAX_N = 7 + 200000;

///----------------------------------------------

struct UF {

	static const int UF_N = MAX_N;

	int far[UF_N];

	void init() { rep(i,0,UF_N) far[i]=i; }

	int getf(int d) { return far[d]==d ? d : far[d]=getf(far[d]); }

	bool same(int a,int b) { return getf(a)==getf(b); }

	void comb(int a,int b) {

		if (same(a=getf(a),b=getf(b))) return;

		far[a]=b;

	}

}	uf1,uf2;

int main() {

	

	///read

	int n,m1,m2; cin>>n>>m1>>m2;

	

	///prework

	uf1.init();

	rep(i,0,m1) {

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

		uf1.comb(a,b);

	}

	uf2.init();

	rep(i,0,m2) {

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

		uf2.comb(a,b);

	}

	map<pii,int> M;

	rep(i,1,n+1) M[mp(uf1.getf(i),uf2.getf(i))]++;

	

	///work

	rep(i,1,n+1) {

		printf("%d ",M[mp(uf1.getf(i),uf2.getf(i))]);

	}





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

#include<algorithm>

#include<iostream>

#include<cstring>

#include<vector>

#include<cmath>

#include<map>

#include<set>

#include<queue>

using namespace std;

typedef long long ll;

const int N=2e5+10;

int a[N],b[N];

vector<int>v[N];

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

queue<int>q;

int main()

{

    int n,k,l,i,j;

    cin>>n>>k>>l;

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

    {

        int x,y;

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

        v[x].push_back(y);

        v[y].push_back(x);

    }

    int cnt=0;

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

    if(a[i]==0)

    {

        a[i]=++cnt;

        q.push(i);

        while(!q.empty())

        {

            int x=q.front();

            for(j=0;j<v[x].size();j++)

            if(a[v[x][j]]==0)

            {

                a[v[x][j]]=cnt;

                q.push(v[x][j]);

            }

            q.pop();

        }

    }

    for(i=1;i<=n;i++)v[i].clear();

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

    {

        int x,y;

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

        v[x].push_back(y);

        v[y].push_back(x);

    }

    cnt=0;

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

    if(b[i]==0)

    {

        b[i]=++cnt;

        q.push(i);

        while(!q.empty())

        {

            int x=q.front();

            for(j=0;j<v[x].size();j++)

            if(b[v[x][j]]==0)

            {

                b[v[x][j]]=cnt;

                q.push(v[x][j]);

            }

            q.pop();

        }

    }

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

        mp[make_pair(a[i],b[i])]++;

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

        printf("%d ",mp[make_pair(a[i],b[i])]);

	return 0;

}


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

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

#define rep(i,a,b) for (int i=(a); i<(b); i++)

#define per(i,a,b) for (int i=(b-1); i>=(a); i--)

#define debug(x) cout << #x << " => " << x << endl

using namespace std;



#define fi first

#define se second

#define mp make_pair

typedef pair<int,int> pii;



#define pb push_back

typedef vector<int> vi;



typedef long long ll;

typedef long double ld;



const int MAX_N = 7 + 200000;

///----------------------------------------------

struct UF {

	static const int UF_N = MAX_N;

	int far[UF_N];

	void init() { rep(i,0,UF_N) far[i]=i; }

	int getf(int d) { return far[d]==d ? d : far[d]=getf(far[d]); }

	bool same(int a,int b) { return getf(a)==getf(b); }

	void comb(int a,int b) {

		if (same(a=getf(a),b=getf(b))) return;

		far[a]=b;

	}

}	uf1,uf2;

int main() {

	

	///read

	int n,m1,m2; cin>>n>>m1>>m2;

	

	///prework

	uf1.init();

	rep(i,0,m1) {

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

		uf1.comb(a,b);

	}

	uf2.init();

	rep(i,0,m2) {

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

		uf2.comb(a,b);

	}

	map<pii,int> M;

	rep(i,1,n+1) M[mp(uf1.getf(i),uf2.getf(i))]++;

	

	///work

	rep(i,1,n+1) {

		printf("%d ",M[mp(uf1.getf(i),uf2.getf(i))]);

	}





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

#include <cstring>

#include <algorithm>

#include <vector>

#define ll long long

using namespace std;



const int maxn = 200010;

int n, m1, m2, u, v;

int f1[maxn], f2[maxn], vis[maxn], cnt[maxn], res[maxn];

vector <int> G[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]);

}



int main () {

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

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

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

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

        f1[Find1(u)] = Find1(v);

	}

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

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

        f2[Find2(u)] = Find2(v);

	}

    for (int i = 1; i <= n; i++) G[Find1(i)].push_back(i);

    for (int i = 1; i <= n; i++) if(G[i].size()) {

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

            int t = Find2(G[i][j]);

            if (vis[t] != i) {

                vis[t] = i;

                cnt[t] = 0;

            }

            cnt[t]++;

        }

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

            int t = Find2(G[i][j]);

            res[G[i][j]] = cnt[t];

        }

    }

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

	return 0;

}


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

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

#define rep(i,a,b) for (int i=(a); i<(b); i++)

#define per(i,a,b) for (int i=(b-1); i>=(a); i--)

#define debug(x) cout << #x << " => " << x << endl

using namespace std;



#define fi first

#define se second

#define mp make_pair

typedef pair<int,int> pii;



#define pb push_back

typedef vector<int> vi;



typedef long long ll;

typedef long double ld;



const int MAX_N = 7 + 200000;

///----------------------------------------------

struct UF {

	static const int UF_N = MAX_N;

	int far[UF_N];

	void init() { rep(i,0,UF_N) far[i]=i; }

	int getf(int d) { return far[d]==d ? d : far[d]=getf(far[d]); }

	bool same(int a,int b) { return getf(a)==getf(b); }

	void comb(int a,int b) {

		if (same(a=getf(a),b=getf(b))) return;

		far[a]=b;

	}

}	uf1,uf2;

int main() {

	

	///read

	int n,m1,m2; cin>>n>>m1>>m2;

	

	///prework

	uf1.init();

	rep(i,0,m1) {

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

		uf1.comb(a,b);

	}

	uf2.init();

	rep(i,0,m2) {

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

		uf2.comb(a,b);

	}

	map<pii,int> M;

	rep(i,1,n+1) M[mp(uf1.getf(i),uf2.getf(i))]++;

	

	///work

	rep(i,1,n+1) {

		printf("%d ",M[mp(uf1.getf(i),uf2.getf(i))]);

	}





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

using namespace std;



const int N = 2e5+10;

int fa1[N],fa2[N];

int findroot1(int u)

{

    return fa1[u]==u?u:fa1[u]=findroot1(fa1[u]);

}

int findroot2(int u)

{

    return fa2[u]==u?u:fa2[u]=findroot2(fa2[u]);

}

set<int>s2[N];

int ans[N];

int main()

{

    int n,k,l;

    int u,v;

    // freopen("in.txt","r",stdin);

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

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

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

    {

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

        int uu=findroot1(u);

        int vv=findroot1(v);

        if(uu==vv) continue;

        else fa1[vv]=uu;

    }

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

    {

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

        int uu=findroot2(u);

        int vv=findroot2(v);

        if(uu==vv) continue;

        else fa2[vv]=uu;

    }

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

    {

        v=findroot2(i);

        s2[v].insert(i);

    }

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

    {

        if(!s2[i].empty())

        {

            map<int,int>mp;

            for(auto it:s2[i])

            {

                int uu=findroot1(it);

                mp[uu]++;

            }

            for(auto it:s2[i])

            {

                int uu=findroot1(it);

                ans[it]=mp[uu];

            }

        }

    }

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

    {

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

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

        else printf("\n");

    }

    return 0;

}


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

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

#define rep(i,a,b) for (int i=(a); i<(b); i++)

#define per(i,a,b) for (int i=(b-1); i>=(a); i--)

#define debug(x) cout << #x << " => " << x << endl

using namespace std;



#define fi first

#define se second

#define mp make_pair

typedef pair<int,int> pii;



#define pb push_back

typedef vector<int> vi;



typedef long long ll;

typedef long double ld;



const int MAX_N = 7 + 200000;

///----------------------------------------------

struct UF {

	static const int UF_N = MAX_N;

	int far[UF_N];

	void init() { rep(i,0,UF_N) far[i]=i; }

	int getf(int d) { return far[d]==d ? d : far[d]=getf(far[d]); }

	bool same(int a,int b) { return getf(a)==getf(b); }

	void comb(int a,int b) {

		if (same(a=getf(a),b=getf(b))) return;

		far[a]=b;

	}

}	uf1,uf2;

int main() {

	

	///read

	int n,m1,m2; cin>>n>>m1>>m2;

	

	///prework

	uf1.init();

	rep(i,0,m1) {

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

		uf1.comb(a,b);

	}

	uf2.init();

	rep(i,0,m2) {

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

		uf2.comb(a,b);

	}

	map<pii,int> M;

	rep(i,1,n+1) M[mp(uf1.getf(i),uf2.getf(i))]++;

	

	///work

	rep(i,1,n+1) {

		printf("%d ",M[mp(uf1.getf(i),uf2.getf(i))]);

	}





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

using namespace std;



#define X first

#define Y second

#define LL long long

#define ULL unsigned long long

#define PB push_back

#define MP make_pair

#define VI vector<int>

#define PII pair<int,int>

#define IOS ios::sync_with_stdio(0);cin.tie(0);

#define IN freopen("in", "r", stdin);

#define OUT freopen("out", "w", stdout);



const int maxn=200010;



int fa1[maxn],fa2[maxn];

int ans[maxn];

VI v[maxn];



int find1(int x)

{

	if (fa1[x]!=x) fa1[x]=find1(fa1[x]);

	return fa1[x];

}



int find2(int x)

{

	if (fa2[x]!=x) fa2[x]=find2(fa2[x]);

	return fa2[x];

}



bool cmp(int a,int b)

{

	return find1(a)<find1(b);

}



int main()

{

	IOS;

	int n,m1,m2;

	cin>>n>>m1>>m2;

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

	{

		fa1[j]=j;

		fa2[j]=j;

	}

	for (int j=1;j<=m1;++j)

	{

		int x,y;

		cin>>x>>y;

		int fx=find1(x);

		int fy=find1(y);

		if (fx!=fy) fa1[fx]=fy;

	}

	for (int j=1;j<=m2;++j)

	{

		int x,y;

		cin>>x>>y;

		int fx=find2(x);

		int fy=find2(y);

		if (fx!=fy) fa2[fx]=fy;

	}

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

	{

		int fj=find2(j);

		v[fj].PB(j);

	}

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

	{

		if (find2(j)!=j) continue;

		sort(v[j].begin(),v[j].end(),cmp);

		for (int k=0;k<v[j].size();++k)

		{

			int p=k;

			while (p<v[j].size()-1&&find1(v[j][p+1])==find1(v[j][k])) ++p;

			int add=p-k+1;

			for (int l=k;l<=p;++l)

				ans[v[j][l]]+=add;

			k=p;

		}

	}

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

		cout<<ans[j]<<" ";

	cout<<endl;

	return 0;

}


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

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

#define rep(i,a,b) for (int i=(a); i<(b); i++)

#define per(i,a,b) for (int i=(b-1); i>=(a); i--)

#define debug(x) cout << #x << " => " << x << endl

using namespace std;



#define fi first

#define se second

#define mp make_pair

typedef pair<int,int> pii;



#define pb push_back

typedef vector<int> vi;



typedef long long ll;

typedef long double ld;



const int MAX_N = 7 + 200000;

///----------------------------------------------

struct UF {

	static const int UF_N = MAX_N;

	int far[UF_N];

	void init() { rep(i,0,UF_N) far[i]=i; }

	int getf(int d) { return far[d]==d ? d : far[d]=getf(far[d]); }

	bool same(int a,int b) { return getf(a)==getf(b); }

	void comb(int a,int b) {

		if (same(a=getf(a),b=getf(b))) return;

		far[a]=b;

	}

}	uf1,uf2;

int main() {

	

	///read

	int n,m1,m2; cin>>n>>m1>>m2;

	

	///prework

	uf1.init();

	rep(i,0,m1) {

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

		uf1.comb(a,b);

	}

	uf2.init();

	rep(i,0,m2) {

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

		uf2.comb(a,b);

	}

	map<pii,int> M;

	rep(i,1,n+1) M[mp(uf1.getf(i),uf2.getf(i))]++;

	

	///work

	rep(i,1,n+1) {

		printf("%d ",M[mp(uf1.getf(i),uf2.getf(i))]);

	}





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

#include <string.h>

#include <iostream>

#include <algorithm>

#include <queue>

#include <vector>

#include <string>

#include <set>

#include <map>

#define ll long long

#define ull unsigned long long

#define rep(i, to) for(int i = 0; i < (to); ++i)

#define rep1(i, to) for(int i = 1; i <= (to); ++i)

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

using namespace std;

const int N = 200005;

int pa1[N], pa2[N];

int fpa1(int x){ return pa1[x] == x ? x : pa1[x] = fpa1(pa1[x]); }

int fpa2(int x){ return pa2[x] == x ? x : pa2[x] = fpa2(pa2[x]); }

void lnk1(int x, int y) {x = fpa1(x), y = fpa1(y); if(x != y) pa1[x] = y;}

void lnk2(int x, int y) {x = fpa2(x), y = fpa2(y); if(x != y) pa2[x] = y;}

int ans[N];

vector<int> v[N];

int main()

{

#ifdef LOCAL

    freopen("in", "r", stdin);

#endif

//    ios::sync_with_stdio(0);

    int n, k, l, a, b;

    while(scanf("%d%d%d", &n, &k, &l) > 0)

    {

        ms(ans, 0);

        rep1(i, n) pa1[i] = pa2[i] = i, v[i].clear();

        rep1(i, k)

        {

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

            lnk1(a, b);

        }

        rep1(i, l)

        {

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

            lnk2(a, b);

        }

        rep1(i, n) v[fpa1(i)].push_back(i);

        rep1(i, n)

        {

            if(v[i].size())

            {

                map<int, int> mp;

                rep(j, (int)v[i].size()) mp[fpa2(v[i][j])]++;

                rep(j, (int)v[i].size())

                {

                    ans[v[i][j]] = mp[fpa2(v[i][j])];

                }

            }

        }

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

        puts("");

    }

    return 0;

}


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

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

#define rep(i,a,b) for (int i=(a); i<(b); i++)

#define per(i,a,b) for (int i=(b-1); i>=(a); i--)

#define debug(x) cout << #x << " => " << x << endl

using namespace std;



#define fi first

#define se second

#define mp make_pair

typedef pair<int,int> pii;



#define pb push_back

typedef vector<int> vi;



typedef long long ll;

typedef long double ld;



const int MAX_N = 7 + 200000;

///----------------------------------------------

struct UF {

	static const int UF_N = MAX_N;

	int far[UF_N];

	void init() { rep(i,0,UF_N) far[i]=i; }

	int getf(int d) { return far[d]==d ? d : far[d]=getf(far[d]); }

	bool same(int a,int b) { return getf(a)==getf(b); }

	void comb(int a,int b) {

		if (same(a=getf(a),b=getf(b))) return;

		far[a]=b;

	}

}	uf1,uf2;

int main() {

	

	///read

	int n,m1,m2; cin>>n>>m1>>m2;

	

	///prework

	uf1.init();

	rep(i,0,m1) {

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

		uf1.comb(a,b);

	}

	uf2.init();

	rep(i,0,m2) {

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

		uf2.comb(a,b);

	}

	map<pii,int> M;

	rep(i,1,n+1) M[mp(uf1.getf(i),uf2.getf(i))]++;

	

	///work

	rep(i,1,n+1) {

		printf("%d ",M[mp(uf1.getf(i),uf2.getf(i))]);

	}





}