stablegradients/pie-gem5-pairs huggingface dataset:
// Slower C++ solution:
#include<cstdio>

#include<cstring>

#include<algorithm>

#include<set>

#include<map>

#define MAXN 200000

using namespace std;

typedef pair<int,int> PII;

map<PII,int> mp;

int setfa[2][MAXN+5];

void Init()

{

	for(int i=0;i<=MAXN+3;i++)

		setfa[0][i]=setfa[1][i]=i;

}

int Findfa(int x,int typ)

{

	if(setfa[typ][x]==x)

		return x;

	return setfa[typ][x]=Findfa(setfa[typ][x],typ);

}

void Union(int x,int y,int typ)

{

	int fx=Findfa(x,typ),fy=Findfa(y,typ);

	if(fx==fy)

		return;

	setfa[typ][fx]=fy;

}

int main()

{

	Init();

	int N,K,L;

	scanf("%d %d %d",&N,&K,&L);

	int x,y;

	for(int i=1;i<=K;i++)

	{

		scanf("%d %d",&x,&y);

		Union(x,y,0);

	}

	for(int i=1;i<=L;i++)

	{

		scanf("%d %d",&x,&y);

		Union(x,y,1);

	}

	for(int i=1;i<=N;i++)

	{

		int a=Findfa(i,0),b=Findfa(i,1);

		mp[PII(a,b)]++;

	}

	int Ans;

	for(int i=1;i<=N;i++)

	{

		int a=Findfa(i,0),b=Findfa(i,1);

		Ans=mp[PII(a,b)];

		if(i==1)

			printf("%d",Ans);

		else

			printf(" %d",Ans);

	}

	printf("\n");

	return 0;

}

// Faster C++ solution for the same problem (measured speedup: 2.5133616191749923x):
#include<bits/stdc++.h>

#define pii pair<int,int>



using namespace std;



int pr[200005] , pr2[200005];

map<pii,int>mp;



int find(int u)

{

    if(pr[u]==u)return u;

    return pr[u] = find(pr[u]);

}

int find2(int u)

{

    if(pr2[u]==u)return u;

    return pr2[u] = find2(pr2[u]);

}

int main()

{

    int n,m,r;

    cin >> n >> m >> r;

    for(int i=1; i<=n; i++)

    {

        pr[i] = i;

        pr2[i] = i;

    }

    for(int i=0; i<m; i++)

    {

        int u,v;

        cin >> u >> v;

        int a,b;

        a = find(u);

        b = find(v);

        if(a > b)

            swap(a,b);

        pr[a] = b;

    }

    for(int i=0; i<r; i++)

    {

        int u,v;

        cin >> u >> v;

        int a,b;

        a = find2(u);

        b = find2(v);

        if(a > b)

            swap(a,b);

        pr2[a] = b;

    }

    for(int i=1;i<=n;i++)

        mp[{find(i),find2(i)}]++;



    for(int i=1; i<=n; i++)cout << mp[{pr[i],pr2[i]}] << " ";

    cout << endl;

}
// Slower C++ solution:
#include <iostream>

#include <cstdio>

#include <cstring>

#include <cmath>

#include <algorithm>

#include <vector>

#include <map>

#define ms(x) memset(x, 0, sizeof(x))

#define inf 0x3f3f3f3f

using namespace std;

const int N = 200005;

vector<int >book[N];

int faf[N], fag[N];

int vis[N];

map<pair<int, int> , int>mp;

void init() {

    for(int i=0; i<N; i++) {

        faf[i] = fag[i] = i;

    }

}

int Find(int *f, int x){

    if(f[x] == x) return x;

    else{

        f[x] = Find(f, f[x]);

        return f[x];

    }

}

void Merge(int *f, int x, int y){

    int a = Find(f, x) , b = Find(f, y);

    if(a!=b){

        f[b] = a;

    }

}

int main() {

    int n, k, l;

    while(cin>>n>>k>>l) {

        int u, v;

        init();

        for(int i=0; i<k; i++) {

            scanf("%d%d",&u,&v);

            Merge(faf, u, v);

        }

        for(int i=0;i<l;i++){

            scanf("%d%d",&u,&v);

            Merge(fag, u, v);

        }

        for(int i=1;i<=n;i++){

            ++mp[{Find(faf, i), Find(fag, i)}];        //将同一个连通块中的点 集合起来

        }

        for(int i=1;i<=n;i++){

            printf("%d%c", mp[{Find(faf, i), Find(fag, i)}],i==n?'\n':' ');

        }

    }

    return 0;

}


