#include <bits/stdc++.h>
//#include <boost/functional/hash.hpp>
//example: unordered_set< pair<int,int>,boost::hash< std::pair<int, int> > > used;
//priority_queue< pair<int,pair<int,int> >, vector<pair<int,pair<int,int>>>, greater<pair<int,pair<int,int> > > > pqueue;    //cost, vertex(行き先)
using namespace std;

#define MODULE 1000000007
#define MP make_pair
#define ALL(v) (v).begin(),(v).end()
#define fi first
#define se second

template<class T, class U>
inline void chmin(T &t, U f) { if (t > f)t = f; }

template<class T, class U>
inline void chmax(T &t, U f) { if (t < f)t = f; }

template<typename A, size_t N, typename T>
inline void Fill(A (&array)[N], const T &val) { //usage: int dp[10][10]; Fill(dp,INF);
    std::fill((T *) array, (T *) (array + N), val);
}

typedef pair<int, int> P;
typedef long long LL;
const int INF = INT_MAX / 2;    //int_max->2*e+9 LLの時はLLONG_MAX
//const int MAXN = 100001;

vector<int> graph[200010];
vector<int> graph2[200010];
vector<int> memo[200010];
/*int dx[4] = {-1, 0, 1, 0};
int dy[4] = {0, -1, 0, 1};*/

//-----Template---------
int n, k, l;
/*bool used[200010];
int res[200010];

int dfs(int v, int counter,vector<int>& me) {
    int tmpCounter = counter;
    me.push_back(v);
    for (int i = 0; i < graph[v].size(); ++i) {
        int tmp = graph[v][i];

        if (used[tmp])
            continue;

        bool flag = false;
        for (int j = 0; j < graph2[v].size(); ++j) {
            if (tmp == graph2[v][j]) { flag = true; }
        }
        if (flag) {
            used[tmp] = true;
            me.push_back(v);
            tmpCounter = dfs(tmp, tmpCounter + 1,me);
        }
    }
    memo[v]=me;
    return tmpCounter;
}*/

struct UnionFind {
    vector<int> data;

    UnionFind(int size) : data(size, -1) {}


    bool unite(int x, int y) {   //併合
        x = root(x);
        y = root(y);
        if (x != y) {
            if (data[y] < data[x]) swap(x, y);
            data[x] += data[y];
            data[y] = x;
        }
        return x != y;
    }

    bool isSame(int x, int y) {    //同じ集合か判定
        return root(x) == root(y);
    }

    int root(int x) {
        return data[x] < 0 ? x : data[x] = root(data[x]);
    }

    int size(int x) {
        return -data[root(x)];
    }
};

UnionFind uf1(200010);
UnionFind uf2(200010);

map<pair<int,int>,int> mp;
int main() {
    ios::sync_with_stdio(false); //cout<< fixed << setprecision(10);
//    memset(res, 1, sizeof(res));
    cin >> n >> k >> l;
    int p, q;
    for (int i = 0; i < k; ++i) {
        cin >> p >> q;  p--; q--;
        uf1.unite(p,q);
        //graph[p].push_back(q);
    }
    for (int i = 0; i < l; ++i) {
        cin >> p >> q; p--; q--;
        uf2.unite(p,q);
        //graph2[p].push_back(q);
    }
    for (int i = 0; i < n; ++i) {
        /*vector<int> h;
        h.push_back(i);
        int restmp=dfs(i,1,h);
        res[i]=restmp;
        for(int j=0;j<graph[i].size();j++){
            res[graph[i][j]]=restmp;
        }*/
        mp[MP(uf1.root(i),uf2.root(i))]++;
    }
    vector<int> ans;
    for (int i = 0; i < n; ++i) {
        ans.push_back(mp[MP(uf1.root(i),uf2.root(i))]);
    }
    for (int i = 0; i < n; ++i) {
        cout<<ans[i]<<" ";
    }
    cout<<endl;
}

Measured memory_bytes: 28660