// Slower C++ solution:
#include <bits/stdc++.h>

using namespace std;

#define INF 0x3f3f3f3f

#define maxn 212345

#define met(a, b) memset(a, b, sizeof(a))

class UMS

{

public:

    int f[maxn];

    UMS()

    {

        for(int i = 0; i < maxn; i++)

        {

            f[i] = i;

        }

    }

    int getf(int u)

    {

        if(u == f[u])

            return f[u];

        else

        {

            f[u] = getf(f[u]);

            return f[u];

        }

    }

    void Merge(int u, int v)

    {

        int f1 = getf(u);

        int f2 = getf(v);

        if(f1 != f2)

        {

            f[f1] = f2;

        }

    }

};

vector<int> vec[maxn];

map<int, int> q;

int main()

{

    UMS u1, u2;

    int n, k, l, u, v;

    scanf("%d%d%d", &n, &k, &l);

    while(k--)

    {

        scanf("%d %d", &u, &v);

        u1.Merge(u, v);

    }

    while(l--)

    {

        scanf("%d %d", &u, &v);

        u2.Merge(u, v);

    }

    int vis[maxn];

    met(vis, 0);

    for(int i = 1; i <= n; i++)

    {

        int fa = u1.getf(i);

        vec[fa].push_back(i);

    }

    for(int i = 1; i <= n; i++)

    {

        q.clear();

        for(int j = 0; j < vec[i].size(); j++)

        {

            q[u2.getf(vec[i][j])] ++;

        }

        for(int j = 0; j < vec[i].size(); j++)

        {

            vis[vec[i][j]] += q[u2.getf(vec[i][j])];

        }



    }

    for(int i = 1; i <= n; i++)

    {

        printf("%d", vis[i]);

        if(i == n) printf("\n");

        else printf(" ");

    }

    return 0;

}


// Faster C++ solution for the same problem (measured speedup: 3.7400000327527514x):
#include <algorithm>

#include <iostream>

#include <iomanip>

#include <cstring>

#include <string>

#include <vector>

#include <queue>

#include <cmath>

using namespace std;



const int MAXN = 200000 + 10;

const int MAXL = 100000 + 10;



struct DSU

{

    int fa[MAXN];



    int find(int x)

    {

        if(x == fa[x])

            return x;

        return fa[x] = find(fa[x]);

    }



    void merge(int x, int y)

    {

        fa[find(x)] = find(y);

    }

}d1, d2;



int tmp[MAXN], ans[MAXN], cnt[MAXN];



void init(DSU & d)

{

    for(int i = 0; i < MAXN; i++)

        d.fa[i] = i;

}



int N, K, L;

int main()

{

    init(d1);

    init(d2);

    int u, v;

    cin >> N >> K >> L ;



    for(int i = 1; i <= K; i++)

        cin >> u >> v, d1.merge(u, v);

    for(int i = 1; i <= L; i++)

        cin >> u >> v, d2.merge(u, v);



    for(int i = 1; i <= N; i++)

        d1.fa[i] = d1.find(i),

        d2.fa[i] = d2.find(i);

    for(int i = 1; i <= N; i++)

        tmp[i] = i;

    sort(tmp+1, tmp+N+1, [](int x, int y)-> bool {return d1.fa[x] < d1.fa[y];});





    for(int i = 1; i <= N; i++)

    {

        int j = i;

        while(j < N && d1.fa[tmp[j]] == d1.fa[tmp[j+1]])

            j++;



        for(int t = i; t <= j; t++)

            cnt[d2.fa[tmp[t]]]++;

        for(int t = i; t <= j; t++)

            ans[tmp[t]] = cnt[d2.fa[tmp[t]]];

        for(int t = i; t <= j; t++)

            cnt[d2.fa[tmp[t]]]--;

        i = j ;

    }



    for(int i = 1; i <= N; i++)

        cout << ans[i] << " " ;



    return 0;

}