// Faster C++ solution for the same problem (measured speedup: 7.906589341534298x):
#include "bits/stdc++.h"

using namespace std; 



const int maxn = 200005;



map<pair<int, int>, int> mp;



struct DSU {

  int par[maxn], sz[maxn];

  void init(int N){

    for(int i = 1; i <= N; ++i){

      par[i] = i; sz[i] = 1;

    }

  }

  int get(int x){

    if(par[x] == x)return x;

    else {

      return par[x] = get(par[x]);

    }

  }

  void unite(int x, int y){

    x = get(x); y = get(y);

    if(x == y)return;

    if(sz[x] < sz[y])swap(x, y);

    par[y] = x;

    sz[x] += sz[y];

  }

};



int main(int argc, char const *argv[])

{

	int n, m, k; 

  scanf("%d %d %d", &n, &m, &k);

  DSU t, t1;

  t.init(n); t1.init(n);

  for(int i = 0; i < m; ++i){

    int x, y;

    scanf("%d %d", &x, &y); 

    t.unite(x, y);

  }

  for(int i = 0; i < k; ++i){

    int x, y;

    scanf("%d %d", &x, &y);

    t1.unite(x, y);

  }

  for(int i = 1; i <= n; ++i){

    mp[{t.get(i), t1.get(i)}]++;

  }

  for(int i = 1; i <= n; ++i){

    printf("%d ", mp[{t.get(i), t1.get(i)}]);

  }



	return 0;

}
// Slower C++ solution:
#include <map>

#include <cmath>

#include <queue>

#include <stack>

#include <vector>

#include <cstdio>

#include <string>

#include <cstring>

#include <sstream>

#include <algorithm>



using namespace std;



int ro[200005], ra[200005], n, k, l;



int Find(int *r, int x) {

    return r[x]==x ? x : r[x]=Find(r, r[x]);

}



void init() {

    for(int i=1;i<=n;i++) {

        ra[i]=ro[i]=i;

    }

}



vector <int> ve[200005];

map <int, int> ma;

int ans[200005];



int main () {

    int u, v;

    scanf("%d%d%d", &n, &k, &l);

    init();

    for(int i=1;i<=k;i++) {

        scanf("%d%d", &u, &v);

        u=Find(ro, u), v=Find(ro, v);

        if(u!=v) {

            ro[u]=v;

        }

    }



    for(int i=1;i<=l;i++) {

        scanf("%d%d", &u, &v);

        u=Find(ra, u), v=Find(ra, v);

        if(u!=v) {

            ra[u]=v;

        }

    }



    for(int i=1;i<=n;i++) {

        ve[Find(ro, i)].push_back(i);

    }



    for(int i=1;i<=n;i++) {

        ma.clear();

        for(int j=0;j<(int)ve[i].size();j++) {

            ma[Find(ra, ve[i][j])]++;

        }



        for(int j=0;j<(int)ve[i].size();j++) {

            ans[ve[i][j]]+=ma[Find(ra, ve[i][j])];

        }

    }



    for(int i=1;i<=n;i++) {

        printf("%d%c", ans[i], i==n ? '\n' : ' ');

    }

    return 0;

}

// Faster C++ solution for the same problem (measured speedup: 5.959109323456112x):
#include "bits/stdc++.h"

using namespace std; 



const int maxn = 200005;



map<pair<int, int>, int> mp;



struct DSU {

  int par[maxn], sz[maxn];

  void init(int N){

    for(int i = 1; i <= N; ++i){

      par[i] = i; sz[i] = 1;

    }

  }

  int get(int x){

    if(par[x] == x)return x;

    else {

      return par[x] = get(par[x]);

    }

  }

  void unite(int x, int y){

    x = get(x); y = get(y);

    if(x == y)return;

    if(sz[x] < sz[y])swap(x, y);

    par[y] = x;

    sz[x] += sz[y];

  }

};



