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

}