Problem p03855 (C++)

Buggy submission (status: Runtime Error):
#include <bits/stdc++.h>
using namespace std;
#define REP(i, n) for (int i = 0; i < n; i++)
#define REPR(i, n) for (int i = n; i >= 0; i--)
#define FOR(i, m, n) for (int i = m; i < n; i++)
#define itrfor(itr, A) for (auto itr = A.begin(); itr != A.end(); itr++)
typedef long long llong;
char moji[26] = {'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i',
                 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r',
                 's', 't', 'u', 'v', 'w', 'x', 'y', 'z'};
char moji2[26] = {'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I',
                  'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R',
                  'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z'};
char moji3[10] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9'};
#define Sort(a) sort(a.begin(), a.end());
#define Reverse(a) reverse(a.begin(), a.end());
#define print(a) cout << a << endl;
#define n_max int(1e5 + 5)

struct UnionFind {
  int A[n_max];
  UnionFind(int n) { REP(i, n) A[i] = i; }

  int root(int a) {
    if (A[a] == a)
      return a;
    int tmp;
    tmp = root(A[a]);
    A[a] = tmp;
    return tmp;
  }

  bool same(int a, int b) {
    if (root(a) == root(b))
      return true;
    return false;
  }

  void merge(int a, int b) { A[root(a)] = root(b); }
};

struct town {
  int k, l;
  int id;
};

bool comp(town a, town b) {
  if (a.k != b.k)
    return a.k < b.k;
  else
    return a.l < b.l;
}

int main() {
  int n, k, l;
  cin >> n >> k >> l;
  UnionFind K(n), L(n);

  int a, b;
  REP(i, k) {
    scanf("%d%d", &a, &b);
    K.merge(a - 1, b - 1);
  }
  REP(i, l) {
    scanf("%d%d", &a, &b);
    L.merge(a - 1, b - 1);
  }

  town T[n_max];
  REP(i, n) {
    T[i].id = i;
    T[i].k = K.root(i);
    T[i].l = L.root(i);
  }

  sort(T, T + n, comp);

  int ans[n_max] = {};

  int i = 0;
  while (1) {
    pair<int, int> p;
    p.first = T[i].k;
    p.second = T[i].l;
    vector<int> ind;
    ind.push_back(T[i].id);
    while (1) {
      i += 1;
      if (i < n and T[i].k == p.first and T[i].l == p.second) {
        ind.push_back(T[i].id);
      } else {
        itrfor(itr, ind) ans[*itr] = ind.size();
        break;
      }
    }
    if (i >= n)
      break;
  }

  REP(i, n) cout << ans[i] << " ";
}

Fixed submission:
#include <bits/stdc++.h>
using namespace std;
#define REP(i, n) for (int i = 0; i < n; i++)
#define REPR(i, n) for (int i = n; i >= 0; i--)
#define FOR(i, m, n) for (int i = m; i < n; i++)
#define itrfor(itr, A) for (auto itr = A.begin(); itr != A.end(); itr++)
typedef long long llong;
char moji[26] = {'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i',
                 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r',
                 's', 't', 'u', 'v', 'w', 'x', 'y', 'z'};
char moji2[26] = {'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I',
                  'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R',
                  'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z'};
char moji3[10] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9'};
#define Sort(a) sort(a.begin(), a.end());
#define Reverse(a) reverse(a.begin(), a.end());
#define print(a) cout << a << endl;
#define n_max int(2 * 1e5 + 5)

struct UnionFind {
  int A[n_max];
  UnionFind(int n) { REP(i, n) A[i] = i; }

  int root(int a) {
    if (A[a] == a)
      return a;
    int tmp;
    tmp = root(A[a]);
    A[a] = tmp;
    return tmp;
  }

  bool same(int a, int b) {
    if (root(a) == root(b))
      return true;
    return false;
  }

  void merge(int a, int b) { A[root(a)] = root(b); }
};

struct town {
  int k, l;
  int id;
};

bool comp(town a, town b) {
  if (a.k != b.k)
    return a.k < b.k;
  else
    return a.l < b.l;
}

int main() {
  int n, k, l;
  cin >> n >> k >> l;
  UnionFind K(n), L(n);

  int a, b;
  REP(i, k) {
    scanf("%d%d", &a, &b);
    K.merge(a - 1, b - 1);
  }
  REP(i, l) {
    scanf("%d%d", &a, &b);
    L.merge(a - 1, b - 1);
  }

  town T[n_max];
  REP(i, n) {
    T[i].id = i;
    T[i].k = K.root(i);
    T[i].l = L.root(i);
  }

  sort(T, T + n, comp);

  int ans[n_max] = {};

  int i = 0;
  while (1) {
    pair<int, int> p;
    p.first = T[i].k;
    p.second = T[i].l;
    vector<int> ind;
    ind.push_back(T[i].id);
    while (1) {
      i += 1;
      if (i < n and T[i].k == p.first and T[i].l == p.second) {
        ind.push_back(T[i].id);
      } else {
        itrfor(itr, ind) ans[*itr] = ind.size();
        break;
      }
    }
    if (i >= n)
      break;
  }

  REP(i, n) cout << ans[i] << " ";
}