int main(int argc, char const *argv[])

{

	int n, m, k; 

  scanf("%d %d %d", &n, &m, &k);

  DSU t, t1;

  t.init(n); t1.init(n);

  for(int i = 0; i < m; ++i){

    int x, y;

    scanf("%d %d", &x, &y); 

    t.unite(x, y);

  }

  for(int i = 0; i < k; ++i){

    int x, y;

    scanf("%d %d", &x, &y);

    t1.unite(x, y);

  }

  for(int i = 1; i <= n; ++i){

    mp[{t.get(i), t1.get(i)}]++;

  }

  for(int i = 1; i <= n; ++i){

    printf("%d ", mp[{t.get(i), t1.get(i)}]);

  }



	return 0;

}
// Slower C++ solution:
#include<cstdio>

#include<cstring>

#include<algorithm>

#include<set>

#include<map>

#define MAXN 200000

using namespace std;

typedef pair<int,int> PII;

map<PII,int> mp;

int setfa[2][MAXN+5];

void Init()

{

	for(int i=0;i<=MAXN+3;i++)

		setfa[0][i]=setfa[1][i]=i;

}

int Findfa(int x,int typ)

{

	if(setfa[typ][x]==x)

		return x;

	return setfa[typ][x]=Findfa(setfa[typ][x],typ);

}

void Union(int x,int y,int typ)

{

	int fx=Findfa(x,typ),fy=Findfa(y,typ);

	if(fx==fy)

		return;

	setfa[typ][fx]=fy;

}

int main()

{

	Init();

	int N,K,L;

	scanf("%d %d %d",&N,&K,&L);

	int x,y;

	for(int i=1;i<=K;i++)

	{

		scanf("%d %d",&x,&y);

		Union(x,y,0);

	}

	for(int i=1;i<=L;i++)

	{

		scanf("%d %d",&x,&y);

		Union(x,y,1);

	}

	for(int i=1;i<=N;i++)

	{

		int a=Findfa(i,0),b=Findfa(i,1);

		mp[PII(a,b)]++;

	}

	int Ans;

	for(int i=1;i<=N;i++)

	{

		int a=Findfa(i,0),b=Findfa(i,1);

		Ans=mp[PII(a,b)];

		if(i==1)

			printf("%d",Ans);

		else

			printf(" %d",Ans);

	}

	printf("\n");

	return 0;

}

// Faster C++ solution for the same problem (measured speedup: 2.3642289640066023x):
#include "bits/stdc++.h"

using namespace std; 



const int maxn = 200005;



map<pair<int, int>, int> mp;



struct DSU {

  int par[maxn], sz[maxn];

  void init(int N){

    for(int i = 1; i <= N; ++i){

      par[i] = i; sz[i] = 1;

    }

  }

  int get(int x){

    if(par[x] == x)return x;

    else {

      return par[x] = get(par[x]);

    }

  }

  void unite(int x, int y){

    x = get(x); y = get(y);

    if(x == y)return;

    if(sz[x] < sz[y])swap(x, y);

    par[y] = x;

    sz[x] += sz[y];

  }

};



int main(int argc, char const *argv[])

{

	int n, m, k; 

  scanf("%d %d %d", &n, &m, &k);

  DSU t, t1;

  t.init(n); t1.init(n);

  for(int i = 0; i < m; ++i){

    int x, y;

    scanf("%d %d", &x, &y); 

    t.unite(x, y);

  }

  for(int i = 0; i < k; ++i){

    int x, y;

    scanf("%d %d", &x, &y);

    t1.unite(x, y);

  }

  for(int i = 1; i <= n; ++i){

    mp[{t.get(i), t1.get(i)}]++;

  }

  for(int i = 1; i <= n; ++i){

    printf("%d ", mp[{t.get(i), t1.get(i)}]);

  }



	return 0;

}
// Slower C++ solution:
#include <iostream>

#include <cstdio>

#include <cstring>

#include <cmath>

#include <algorithm>

#include <vector>

#include <map>

#define ms(x) memset(x, 0, sizeof(x))

#define inf 0x3f3f3f3f

using namespace std;

const int N = 200005;

vector<int >book[N];

int faf[N], fag[N];

int vis[N];

