#include<bits/stdc++.h>
using namespace std;
struct _IO{_IO(){ios::sync_with_stdio(0);cin.tie(0);}}_io;

typedef long long ll;
typedef long double db;
typedef unsigned long long ull;
typedef vector<int> vi; typedef vector<vi> vii;
typedef pair<int, int> pi;
typedef tuple<int, int, int> t3;
typedef map<int, int> mi;
#define fi first
#define se second
#define vt vector
#define be begin()
#define ed end()
#define sz size()
#define cl clear()
#define pb push_back
#define eb emplace_back
#define all(x) x.begin(), x.end()
#define lb(v, x) lower_bound(v.begin(), v.end(), x)
#define lbi(v, x) (lb(v, x) - v.begin())
#define tp(t, x, y) t x, y; tie(x, y)
#define tp3(t, x, y, z) t x, y, z; tie(x, y, z)
#define mp make_pair
#define mt make_tuple
#define co const
#define fc(x) for(int x = 1, _end = ri(); x <= _end; x++)
void uni(vi &v) { sort(v.begin(), v.end()); v.erase(unique(v.begin(), v.end()), v.end()); }

db rd() { db x; cin >> x; return x; }
ll ri() { ll x; cin >> x; return x; }
string rs() { string s; cin >> s; return s; }
pi rpi() { pi x; cin >> x.fi >> x.se; return x; }
vi rvi(int n, int f = 0) { vi v(n + f); for (int i = f; i < v.size(); i++) cin >> v[i]; return v; }
vii rvii(int n, int m, int f = 0) { vii v(n + f, vi(n + f)); for (int i = f; i < v.size(); i++) for (int j = f; j < v[0].size(); j++) cin >> v[i][j]; return v; }
void pr() {}; template <class T, class ...U> void pr(T x, U ...y) { cout << x << ' ', pr(y...); }
void prl() { cout << '\n'; }; template <class T, class ...U> void prl(T x, U ...y) { cout << x << ' ', prl(y...); }
void pr(const vi &v, int f = 0) { for (int i = f; i < v.size(); i++) cout << v[i] << ' '; }
void prl(const vi &v, int f = 0) { pr(v, f); cout << '\n'; }
void pr(const pi &x) { cout << x.fi << ' ' << x.se; };
void prl(const pi &x) { pr(x); cout << '\n'; }

#define rep(i, l, r) for (int i = l; i < r; i++)
#define per(i, l, r) for (int i = l; i >= r; i--)

const int N = 2e5 + 5, M = 1e9 + 7;

int fa[N];
int fi(int x) {
  return !fa[x] || fa[x] == x ? x : fa[x] = fi(fa[x]);
}

vi g[N];
map<int, vi> cnt;
bool vis[N];
void dfs(int u) {
  vis[u] = 1;
  cnt[fi(u)].pb(u);
  for (auto &v : g[u]) {
    if (!vis[v]) dfs(v);
  }
}

int main() {
  int n = ri(), a = ri(), b = ri();
  rep(i, 0, a) {
    int x = ri(), y = ri();
    fa[fi(x)] = fi(y);
  }
  rep(i, 0, b) {
    int u = ri(), v = ri();
    g[u].pb(v);
    g[v].pb(u);
  }
  vi ans(n + 1);
  rep(i, 1, n + 1) {
    if (!vis[i]) {
      cnt.clear();
      dfs(i);
      for (auto &p : cnt) {
        for (auto &v : p.se) {
          ans[v] = p.se.sz;
        }
      }
    }
  }
  pr(ans, 1);
}

#include <bits/stdc++.h>
// statics
using namespace std;
using int64 = int_fast64_t;
using PAIR = pair<int, int>;
constexpr int INF = 1 << 30;
constexpr int64 LINF = 1LL << 60;
constexpr int MOD = 1e9 + 7;
constexpr int MAX_N = 1e5 + 1;

// init/input
#define int int64
#define INIT ios::sync_with_stdio(false);cin.tie(0);
#define VAR(type, ...) type __VA_ARGS__;MACRO_VAR_Scan(__VA_ARGS__);
template<typename T> void MACRO_VAR_Scan(T &t) {cin>>t;}
template<typename First, typename...Rest> void MACRO_VAR_Scan(First &first, Rest&...rest) {cin>>first;MACRO_VAR_Scan(rest...);}
#define VEC(type, c, n) vector<type> c(n);for(auto &&i:c)cin>>i;

// out
#define OUT(dist) cout<<(dist);
#define FOUT(n, dist) cout<<fixed<<setprecision(n)<<(dist);
#define SP cout<<" ";
#define BR cout<<"\n";
#define debug(x) cerr<<#x<<":"<< (x);BR;

// utility
#define ALL(a) (a).begin(), (a).end()
#define EACH(i, a) for(auto &&i:(a))
#define FOR(i, a, b) for(int i=(a);i<(b);++i)
#define RFOR(i, a, b) for(int i=(b)-1;i>=0;--i)
#define REP(i, n) for(int i=0;i<(n);++i)
#define RREP(i, n) for(int i=(n)-1;i>=0;--i)

struct UnionFind {
  vector< int > par;
  UnionFind(int n = 1) {
    init(n);
  }

  void init(int n = 1) {
    par.resize(n);
    for(int i = 0; i < n; i++)
      par[i] = -1;
  }
  
  int root(int n) {
    if (par[n] < 0) return n;
    return par[n] = root(par[n]);
  }

  bool merge(int x, int y) {
    x = root(x); y = root(y);
    if (x == y) return false;
    if (par[x] > par[y]) swap(x, y);
    par[x] += par[y];
    par[y] = x;

    return true;
  }

  bool issame(int x, int y) {
    return root(x) == root(y);
  }
};

signed main() {
  INIT;
	VAR(int, n, k, l);
	UnionFind road(n + 1);
	REP(i, k) {
		VAR(int, p, q);
		road.merge(--p, --q);
	}
	UnionFind train(n + 1);
	REP(i, l) {
		VAR(int, s, t);
		train.merge(--s, --t);
	}

	map< PAIR, int > mp;
	REP(i, n) {
		mp[make_pair(road.root(i), train.root(i))]++;
	}

	REP(i, n) {
		OUT(mp[make_pair(road.root(i), train.root(i))]);
		if (i < n - 1) SP
		else BR
	}
  
  return 0;
}
