Problem p02906 (C++)

Buggy submission (status: Runtime Error):
#include <algorithm>
#include <assert.h>
#include <bitset>
#include <complex>
#include <deque>
#include <functional>
#include <iomanip>
#include <iostream>
#include <map>
#include <math.h>
#include <numeric>
#include <queue>
#include <set>
#include <stack>
#include <string>
#include <vector>
using namespace std;
#define REP(i, m, n) for (int i = (int)(m); i < (int)(n); ++i)
#define rep(i, n) REP(i, 0, n)
using ll = long long;
const int inf = 1e9 + 7;
const ll longinf = 1LL << 60;
const ll mod = 1e9 + 7;

struct UnionFind {
  vector<int> par;
  UnionFind(int n) : par(n, -1) {}
  int find(int x) {
    if (par[x] < 0)
      return x;
    return par[x] = find(par[x]);
  }
  bool unite(int x, int y) {
    x = find(x);
    y = find(y);
    if (x == y)
      return false;
    if (par[x] > par[y]) {
      par[y] += par[x];
      par[x] = y;
    } else {
      par[x] += par[y];
      par[y] = x;
    }
    return true;
  }

  bool same(int x, int y) { return find(x) == find(y); }
  int size(int x) { return -par[find(x)]; }
};
int main() {
  ll n, m, q;
  cin >> n >> m >> q;
  vector<pair<int, int>> edge;
  UnionFind uf(n);
  ll nn = n;
  while (q--) {
    int x, y, t;
    cin >> x >> y >> t;
    --x;
    --y;
    if (t) {
      edge.emplace_back(x, y);
    } else {
      if (uf.unite(x, y)) {
        --m;
        --nn;
      }
    }
  }
  vector<int> used(n);
  ll cnt = 0;
  for (auto p : edge) {
    int x = uf.find(p.first), y = uf.find(p.second);
    if (x == y) {
      cout << "No" << endl;
      return 0;
    }
    if (!used[x])
      ++cnt;
    if (!used[y])
      ++cnt;
    used[x] = used[y] = 1;
  }
  if (cnt == 0) {
    ll mi = nn - 1, ma = nn * (nn - 1) / 2;
    if (mi <= m && m <= ma) {
      cout << "Yes" << endl;
    } else
      cout << "No" << endl;
  } else {
    ll mi = nn, ma = nn * (nn - 1) / 2;
    if (mi <= m && m <= ma) {
      cout << "Yes" << endl;
    } else
      cout << "No" << endl;
  }
  return 0;
}

Fixed submission:
#include <algorithm>
#include <assert.h>
#include <bitset>
#include <complex>
#include <deque>
#include <functional>
#include <iomanip>
#include <iostream>
#include <map>
#include <math.h>
#include <numeric>
#include <queue>
#include <set>
#include <stack>
#include <string>
#include <vector>
using namespace std;
#define REP(i, m, n) for (int i = (int)(m); i < (int)(n); ++i)
#define rep(i, n) REP(i, 0, n)
using ll = long long;
const int inf = 1e9 + 7;
const ll longinf = 1LL << 60;
const ll mod = 1e9 + 7;

struct UnionFind {
  vector<int> par;
  UnionFind(int n) : par(n, -1) {}
  int find(int x) {
    if (par[x] < 0)
      return x;
    return par[x] = find(par[x]);
  }
  bool unite(int x, int y) {
    x = find(x);
    y = find(y);
    if (x == y)
      return false;
    if (par[x] > par[y]) {
      par[y] += par[x];
      par[x] = y;
    } else {
      par[x] += par[y];
      par[y] = x;
    }
    return true;
  }

  bool same(int x, int y) { return find(x) == find(y); }
  int size(int x) { return -par[find(x)]; }
};
int main() {
  ll n, m, q;
  cin >> n >> m >> q;
  vector<pair<int, int>> edge;
  UnionFind uf(n);
  ll nn = n;
  while (q--) {
    int x, y, t;
    cin >> x >> y >> t;
    if (t) {
      edge.emplace_back(x, y);
    } else {
      if (uf.unite(x, y)) {
        --m;
        --nn;
      }
    }
  }
  vector<int> used(n);
  ll cnt = 0;
  for (auto p : edge) {
    int x = uf.find(p.first), y = uf.find(p.second);
    if (x == y) {
      cout << "No" << endl;
      return 0;
    }
    if (!used[x])
      ++cnt;
    if (!used[y])
      ++cnt;
    used[x] = used[y] = 1;
  }
  if (cnt == 0) {
    ll mi = nn - 1, ma = nn * (nn - 1) / 2;
    if (mi <= m && m <= ma) {
      cout << "Yes" << endl;
    } else
      cout << "No" << endl;
  } else {
    ll mi = nn, ma = nn * (nn - 1) / 2;
    if (mi <= m && m <= ma) {
      cout << "Yes" << endl;
    } else
      cout << "No" << endl;
  }
  return 0;
}