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

}