#include <bits/stdc++.h>
#define REP(i, n) for(int i = 0, i##_len = (n); i < i##_len; ++i)
#define REPS(i, n) for(int i = 1, i##_len = (n); i < i##_len; ++i)
#define ALL(x) (x).begin(), (x).end()
#define PRINT(A) std::cout << (#A) << ":" << (A) << std::endl;
using namespace std;
#define repi(itr, ds) for(auto itr = ds.begin(); itr != ds.end(); itr++)

// vector
template <typename T>
istream &operator>>(istream &is, vector<T> &vec) {
  for(T &x : vec) is >> x;
  return is;
}
// pair
template <typename T, typename U>
ostream &operator<<(ostream &os, pair<T, U> &pair_var) {
  os << "(" << pair_var.first << ", " << pair_var.second << ")";
  return os;
}
// vector
template <typename T>
ostream &operator<<(ostream &os, const vector<T> &vec) {
  os << "{";
  for(int i = 0; i < vec.size(); i++) {
    os << vec[i] << (i + 1 == vec.size() ? "" : ", ");
  }
  os << "}\n   ";
  return os;
}
// map
template <typename T, typename U>
ostream &operator<<(ostream &os, map<T, U> &map_var) {
  os << "{";
  repi(itr, map_var) {
    os << *itr;
    itr++;
    if(itr != map_var.end()) os << ", ";
    itr--;
  }
  os << "}";
  return os;
}
// set
template <typename T>
ostream &operator<<(ostream &os, set<T> &set_var) {
  os << "{";
  repi(itr, set_var) {
    os << *itr;
    itr++;
    if(itr != set_var.end()) os << ", ";
    itr--;
  }
  os << "}";
  return os;
}

#define DUMPOUT cerr

void dump_func() { DUMPOUT << endl; }
template <class Head, class... Tail>
void dump_func(Head &&head, Tail &&... tail) {
  DUMPOUT << head;
  if(sizeof...(Tail) > 0) {
    DUMPOUT << ", ";
  }
  dump_func(std::move(tail)...);
}
#ifdef DEBUG_
#define DEB
#define dump(...)                                                             \
  DUMPOUT << "  " << string(#__VA_ARGS__) << ": "                             \
          << "[" << to_string(__LINE__) << ":" << __FUNCTION__ << "]" << endl \
          << "    ",                                                          \
      dump_func(__VA_ARGS__)
#else
#define DEB if(false)
#define dump(...)
#endif

typedef long long int ll;
const int MOD = 1e9 + 7;
const int INF = 1e9;

class UnionFind {
 public:
  vector<ll> par;
  vector<ll> siz;

  // Constructor
  UnionFind(ll sz_) : par(sz_), siz(sz_, 1LL) {
    for(ll i = 0; i < sz_; ++i) par[i] = i;
  }
  void init(ll sz_) {
    par.resize(sz_);
    siz.assign(sz_, 1LL);
    for(ll i = 0; i < sz_; ++i) par[i] = i;
  }

  // Member Function
  // Find
  ll root(ll x) {
    while(par[x] != x) {
      x = par[x] = par[par[x]];
    }
    return x;
  }

  // Union(Unite, Merge)
  bool merge(ll x, ll y) {
    x = root(x);
    y = root(y);
    if(x == y) return false;
    if(siz[x] < siz[y]) swap(x, y);
    siz[x] += siz[y];
    par[y] = x;
    return true;
  }

  bool issame(ll x, ll y) {  // 連結判定
    return root(x) == root(y);
  }

  ll size(ll x) {  // 素集合のサイズ
    return siz[root(x)];
  }
};

int main() {
  int N, K, L;
  cin >> N >> K >> L;
  auto road = UnionFind(N);
  auto railway = UnionFind(N);
  REP(i, K) {
    int p, q;
    cin >> p >> q;
    p--;
    q--;
    road.merge(p, q);
  }
  REP(i, L) {
    int r, s;
    cin >> r >> s;
    r--;
    s--;
    railway.merge(r, s);
  }
  auto roots = map<pair<int, int>, int>();
  REP(i, N) {
    pair<int, int> p = {road.root(i), railway.root(i)};
    roots[p]++;
  }
  REP(i, N) {
    pair<int, int> p = {road.root(i), railway.root(i)};
    int cnt = roots[p];
    cout << cnt;
    if(i != N - 1) {
      cout << " ";
    } else {
      cout << endl;
    }
  }
}

#include <bits/stdc++.h>

#define rep(i,n) for(int i=0;i<n;i++)
#define repn(i,n) for(int i=1;i<=n;i++)
#define LL long long
#define pii pair <int,int>
#define fi first
#define se second
#define pb push_back
#define mpr make_pair

using namespace std;

const LL MOD=1e9+7;

int n,n2=1,q,a[500010],lst[500010],dat[2000010],ans[500010];
vector <pii> v[500010];

void upd(int k,int val)
{
	dat[k]+=val;
	while(k>0)
	{
		k=(k-1)/2;
		dat[k]+=val;
	}
}

int query(int k,int lb,int ub,int tlb,int tub)
{
	if(ub<tlb||tub<lb) return 0;
	if(tlb<=lb&&ub<=tub) return dat[k];
	return query(k*2+1,lb,(lb+ub)/2,tlb,tub)+query(k*2+2,(lb+ub)/2+1,ub,tlb,tub);
}

int main()
{
	cin>>n>>q;
	rep(i,n) scanf("%d",&a[i]);
	int x,y;
	rep(i,q)
	{
		scanf("%d%d",&x,&y);
		x--;
		y--;
		v[y].pb(mpr(x,i));
	}
	rep(i,n+5) lst[i]=-1;
	while(n2<n) n2*=2;
	rep(i,n)
	{
		if(lst[a[i]]>-1) upd(lst[a[i]]+n2-1,-1);
		upd(i+n2-1,1);
		lst[a[i]]=i;
		rep(j,v[i].size()) ans[v[i][j].se]=query(0,0,n2-1,v[i][j].fi,i);
	}
	rep(i,q) printf("%d\n",ans[i]);
	return 0;
}