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.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.util.Arrays;
import java.util.StringTokenizer;


public class D275 {
	public static void main(String[] args) {
		MyScanner scan = new MyScanner();
		PrintWriter out = new PrintWriter(System.out);
		int N = scan.nextInt(), M = scan.nextInt();
		int[] l = new int[M], r = new int[M], q = new int[M];
		ST st = new ST(N);
		for(int i=0;i<M;i++){
			l[i] = scan.nextInt()-1;
			r[i] = scan.nextInt()-1;
			q[i] = scan.nextInt();
			st.update(l[i], r[i], q[i]);
		}
		boolean valid = true;
		for(int i=0;i<M;i++){
			if(st.query(l[i], r[i])!=q[i])valid=false;
			if(!valid)break;
		}
		if(!valid){out.println("NO");}
		else{
			out.println("YES");
			for(int i=0;i<N;i++){
				out.print(st.query(i, i)+" ");
			}out.println();
		}
		out.close();
	}
	private static class ST {
		int K;
		int[] val, delta;
		public ST(int N) {
			K = (int)Math.ceil(Math.log(N)/Math.log(2));
			val = new int[4*N];
			delta = new int[4*N];
			Arrays.fill(delta, -1);
		}
		public void update(int L, int R, int V){update(L,R,0,(1<<K)-1, 1, V);}
		public int query(int L, int R){return query(L,R,0,(1<<K)-1,1);}
		private int query(int L, int R, int tL, int tR, int idx) {
			if(tL<L&&tR<L||tL>R&&tR>R)return (1<<30)-1;
			if(tL>=L&&tR<=R){
				return val[idx];
			}
			prop(tL,tR,idx);
			int mid = (tL+tR)/2;
			return (query(L,R,tL,mid,idx*2))&(query(L,R,mid+1,tR,idx*2+1));
		}
		private void update(int L, int R, int tL, int tR, int idx, int V) {
			if(tL<L&&tR<L||tL>R&&tR>R)return;
			if(tL>=L&&tR<=R){
				val[idx] |= V;
				delta[idx] = (delta[idx]==-1)?V:delta[idx]|V;
				return;
			}
			prop(tL,tR,idx);
			int mid = (tL+tR)/2;
			update(L,R,tL,mid,idx*2,V);
			update(L,R,mid+1,tR,idx*2+1,V);
		}
		private void prop(int L, int R, int idx){
			if(delta[idx] == -1)return;
			int mid = (L+R)/2;
			update(L,R,L,mid,idx*2,delta[idx]);
			update(L,R,mid+1,R,idx*2+1,delta[idx]);
			delta[idx] = -1;
		}
	}
	private static class MyScanner {
		BufferedReader br;
		StringTokenizer st;
		public MyScanner() {br = new BufferedReader(new InputStreamReader(System.in));}
		String next(){
			while(st==null||!st.hasMoreElements()){
				try{st = new StringTokenizer(br.readLine());}
				catch(IOException e){e.printStackTrace();}
			}return st.nextToken();
		}
		int nextInt() {return Integer.parseInt(next());}
		long nextLong(){return Long.parseLong(next());}
	}
}
