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

#include <iostream>

#include <algorithm>

#define N 200007

using namespace std;

int n,k,l,p,q,r,s,f1[N],f2[N],a[N],cnt[N],ans[N];

int find1(int x){return f1[x]==x ? x:f1[x]=find1(f1[x]);}

int find2(int x){return f2[x]==x ? x:f2[x]=find2(f2[x]);}

bool cmp(int x,int y){return f1[x]<f1[y];}

int main(){

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

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

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

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

		f1[find1(p)]=find1(q);

	}

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

		scanf("%d%d",&r,&s);

		f2[find2(r)]=find2(s);

	}

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

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

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

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

		int j=i;

		while(j<n && f1[a[j+1]]==f1[a[j]])++j;

		for(int t=i;t<=j;++t)++cnt[f2[a[t]]];

		for(int t=i;t<=j;++t)ans[a[t]]=cnt[f2[a[t]]];

		for(int t=i;t<=j;++t)--cnt[f2[a[t]]];

		i=j;

	}

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

}

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

#include<cstring>

#include<algorithm>

struct abc {

	int aa, bb, cc;

	bool operator < (const abc&T) const {

		return(aa < T.aa || (aa == T.aa && bb < T.bb) || (aa == T.aa && bb == T.bb && cc < T.cc));

	}

	bool operator == (const abc&T) const {

		return(aa == T.aa && bb == T.bb);

	}

} ans[200005];

using namespace std;

int N, KK, LL, i, j, k, l, m, n, pt1[200005], pt2[200005], s1[200005], s2[200005], z;

int sz[200005], ans2[200005];

int find1(int aa) {

	if(pt1[aa] != aa) 

		pt1[aa] = find1(pt1[aa]);

	return(pt1[aa]);

}

int find2(int bb) {

	if(pt2[bb] != bb) 

		pt2[bb] = find2(pt2[bb]);

	return(pt2[bb]);

}

int main() {

	scanf("%d%d%d", &N, &KK, &LL);

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

		pt1[i] = i;

		pt2[i] = i;

		s1[i] = 1;

		s2[i] = 1;

	}

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

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

		if(find1(j) == find1(l)) continue;

		s1[find1(l)] += s1[find1(j)];

		pt1[find1(j)] = find1(l);

	}

	

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

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

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

		s2[find2(l)] += s2[find2(j)];

		pt2[find2(j)] = find2(l);

	}

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

		pt1[i] = find1(i);

		pt2[i] = find2(i);

		ans[i].aa = pt1[i];

		ans[i].bb = pt2[i];

		ans[i].cc = i;

	}

//	for(i = 1; i <= N; i++) printf("%d %d\n", pt1[i], pt2[i]);

	

	sort(ans + 1, ans + N + 1);

	sz[1] = 1;

	for(i = 2; i <= N; i++) if(ans[i] == ans[i - 1]) {

		sz[i] = sz[i - 1] + 1;

	} else {

		sz[i] = 1;

	}

	for(i = N - 1; i >= 1; i--) 

	if(ans[i] == ans[i + 1]) sz[i] = sz[i + 1];

	

	//for(i = 1; i <= N; i++) printf("%d %d %d %d\n", ans[i].aa, ans[i].bb, ans[i].cc, sz[i]);

	

	for(i = 1; i <= N; i++) ans2[ans[i].cc] = sz[i];

	

	for(i = 1; i < N; i++) printf("%d ", ans2[i]);

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

}

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

#include <algorithm>

#include <map>

#include <iostream>

using namespace std;

#define x first

#define y second

#define mp make_pair

#define REP(i,j,k)  for(int i = (j); i <= (k); ++i)

#define REPD(i,j,k) for(int i = (j); i >= (k); --i)

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





const int maxn = 3e5;



int f[maxn];

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



void go(int n,int m,int a[])

{

	REP(i,1,n)

		f[i]=i;

	while(m--)

	{

		int x,y;

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

		if(find(x)!=find(y))

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

	}

	REP(i,1,n)

		a[i]=find(i);

}

int a[maxn],b[maxn];

