#include<bits/stdc++.h>
#include<string.h>
 
typedef long long int ll;
#define all(x) (x).begin(), (x).end()
 
using namespace std;

int nxt() {
    int x;
    cin >> x;
    return x;
}

ll nxtl(){
    ll x;
    cin>>x;
    return x;
}
 
void SieveOfEratosthenes(int n,vector <int> &primes) 
{ 
    // Create a boolean array "prime[0..n]" and initialize 
    // all entries it as true. A value in prime[i] will 
    // finally be false if i is Not a prime, else true. 
    bool prime[n+1]; 
    memset(prime, true, sizeof(prime)); 
  
    for (int p=2; p*p<=n; p++) 
    { 
        // If prime[p] is not changed, then it is a prime 
        if (prime[p] == true) 
        { 
            // Update all multiples of p greater than or  
            // equal to the square of it 
            // numbers which are multiple of p and are 
            // less than p^2 are already been marked.  
            for (int i=p*p; i<=n; i += p) 
                prime[i] = false; 
        } 
    } 
  
    // Print all prime numbers 
    for (int p=2; p<=n; p++) 
       if (prime[p]) 
          primes.push_back(p);
} 
 
ll max(ll a,ll b)
{
    if(a>b)
        return a;
    return b;
}
 
ll power(ll x, ll y,ll mod) 
{ 
    ll temp; 
    if( y == 0) 
        return 1; 
    temp = power(x, y/2,mod); 
    if (y%2 == 0) 
        return (temp*temp)%mod; 
    else
        return (((x*temp)%mod)*temp)%mod; 
}

vector <set <int> > g;
vector <set<int>  > g2;
vector <set <int> > g3;
void bfs(int s,vector <bool> &visited,vector <int> &count,vector <set <int> > &g3);

vector <set <int> > comp;
vector <int> comp_n;
vector <set <int> > comp2;
vector <int> comp_n2;
void bfs2(int s,vector <bool> &visited,vector <set <int> > &g3,vector <set <int> > &comp,vector <int> &comp_n);

int main()
{
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);
    int n=nxt(),k=nxt(),l=nxt();
    set <int> s;
    g.resize(n+1,s);
    g2.resize(n+1,s);
    g3.resize(n+1,s);
    for(int i=0;i<k;i++)
    {
        int u=nxt(),v=nxt();
        g[u].insert(v);
        g[v].insert(u);
    }
    for(int i=0;i<l;i++)
    {
        int u=nxt(),v=nxt();
        g2[u].insert(v);
        g2[v].insert(u);
    }

    comp_n.resize(n+1);
    vector <bool> visited;
    visited.resize(n+1,0);
    for(int i=1;i<=n;i++)
        if(!visited[i])
            bfs2(i,visited,g,comp,comp_n);

    for(int i=1;i<=n;i++)
        visited[i]=0;
    comp_n2.resize(n+1);
    for(int i=1;i<=n;i++)
        if(!visited[i])
            bfs2(i,visited,g2,comp2,comp_n2);

    map <pair<int,int> ,ll> m2;

    for(int i=1;i<=n;i++)
        m2[{comp_n[i],comp_n2[i]}]+=1;
    for(int i=1;i<=n;i++)
        cout<<m2[{comp_n[i],comp_n2[i]}]<<" ";
    cout<<endl;


    
    
    
    return 0;   
}

void bfs(int s,vector <bool> &visited,vector <int> &count,vector <set <int> > &g3)
{
    visited[s]=1;
    int c=1;
    queue <int> q;
    q.push(s);
    set <int> nodes;
    nodes.insert(s);
    while(q.size())
    {
        int x=q.front();
        q.pop();
        for(auto it=g3[x].begin();it!=g3[x].end();it++)
            if(!visited[*it])
            {
                visited[*it]=1;
                q.push(*it);
                c++;
                nodes.insert(*it);
            }
    }
    for(auto it=nodes.begin();it!=nodes.end();it++)
        count[*it]=c;

}

void bfs2(int s,vector <bool> &visited,vector <set <int> > &g3,vector <set <int> > &comp,vector <int> &comp_n)
{
    visited[s]=1;
    queue <int> q;
    q.push(s);
    set <int> nodes;
    nodes.insert(s);
    while(q.size())
    {
        int x=q.front();
        q.pop();
        for(auto it=g3[x].begin();it!=g3[x].end();it++)
            if(!visited[*it])
            {
                visited[*it]=1;
                q.push(*it);
                nodes.insert(*it);
            }
    }
    comp.push_back(nodes);
    for(auto it=nodes.begin();it!=nodes.end();it++){
        comp_n[*it]=comp.size()-1;
        //cout<<*it<<" ";
    }
    //cout<<endl;

}



 
 


Measured memory_bytes: 95400