package main
import (
"bufio"
"os"
)
type FastScanner struct {
r *bufio.Reader
}
func (fs *FastScanner) NextInt() int {
sign := 1
val := 0
c, err := fs.r.ReadByte()
for err == nil && c <= ' ' {
c, err = fs.r.ReadByte()
}
if err != nil {
return 0
}
if c == '-' {
sign = -1
c, err = fs.r.ReadByte()
}
for err == nil && c >= '0' && c <= '9' {
val = val*10 + int(c-'0')
c, err = fs.r.ReadByte()
}
if err == nil {
_ = fs.r.UnreadByte()
}
return sign * val
}
type Constraint struct {
l, r, q int
}
func main() {
in := &FastScanner{r: bufio.NewReaderSize(os.Stdin, 1<<20)}
out := bufio.NewWriterSize(os.Stdout, 1<<20)
defer out.Flush()
n := in.NextInt()
m := in.NextInt()
const B = 30
diffs := make([][]int, B)
for b := 0; b < B; b++ {
diffs[b] = make([]int, n+3)
}
cons := make([]Constraint, m)
for i := 0; i < m; i++ {
l := in.NextInt()
r := in.NextInt()
q := in.NextInt()
cons[i] = Constraint{l: l, r: r, q: q}
for b := 0; b < B; b++ {
if (q>>b)&1 == 1 {
diffs[b][l]++
diffs[b][r+1]--
}
}
}
a := make([]int, n+1)
cur := make([]int, B)
for i := 1; i <= n; i++ {
val := 0
for b := 0; b < B; b++ {
cur[b] += diffs[b][i]
if cur[b] > 0 {
val |= (1 << b)
}
}
a[i] = val
}
allBits := (1 << B) - 1
size := 1
for size < n {
size <<= 1
}
tree := make([]int, 2*size)
for i := range tree {
tree[i] = allBits
}
for i := 0; i < n; i++ {
tree[size+i] = a[i+1]
}
for i := size - 1; i > 0; i-- {
tree[i] = tree[2*i] & tree[2*i+1]
}
query := func(l, r int) int {
l += size
r += size
res := allBits
for l <= r {
if l&1 == 1 {
res &= tree[l]
l++
}
if r&1 == 0 {
res &= tree[r]
r--
}
l >>= 1
r >>= 1
}
return res
}
for _, c := range cons {
if query(c.l-1, c.r-1) != c.q {
out.WriteString("NO\n")
return
}
}
out.WriteString("YES\n")
for i := 1; i <= n; i++ {
if i > 1 {
out.WriteByte(' ')
}
writeInt(out, a[i])
}
out.WriteByte('\n')
}
func writeInt(w *bufio.Writer, x int) {
if x == 0 {
w.WriteByte('0')
return
}
if x < 0 {
w.WriteByte('-')
x = -x
}
var buf [20]byte
i := len(buf)
for x > 0 {
i--
buf[i] = byte('0' + x%10)
x /= 10
}
w.Write(buf[i:])
}