// Original C++ solution (slower):
#include<iostream>

#include<cstdio>

#include<algorithm>

#include<cmath>

#include<string>

#include<cstring>

#include<vector>

#include<map>

#include<list>

#include<stack>

#include<queue>

#include<climits> //llong int_MIN/MAX





using namespace std;



#define FOR(i,s,e) for(llong int (i)=(s);(i)<(e);(i)++)

#define FORR(i,s,e) for(llong int (i)=(s);(i)>(e);(i)--)

#define MOD 1000000007

#define llong long long

#define debug(x) cout<<#x<<": "<<x<<endl

#define non -1

#define MAX 200010

llong n;



llong int color1[MAX];

llong int color2[MAX];

vector<llong int> G1[MAX];

vector<llong int> G2[MAX];

llong City[MAX];



void dfs1(llong int r, llong int c, llong int color[MAX], vector<llong int> G[MAX]) {//r

    stack<llong int>S;

    S.push(r);

    color[r] = c;

    while (!S.empty()) {

        llong int u = S.top();

        S.pop();



        FOR(i, 0, (llong int)G[u].size()) {

            llong int v = G[u][i];

            if (color[v] == non) {

                color[v] = c;

                S.push(v);

            }

        }

    }

}









void assigncolor1(llong int color[MAX], vector<llong int>G[MAX]) {

    llong int id = 1;

    FOR(i, 1, n + 1)

        color[i] = non;

    FOR(u, 1, n + 1) {

        if (color[u] == non)

            dfs1(u, id++, color, G);

    }

}











int main()

{

    cin.tie(0);

    ios_base::sync_with_stdio(false);



    llong int k, l;

    cin >> n >> k >> l;





    bool visit1[MAX];

    bool visit2[MAX];

    bool CityP[MAX];





    FOR(i, 1, n + 1) {

        visit1[i] = false;

        visit2[i] = false;

        City[i] = 1;

        CityP[i] = false;

    }





    FOR(i, 0, k) {

        llong int s, t;

        cin >> s >> t;

        G1[s].push_back(t);

        G1[t].push_back(s);



    }





    FOR(i, 0, l) {

        llong int s, t;

        cin >> s >> t;

        G2[s].push_back(t);

        G2[t].push_back(s);



    }



    assigncolor1(color1, G1);

    /*

      FOR(i, 1, n + 1) {

          cout << "color1 : v" << i << ": " << color1[i] << endl;

      }*/



    assigncolor1(color2, G2);



    /*FOR(i, 1, n + 1) {

        cout << "color2 : v" << i << ": " << color2[i] << endl;

    }

*/



//

//    FOR(v, 1, n + 1) {

//        if (visit1[v] == true)continue;

//        llong int count = 1;

//        queue<llong int >Q;

//       // queue<llong int >Q2;

//

//        Q.push(v);

//        //Q2.push(v);

//

//        while (!Q.empty()) {

//            llong int u = Q.front();

//            Q.pop();

//            visit1[u] = true;

//            FOR(i, 0, (llong int)G2[u].size()) {

//                llong int p = G2[u][i];

//                if (visit1[p] == false)

//                    if (color1[u] == color1[p] && color2[u] == color2[p]) {

//                        count++;

//                        /*  debug(count);

//                            debug(u);

//                            debug(p);

//        */

//                        Q.push(p);

//          //              Q2.push(p);

//                        visit1[p] = true;

//                    }

//            }

//        }

///*

//        count = Q2.size();

//        while (!Q2.empty()) {

//            llong int u = Q2.front();

//            Q2.pop();

//            City[u] = count;

//        }*/

//

//    }

//

//

    map<pair<int, int>, int>M;





    FOR(i, 1, n + 1) {

        M[make_pair(color1[i], color2[i])]++;

    }



    FOR(i, 1, n) {



        cout << M[make_pair(color1[i], color2[i])] << " ";



    }

    cout << M[make_pair(color1[n],color2[n])] << endl;





    return 0;

}


// Optimized solution to the same problem (faster):
#include <bits/stdc++.h>

using namespace std;



using VS = vector<string>;    using LL = long long;

using VI = vector<int>;       using VVI = vector<VI>;

using PII = pair<int, int>;   using PLL = pair<LL, LL>;

using VL = vector<LL>;        using VVL = vector<VL>;



#define ALL(a)  begin((a)),end((a))

#define RALL(a) (a).rbegin(), (a).rend()

#define SZ(a) int((a).size())

#define SORT(c) sort(ALL((c)))

#define RSORT(c) sort(RALL((c)))

#define UNIQ(c) (c).erase(unique(ALL((c))), end((c)))

#define FOR(i, s, e) for (int(i) = (s); (i) < (e); (i)++)

#define FORR(i, s, e) for (int(i) = (s); (i) > (e); (i)--)

//#pragma GCC optimize ("-O3") 

#ifdef YANG33

#include "mydebug.hpp"

#else

#define DD(x) 

#endif

const int INF = 1e9;                          const LL LINF = 1e16;

const LL MOD = 1000000007;                    const double PI = acos(-1.0);

int DX[8] = { 0, 0, 1, -1, 1, 1, -1, -1 };    int DY[8] = { 1, -1, 0, 0, 1, -1, 1, -1 };



/* -----  2019/04/03  Problem: ABC 049 D / Link: http://abc049.contest.atcoder.jp/tasks/abc049_d  ----- */







struct UnionFind {

	vector<int> data;

	UnionFind(int n) { data.assign(n, -1); }

	bool unionSet(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 same(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)]; }

};



int main() {

	cin.tie(0);

	ios_base::sync_with_stdio(false);



	LL N, K, L; cin >> N >> K >> L;

	UnionFind A(N), B(N);

	FOR(i, 0, K) {

		int a, b; cin >> a >> b;

		a--, b--;

		A.unionSet(a, b);

	}

	FOR(i, 0, L) {

		int a, b; cin >> a >> b;

		a--, b--;

		B.unionSet(a, b);

	}

	map<PII, int>M;

	FOR(i, 0, N) {

		M[PII(A.root(i), B.root(i))]++;

	}



	FOR(i, 0, N) {

		cout << M[PII(A.root(i), B.root(i))] << " \n"[i == N - 1];

	}



	return 0;

}


// Fastest known solution for this problem: