#include <bits/stdc++.h>
using namespace std;
const int MAXN = 1e5 + 5;
const int MAXK = 30;
const int MAXST = (1 << (32 - __builtin_clz(MAXN)));
const int NEUT = (1 << 30) - 1;
struct mon {
  int v;
  mon operator+(const mon &o) const { return {v & o.v}; }
};
struct queryTyp {
  int l, r, q;
};
int arr[MAXN];
int dp[MAXN][MAXK], acc[MAXK];
int rta[MAXN], N;
queryTyp queries[MAXN];
mon ST[2 * MAXST];
void update(int p, int v) {
  p += N;
  ST[p].v = v;
  while (p > 1) {
    p /= 2;
    ST[p] = ST[2 * p + 1] + ST[2 * p];
  }
}
mon query(int i, int tl, int tr, int bl, int br) {
  if (tl >= br || tr <= bl) return {NEUT};
  if (tl >= bl && tr <= br) return ST[i];
  int mid = (tl + tr) / 2;
  return query(2 * i, tl, mid, bl, br) + query(2 * i + 1, mid, tr, bl, br);
}
int main() {
  int n, m;
  scanf("%d %d", &n, &m);
  N = (1 << (32 - __builtin_clz(n)));
  for (int i = 0; i < int(m); i++) {
    int l, r, q;
    scanf("%d %d %d", &l, &r, &q);
    queries[i] = {l, r, q};
    for (int j = 0; j < int(MAXK); j++)
      if (q & (1 << j)) dp[l][j]++, dp[r + 1][j]--;
  }
  for (int i = int(1); i < int(n + 1); i++)
    for (int j = 0; j < int(MAXK); j++) dp[i][j] += dp[i - 1][j];
  for (int i = int(1); i < int(n + 1); i++)
    for (int j = 0; j < int(MAXK); j++)
      ST[i - 1 + N].v |= (dp[i][j] > 0) * (1 << j);
  for (int i = int(N) - 1; i >= int(1); i--) ST[i] = ST[2 * i] + ST[2 * i + 1];
  bool posib = true;
  for (int i = 0; i < int(m); i++) {
    queryTyp x = queries[i];
    mon val = query(1, 0, N, x.l - 1, x.r);
    if (val.v != x.q) {
      posib = false;
      break;
    }
  }
  if (posib) {
    printf("YES\n");
    for (int i = 0; i < int(n); i++) printf("%d ", ST[i + N].v);
  } else
    printf("NO");
  return 0;
}
