#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <stdint.h>
#include <string>

// C++ Libraries
#include <map>

#define NUM 200010

unsigned int n, k, l;
unsigned int road[NUM][2];
unsigned int rail[NUM][2];

unsigned int check[NUM];
unsigned int passed[NUM];
unsigned int station[NUM];
unsigned int ans[NUM];

unsigned int road_category[NUM];
unsigned int rail_category[NUM];

// typedef struct node {
//      long long int value;
//      unsigned int count;
// } node;

typedef struct node {
     unsigned long long int value;
     unsigned int count;
     struct node *right;
     struct node *left;
} node;


node root_loc = {0, 0, NULL, NULL};

// unsigned int union_road[NUM];
unsigned int par_road[NUM];
unsigned int rank_road[NUM];
unsigned int count_road[NUM];
// unsigned int union_rail[NUM];
unsigned int par_rail[NUM];
unsigned int rank_rail[NUM];
unsigned int count_rail[NUM];
// uint16_t count[NUM][NUM];
node count[NUM];

unsigned int hash_length=0;

unsigned int root(unsigned int x, unsigned int* par, unsigned int* rank) {
    return par[x]==x ? x : (par[x]=root(par[x], par, rank));
}

// bool same(unsigned int x, unsigned int y, unsigned int* par, unsigned int* rank) {
//     return root(x, par, rank) == root(y, par, rank);
// }

void unite(unsigned int x, unsigned int y, unsigned int* par, unsigned int* rank, unsigned int* count) {
    x = root(x, par, rank);
    y = root(y, par, rank);
    if (x == y) return;
    
    if(rank[x] < rank[y]) {
        par[x] = y;
        count[y] = count[x] + count[y] + 1;
    } else {
        par[y] = x;
        count[x] = count[y] + count[x] + 1;
        if (rank[x] == rank[y]) rank[x]++;
    }
}



int main(){
    unsigned int i, j, h;
    unsigned int terminal_road, terminal_rail;
    int flag;
    scanf("%d%d%d", &n, &k, &l);
    
    
    for(i=0; i<NUM; i++) {
        par_road[i] = i;
        rank_road[i] = 0;
        count_road[i] = 0;
        par_rail[i] = i;
        rank_rail[i] = 0;
        count_rail[i] = 0;
        count[i].value=0;
        count[i].count=0;
        
        // for(j=1; j<n; j++) {
        //     count[i][j] = 0;
        // }
    }
    
    for(i=1; i<=k; i++) {
        scanf("%d%d", &road[i][0], &road[i][1]);
        int c1 = road[i][0];
        int c2 = road[i][1];
        unite(c1, c2, par_road, rank_road, count_road);
    }
    for(i=1; i<=l; i++) {
        scanf("%d%d", &rail[i][0], &rail[i][1]);
        int c1 = rail[i][0];
        int c2 = rail[i][1];
        unite(c1, c2, par_rail, rank_rail, count_rail);
    }
    
    node* temp_loc;
    unsigned long long int hash;
    // std::map<unsigned long long int, unsigned int> mp;
    std::map<std::string, unsigned int> mp;
    std::string hash_str;
    
    for(i=1; i<=n; i++) {
        //hash = root(i, par_road, rank_road)*(n+2) + root(i, par_rail, rank_rail);
        hash_str = std::to_string(root(i, par_road, rank_road)) + "with" + std::to_string(root(i, par_rail, rank_rail));
        
        // auto itr = mp.find(hash);        // "xyz" が設定されているか？
        // if( itr != mp.end() ) {
        //     mp[hash]++;
        // } else {
        //     mp[hash] = 1;
        // }
        
        auto itr = mp.find(hash_str);        // "xyz" が設定されているか？
        if( itr != mp.end() ) {
            mp[hash_str]++;
        } else {
            mp[hash_str] = 1;
        }
        
        
        
        
        
        
        // temp_loc = &root_loc;
        // if(temp_loc->value == 0) {
        //     temp_loc->value = hash;
        //     temp_loc->count = 1;
        // }
        // else {
        //     while(1){
        //         if(hash > temp_loc->value) {
        //             if(temp_loc->right != NULL) {
        //                 temp_loc = temp_loc->right;
        //             }
        //             else {
        //                 node* temp = (node*)malloc(sizeof(node));
        //                 temp->value = hash;
        //                 temp->count = 1;
        //                 temp->right = NULL;
        //                 temp->left = NULL;
        //                 temp_loc->right = temp;
        //                 break;
        //             }
        //         }
        //         else if(hash < temp_loc->value) {
        //             if(temp_loc->left != NULL) {
        //                 temp_loc = temp_loc->left;
        //             }
        //             else {
        //                 node* temp = (node*)malloc(sizeof(node));
        //                 temp->value = hash;
        //                 temp->count = 1;
        //                 temp->right = NULL;
        //                 temp->left = NULL;
        //                 temp_loc->left = temp;
        //                 break;
        //             }
        //         }
        //         else {
        //             temp_loc->count++;
        //             break;
        //         }
        //     }
        // }
        
        
    }
    
    for(i=1; i<=n; i++) {
        // hash = root(i, par_road, rank_road)*(n+2) + root(i, par_rail, rank_rail);
        hash_str = std::to_string(root(i, par_road, rank_road)) + "with" + std::to_string(root(i, par_rail, rank_rail));
        
        // temp_loc = &root_loc;
        // while(1) {
        //     if(temp_loc->value < hash) {
        //         temp_loc = temp_loc->right;
        //     }
        //     else if(temp_loc->value > hash) {
        //         temp_loc = temp_loc->left;
        //     }
        //     else {
        //         printf("%d ", temp_loc->count);
        //         break;
        //     }
        // }
        printf("%d ", mp[hash_str]);
    }
    
    
    
    // for(i=1; i<=n; i++) {
    //     count[root(i, par_road, rank_road)][root(i, par_rail, rank_rail)]++;
    // }
    
    // for(i=1; i<=n; i++) {
    //     printf("%d ", count[root(i, par_road, rank_road)][root(i, par_rail, rank_rail)]);
    // }
    
    
    
    
    // categorize_city();
    
    // for(i=1;i<=n;i++) {
    //     unsigned long long int hash = root(i, par_road, rank_road)*(n+1) + root(i, par_rail, rank_rail);
    //     flag = 0;
    //     j=1;
    //     while(count[j].value != 0){
    //         if(count[j].value == hash) {
    //             flag = 1;
    //             break;
    //         }
    //         j++;
    //     }
    //     if(flag == 0) {
    //         count[j].value = hash;
    //         count[j].count++;
    //     }
    //     else{
    //         count[j].count++;
    //     }
    // }
    
    // for (j=1;j<=n;j++) {
    //     terminal_road = root(j, par_road, rank_road);
    //     terminal_rail = root(j, par_rail, rank_rail);
        
    //     for(i=1; i<=n; i++) {
    //         if(par_road[i] == terminal_road && par_rail[i] == terminal_rail) {
    //             ans[j]++;
    //         }
    //     }
        
    //     printf("%d ", ans[j]);
    // }
    
    
    // for(i=1; i<=n; i++) {
    //     unsigned long long int hash = root(i, par_road, rank_road)*(n+1) + root(i, par_rail, rank_rail);
    //     for(j=1; j<=n+1; j++) {
    //         if(count[j].value == hash){
    //             printf("%d ", count[j].count);
    //             break;
    //         }
    //     }
    // }
    return 0;
}


Measured memory_bytes: 39936