Problem p03855 (C++)

Buggy submission (status: Time Limit Exceeded):
#include <bits/stdc++.h>
using namespace std;
using Graph = vector<vector<int>>;
#define rep(i, a) for (int i = 0; i < (a); i++)
#define FOR(i, m, n) for (int i = m; i < n; i++)

typedef pair<int, int> P;
typedef long long ll;

const int INF = 1001001001;
const int MOD = 1000000007;
const double PI = acos(-1);

//---------------------------------------------
class UnionFind {
public:
  vector<ll> par; // 各元の親を表す配列
  vector<ll> siz;
  vector<ll> tree_rank;

  // Constructor
  UnionFind(ll sz_) : par(sz_), siz(sz_, 1), tree_rank(sz_) {
    for (ll i = 0; i < sz_; ++i) {
      par[i] = i; // 初期では親は自分自身
      tree_rank[i] = 0;
    }
  }
  void init(ll sz_) {
    par.resize(sz_);
    siz.resize(sz_, 1);
    tree_rank.resize(sz_);
    for (ll i = 0; i < sz_; ++i) {
      par[i] = i; // 初期では親は自分自身
      tree_rank[i] = 0;
    }
  }

  // Member Function
  // Find
  ll root(ll x) { // 根の検索
    if (par[x] == x) {
      return x;
    } else {
      return par[x] = root(par[x]);
    }
  }

  // Union(Unite, Merge)
  void unite(ll x, ll y) {
    x = root(x);
    y = root(y);
    if (x == y)
      return;
    if (tree_rank[x] < tree_rank[y]) {
      par[x] = y;
      siz[y] += siz[x];
    } else {
      par[y] = x;
      siz[x] += siz[y];
      if (tree_rank[x] == tree_rank[y])
        tree_rank[x]++;
    }
  }

  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;

  UnionFind UFK(N), UFL(N);

  rep(i, K) {
    int p, q;
    cin >> p >> q;
    p--;
    q--;
    UFK.unite(p, q);
  }
  rep(i, L) {
    int r, s;
    cin >> r >> s;
    r--;
    s--;
    UFL.unite(r, s);
  }

  rep(i, N) {
    int ans = 1;
    rep(j, N) {
      if (i == j) {
        continue;
      } else {
        if (UFK.issame(i, j) && UFL.issame(i, j)) {
          ans++;
        }
      }
    }
    cout << ans << " ";
  }
  cout << endl;
}

Fixed submission:
#include <bits/stdc++.h>
using namespace std;
using Graph = vector<vector<int>>;
#define rep(i, a) for (int i = 0; i < (a); i++)
#define FOR(i, m, n) for (int i = m; i < n; i++)

typedef pair<int, int> P;
typedef long long ll;

const int INF = 1001001001;
const int MOD = 1000000007;
const double PI = acos(-1);

//---------------------------------------------
class UnionFind {
public:
  vector<ll> par; // 各元の親を表す配列
  vector<ll> siz;
  vector<ll> tree_rank;

  // Constructor
  UnionFind(ll sz_) : par(sz_), siz(sz_, 1), tree_rank(sz_) {
    for (ll i = 0; i < sz_; ++i) {
      par[i] = i; // 初期では親は自分自身
      tree_rank[i] = 0;
    }
  }
  void init(ll sz_) {
    par.resize(sz_);
    siz.resize(sz_, 1);
    tree_rank.resize(sz_);
    for (ll i = 0; i < sz_; ++i) {
      par[i] = i; // 初期では親は自分自身
      tree_rank[i] = 0;
    }
  }

  // Member Function
  // Find
  ll root(ll x) { // 根の検索
    if (par[x] == x) {
      return x;
    } else {
      return par[x] = root(par[x]);
    }
  }

  // Union(Unite, Merge)
  void unite(ll x, ll y) {
    x = root(x);
    y = root(y);
    if (x == y)
      return;
    if (tree_rank[x] < tree_rank[y]) {
      par[x] = y;
      siz[y] += siz[x];
    } else {
      par[y] = x;
      siz[x] += siz[y];
      if (tree_rank[x] == tree_rank[y])
        tree_rank[x]++;
    }
  }

  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;

  UnionFind UFK(N), UFL(N);

  rep(i, K) {
    int p, q;
    cin >> p >> q;
    p--;
    q--;
    UFK.unite(p, q);
  }
  rep(i, L) {
    int r, s;
    cin >> r >> s;
    r--;
    s--;
    UFL.unite(r, s);
  }

  map<pair<ll, ll>, int> m;

  rep(i, N) { m[{UFK.root(i), UFL.root(i)}]++; }
  rep(i, N) { cout << m[{UFK.root(i), UFL.root(i)}] << " "; }
  cout << endl;
}