map<pair<int,int>,int> tot;

int init()

{

	int n,m,p;

	if(scanf("%d%d%d",&n,&m,&p)==EOF) return 0;

	go(n,m,a);

	go(n,p,b);

	tot.clear();

	REP(i,1,n)

		if(tot.count(mp(a[i],b[i]))==0)

			tot[mp(a[i],b[i])]=1;

		else ++tot[mp(a[i],b[i])];

	REP(i,1,n)

		if(i==n)

			printf("%d\n",tot[mp(a[i],b[i])]);

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

	return 1;

}



void solve()

{

}



int main()

{

	IOS

	

	while(init())

	solve();

	

	return 0;

}

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

#include<cstring>

#include<algorithm>

struct abc {

	int aa, bb, cc;

	bool operator < (const abc&T) const {

		return(aa < T.aa || (aa == T.aa && bb < T.bb) || (aa == T.aa && bb == T.bb && cc < T.cc));

	}

	bool operator == (const abc&T) const {

		return(aa == T.aa && bb == T.bb);

	}

} ans[200005];

using namespace std;

int N, KK, LL, i, j, k, l, m, n, pt1[200005], pt2[200005], s1[200005], s2[200005], z;

int sz[200005], ans2[200005];

int find1(int aa) {

	if(pt1[aa] != aa) 

		pt1[aa] = find1(pt1[aa]);

	return(pt1[aa]);

}

int find2(int bb) {

	if(pt2[bb] != bb) 

		pt2[bb] = find2(pt2[bb]);

	return(pt2[bb]);

}

int main() {

	scanf("%d%d%d", &N, &KK, &LL);

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

		pt1[i] = i;

		pt2[i] = i;

		s1[i] = 1;

		s2[i] = 1;

	}

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

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

		if(find1(j) == find1(l)) continue;

		s1[find1(l)] += s1[find1(j)];

		pt1[find1(j)] = find1(l);

	}

	

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

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

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

		s2[find2(l)] += s2[find2(j)];

		pt2[find2(j)] = find2(l);

	}

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

		pt1[i] = find1(i);

		pt2[i] = find2(i);

		ans[i].aa = pt1[i];

		ans[i].bb = pt2[i];

		ans[i].cc = i;

	}

//	for(i = 1; i <= N; i++) printf("%d %d\n", pt1[i], pt2[i]);

	

	sort(ans + 1, ans + N + 1);

	sz[1] = 1;

	for(i = 2; i <= N; i++) if(ans[i] == ans[i - 1]) {

		sz[i] = sz[i - 1] + 1;

	} else {

		sz[i] = 1;

	}

	for(i = N - 1; i >= 1; i--) 

	if(ans[i] == ans[i + 1]) sz[i] = sz[i + 1];

	

	//for(i = 1; i <= N; i++) printf("%d %d %d %d\n", ans[i].aa, ans[i].bb, ans[i].cc, sz[i]);

	

	for(i = 1; i <= N; i++) ans2[ans[i].cc] = sz[i];

	

	for(i = 1; i < N; i++) printf("%d ", ans2[i]);

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

}

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

#include <algorithm>

#include <cstdio>

#include <map>

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

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

#define MAXN 200005

#define ll long long

using namespace std;

int f1[MAXN],f2[MAXN],res[MAXN];

typedef pair<int,int> pii;

map<pii,int> m;

void init(int n)

{

    rep(i,1,n)

        f1[i] = f2[i] = i,res[i] =1;

}

int getf(int x,int f[])

{

    if(x != f[x])

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

    return f[x];

}

void Union(int a,int b,int f[])

{

    a = getf(a,f);

    b = getf(b,f);

    if(a != b){

        f[a] = f[b];

    }

}

bool isSame(int a,int b,int f[])

{

    return getf(a,f) == getf(b,f);

}

int main()

