Problem p03921 (C++)

Buggy submission (status: Runtime Error):
#include <bits/stdc++.h>

using namespace std;

using ll = long long int;
using ld = long double;
using pii = pair<int, int>;
using pll = pair<ll, ll>;
template <typename Q_temp>
using smaller_queue = priority_queue<Q_temp, vector<Q_temp>, greater<Q_temp>>;

const int INF = (int)1e9;
const ll LINF = (ll)4e18;
const ll MOD = (ll)(1e9 + 7);
const double PI = acos(-1.0);
const int limit = 100010;

#define REP(i, m, n) for (ll i = m; i < (ll)(n); ++i)
#define rep(i, n) REP(i, 0, n)
#define MP make_pair
#define YES(n) cout << ((n) ? "YES" : "NO") << endl
#define Yes(n) cout << ((n) ? "Yes" : "No") << endl
#define Possible(n) cout << ((n) ? "Possible" : "Impossible") << endl
#define NP(v) next_permutation(v.begin(), v.end())
#define debug(x) cout << #x << ":" << x << endl;
#define debug2(x)                                                              \
  for (auto a : x)                                                             \
    cout << a << " ";                                                          \
  cout << endl;

vector<pii> around = {MP(1, 0), MP(-1, 0), MP(0, 1), MP(0, -1)};

//------------------------------------------------------

class UnionFind {
public:
  vector<int> par, sizes;

  UnionFind(int n) : par(n), sizes(n, 1) { rep(i, n) par[i] = i; }

  int root(int x) {
    if (x == par[x])
      return x;
    return par[x] = root(par[x]);
  }

  void unite(int x, int y) {
    x = root(x);
    y = root(y);
    if (x == y)
      return;
    if (sizes[x] < sizes[y])
      swap(x, y);
    par[y] = x;
    sizes[x] += sizes[y];
  }

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

  int size(int x) { return sizes[root(x)]; }
};

int main() {
  cin.tie(0);
  ios::sync_with_stdio(false);

  int n, m;
  cin >> n >> m;
  UnionFind uf(n);
  vector<int> can_lang[m], p[n];

  rep(i, n) {
    int k;
    cin >> k;

    rep(j, k) {
      int l;
      cin >> l;
      l--;
      can_lang[l].push_back(i);
      p[i].push_back(l);
    }
  }

  rep(l, m) rep(i, (int)(can_lang[l].size()) - 1) {
    uf.unite(can_lang[l][i], can_lang[l][i + 1]);
  }

  rep(pi, n) rep(i, (int)(p[pi].size()) - 1) {
    uf.unite(p[pi][i], p[pi][i + 1]);
  }
  YES(uf.size(0) == n);
  return 0;
}


Fixed submission:
#include <bits/stdc++.h>

using namespace std;

using ll = long long int;
using ld = long double;
using pii = pair<int, int>;
using pll = pair<ll, ll>;
template <typename Q_temp>
using smaller_queue = priority_queue<Q_temp, vector<Q_temp>, greater<Q_temp>>;

const int INF = (int)1e9;
const ll LINF = (ll)4e18;
const ll MOD = (ll)(1e9 + 7);
const double PI = acos(-1.0);
const int limit = 100010;

#define REP(i, m, n) for (ll i = m; i < (ll)(n); ++i)
#define rep(i, n) REP(i, 0, n)
#define MP make_pair
#define YES(n) cout << ((n) ? "YES" : "NO") << endl
#define Yes(n) cout << ((n) ? "Yes" : "No") << endl
#define Possible(n) cout << ((n) ? "Possible" : "Impossible") << endl
#define NP(v) next_permutation(v.begin(), v.end())
#define debug(x) cout << #x << ":" << x << endl;
#define debug2(x)                                                              \
  for (auto a : x)                                                             \
    cout << a << " ";                                                          \
  cout << endl;

vector<pii> around = {MP(1, 0), MP(-1, 0), MP(0, 1), MP(0, -1)};

//------------------------------------------------------

class UnionFind {
public:
  vector<int> par, sizes;

  UnionFind(int n) : par(n), sizes(n, 1) { rep(i, n) par[i] = i; }

  int root(int x) {
    if (x == par[x])
      return x;
    return par[x] = root(par[x]);
  }

  void unite(int x, int y) {
    x = root(x);
    y = root(y);
    if (x == y)
      return;
    if (sizes[x] < sizes[y])
      swap(x, y);
    par[y] = x;
    sizes[x] += sizes[y];
  }

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

  int size(int x) { return sizes[root(x)]; }
};

int main() {
  cin.tie(0);
  ios::sync_with_stdio(false);

  int n, m;
  cin >> n >> m;
  UnionFind uf(n);
  vector<int> can_lang[m], p[n];

  rep(i, n) {
    int k;
    cin >> k;

    rep(j, k) {
      int l;
      cin >> l;
      l--;
      can_lang[l].push_back(i);
      p[i].push_back(l);
    }
  }

  rep(l, m) rep(i, (int)(can_lang[l].size()) - 1) {
    uf.unite(can_lang[l][i], can_lang[l][i + 1]);
  }

  rep(pi, n) rep(i, (int)(p[pi].size()) - 1) {
    int la = p[pi][i], lb = p[pi][i + 1];
    if (can_lang[la].size() == 0 || can_lang[lb].size() == 0)
      continue;
    uf.unite(can_lang[la][0], can_lang[lb][0]);
  }
  YES(uf.size(0) == n);
  return 0;
}