// 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: 4.214149568462378x):
#include<cstdio>

#include<queue>

#include<climits>

#include<algorithm>

#include<cstdlib>

#include<cmath>

#include<cstring>

#include<string>

#include<ctype.h>

#include<set>

#include<vector>

#include<map>

#include<time.h>

#include<list>

#include<stack>

#include<iostream>

using namespace std;

#define mod 1000000007

#define mem(x,k ) memset(x, (k) ,sizeof(x))

#define mp(A, B) make_pair(A, B)

#define pb push_back

#define sca scanf

#define pri printf

#define fi first

#define se second



typedef long long LL;

typedef long double LD;

typedef pair< int , int  > pii;



const LL INFLL=0x3f3f3f3f3f3f3f3fll;

const int INF=0x7fffffff;

const double PI=acos(-1.0);

const double  eps=1e-9;

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

//freopen("D.out","w",stdout);

int n,m,k;

int f[200005];

int f2[200005];

map<pair<int ,int >,int> G;

int Father(int k)

{

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

	return f[k]=Father(f[k]);

}



void Union(int x,int y)

{

    if (Father(x)==Father(y)) return;

    else

    {

        f[ f[x] ]=f[y];

        return;

    }

}

int Father2(int k)

{

    if (k==f2[k]) return k;

	return f2[k]=Father2(f2[k]);

}



void Union2(int x,int y)

{

    if (Father2(x)==Father2(y)) return;

    else

    {

        f2[ f2[x] ]=f2[y];

        return;

    }

}

int main(){

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

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

        f[i]=f2[i]=i;

    }

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

        int u,v;

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

        Union2(u,v);

    }

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

        int u,v;

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

        Union(u,v);

    }

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

        G[make_pair(Father(i),Father2(i))]++;

    }

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

        //printf("@%d@",Father(i));

        printf("%d",G[make_pair(Father(i),Father2(i))]);

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

    }

    printf("\n");

    return 0;

}