#include <bits/stdc++.h>
using namespace std;
const int MAX_N = 5e5 + 14, LG = 19;
struct Dsu {
  int par[MAX_N];
  Dsu() { memset(par, -1, sizeof par); }
  int root(int v) { return par[v] < 0 ? v : par[v] = root(par[v]); }
  bool fri(int v, int u) { return root(v) == root(u); }
  bool merge(int v, int u) {
    if ((v = root(v)) == (u = root(u))) return 0;
    par[u] += par[v];
    par[v] = u;
    return 1;
  }
} dsu;
int fen[MAX_N];
int get(int p) {
  int ans = 0;
  for (p++; p; p ^= p & -p) ans += fen[p];
  return ans;
}
void upd(int p, int v) {
  for (p++; p < MAX_N; p += p & -p) fen[p] += v;
}
void upd(int l, int r, int v) { upd(l, v), upd(r, -v); }
struct Edge {
  int v, u, x;
  bool include;
};
int n, q, h[MAX_N], par[LG][MAX_N], st[MAX_N], en[MAX_N];
bool weight_parity[MAX_N];
vector<pair<int, bool>> g[MAX_N];
void dfs(int v = 0, int p = -1) {
  static int time = 0;
  st[v] = time++;
  for (auto [u, w] : g[v])
    if (u != p) {
      par[0][u] = v;
      h[u] = h[v] + 1;
      weight_parity[u] = weight_parity[v] ^ w;
      dfs(u, v);
    }
  en[v] = time;
}
int lca(int v, int u) {
  if (h[v] > h[u]) swap(v, u);
  for (int i = 0; i < LG; i++)
    if (h[u] - h[v] >> i & 1) u = par[i][u];
  for (int i = LG - 1; i >= 0; i--)
    if (par[i][v] != par[i][u]) v = par[i][v], u = par[i][u];
  return v == u ? v : par[0][v];
}
Edge edges[MAX_N];
void block_path(int v, int p) {
  while (v != p) {
    upd(st[v], en[v], +1);
    v = par[0][v];
  }
}
int main() {
  ios::sync_with_stdio(0), cin.tie(0);
  cin >> n >> q;
  for (int i = 0; i < q; ++i) {
    cin >> edges[i].v >> edges[i].u >> edges[i].x;
    --edges[i].v;
    --edges[i].u;
    if (dsu.merge(edges[i].v, edges[i].u)) {
      edges[i].include = true;
      g[edges[i].v].emplace_back(edges[i].u, edges[i].x);
      g[edges[i].u].emplace_back(edges[i].v, edges[i].x);
    }
  }
  for (int i = 0; i < n; ++i)
    if (h[i] == 0) {
      dfs(i);
      par[0][i] = i;
    }
  for (int k = 1; k < LG; k++)
    for (int i = 0; i < n; i++) par[k][i] = par[k - 1][par[k - 1][i]];
  for (int i = 0; i < q; ++i) {
    if (!edges[i].include &&
        (edges[i].x ^ weight_parity[edges[i].v] ^ weight_parity[edges[i].u]) &&
        get(st[edges[i].v]) == get(st[edges[i].u]) &&
        get(st[edges[i].v]) == get(st[lca(edges[i].v, edges[i].u)])) {
      block_path(edges[i].v, lca(edges[i].v, edges[i].u));
      block_path(edges[i].u, lca(edges[i].v, edges[i].u));
      edges[i].include = true;
    }
    cout << (edges[i].include ? "YES\n" : "NO\n");
  }
}