map<pair<int, int> , int>mp;

void init() {

    for(int i=0; i<N; i++) {

        faf[i] = fag[i] = i;

    }

}

int Find(int *f, int x){

    if(f[x] == x) return x;

    else{

        f[x] = Find(f, f[x]);

        return f[x];

    }

}

void Merge(int *f, int x, int y){

    int a = Find(f, x) , b = Find(f, y);

    if(a!=b){

        f[b] = a;

    }

}

int main() {

    int n, k, l;

    while(cin>>n>>k>>l) {

        int u, v;

        init();

        for(int i=0; i<k; i++) {

            scanf("%d%d",&u,&v);

            Merge(faf, u, v);

        }

        for(int i=0;i<l;i++){

            scanf("%d%d",&u,&v);

            Merge(fag, u, v);

        }

        for(int i=1;i<=n;i++){

            ++mp[{Find(faf, i), Find(fag, i)}];        //将同一个连通块中的点 集合起来

        }

        for(int i=1;i<=n;i++){

            printf("%d%c", mp[{Find(faf, i), Find(fag, i)}],i==n?'\n':' ');

        }

    }

    return 0;

}


// Faster C++ solution for the same problem (measured speedup: 3.182336451917532x):
#include <bits/stdc++.h>

using namespace std;



using ll = long long;

using ii = pair<int, int>;

using vi = vector<int>;

#define all(v) begin(v), end(v)



const int N = 2e5 + 5;



struct dsu {

  int sz[N], par[N];

  int n;

  dsu(int _n) : n(_n) {

    fill(sz+1, sz+1+n, 1);

    memset(par, 0, sizeof par);

    iota(par+1, par+1+n, 1);

  }

  int find(int u) {

    return par[u] == u ? u : par[u] = find(par[u]);

  }

  int unite(int u, int v) {

    u = find(u);

    v = find(v);

    if(u != v) {

      if(sz[u] > sz[v]) swap(u, v);

      sz[v] += sz[u];

      par[u] = v;

      return 1;

    } return 0;

  }

};



int n, k, l;



int main(int argc, char const *argv[])

{

#ifdef LOCAL

  freopen("in", "r", stdin);

#endif

  scanf("%d %d %d", &n, &k, &l);

  dsu road(n), rail(n);

  for(int i = 0; i < k; ++i) {

    int u, v;

    scanf("%d %d", &u, &v);

    road.unite(u, v);

  }

  for(int i = 0; i < l; ++i) {

    int u, v;

    scanf("%d %d", &u, &v);

    /*if(road.find(u) == road.find(v)) {

      rail.unite(u, v);

    }*/

    rail.unite(u, v);

  }

  map<ii, int> cnt;

  for(int i = 1; i <= n; ++i) {

    cnt[ii(road.find(i), rail.find(i))]++;

  }

  for(int i = 1; i <= n; ++i) {

    // printf("%d ", rail.sz[rail.find(i)]);

    printf("%d ", cnt[ii(road.find(i), rail.find(i))]);

  }

  puts("");

  return 0;

}
// Slower C++ solution:
#include <map>

#include <cmath>

#include <queue>

#include <stack>

#include <vector>

#include <cstdio>

#include <string>

#include <cstring>

#include <sstream>

#include <algorithm>



using namespace std;



int ro[200005], ra[200005], n, k, l;



int Find(int *r, int x) {

    return r[x]==x ? x : r[x]=Find(r, r[x]);

}



void init() {

    for(int i=1;i<=n;i++) {

        ra[i]=ro[i]=i;

    }

}



vector <int> ve[200005];

map <int, int> ma;

int ans[200005];



int main () {

    int u, v;

    scanf("%d%d%d", &n, &k, &l);

    init();

    for(int i=1;i<=k;i++) {

        scanf("%d%d", &u, &v);

        u=Find(ro, u), v=Find(ro, v);

        if(u!=v) {

            ro[u]=v;

        }

    }



    for(int i=1;i<=l;i++) {

        scanf("%d%d", &u, &v);

        u=Find(ra, u), v=Find(ra, v);

        if(u!=v) {

            ra[u]=v;

        }

    }



    for(int i=1;i<=n;i++) {

        ve[Find(ro, i)].push_back(i);

    }



    for(int i=1;i<=n;i++) {

        ma.clear();

        for(int j=0;j<(int)ve[i].size();j++) {

            ma[Find(ra, ve[i][j])]++;

        }



        for(int j=0;j<(int)ve[i].size();j++) {

            ans[ve[i][j]]+=ma[Find(ra, ve[i][j])];

        }

    }



    for(int i=1;i<=n;i++) {

        printf("%d%c", ans[i], i==n ? '\n' : ' ');

    }

    return 0;

}

