We'll call an array of n non-negative integers a[1], a[2], ..., a[n] interesting, if it meets m constraints. The i-th of the m constraints consists of three integers li, ri, qi (1 ≤ li ≤ ri ≤ n) meaning that value <image> should be equal to qi. 

Your task is to find any interesting array of n elements or state that such array doesn't exist.

Expression x&y means the bitwise AND of numbers x and y. In programming languages C++, Java and Python this operation is represented as "&", in Pascal — as "and".

Input

The first line contains two integers n, m (1 ≤ n ≤ 105, 1 ≤ m ≤ 105) — the number of elements in the array and the number of limits.

Each of the next m lines contains three integers li, ri, qi (1 ≤ li ≤ ri ≤ n, 0 ≤ qi < 230) describing the i-th limit.

Output

If the interesting array exists, in the first line print "YES" (without the quotes) and in the second line print n integers a[1], a[2], ..., a[n] (0 ≤ a[i] < 230) decribing the interesting array. If there are multiple answers, print any of them.

If the interesting array doesn't exist, print "NO" (without the quotes) in the single line.

Examples

Input

3 1
1 3 3


Output

YES
3 3 3


Input

3 2
1 3 3
1 3 2


Output

NO
#include <bits/stdc++.h>
using namespace std;
int l[200000], r[200000], q[200000];
struct segment_tree {
  int Q[2000000], la[2000000];
  int x, y, z;
  inline void pushdown(int o) {
    la[2 * o] |= la[o];
    Q[2 * o] |= la[o];
    la[2 * o + 1] |= la[o];
    Q[2 * o + 1] |= la[o];
    la[o] = 0;
    return;
  }
  inline void add(int l, int r, int o) {
    if (x <= l && r <= y) {
      Q[o] |= z;
      la[o] |= z;
      return;
    }
    pushdown(o);
    int mid = (l + r) / 2;
    if (x <= mid) add(l, mid, 2 * o);
    if (y > mid) add(mid + 1, r, 2 * o + 1);
    Q[o] = Q[2 * o] & Q[2 * o + 1];
    return;
  }
  inline int query(int l, int r, int o) {
    if (x <= l && r <= y) {
      return Q[o];
    }
    pushdown(o);
    int mid = (l + r) / 2;
    int ret = 2147483647;
    if (x <= mid) ret &= query(l, mid, 2 * o);
    if (y > mid) ret &= query(mid + 1, r, 2 * o + 1);
    return ret;
  }
} wt;
int main() {
  memset(wt.Q, 0, sizeof(wt.Q));
  memset(wt.la, 0, sizeof(wt.la));
  int n, m;
  scanf("%d%d", &n, &m);
  for (int i = 1; i <= m; i++) {
    scanf("%d%d%d", &l[i], &r[i], &q[i]);
    wt.x = l[i];
    wt.y = r[i];
    wt.z = q[i];
    wt.add(1, n, 1);
  }
  for (int i = 1; i <= m; i++) {
    wt.x = l[i];
    wt.y = r[i];
    if (wt.query(1, n, 1) != q[i]) {
      printf("NO\n");
      return 0;
    }
  }
  printf("YES\n");
  for (int i = 1; i < n; i++) {
    wt.x = i;
    wt.y = i;
    printf("%d ", wt.query(1, n, 1));
  }
  wt.x = n;
  wt.y = n;
  printf("%d\n", wt.query(1, n, 1));
  return 0;
}