{

    //freopen("data","r",stdin);

    int n,k,l;

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

    init(n);

    int a,b;

    rep(i,1,k)

    {

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

        Union(a,b,f1);

    }

    rep(i,1,l)

    {

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

        Union(a,b,f2);

    }

    rep(i,1,n){

        m[make_pair(getf(i,f1),getf(i,f2))]++;

    }

    rep(i,1,n)

    {

        printf("%d ",m[make_pair(getf(i,f1),getf(i,f2))]);

    }

    return 0;

}


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

#include<cstring>

#include<algorithm>

struct abc {

	int aa, bb, cc;

	bool operator < (const abc&T) const {

		return(aa < T.aa || (aa == T.aa && bb < T.bb) || (aa == T.aa && bb == T.bb && cc < T.cc));

	}

	bool operator == (const abc&T) const {

		return(aa == T.aa && bb == T.bb);

	}

} ans[200005];

using namespace std;

int N, KK, LL, i, j, k, l, m, n, pt1[200005], pt2[200005], s1[200005], s2[200005], z;

int sz[200005], ans2[200005];

int find1(int aa) {

	if(pt1[aa] != aa) 

		pt1[aa] = find1(pt1[aa]);

	return(pt1[aa]);

}

int find2(int bb) {

	if(pt2[bb] != bb) 

		pt2[bb] = find2(pt2[bb]);

	return(pt2[bb]);

}

int main() {

	scanf("%d%d%d", &N, &KK, &LL);

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

		pt1[i] = i;

		pt2[i] = i;

		s1[i] = 1;

		s2[i] = 1;

	}

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

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

		if(find1(j) == find1(l)) continue;

		s1[find1(l)] += s1[find1(j)];

		pt1[find1(j)] = find1(l);

	}

	

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

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

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

		s2[find2(l)] += s2[find2(j)];

		pt2[find2(j)] = find2(l);

	}

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

		pt1[i] = find1(i);

		pt2[i] = find2(i);

		ans[i].aa = pt1[i];

		ans[i].bb = pt2[i];

		ans[i].cc = i;

	}

//	for(i = 1; i <= N; i++) printf("%d %d\n", pt1[i], pt2[i]);

	

	sort(ans + 1, ans + N + 1);

	sz[1] = 1;

	for(i = 2; i <= N; i++) if(ans[i] == ans[i - 1]) {

		sz[i] = sz[i - 1] + 1;

	} else {

		sz[i] = 1;

	}

	for(i = N - 1; i >= 1; i--) 

	if(ans[i] == ans[i + 1]) sz[i] = sz[i + 1];

	

	//for(i = 1; i <= N; i++) printf("%d %d %d %d\n", ans[i].aa, ans[i].bb, ans[i].cc, sz[i]);

	

	for(i = 1; i <= N; i++) ans2[ans[i].cc] = sz[i];

	

	for(i = 1; i < N; i++) printf("%d ", ans2[i]);

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

}

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

#include <cstdio>

#include <algorithm>

#include <vector>

#include <stack>

#include <queue>

#include <map>

#include <set>

#include <string>

#include <cstring>

#include <bitset>

#define ll long long

#define rep(x,n) for(ll (x)=0;(x)<n;(x)++)

#define rep1(x,n) for(ll (x)=1;(x)<=n;(x)++)

#define lson(x) ((x)<<1)

#define rson(x) ((x)<<1|1)

using namespace std;



const int N=200005;

int pa1[N],pa2[N],ans[N];

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



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]);

}



int main()

{

    #ifdef LOCAL

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

    #endif // LOCAL

    int n,k,l,a,b;

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

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

    while(k--)

    {

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

        pa1[fpa1(a)]=fpa1(b);

    }

    while(l--)

    {

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

        pa2[fpa2(a)]=fpa2(b);

    }

    rep1(i,n) cnt[make_pair(fpa1(i),fpa2(i))]++;

    rep1(i,n) ans[i]=cnt[make_pair(fpa1(i),fpa2(i))];

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

    printf("\n");

}


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

#include<cstring>

#include<algorithm>

struct abc {

	int aa, bb, cc;

	bool operator < (const abc&T) const {

		return(aa < T.aa || (aa == T.aa && bb < T.bb) || (aa == T.aa && bb == T.bb && cc < T.cc));

	}

