#ifdef _MSC_VER
#define _CRT_SECURE_NO_WARNINGS
#  include <intrin.h>
#  define __builtin_popcount __popcnt
#endif

#define _USE_MATH_DEFINES

#include <stdio.h>
#include <stdlib.h>
#include <iostream>
#include <vector>
#include <unordered_map>
#include <stack>
#include <list>
#include <math.h>
#include <bitset>
#include <iterator>
#include <map>
#include <iomanip>
#include <functional>
#include <string>
#include <algorithm>
#include <queue>
#include <random>
#include <numeric>
#include <set>
#include <cassert>
#include <cmath>
#include <cinttypes>

using namespace std;

template<class T> ostream& operator<<(ostream& os, const vector<T>& v) { for (auto i = begin(v); i != end(v); i++) os << *i << (i == end(v) - 1 ? "" : " "); return os; }
template<class T> istream& operator>>(istream& is, vector<T>& v) { for (auto i = begin(v); i != end(v); i++) is >> *i; return is; }
struct fast_io {
	fast_io& operator>> (int& target) { scanf("%" PRId32, &target);  return *this; }
	fast_io& operator>> (unsigned int& target) { scanf("%" PRIu32, &target);  return *this; }
	fast_io& operator>> (long long& target) { scanf("%" PRId64, &target);  return *this; }
	fast_io& operator>> (unsigned long long& target) { scanf("%" PRIu64, &target);  return *this; }
	template<typename T> fast_io& operator>> (vector<T>& target) { for (auto& value : target) { *this >> value; } return *this; }
	fast_io& operator<< (const int value) { printf("%" PRId32, value); return *this; }
	fast_io& operator<< (const unsigned int value) { printf("%" PRIu32, value); return *this; }
	fast_io& operator<< (const long long value) { printf("%" PRId64, value); return *this; }
	fast_io& operator<< (const unsigned long long value) { printf("%" PRIu64, value); return *this; }
	fast_io& operator<< (const string& value) { printf("%s", value.c_str()); return *this; }
	template<typename T> fast_io& operator<< (const vector<T>& target) { for (auto& value : target) { *this << value << " "; } return *this; }
}; fast_io fio;

template<class ForwardIt, class UnaryPredicate>
ForwardIt first_true(ForwardIt first, ForwardIt last, UnaryPredicate predicate) {
	ForwardIt it;
	typename std::iterator_traits<ForwardIt>::difference_type count, step; count = std::distance(first, last);
	while (count > 0) {
		it = first;	step = count / 2;
		std::advance(it, step);
		if (!predicate(*it)) { first = ++it; count -= step + 1; }
		else count = step;
	}
	return first;
}

#define MOD 1000000007
#define pii pair<int,int>
#define pll pair<long long, long long>
#define all(x) (x).begin(), (x).end()
#define sort_all(x) sort(all(x))
#define make_unique(x) (x).erase(unique(all(x)), (x).end())


struct DsuNode
{
	int parent_id;
	int node_cnt = 1;
	int edge_cnt = 0;
};

class Dsu
{
#define USE_RECURSIVE_DSU_IMPLEMENTATION 1
private:
	vector<DsuNode> nodes;
	vector<int> tmp_stack;
public:
	Dsu(const int cnt)
	{
		nodes.resize(cnt);
		for (int i = 0; i < cnt; i++)
			nodes[i].parent_id = i;
	}

	int find_id(int id)
	{
		assert(id < nodes.size());
#if USE_RECURSIVE_DSU_IMPLEMENTATION
		if (nodes[id].parent_id == id)
			return id;
		return (nodes[id].parent_id = find_id(nodes[id].parent_id));
#else
		if (nodes[id].parent_id == id)
			return id;
		do
		{
			tmp_stack.push_back(id);
			id = nodes[id].parent_id;
		} while (nodes[id].parent_id != id);

		for (const int u : tmp_stack)
			nodes[u].parent_id = id;
		tmp_stack.clear();
		return id;
#endif
	}

	DsuNode& find(const int id)
	{
		return nodes[find_id(id)];
	}

	bool are_same(const int a, const int b)
	{
		return find_id(a) == find_id(b);
	}

	void join(int a, int b)
	{
		a = find_id(a);
		b = find_id(b);
		if (a != b)
		{
			if (nodes[a].node_cnt < nodes[b].node_cnt)
				swap(a, b);
			nodes[b].parent_id = a;

			nodes[a].node_cnt += nodes[b].node_cnt;
			nodes[a].edge_cnt += nodes[b].edge_cnt;
		}
	}
};


int main() {

#if defined(_DEBUG) 
	freopen("input.txt", "r", stdin);
	freopen("output.txt", "w", stdout);
#endif

	int n, k, l;
	fio >> n >> k >> l;

	vector<pii> vec;
	Dsu a(n), b(n);
	for (int i = 0; i < k; i++)
	{
		int u, v;
		fio >> u >> v;
		u--, v--;
		vec.push_back({ u,v });
		a.join(u, v);
	}

	for (int i = 0; i < l; i++)
	{
		int u, v;
		fio >> u >> v;
		u--, v--;
		vec.push_back({ u,v });
		b.join(u, v);
	}

	map<int, vector<int>> comps;
	for (int i = 0; i < n; i++)
		comps[a.find_id(i)].push_back(i);
	map<int, vector<int>> inner;
	vector<int> ans(n);
	for (auto& x : comps)
	{
		for (int j : x.second)
		{
			inner[b.find_id(j)].push_back(j);
		}
		for (auto& y : inner)
		{
			for (int jj : y.second)
			{
				ans[jj] = y.second.size();
			}
		}
		for (int j : x.second)
		{
			inner.erase(b.find_id(j));// ].push_back(j);
		}
	}

	fio << ans;


	return 0;
}


Measured memory_bytes: 29924