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

#include <cstdlib>

#include <cstring>

#include <iostream>

#include <algorithm>

using namespace std;

typedef long long LL;

inline int read() {

	int f=1,x=0; char ch=getchar();

	while (ch<'0'||ch>'9') { if (ch=='-') f=-1; ch=getchar(); }

	while (ch>='0'&&ch<='9') { x=x*10+ch-'0'; ch=getchar(); }

	return x*f;

}



const int MAXN=200005;

int n,m,r,tot,v[MAXN],f[MAXN],ans[MAXN];

struct List{

	int l,lt[MAXN],nt[MAXN<<1],v[MAXN<<1];

	void clear() { l=0; memset(lt,0,sizeof(lt)); }

	void addedge(int x,int y) { nt[++l]=lt[x]; lt[x]=l; v[l]=y; }

}E;

struct Data{

	int x,y;

	bool operator <(const Data &B)const { return x<B.x; }

}A[MAXN];

int ask(int x) { if (f[x]==x) return x; f[x]=ask(f[x]); return f[x]; }

void dfs(int x) {

	v[x]=1; A[++tot].x=ask(x); A[tot].y=x;

	for (int i=E.lt[x];i;i=E.nt[i]) if (!v[E.v[i]]) dfs(E.v[i]);

}

int main() {

	int i,j,k,l;

	n=read(); m=read(); r=read();

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

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

		j=read(); k=read();

		E.addedge(j,k); E.addedge(k,j);

	}

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

		j=ask(read()); k=ask(read());

		if (j!=k) f[j]=k;

	}

	memset(v,0,sizeof(v));

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

	if (!v[i]) {

		tot=0; dfs(i); sort(A+1,A+1+tot);

		for (j=1;j<=tot;j=k+1) {

			for (k=j;k<tot&&A[k+1].x==A[j].x;++k);

			for (l=j;l<=k;++l) ans[A[l].y]=k-j+1;

		}

	}

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

	return 0;

}



/*

4 3 1

1 2

2 3

3 4

2 3



*/


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

#include <cstdlib>

#include <cstring>

#include <cmath>

#include <algorithm>

using namespace std;

#define inf (0x3f3f3f3f)

#define ls int len=s.size()

#define ls1 int len1=s1.size()

#define sd(x) scanf("%d",&x)

#define slld(x) scanf("%I64d",&x)

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

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

#define repn(i,n) for(int i=n-1;i>=0;i--)

typedef long long int LL;

typedef long long int ll;



#include <iostream>

#include <sstream>

#include <vector>

#include <set>

#include <map>

#include <queue>

#include <string>

#include<stack>

#include<ctime>

void g(int t){if(t){g((t-1)/26);putchar(65+(t-1)%26);}}



const int M=2*1e5+100;

int f[M],f1[M],r[M],r1[M];



void init(int n){

    rep(i,n){

        f[i]=i;f1[i]=i;

        r[i]=r1[i]=0;

    }

}

int find(int x){

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

}

int find1(int x){

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

}

void unite(int x,int y){

    x=find(x);y=find(y);

    if(x==y) return;



    if(r[x]<r[y]) f[x]=y;

    else{

        f[y]=x;

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

    }

}

void unite1(int x,int y){

    x=find1(x);y=find1(y);

    if(x==y) return;

    if(r1[x]<r1[y]) f1[x]=y;

    else{

        f1[y]=x;

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

    }

}



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



int main()

{

#ifdef LOCAL

    freopen("data.h", "r", stdin);

    //freopen("1.h","w",stdout);

#endif

    int n,K,L;

    scanf("%d%d%d",&n,&K,&L);

    init(n);

    rep(i,K){

        int v,u;

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

        unite(v,u);

    }

    rep(i,L){

        int v,u;

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

        unite1(v,u);

    }

    mp.clear();

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

        mp[make_pair(find(i),find1(i))]++;

    }



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

        printf("%d ",mp[make_pair(find(i),find1(i))]);

    }

    cout<<endl;

}