	bool operator == (const abc&T) const {

		return(aa == T.aa && bb == T.bb);

	}

} ans[200005];

using namespace std;

int N, KK, LL, i, j, k, l, m, n, pt1[200005], pt2[200005], s1[200005], s2[200005], z;

int sz[200005], ans2[200005];

int find1(int aa) {

	if(pt1[aa] != aa) 

		pt1[aa] = find1(pt1[aa]);

	return(pt1[aa]);

}

int find2(int bb) {

	if(pt2[bb] != bb) 

		pt2[bb] = find2(pt2[bb]);

	return(pt2[bb]);

}

int main() {

	scanf("%d%d%d", &N, &KK, &LL);

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

		pt1[i] = i;

		pt2[i] = i;

		s1[i] = 1;

		s2[i] = 1;

	}

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

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

		if(find1(j) == find1(l)) continue;

		s1[find1(l)] += s1[find1(j)];

		pt1[find1(j)] = find1(l);

	}

	

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

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

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

		s2[find2(l)] += s2[find2(j)];

		pt2[find2(j)] = find2(l);

	}

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

		pt1[i] = find1(i);

		pt2[i] = find2(i);

		ans[i].aa = pt1[i];

		ans[i].bb = pt2[i];

		ans[i].cc = i;

	}

//	for(i = 1; i <= N; i++) printf("%d %d\n", pt1[i], pt2[i]);

	

	sort(ans + 1, ans + N + 1);

	sz[1] = 1;

	for(i = 2; i <= N; i++) if(ans[i] == ans[i - 1]) {

		sz[i] = sz[i - 1] + 1;

	} else {

		sz[i] = 1;

	}

	for(i = N - 1; i >= 1; i--) 

	if(ans[i] == ans[i + 1]) sz[i] = sz[i + 1];

	

	//for(i = 1; i <= N; i++) printf("%d %d %d %d\n", ans[i].aa, ans[i].bb, ans[i].cc, sz[i]);

	

	for(i = 1; i <= N; i++) ans2[ans[i].cc] = sz[i];

	

	for(i = 1; i < N; i++) printf("%d ", ans2[i]);

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

}

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

	}





}


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

#include<cstring>

#include<algorithm>

struct abc {

	int aa, bb, cc;

	bool operator < (const abc&T) const {

		return(aa < T.aa || (aa == T.aa && bb < T.bb) || (aa == T.aa && bb == T.bb && cc < T.cc));

	}

	bool operator == (const abc&T) const {

		return(aa == T.aa && bb == T.bb);

	}

} ans[200005];

using namespace std;

int N, KK, LL, i, j, k, l, m, n, pt1[200005], pt2[200005], s1[200005], s2[200005], z;

int sz[200005], ans2[200005];

int find1(int aa) {

	if(pt1[aa] != aa) 

		pt1[aa] = find1(pt1[aa]);

	return(pt1[aa]);

}

int find2(int bb) {

	if(pt2[bb] != bb) 

		pt2[bb] = find2(pt2[bb]);

	return(pt2[bb]);

}

int main() {

	scanf("%d%d%d", &N, &KK, &LL);

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

		pt1[i] = i;

		pt2[i] = i;

		s1[i] = 1;

		s2[i] = 1;

	}

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

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

		if(find1(j) == find1(l)) continue;

		s1[find1(l)] += s1[find1(j)];

		pt1[find1(j)] = find1(l);

	}

	

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

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

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

		s2[find2(l)] += s2[find2(j)];

		pt2[find2(j)] = find2(l);

	}

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

		pt1[i] = find1(i);

		pt2[i] = find2(i);

		ans[i].aa = pt1[i];

		ans[i].bb = pt2[i];

		ans[i].cc = i;

	}

