#include <iostream>
#include <vector>
#include <map>
#include <cstdio>
#include <cstring>
#include <math.h>
#include <bitset>
#include <time.h>
#include <set>
#include <algorithm>
#define MAXN 200000
#define ll long long
using namespace std;


vector<int> edges1[MAXN+2];
vector<int> edges2[MAXN+2];
bool done1[MAXN+2];
bool done2[MAXN+2];
int answer[MAXN+2];

void dfs1(int par,int u, vector<int>* verts) {
    if (done1[u])
        return;
    done1[u]=true;
    verts->push_back(u);
    for(int j=0;j<edges1[u].size();j++) {
        int v=edges1[u][j];
        if (v==par)
            continue;
        dfs1(u,v,verts);
    }
}



void dfs2(int par,int u, vector<int>* verts) {
    if (done2[u])
        return;
    done2[u]=true;
    verts->push_back(u);
    for(int j=0;j<edges2[u].size();j++) {
        int v=edges2[u][j];
        if (v==par)
            continue;
        dfs2(u,v,verts);
    }
}

vector<int> vert_in_roadcomp[MAXN+2];
int road_comp_id[MAXN+2];

int GetIntersection(const vector<int>& A, const vector<int>& B) {
    
    int p2=0;
    int p1=0;
    int answer=0;
    
    
    
    while(p1 < A.size() && p2 < B.size()) {
        if (B.back() < A[p1])
            break;
        
        int low=p2;
        int high=B.size()-1;
        while(low < high) {
            int mid = (low+high)/2;
            if (B[mid] < A[p1])
                low=mid+1;
            else
                high=mid;
            
        }
        
        p2=low;
        
        if (B[p2]==A[p1]) {
            p1++;
            p2++;
            answer++;
        } else {
            
            // edges[u][k] > road_verts[p1].
            
            // first p1 such that edges[u][k] <= road_verts[p1].
            
            if (A.back() < B[p2])
                break;
            
            
            low=0;
            high=A.size()-1;
            while(low < high) {
                int mid = (low+high)/2;
                if (B[p2] > A[mid])
                    low=mid+1;
                else
                    high=mid;
                
            }
            
            
            p1 = low;
            
            
        }
    }
    return answer;
}


int main() {
    int N,K,L;
    cin>>N>>K>>L;
    for(int i=1;i<=K;i++) {
        int u,v;
        cin>>u>>v;
        edges1[u].push_back(v);
        edges1[v].push_back(u);
    }
    
    for(int i=1;i<=L;i++) {
        int u,v;
        cin>>u>>v;
        edges2[u].push_back(v);
        edges2[v].push_back(u);
    }
    
    
    for(int i=1;i<=N;i++) {
        sort(edges2[i].begin(),edges2[i].end());
    }
    
    for(int i=1;i<=N;i++)
        done1[i]=done2[i]=false;
    
    for(int i=1;i<=N;i++)
        answer[i]=0;
    
    int roadcid=0;
    for(int i=1;i<=N;i++) {
        if (done1[i])
            continue;
        dfs1(-1,i,&vert_in_roadcomp[roadcid]);
        sort(vert_in_roadcomp[roadcid].begin(),vert_in_roadcomp[roadcid].end());
        for(int j=0;j<vert_in_roadcomp[roadcid].size();j++) {
            int u=vert_in_roadcomp[roadcid][j];
            road_comp_id[u]=roadcid;
        }
        roadcid++;
    }
    
    int railcid=0;
    for(int i=1;i<=N;i++) {
        if (done2[i])
            continue;
        vector<int> vert_in_railcomp;
        dfs2(-1,i,&vert_in_railcomp);
        sort(vert_in_railcomp.begin(),vert_in_railcomp.end());
        
        map<int,int> hashed;
        
        for(int j=0;j<vert_in_railcomp.size();j++) {
            int u=vert_in_railcomp[j];
            int cid=road_comp_id[u];
            if (hashed.find(cid) != hashed.end()) {
                answer[u]=hashed[cid];
            } else {
                answer[u]=GetIntersection(vert_in_railcomp,vert_in_roadcomp[cid]);
                hashed[cid]=answer[u];
            }
        }
        
        
        
        railcid++;
    }
    
    
    
    for(int i=1;i<=N;i++)
        printf("%d ",answer[i]);
    printf("\n");
    
    
    
}

Measured memory_bytes: 28752