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

import java.io.*;
import java.util.*;

public class CF_483_D_INTERESTING_ARRAY {

	public static void main(String[] args) throws Exception {
		Scanner sc = new Scanner(System.in);

		int n = sc.nextInt();
		int m = sc.nextInt();

		SegmentTree st = new SegmentTree(n + 1);
		Triple[] queries = new Triple[m];
		for (int i = 0; i < m; i++) {
			int l = sc.nextInt();
			int r = sc.nextInt();
			int q = sc.nextInt();
			st.updateRange(l, r, q);
			queries[i] = new Triple(l, r, q);

		}
		boolean isInteresting = true;
		
		for(int i = 1 ; i <=n ; i++)
			st.query(i, i);

		for (int i = 0; i < m; i++) {
			Triple t = queries[i];

			int q = st.query(t.l, t.r);
			
			isInteresting &= q == t.q;

		}

		StringBuilder sb = new StringBuilder();

		if (!isInteresting)
			sb.append("NO").append("\n");
		else {
			sb.append("YES").append("\n");

			for (int i = 1; i <= n; i++)
				sb.append(st.query(i, i)).append(" ");
			
			sb.append("\n");
		}

		System.out.print(sb);

	}


	static class Triple {
		int l, r, q;

		Triple(int l, int r, int q) {
			this.l = l;
			this.r = r;
			this.q = q;

		}

	}

	static class SegmentTree {
		int[] lazy, sTree;
		int n;

		SegmentTree(int in) {
			n = 1;

			while (n < in - 1)
				n <<= 1;

			sTree = new int[n << 1];
			lazy = new int[n << 1];
			
		}

		void propagate(int node) {

			lazy[node << 1] |= lazy[node];
			lazy[node << 1 | 1] |= lazy[node];
			sTree[node << 1] |= lazy[node];
			sTree[node << 1 | 1] |= lazy[node];

			lazy[node] = 0;

		}

		void updateRange(int i, int j, int val) {
			updateRange(1, 1, n, i, j, val);

		}

		void updateRange(int node, int b, int e, int i, int j, int val) {
			if (b > j || e < i)
				return;

			if (i <= b && e <= j) {
				sTree[node] |= val;
				lazy[node] |= val;
				return;
			}

			int mid = (b + e) >> 1;
			propagate(node);

			updateRange(node << 1, b, mid, i, j, val);
			updateRange(node << 1 | 1, mid + 1, e, i, j, val);

			sTree[node] = sTree[node << 1] & sTree[node << 1 | 1];
			// System.out.println(Arrays.toString(sTree));
			
		}

		int query(int i, int j) {

			return query(1, 1, n, i, j);
		}

		int query(int node, int b, int e, int i, int j) {
			if (b > j || e < i)
				return -1;

			if (i <= b && e <= j)
				return sTree[node];

			propagate(node);

			int mid = (b + e) >> 1;

			int q1 = query(node << 1, b, mid, i, j);
			int q2 = query(node << 1 | 1, mid + 1, e, i, j);

			return q1 & q2;

		}

	}

	static class Scanner {
		StringTokenizer st;
		BufferedReader br;

		public Scanner(InputStream s) {
			br = new BufferedReader(new InputStreamReader(s));
		}

		public String next() throws IOException {
			while (st == null || !st.hasMoreTokens())
				st = new StringTokenizer(br.readLine());
			return st.nextToken();
		}

		public int nextInt() throws IOException {
			return Integer.parseInt(next());
		}

		public long nextLong() throws IOException {
			return Long.parseLong(next());
		}

		public String nextLine() throws IOException {
			return br.readLine();
		}

		public double nextDouble() throws IOException {
			String x = next();
			StringBuilder sb = new StringBuilder("0");
			double res = 0, f = 1;
			boolean dec = false, neg = false;
			int start = 0;
			if (x.charAt(0) == '-') {
				neg = true;
				start++;
			}
			for (int i = start; i < x.length(); i++)
				if (x.charAt(i) == '.') {
					res = Long.parseLong(sb.toString());
					sb = new StringBuilder("0");
					dec = true;
				} else {
					sb.append(x.charAt(i));
					if (dec)
						f *= 10;
				}
			res += Long.parseLong(sb.toString()) / f;
			return res * (neg ? -1 : 1);
		}

		public boolean ready() throws IOException {
			return br.ready();
		}

	}

}
