#include <bits/stdc++.h>
using namespace std;
const int N = 3e5 + 5, inf = 1e9 + 1;
int type[N], l[N], r[N], x[N], k[N], d[N];
bool visited[N];
int val[N], ans[N], seg1[4 * N], seg2[4 * N];
void build(int nd, int l, int r) {
  if (l != r) {
    int mid = (l + r) / 2;
    build(nd * 2, l, mid);
    build(nd * 2 + 1, mid + 1, r);
  }
  seg1[nd] = seg2[nd] = inf;
}
void build2(int nd, int l, int r) {
  if (l == r)
    seg2[nd] = -ans[l];
  else {
    int mid = (l + r) / 2;
    build2(nd * 2, l, mid);
    build2(nd * 2 + 1, mid + 1, r);
    seg2[nd] = min(seg2[nd * 2], seg2[nd * 2 + 1]);
  }
}
void update1(int nd, int l, int r, int x, int y, int val) {
  if (l > y or r < x)
    return;
  else if (l >= x and r <= y)
    seg1[nd] = min(seg1[nd], val);
  else {
    int mid = (l + r) / 2;
    update1(nd * 2, l, mid, x, y, val);
    update1(nd * 2 + 1, mid + 1, r, x, y, val);
  }
}
int query1(int nd, int l, int r, int x) {
  if (l == r)
    return seg1[nd];
  else {
    int mid = (l + r) / 2;
    if (x > mid)
      return min(seg1[nd], query1(nd * 2 + 1, mid + 1, r, x));
    else
      return min(seg1[nd], query1(nd * 2, l, mid, x));
  }
}
void update2(int nd, int l, int r, int x, int val) {
  if (l == r)
    seg2[nd] = val;
  else {
    int mid = (l + r) / 2;
    if (x > mid)
      update2(nd * 2 + 1, mid + 1, r, x, val);
    else
      update2(nd * 2, l, mid, x, val);
    seg2[nd] = min(seg2[nd * 2], seg2[nd * 2 + 1]);
  }
}
int query2(int nd, int l, int r, int x, int y) {
  if (l > y or r < x)
    return inf;
  else if (l >= x and r <= y)
    return seg2[nd];
  else {
    int mid = (l + r) / 2;
    return min(query2(nd * 2, l, mid, x, y),
               query2(nd * 2 + 1, mid + 1, r, x, y));
  }
}
int main() {
  memset(ans, -1, sizeof(ans));
  int n, m;
  set<int> S;
  scanf("%d %d", &n, &m);
  build(1, 1, n);
  for (int i = 1; i <= m; i++) {
    scanf("%d", &type[i]);
    if (type[i] == 1) {
      scanf("%d %d %d", &l[i], &r[i], &x[i]);
      int tmp = query2(1, 1, n, l[i], r[i]);
      update1(1, 1, n, l[i], r[i], x[i]);
      if (tmp != x[i]) S.insert(x[i]);
    } else {
      scanf("%d %d", &k[i], &d[i]);
      update2(1, 1, n, k[i], d[i]);
      if (!visited[k[i]]) {
        val[k[i]] = query1(1, 1, n, k[i]);
        visited[k[i]] = 1;
      }
    }
  }
  for (int i = 1; i <= n; i++) {
    if (!visited[i]) {
      val[i] = query1(1, 1, n, i);
      visited[i] = 1;
    }
  }
  for (int i = 1; i <= n; i++) {
    if (S.find(val[i]) != S.end()) {
      S.erase(val[i]);
      ans[i] = val[i];
    }
  }
  int cute = 0;
  vector<pair<int, int> > V;
  for (int i = 1; i <= n; i++) {
    if (val[i] == inf) val[i]--;
    if (ans[i] == -1)
      V.push_back({val[i], i});
    else
      cute |= ans[i];
  }
  vector<int> yo;
  for (int i = 29; i >= 0; i--) {
    if ((cute & (1 << i)) == 0) yo.push_back(i);
  }
  sort(V.begin(), V.end());
  reverse(V.begin(), V.end());
  for (auto v : V) {
    int tmp = 0;
    for (auto it : yo) {
      if (tmp + (1 << it) <= v.first) {
        tmp |= (1 << it);
      }
    }
    vector<int> honey;
    for (auto it : yo) {
      if ((tmp & (1 << it)) == 0) honey.push_back(it);
    }
    yo = honey;
    ans[v.second] = tmp;
  }
  build2(1, 1, n);
  for (int i = 1; i <= m; i++) {
    if (type[i] == 1) {
      if (-query2(1, 1, n, l[i], r[i]) != x[i]) {
        cout << "NO\n";
        return 0;
      }
    } else {
      update2(1, 1, n, k[i], -d[i]);
    }
  }
  cout << "YES\n";
  for (int i = 1; i <= n; i++) cout << ans[i] << " ";
}