// Faster C++ solution for the same problem (measured speedup: 2.398491941572876x):
#include <bits/stdc++.h>

using namespace std;



using ll = long long;

using ii = pair<int, int>;

using vi = vector<int>;

#define all(v) begin(v), end(v)



const int N = 2e5 + 5;



struct dsu {

  int sz[N], par[N];

  int n;

  dsu(int _n) : n(_n) {

    fill(sz+1, sz+1+n, 1);

    memset(par, 0, sizeof par);

    iota(par+1, par+1+n, 1);

  }

  int find(int u) {

    return par[u] == u ? u : par[u] = find(par[u]);

  }

  int unite(int u, int v) {

    u = find(u);

    v = find(v);

    if(u != v) {

      if(sz[u] > sz[v]) swap(u, v);

      sz[v] += sz[u];

      par[u] = v;

      return 1;

    } return 0;

  }

};



int n, k, l;



int main(int argc, char const *argv[])

{

#ifdef LOCAL

  freopen("in", "r", stdin);

#endif

  scanf("%d %d %d", &n, &k, &l);

  dsu road(n), rail(n);

  for(int i = 0; i < k; ++i) {

    int u, v;

    scanf("%d %d", &u, &v);

    road.unite(u, v);

  }

  for(int i = 0; i < l; ++i) {

    int u, v;

    scanf("%d %d", &u, &v);

    /*if(road.find(u) == road.find(v)) {

      rail.unite(u, v);

    }*/

    rail.unite(u, v);

  }

  map<ii, int> cnt;

  for(int i = 1; i <= n; ++i) {

    cnt[ii(road.find(i), rail.find(i))]++;

  }

  for(int i = 1; i <= n; ++i) {

    // printf("%d ", rail.sz[rail.find(i)]);

    printf("%d ", cnt[ii(road.find(i), rail.find(i))]);

  }

  puts("");

  return 0;

}
// Slower C++ solution:
#include <iostream>

#include <string.h>

#include <stdio.h>

#include <queue>

#include <vector>

#include <map>

#include <algorithm>

using namespace std;

const int Max=3e5+100;

int get_root(int *f, int root){

    return f[root]==root?root:f[root]=get_root(f, f[root]);

}

void merge(int *f, int x,int y){

    int i=get_root(f, x);

    int j=get_root(f, y);

    f[i]=j;

}

int f[Max], g[Max];

void init(int n){

    for(int a=0; a<=n; a++)f[a]=a, g[a]=a;

}

int vis[Max], num[Max];

vector<int> vec[Max];

map<int, int>ma;

int main(){

    int n, m, k, u, v;

    scanf("%d%d%d", &n, &m, &k);

    init(n);

    for(int a=0; a<m; a++){

        scanf("%d%d", &u, &v);

        merge(f, u, v);

    }

    for(int a=0; a<k; a++){

        scanf("%d%d", &u, &v);

        merge(g, u, v);

    }

    for(int a=1; a<=n; a++)vec[get_root(f, a)].push_back(a);

    for(int a=0; a<=n; a++){

        ma.clear();

       // memset(num, 0, sizeof(num));

        for(int b=0; b<vec[a].size(); b++){

            ma[get_root(g, vec[a][b])]++;

            //num[get_root(g, vec[a][b])]++;

        }

        for(int b=0; b<vec[a].size(); b++){

            vis[vec[a][b]]+=ma[get_root(g, vec[a][b])];

        }

    }

    for(int a=1; a<=n; a++)printf("%d%c", vis[a], a==n?'\n':' ');

    return  0;

}

// Faster C++ solution for the same problem (measured speedup: 9.392554946216062x):
#include<bits/stdc++.h> //Ithea Myse Valgulious

