// 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: 7.270235820567726x):
#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;

}