//	for(i = 1; i <= N; i++) printf("%d %d\n", pt1[i], pt2[i]);

	

	sort(ans + 1, ans + N + 1);

	sz[1] = 1;

	for(i = 2; i <= N; i++) if(ans[i] == ans[i - 1]) {

		sz[i] = sz[i - 1] + 1;

	} else {

		sz[i] = 1;

	}

	for(i = N - 1; i >= 1; i--) 

	if(ans[i] == ans[i + 1]) sz[i] = sz[i + 1];

	

	//for(i = 1; i <= N; i++) printf("%d %d %d %d\n", ans[i].aa, ans[i].bb, ans[i].cc, sz[i]);

	

	for(i = 1; i <= N; i++) ans2[ans[i].cc] = sz[i];

	

	for(i = 1; i < N; i++) printf("%d ", ans2[i]);

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

}

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

#include <vector>

#include <map>

#define N 200005

using namespace std;

int n, k, l, num, u[N], v[N];

vector<int> a[N], b[N];

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



void f(int p, int q) {

	if(u[p]) return;

	u[p] = q;

	for(int i=0; i<a[p].size(); i++) {

		f(a[p][i], q);

	}

}



void g(int p, int q) {

	if(v[p]) return;

	v[p] = q;

	for(int i=0; i<b[p].size(); i++) {

		g(b[p][i], q);

	}

}



int main() {

	int i, x, y;

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

	while(k--) {

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

		a[x].push_back(y);

		a[y].push_back(x);

	}

	while(l--) {

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

		b[x].push_back(y);

		b[y].push_back(x);

	}

	for(i=1, num=0; i<=n; i++) if(!u[i]) f(i, ++num);

	for(i=1, num=0; i<=n; i++) if(!v[i]) g(i, ++num);

	for(i=1; i<=n; i++) mp[{u[i],v[i]}]++;

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

		if(!u[i] || !v[i]) printf("1 ");

		else printf("%d ",  mp[{u[i],v[i]}]);

	}

	return 0;

}

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

#include <map>

using namespace std;

int n, k, l, a[200005], b[200005];

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



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

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

	else return x[p] = f(x[p], x);

}



int main() {

	int i, u, v;

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

	for(i=1; i<=n; i++) a[i] = b[i] = i;

	while(k--) {

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

		u = f(u,a), v = f(v,a);

		if(u!=v) a[u] = v;

	}

	while(l--) {

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

		u = f(u,b), v = f(v,b);

		if(u!=v) b[u] = v;

	}

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

		u = f(i,a), v = f(i,b);

		mp[{u,v}]++;

	}

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

		u = f(i,a), v = f(i,b);

		printf("%d ", mp[{u,v}]);

	}

	return 0;

}


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

#include <cstring>

#include <iostream>

#include <algorithm>

using namespace std;

#define N 200005

int n, k, l;

int tar[2 * N], nex[2 * N], fir[N], cnt;

int bel[N], sum[N], ans[N], stk[N], vis[N], top;

int Getbel(int x)

{

	if (!bel[x])

		return x;

	return bel[x] = Getbel(bel[x]);

}

void add(int a, int b)

{

	++cnt;

	tar[cnt] = b;

	nex[cnt] = fir[a];

	fir[a] = cnt;

}

void dfs(int r)

{

	vis[r] = 1;

	stk[++top] = r;

	for (int i = fir[r]; i; i = nex[i])

	{

		int v = tar[i];

		if (!vis[v])

			dfs(v);

	}

}

int main()

{

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

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

	{

		int a, b;

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

		a = Getbel(a), b = Getbel(b);

		if (a != b)

			bel[a] = b;

	}

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

	{

		int a, b;

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

		add(a, b), add(b, a);

	}

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

	{

		if (!vis[i])

		{

			dfs(i);

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

				sum[Getbel(stk[j])]++;

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

				ans[stk[j]] = sum[Getbel(stk[j])];

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

				sum[Getbel(stk[j])]--;

			top = 0;

		}

	}

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

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

}


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

#define N 200010

#define F for(register int j(1);j<=now;j++)

int n,m,k,now,cnt,pre[N],a[N],b[N],opt[N],head[N],nxt[N<<1],dis[N<<1];

bool used[N];

int find(int x)

{

	return !pre[x]?x:pre[x]=find(pre[x]);

}

inline void add(int x,int y)