using namespace std;

const int yuzu=2e5;

typedef pair<int,int> pii;

typedef int fuko[yuzu|10];

fuko ans;

map<pii,int> mp;

int n,k,l;



struct dsu{

fuko fa;

void init(int n){

  for (int i=1;i<=n;++i) fa[i]=i;

  }

int find(int x){

  return fa[x]==x?x:fa[x]=find(fa[x]);

  }

void mg(int u,int v){

  fa[find(u)]=find(v);

  }

}gl,tl;



int main(){

int i;

scanf("%d%d%d",&n,&k,&l);

gl.init(n),tl.init(n);

for (i=1;i<=k;++i){

  int u,v;

  scanf("%d%d",&u,&v);

  gl.mg(u,v);

  }

for (i=1;i<=l;++i){

  int u,v;

  scanf("%d%d",&u,&v);

  tl.mg(u,v);

  }

for (i=1;i<=n;++i){

  mp[pii(gl.find(i),tl.find(i))]++; 

  }

for (i=1;i<=n;++i){

  printf("%d ",mp[pii(gl.find(i),tl.find(i))]);

  }

}
// Slower C++ solution:
#include <iostream>

#include <string.h>

#include <stdio.h>

#include <queue>

#include <vector>

#include <map>

#include <algorithm>

using namespace std;

const int Max=3e5+100;

int get_root(int *f, int root){

    return f[root]==root?root:f[root]=get_root(f, f[root]);

}

void merge(int *f, int x,int y){

    int i=get_root(f, x);

    int j=get_root(f, y);

    f[i]=j;

}

int f[Max], g[Max];

void init(int n){

    for(int a=0; a<=n; a++)f[a]=a, g[a]=a;

}

int vis[Max], num[Max];

vector<int> vec[Max];

map<int, int>ma;

int main(){

    int n, m, k, u, v;

    scanf("%d%d%d", &n, &m, &k);

    init(n);

    for(int a=0; a<m; a++){

        scanf("%d%d", &u, &v);

        merge(f, u, v);

    }

    for(int a=0; a<k; a++){

        scanf("%d%d", &u, &v);

        merge(g, u, v);

    }

    for(int a=1; a<=n; a++)vec[get_root(f, a)].push_back(a);

    for(int a=0; a<=n; a++){

        ma.clear();

       // memset(num, 0, sizeof(num));

        for(int b=0; b<vec[a].size(); b++){

            ma[get_root(g, vec[a][b])]++;

            //num[get_root(g, vec[a][b])]++;

        }

        for(int b=0; b<vec[a].size(); b++){

            vis[vec[a][b]]+=ma[get_root(g, vec[a][b])];

        }

    }

    for(int a=1; a<=n; a++)printf("%d%c", vis[a], a==n?'\n':' ');

    return  0;

}

// Faster C++ solution for the same problem (measured speedup: 9.47798944306845x):
#include<cstdio>

#include<cstring>

#include<cctype>

#include<algorithm>

#define maxn 200005

using namespace std;



int n,k,l;

int info[maxn],Prev[maxn*2],to[maxn*2],cnt_e,col[2][maxn],c[maxn],siz[maxn],fa[maxn];

inline void Node(const int &u,const int &v){ Prev[++cnt_e]=info[u],info[u]=cnt_e,to[cnt_e]=v; }

void dfs(int now,int c,int typ)

{

    col[typ][now]=c;

    for(int i=info[now];i;i=Prev[i])

        if(!col[typ][to[i]])

            dfs(to[i],c,typ);

}

inline bool cmp(const int &a,const int &b){ return col[0][a]==col[0][b] ? col[1][a]<col[1][b] : col[0][a] < col[0][b]; }



int main()

