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

#include <cstdio>

#include <cstring>

#include <cmath>

#include <algorithm>

#include <vector>

#include <queue>

#include <string>

#include <stack>

#include <map>

#include <ctime>

#include <set>

#include <bitset>

#include <ctime>

#define X first

#define Y second

#define clr(u,v); memset(u,v,sizeof(u));

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

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

#define Clear(Q); while (!Q.empty()) Q.pop();

#define pb push_back

using namespace std;

typedef long long ll;

typedef pair<int, int> pii;

typedef pair<char, int> pci;

const int maxn = 2e5 + 10;

const int INF = 0x3f3f3f3f;

int f[maxn];

int f2[maxn];

int f3[maxn];



int sum[maxn];

void init(int n)

{

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

        f[i] = i, f2[i] = i, f3[i] = i, sum[i] = 1;

}

int find(int x)

{

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

}

int find2(int x)

{

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

}



int find3(int x)

{

    return f3[x] == x ? x : f3[x] = find3(f3[x]);

}





void mix(int x, int y)

{

    int fx = find(x), fy = find(y);

    if (fx == fy) return ;

    f[fx] = fy;

}

void mix2(int x, int y)

{

    int fx = find2(x), fy = find2(y);

    if (fx == fy) return ;

    f2[fx] = fy;

}

void mix3(int x, int y)

{

    int fx = find3(x), fy = find3(y);

    if (fx == fy) return ;

    f3[fx] = fy;

    sum[fy] += sum[fx];

}

map <pii, int> M;



int main()

{

#ifdef LOCAL

//    in();

#endif

    int n, k, l, a, b;

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

    init(n);

    while (k--)

    {

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

        mix(a, b);

    }

    while (l--)

    {

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

        mix2(a, b);

//        else mix3(a,b);

    }

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

        M[make_pair(find(i), find2(i))]++;



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

        printf("%d ", M[make_pair(find(i), find2(i))]);

    puts("");

    return 0;

}


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

	}





}