{

	dis[++cnt]=y,nxt[cnt]=head[x],head[x]=cnt;

	return;

}

void dfs(int x)

{

	used[x]=1,a[++now]=x;

	for(register int i(head[x]);i;i=nxt[i])

		if(!used[dis[i]])

			dfs(dis[i]);

	return;

}

signed main()

{

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

	while(m--)

		scanf("%d%d",&x,&y),(x=find(x))-(y=find(y))?pre[x]=y:8;

	while(k--)

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

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

		if(!used[i])

		{

			dfs(i);

			F

				b[find(a[j])]++;

			F

				opt[a[j]]=b[find(a[j])];

			F

				b[find(a[j])]--;

			now=0;

		}

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

		printf("%d%c",opt[i],i-n?32:10);

	return 0;

}

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

}

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

#define N 200010

#define F for(register int j(1);j<=now;j++)

int n,m,k,now,cnt,pre[N],a[N],b[N],opt[N],head[N],nxt[N<<1],dis[N<<1];

bool used[N];

int find(int x)

{

	return !pre[x]?x:pre[x]=find(pre[x]);

}

inline void add(int x,int y)

{

	dis[++cnt]=y,nxt[cnt]=head[x],head[x]=cnt;

	return;

}

void dfs(int x)

{

	used[x]=1,a[++now]=x;

	for(register int i(head[x]);i;i=nxt[i])

		if(!used[dis[i]])

			dfs(dis[i]);

	return;

}

signed main()

{

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

	while(m--)

		scanf("%d%d",&x,&y),(x=find(x))-(y=find(y))?pre[x]=y:8;

	while(k--)

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

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

		if(!used[i])

		{

			dfs(i);

			F

				b[find(a[j])]++;

			F

				opt[a[j]]=b[find(a[j])];

			F

				b[find(a[j])]--;

			now=0;

		}

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

		printf("%d%c",opt[i],i-n?32:10);

	return 0;

}

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

using namespace std;

const int MAXN = 2e5+2;

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

    {

        mp[make_pair(pre1[i],pre2[i])] ++;

    }

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

    {

        cout<<mp[make_pair(pre1[i],pre2[i])]<<" ";

    }

    cout<<endl;

}

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

#define N 200010

#define F for(register int j(1);j<=now;j++)

int n,m,k,now,cnt,pre[N],a[N],b[N],opt[N],head[N],nxt[N<<1],dis[N<<1];

bool used[N];

int find(int x)

{

	return !pre[x]?x:pre[x]=find(pre[x]);

}

inline void add(int x,int y)

{

	dis[++cnt]=y,nxt[cnt]=head[x],head[x]=cnt;

	return;

}

void dfs(int x)

{

	used[x]=1,a[++now]=x;

	for(register int i(head[x]);i;i=nxt[i])

		if(!used[dis[i]])

			dfs(dis[i]);

	return;

}

signed main()

{

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

	while(m--)

		scanf("%d%d",&x,&y),(x=find(x))-(y=find(y))?pre[x]=y:8;

	while(k--)

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

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

		if(!used[i])

		{

			dfs(i);

			F

				b[find(a[j])]++;

			F

				opt[a[j]]=b[find(a[j])];

			F

				b[find(a[j])]--;

			now=0;

		}

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

		printf("%d%c",opt[i],i-n?32:10);

	return 0;

}

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

#include <string>



using namespace std;



int main(void) {

    string X[3];

    int i;

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

        cin >> X[i];



    unsigned int x[3]={};

    int next=0;

    while (true) {

        if (X[next].length() == x[next]) {

            printf("%c\n", next+'A');

            return 0;

        }

        x[next]++;

        next = X[next][x[next]-1]-'a';

    }

    return 0;

}


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

#include <string>



using namespace std;



int main() {

    char S[3][128];

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

        scanf("%s", S[i]);



    size_t pos[3]={};

    int next=0;

    while (true)

        if (S[next][pos[next]]) {

            next = S[next][pos[next]++]-'a';

        } else {

            return !printf("%c\n", next+'A');

        }

}


// Fastest known solution for this problem: