Problem p03921 (C++)

Buggy submission (status: Runtime Error):
#include <algorithm>
#include <cmath>
#include <cstring>
#include <deque>
#include <iomanip> //cout << fixed << setprecision(15) << x << endl;
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <string>
#include <unordered_map>
#include <vector>

using namespace std;
typedef long long ll;
const ll INF = 1e9 + 6;
const ll MOD = 1e9 + 7;
const ll LLINF = 1LL << 60;
#define P pair<int, int>
#define rng(i, a, b) for (int i = int(a); i < int(b); i++)
#define rep(i, b) rng(i, 0, b)
#define pb push_back
#define mp make_pair
#define all(x) (x).begin(), (x).end()
/* -- template -- */

struct UnionFind {
  vector<int> par;
  vector<int> siz;

  UnionFind(int N) : par(N), siz(N) { // 最初は全てが根であるとして初期化
    for (int i = 0; i < N; i++)
      par[i] = i, siz[i] = 1;
  }

  int root(int x) { // データxが属する木の根を再帰で得る：root(x) = {xの木の根}
    if (par[x] == x)
      return x;
    return par[x] = root(par[x]);
  }

  void unite(int x, int y) { // xとyの木を併合
    int rx = root(x);        // xの根をrx
    int ry = root(y);        // yの根をry
    if (rx == ry)
      return; // xとyの根が同じ(=同じ木にある)時はそのまま
    siz[ry] += siz[rx];
    par[rx] =
        ry; // xとyの根が同じでない(=同じ木にない)時：xの根rxをyの根ryにつける
  }

  bool same(int x, int y) { // 2つのデータx, yが属する木が同じならtrueを返す
    int rx = root(x);
    int ry = root(y);
    return rx == ry;
  }

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

int main() {
  int N, M;
  cin >> N >> M;
  vector<int> L(M, -1);
  UnionFind G(N);
  rep(i, N) {
    int K;
    cin >> K;
    rep(j, K) {
      int l;
      cin >> l;
      --l;
      if (L[l] != -1) {
        G.unite(L[i], i);
      }
      L[l] = i;
    }
  }

  cout << ((G.size(0) == N) ? "YES" : "NO") << endl;
}


Fixed submission:
#include <algorithm>
#include <cmath>
#include <cstring>
#include <deque>
#include <iomanip> //cout << fixed << setprecision(15) << x << endl;
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <string>
#include <unordered_map>
#include <vector>

using namespace std;
typedef long long ll;
const ll INF = 1e9 + 6;
const ll MOD = 1e9 + 7;
const ll LLINF = 1LL << 60;
#define P pair<int, int>
#define rng(i, a, b) for (int i = int(a); i < int(b); i++)
#define rep(i, b) rng(i, 0, b)
#define pb push_back
#define mp make_pair
#define all(x) (x).begin(), (x).end()
/* -- template -- */

struct UnionFind {
  vector<int> par;
  vector<int> siz;

  UnionFind(int N) : par(N), siz(N) { // 最初は全てが根であるとして初期化
    for (int i = 0; i < N; i++)
      par[i] = i, siz[i] = 1;
  }

  int root(int x) { // データxが属する木の根を再帰で得る：root(x) = {xの木の根}
    if (par[x] == x)
      return x;
    return par[x] = root(par[x]);
  }

  void unite(int x, int y) { // xとyの木を併合
    int rx = root(x);        // xの根をrx
    int ry = root(y);        // yの根をry
    if (rx == ry)
      return; // xとyの根が同じ(=同じ木にある)時はそのまま
    siz[ry] += siz[rx];
    par[rx] =
        ry; // xとyの根が同じでない(=同じ木にない)時：xの根rxをyの根ryにつける
  }

  bool same(int x, int y) { // 2つのデータx, yが属する木が同じならtrueを返す
    int rx = root(x);
    int ry = root(y);
    return rx == ry;
  }

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

int main() {
  int N, M;
  cin >> N >> M;
  vector<int> L(M, -1);
  UnionFind G(N);
  rep(i, N) {
    int K;
    cin >> K;
    rep(j, K) {
      int l;
      cin >> l;
      --l;
      if (L[l] != -1) {
        G.unite(L[l], i);
      }
      L[l] = i;
    }
  }

  cout << ((G.size(0) == N) ? "YES" : "NO") << endl;
}