Problem p03855 (C++)

Buggy submission (status: Runtime Error):
#include <algorithm>
#include <bitset>
#include <cstdio>
#include <functional>
#include <iomanip>
#include <iostream>
#include <map>
#include <math.h>
#include <queue>
#include <set>
#include <sstream>
#include <string.h>
#include <unordered_map>
#include <unordered_set>
#include <vector>

using ll = long long;

#define rep(i, n) for (int i = 0; i < (int)(n); i++)
#define reps(i, x) for (int i = 1; i <= (int)(x); i++)
#define rrep(i, x) for (int i = ((int)(x)-1); i >= 0; i--)
#define rreps(i, x) for (int i = (int)(x); i > 0; i--)
#define all(x) (x).begin(), (x).end()
#define m0(x) memset(x, 0, sizeof(x))
#define vll vector<ll>
#define vi vector<int>
#define vpll vector<pair<ll, ll>>
#define vpi vector<pair<int, int>>
#define mod 1000000007

template <class T> inline bool chmax(T &a, T b) {
  if (a < b) {
    a = b;
    return 1;
  }
  return 0;
}

template <class T> inline bool chmin(T &a, T b) {
  if (a > b) {
    a = b;
    return 1;
  }
  return 0;
}

using namespace std;

struct UnionFind {
  vector<int> rank, parent;

  UnionFind() {}

  UnionFind(int size) {
    rank.resize(size, 0);
    parent.resize(size, 0);
    for (int i = 0; i < size; ++i) {
      makeSet(i);
    }
  }

  void makeSet(int x) {
    parent[x] = x;
    rank[x] = 0;
  }

  void link(int x, int y) {
    if (rank[x] < rank[y]) {
      parent[x] = y;
    } else {
      parent[y] = x;
      if (rank[x] == rank[y])
        rank[x]++;
    }
  }

  bool same(int x, int y) { return find(x) == find(y); }

  void unite(int x, int y) { link(find(x), find(y)); }

  int find(int x) {
    if (parent[x] != x) {
      parent[x] = find(parent[x]);
    }
    return parent[x];
  }
};

int main() {
  int n, k, l, p, q;
  cin >> n >> k >> l;
  UnionFind ro(n + 1);
  UnionFind ra(n + 1);
  rep(i, k) {
    cin >> p >> q;
    ro.unite(p, q);
  }
  rep(i, l) {
    cin >> p >> q;
    ra.unite(p, q);
  }
  vector<pair<int, int>> com(n);
  map<pair<int, int>, int> s;
  reps(i, n) {
    com[i].first = ro.find(i);
    com[i].second = ra.find(i);
    s[com[i]]++;
  }
  for (int i = 0; i < n; i++) {
    cout << s[com[i]] << " ";
  }
  printf("\n");
}


Fixed submission:
#include <algorithm>
#include <bitset>
#include <cstdio>
#include <functional>
#include <iomanip>
#include <iostream>
#include <map>
#include <math.h>
#include <queue>
#include <set>
#include <sstream>
#include <string.h>
#include <unordered_map>
#include <unordered_set>
#include <vector>

using ll = long long;

#define rep(i, n) for (int i = 0; i < (int)(n); i++)
#define reps(i, x) for (int i = 1; i <= (int)(x); i++)
#define rrep(i, x) for (int i = ((int)(x)-1); i >= 0; i--)
#define rreps(i, x) for (int i = (int)(x); i > 0; i--)
#define all(x) (x).begin(), (x).end()
#define m0(x) memset(x, 0, sizeof(x))
#define vll vector<ll>
#define vi vector<int>
#define vpll vector<pair<ll, ll>>
#define vpi vector<pair<int, int>>
#define mod 1000000007

template <class T> inline bool chmax(T &a, T b) {
  if (a < b) {
    a = b;
    return 1;
  }
  return 0;
}

template <class T> inline bool chmin(T &a, T b) {
  if (a > b) {
    a = b;
    return 1;
  }
  return 0;
}

using namespace std;

struct UnionFind {
  vector<int> rank, parent;

  UnionFind() {}

  UnionFind(int size) {
    rank.resize(size, 0);
    parent.resize(size, 0);
    for (int i = 0; i < size; ++i) {
      makeSet(i);
    }
  }

  void makeSet(int x) {
    parent[x] = x;
    rank[x] = 0;
  }

  void link(int x, int y) {
    if (rank[x] < rank[y]) {
      parent[x] = y;
    } else {
      parent[y] = x;
      if (rank[x] == rank[y])
        rank[x]++;
    }
  }

  bool same(int x, int y) { return find(x) == find(y); }

  void unite(int x, int y) { link(find(x), find(y)); }

  int find(int x) {
    if (parent[x] != x) {
      parent[x] = find(parent[x]);
    }
    return parent[x];
  }
};

int main() {
  int n, k, l, p, q;
  cin >> n >> k >> l;
  UnionFind ro(n + 1);
  UnionFind ra(n + 1);
  rep(i, k) {
    cin >> p >> q;
    ro.unite(p, q);
  }
  rep(i, l) {
    cin >> p >> q;
    ra.unite(p, q);
  }
  vector<pair<int, int>> com(n);
  map<pair<int, int>, int> s;
  rep(i, n) {
    com[i].first = ro.find(i + 1);
    com[i].second = ra.find(i + 1);
    s[com[i]]++;
  }
  for (int i = 0; i < n; i++) {
    cout << s[com[i]] << " ";
  }
  printf("\n");
}