#include <bits/stdc++.h>
using namespace std;
const int inf = 1e9;
struct segtree {
  struct node {
    int max = -1;
    int id = -1;
    int lazy = inf;
    void apply(int x) {
      max = max < x ? max : x;
      lazy = lazy < x ? lazy : x;
    }
  };
  vector<node> t;
  int n;
  node unite(node l, node r) {
    node res;
    res.max = max(l.max, r.max);
    res.id = l.max > r.max ? l.id : r.id;
    return res;
  }
  inline void push(int v) {
    if (t[v].lazy != inf) {
      t[2 * v + 1].apply(t[v].lazy);
      t[2 * v + 2].apply(t[v].lazy);
      t[v].lazy = inf;
    }
  }
  inline void pull(int v) { t[v] = unite(t[2 * v + 1], t[2 * v + 2]); }
  void build(int v, int d, int l, int r) {
    if (r - l == 1) {
      t[v].max = d;
      t[v].id = l;
      return;
    }
    int m = (l + r) / 2;
    build(2 * v + 1, d, l, m);
    build(2 * v + 2, d, m, r);
    pull(v);
  }
  void smin(int v, int l, int r, int x, int tl, int tr) {
    if (r <= tl || tr <= l) return;
    if (l <= tl && tr <= r) return t[v].apply(x);
    push(v);
    int tm = (tl + tr) / 2;
    smin(2 * v + 1, l, r, x, tl, tm);
    smin(2 * v + 2, l, r, x, tm, tr);
    pull(v);
  }
  void modify(int v, int id, int x, int tl, int tr) {
    if (tr - tl == 1) {
      t[v].max = x;
      t[v].id = tl;
      return;
    }
    push(v);
    int tm = (tl + tr) / 2;
    id < tm ? modify(2 * v + 1, id, x, tl, tm)
            : modify(2 * v + 2, id, x, tm, tr);
    pull(v);
  }
  node get(int v, int l, int r, int tl, int tr) {
    if (r <= tl || tr <= l) return node();
    if (l <= tl && tr <= r) return t[v];
    push(v);
    int tm = (tl + tr) / 2;
    return unite(get(2 * v + 1, l, r, tl, tm), get(2 * v + 2, l, r, tm, tr));
  }
  segtree(int k, int v = 0) : n(k) {
    t.resize(4 * n);
    build(0, v, 0, n);
  }
};
int main() {
  ios::sync_with_stdio(false);
  cin.tie(0);
  int n, m;
  cin >> n >> m;
  segtree st(n, inf), red(n, 0);
  vector<int> M(n, -1);
  vector<tuple<int, int, int>> que;
  for (int i = 0; i < m; i++) {
    int type;
    cin >> type;
    if (type == 1) {
      int l, r, x;
      cin >> l >> r >> x;
      --l;
      int val = red.get(0, l, r, 0, n).max;
      if (val > x) {
        cout << "NO" << '\n';
        return 0;
      } else if (val < x) {
        que.emplace_back(l, r, x);
      }
      st.smin(0, l, r, x, 0, n);
    } else {
      int k, d;
      cin >> k >> d;
      --k;
      que.emplace_back(k, d, -1);
      red.modify(0, k, d, 0, n);
      if (M[k] == -1) {
        M[k] = st.get(0, k, k + 1, 0, n).max;
      }
    }
  }
  for (int i = 0; i < n; i++) {
    if (M[i] == -1) {
      M[i] = st.get(0, i, i + 1, 0, n).max;
    } else {
      st.modify(0, i, M[i], 0, n);
    }
  }
  vector<int> b(n, -1);
  vector<bool> done(n, false);
  for (auto u : que) {
    if (get<2>(u) == -1) {
      int k = get<0>(u), d = get<1>(u);
      st.modify(0, k, d, 0, n);
    } else {
      int l = get<0>(u), r = get<1>(u), x = get<2>(u);
      segtree::node v = st.get(0, l, r, 0, n);
      int val = v.max, id = v.id;
      if (val < x) {
        cout << "NO" << '\n';
        return 0;
      }
      assert(val == x);
      b[id] = val;
      done[id] = 1;
    }
  }
  cout << "YES" << '\n';
  auto print = [&]() {
    for (int i = 0; i < n; i++) {
      cout << (b[i] == -1 ? M[i] : b[i]) << " \n"[i == n - 1];
    }
  };
  for (int i = 30; i >= 0; i--) {
    int first = -1, last = -1;
    bool found = false;
    for (int j = 0; j < n; j++) {
      if (!done[j]) {
        if (M[j] >= (1 << i)) {
          if (first == -1) first = j;
          last = j;
        }
      } else if (b[j] & (1 << i)) {
        found = true;
        break;
      }
    }
    if (found || (first == -1)) continue;
    if (first != last) {
      if (b[first] == -1) b[first] = 0;
      if (b[last] == -1) b[last] = 0;
      b[first] |= 1 << i;
      b[last] |= (1 << i) - 1;
      print();
      return 0;
    }
    if (b[first] == -1) b[first] = 0;
    b[first] |= 1 << i;
    M[first] -= 1 << i;
  }
  print();
  return 0;
}
