#include <iostream>
using namespace std;
#include <algorithm>
#include <vector>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <cstring>
#include <queue>
#define MOD1 1000000007
#define MOD2 998244353
#define LIMIT1 200002
#define LIMIT2 500002
typedef long long ll;
typedef long double ld;
typedef const void cv;
#define rep(i,n) for((i)=0;(i)<(n);(i)++)
#define per(i,n) for((i)=(n)-1;(i)>=0;(i)--)
#define max(a,b) ((a)>(b) ? (a) : (b))
#define min(a,b) ((a)<(b) ? (a) : (b))
#define zt(a,b) (max((a),(b))-min((a),(b)))
ll gcd(ll a,ll b){return b?gcd(b,a%b):a;}
ll nPr(int n,int r){ll i,result=1;rep(i,r){result*=(ll)(n-i);}return result;}
ll nCr(int n,int r){ll i,result=1;if(n<r) return 0;rep(i,min(r,n-r)){result*=(ll)(n-i);result/=(ll)(i+1);}return result;}
#define nHr(n,r) nCr((int)((n)+(r)+1),(int)(r))
#define sankaku(x) (((x)*((x)+1))/2)
int dx[8]={1,0,-1,0,1,-1,-1,1},dy[8]={0,1,0,-1,1,1,-1,-1};
int upint(cv *a, cv *b) { return *(int *)a < *(int *)b ? -1 : *(int *)a > *(int *)b ? 1 : 0; }
int downint(cv *a, cv *b) { return *(int *)a < *(int *)b ? 1 : *(int *)a > *(int *)b ? -1 : 0; }
int upchar(cv *left, cv *right) {return strcmp((char *)left,(char *)right);}
int downchar(cv *left, cv *right) {return strcmp((char *)right,(char *)left);}
void tmpInit(int *c,ll m) {ll i;rep(i,m) c[i]=i;}
ll modpow(ll a, ll n, ll mod) {
  ll res = 1;
  while (n > 0) {
    if (n & 1){
      res *= a; if(mod>=1) res %= mod;
    }
    a *= a; if(mod>=1) a %= mod;
    n >>= 1;
  }
  return res;
}
void initialize(){
  
}
int parentA[200010];
int parentB[200010];
int c[200010];
int tmp(cv *p,cv *q){
  int n = parentA[*(int *)p]-parentA[*(int *)q];
  if(n != 0) return n;
  else return parentB[*(int *)p]-parentB[*(int *)q];
}
int main(void){
  initialize();
  ll n,m,i,j,k,l,p,q,count=0;
  ll a[LIMIT1]={0};
  queue<ll> que;
  cin >> n >> k >> l;
  vector<vector<int> > road(n+1,vector<int>()),train(n+1,vector<int>());

  rep(i,n+1){
    parentA[i]=-1;
    parentB[i]=-1;
  }
  rep(i,k){
    cin >> p >> q;
    p--;
    q--;
    road[p].push_back(q);
    road[q].push_back(p);
  }
  rep(i,l){
    cin >> p >> q;
    p--;
    q--;
    train[p].push_back(q);
    train[q].push_back(p);
  }
  rep(i,n){
    if(parentA[i]!=-1) continue;
    que.push(i);
    //parentA[i]=(int)i;
    while(!que.empty()){
      j = (ll)que.front();
      que.pop();
      if(parentA[j]!=-1) continue;
      parentA[j]=(int)i;
      while(!road[j].empty()){
        m = road[j][road[j].size()-1];
        road[j].pop_back();
        if(parentA[m]!=-1) continue;
        //parentA[m]=(int)i;
        que.push(m);
      }
    }
  }
  rep(i,n){
    if(parentB[i]!=-1) continue;
    que.push(i);
    //parentB[i]=(int)i;
    while(!que.empty()){
      j = (ll)que.front();
      que.pop();
      if(parentB[j]!=-1) continue;
      parentB[j]=(int)i;
      while(!train[j].empty()){
        m = train[j][train[j].size()-1];
        train[j].pop_back();
        if(parentB[m]!=-1) continue;
        //parentB[m]=(int)i;
        que.push(m);
      }
    }
  }
  rep(i,n) c[i]=(int)i;
  qsort(c,n,sizeof(int),tmp);
  count=1;
  rep(i,n){
    j = c[i];
    if(i!=n-1) m = c[i+1];
    else m=-1;
    if(i!=n-1 && parentA[j]==parentA[m] && parentB[j]==parentB[m]){
      que.push(j);
      count++;
    }else{
        count = que.size()+1;
      while(!que.empty()){
        m = que.front();
        que.pop();
        a[m]=count;
      }
      a[j]=count;
      count=1;
    }
  }
  //cerr << parentA[6013] << " " << parentB[6013] << endl;
  rep(i,n) cout << a[i] << (i==n-1 ? "\n" : " ");
  //rep(i,n) cout << parentA[i] << (i==n-1 ? "\n" : " ");
  //rep(i,n) cout << parentB[i] << (i==n-1 ? "\n" : " ");
  //rep(i,n) cout << c[i] << " " << parentA[c[i]] << " " << parentB[c[i]] << endl;

  return 0;
}

Measured memory_bytes: 23204