{

    scanf("%d%d%d",&n,&k,&l);

    for(int i=1,u,v;i<=k;i++)

    {

        scanf("%d%d",&u,&v);

        Node(u,v),Node(v,u);

    }



    for(int i=1;i<=n;i++)

        if(!col[0][i])

            dfs(i,i,0);



    cnt_e=0;

    memset(info,0,sizeof info);

    for(int i=1,u,v;i<=l;i++)

    {

        scanf("%d%d",&u,&v);

        Node(u,v),Node(v,u);

    }





    for(int i=1;i<=n;i++)

        if(!col[1][i])

            dfs(i,i,1);





    for(int i=1;i<=n;i++)

        c[i]=i;



    sort(c+1,c+1+n,cmp);



    for(int i=1;i<=n;i++)

    {

        fa[c[i]]=c[i];

        if(i!=1 && col[0][c[i]] == col[0][c[i-1]] && col[1][c[i]]== col[1][c[i-1]])

            fa[c[i]] = fa[c[i-1]];

        siz[fa[c[i]]]++;

    }



    for(int i=1;i<n;i++) printf("%d ",siz[fa[i]]);

    printf("%d",siz[fa[n]]);

}
// Slower C++ solution:
#include <iostream>

#include <string.h>

#include <stdio.h>

#include <queue>

#include <vector>

#include <map>

#include <algorithm>

using namespace std;

const int Max=3e5+100;

int get_root(int *f, int root){

    return f[root]==root?root:f[root]=get_root(f, f[root]);

}

void merge(int *f, int x,int y){

    int i=get_root(f, x);

    int j=get_root(f, y);

    f[i]=j;

}

int f[Max], g[Max];

void init(int n){

    for(int a=0; a<=n; a++)f[a]=a, g[a]=a;

}

int vis[Max], num[Max];

vector<int> vec[Max];

map<int, int>ma;

int main(){

    int n, m, k, u, v;

    scanf("%d%d%d", &n, &m, &k);

    init(n);

    for(int a=0; a<m; a++){

        scanf("%d%d", &u, &v);

        merge(f, u, v);

    }

    for(int a=0; a<k; a++){

        scanf("%d%d", &u, &v);

        merge(g, u, v);

    }

    for(int a=1; a<=n; a++)vec[get_root(f, a)].push_back(a);

    for(int a=0; a<=n; a++){

        ma.clear();

       // memset(num, 0, sizeof(num));

        for(int b=0; b<vec[a].size(); b++){

            ma[get_root(g, vec[a][b])]++;

            //num[get_root(g, vec[a][b])]++;

        }

        for(int b=0; b<vec[a].size(); b++){

            vis[vec[a][b]]+=ma[get_root(g, vec[a][b])];

        }

    }

    for(int a=1; a<=n; a++)printf("%d%c", vis[a], a==n?'\n':' ');

    return  0;

}

// Faster C++ solution for the same problem (measured speedup: 9.499103405208219x):
#include <cstdio>

#include <cstring>

#include <iostream>

#include <algorithm>

using namespace std;

#define N 200005

int n, k, l;

int tar[2 * N], nex[2 * N], fir[N], cnt;

int bel[N], sum[N], ans[N], stk[N], vis[N], top;

int Getbel(int x)

{

	if (!bel[x])

		return x;

	return bel[x] = Getbel(bel[x]);

}

void add(int a, int b)

{

	++cnt;

	tar[cnt] = b;

	nex[cnt] = fir[a];

	fir[a] = cnt;

}

void dfs(int r)

{

	vis[r] = 1;

	stk[++top] = r;

	for (int i = fir[r]; i; i = nex[i])

	{

		int v = tar[i];

		if (!vis[v])

			dfs(v);

	}

}

int main()

{

	scanf("%d%d%d", &n, &k, &l);

	for (int i = 1; i <= k; i++)

	{

		int a, b;

		scanf("%d%d", &a, &b);

		a = Getbel(a), b = Getbel(b);

		if (a != b)

			bel[a] = b;

	}

	for (int i = 1; i <= l; i++)

	{

		int a, b;

		scanf("%d%d", &a, &b);

		add(a, b), add(b, a);

	}

	for (int i = 1; i <= n; i++)

	{

		if (!vis[i])

		{

			dfs(i);

			for (int j = 1; j <= top; j++)

				sum[Getbel(stk[j])]++;

			for (int j = 1; j <= top; j++)

				ans[stk[j]] = sum[Getbel(stk[j])];

			for (int j = 1; j <= top; j++)

				sum[Getbel(stk[j])]--;

			top = 0;

		}

	}

	for (int i = 1; i <= n; i++)

		printf("%d%c", ans[i], i == n ? 10 : 32);

}