#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using vll = vector<long long>;
using pll = pair<long long, long long>;
const ll INF = 1LL << 60;

struct UnionFind{
    vll par;
    vll rank;
    vll num;
    //* member functions
    UnionFind(ll n){
        par = vll(n);
        rank = vll(n, 0);
        num = vll(n, 1);
        for(ll i=0; i< n; i++) par[i] = i;
    }

    ll find(ll x){
        if(par[x] == x) return x;
        else{
            return par[x] = find(par[x]);
        }
    }

    void unite(ll x, ll y){
        x = find(x); y = find(y);
        if(x == y) return;

        if(rank[x] < rank[y]){
            par[x] = y; //* new root is y
            num[y] += num[x];
        }
        else {
            par[y] = x; //* new root is x
            num[x] += num[y];
            if(rank[x] == rank[y]) rank[x] ++;
        }
    }

    ll getNumber(ll x){
        return num[find(x)];
    }

    bool same(ll x, ll y){
        return find(x) == find(y);
    }
};

void solve(long long N, long long K, long long L, std::vector<long long> p, std::vector<long long> q, std::vector<long long> r, std::vector<long long> s){
    //* sort 
    vector<pll> vecK(K), vecL(L);
    for(int i=0; i< K; i++){
        vecK[i].first = min(p[i]-1, q[i]-1);
        vecK[i].second = max(p[i]-1, q[i]-1);
    }
    for(int i=0; i< L; i++){
        vecL[i].first = min(r[i]-1, s[i]-1);
        vecL[i].second = max(r[i]-1, s[i]-1);
    }
    sort(vecK.begin(), vecK.end());
    sort(vecL.begin(), vecL.end());
    //* read edges for K
    UnionFind ufK(N), ufL(N), ufBoth(N);
    for(ll i=0; i< K; i++){
        ufK.unite(vecK[i].first, vecK[i].second);
    }
    //* read edges for L
    for(ll i=0; i< L; i++){
        ll a = vecL[i].first, b = vecL[i].second;
        ufL.unite(a, b);
    }
    //* store roots for every node
    vector<ll> arrK(N), arrL(N);
    for(ll i=0; i< N; i++){
        arrK[i] = ufK.find(i);
        arrL[i] = ufL.find(i);
    }
    //* make root pair
    vector<pair<pll, ll> > nodes(N+1);
    for(ll i=0; i< N; i++){
        nodes[i].first = make_pair(arrK[i], arrL[i]);
        nodes[i].second= i;
    }
    nodes[N].first = make_pair(INF, INF); 
    nodes[N].second = INF;
    //* sort root pair
    sort(nodes.begin(), nodes.end());
    //* the nodes with the same root pairs are in the same connected component
    ll i=0, j=0, k;
    vector<ll> res(N, 0);
    while(i<N){
        while(j< N && nodes[j].first == nodes[j+1].first){
            j++;
        }
        //* [i , j] are in the same connected component
        ll num_component = j-i+1;
        for(k=i; k<=j; k++){
            res[nodes[k].second] = num_component;
        }
        j++;
        i=j;
    }
    //* print answer
    for(i=0; i<N; i++){
        cout << res[i] << endl;
    }
    return;
}

int main(){
    long long N;
    scanf("%lld",&N);
    long long K;
    scanf("%lld",&K);
    long long L;
    scanf("%lld",&L);
    std::vector<long long> p(K);
    std::vector<long long> q(K);
    for(int i = 0 ; i < K ; i++){
        scanf("%lld",&p[i]);
        scanf("%lld",&q[i]);
    }
    std::vector<long long> r(L);
    std::vector<long long> s(L);
    for(int i = 0 ; i < L ; i++){
        scanf("%lld",&r[i]);
        scanf("%lld",&s[i]);
    }
    solve(N, K, L, std::move(p), std::move(q), std::move(r), std::move(s));
    return 0;
}


Measured memory_bytes: 29952