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.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.util.HashSet;
import java.util.Set;
import java.util.StringTokenizer;



	
	
public class Solution  {
	
	static class FastScanner{
		BufferedReader s;
		StringTokenizer st;
		
		
		public FastScanner(){
			st = new StringTokenizer("");
			s = new BufferedReader(new InputStreamReader(System.in));
		}
		
		public FastScanner(File f) throws FileNotFoundException{
			st = new StringTokenizer("");
			s = new BufferedReader (new FileReader(f));
		}
		
		public int nextInt() throws IOException{
			if(st.hasMoreTokens())
				return Integer.parseInt(st.nextToken());
			else{
				st = new StringTokenizer(s.readLine());
				return nextInt();
			}
		}
		
		public double nextDouble() throws IOException{
			if(st.hasMoreTokens())
				return Double.parseDouble(st.nextToken());
			else{
				st = new StringTokenizer(s.readLine());
				return nextDouble();
			}
		}
		
		public long nextLong() throws IOException{
			if(st.hasMoreTokens())
				return Long.parseLong(st.nextToken());
			else{
				st = new StringTokenizer(s.readLine());
				return nextLong();
			}
		}
		
		public String nextString() throws IOException{
			if(st.hasMoreTokens())
				return st.nextToken();
			else{
				st = new StringTokenizer(s.readLine());
				return nextString();
			}
			
		}
		public String readLine() throws IOException{
			return s.readLine();
		}
		
		public void close() throws IOException{
			s.close();
		}
		
	}
	
	
	
	
	//FastScanner s = new FastScanner(new File("input.txt"));       copy inside void solve
    //PrintWriter ww = new PrintWriter(new FileWriter("output.txt"));
    static FastScanner s = new FastScanner();   
    static PrintWriter ww = new PrintWriter(new OutputStreamWriter(System.out));
	
    public static void main(String args[])throws IOException{
    	//Main ob=new Main();
    	Solution ob=new Solution();
		ob.solve();
			ww.close();
    }
    /////////////////////////////////////////////
    
  
  

   
    int tree[];
    int dp[];
    int arr[];
    /*
    
   void build(int l,int r,int node){
    	if(l+1==r){
    		tree[node]=arr[l];
    		return;
    	}
    	
    	int mid = (l+r)/2;
    	build(l,mid,node*2);
    	build(mid,r,node*2+1);
    	tree[node]=tree[node*2]&tree[node*2+1];
    			
   }
   
   int  query(int i,int j,int node,int l,int h){
		 
	   if (i == l && j == h) {
	 	 	return tree[node];
	 	}
	 	int mid = (l + h) >> 1;
	 	int ans = (1 << 30) - 1;
	   
	   if (l < mid) 
	 		ans &= query(i, Math.min(j, mid),node*2, l, mid);
	 	if (mid < h) 
	 		ans &= query(Math.max(i, mid),j, node*2+1, mid, h);
	  
	   return ans;
	   
   }
   
   
   */
     void build(int v, int l, int r) {
     	if (l + 1 == r) {
     	 	tree[v] = arr[l];
     	 	return;
     	}

     	int mid = (l + r) >> 1;
    	build(v * 2, l, mid);
    	build(v * 2 + 1, mid, r);

    	tree[v] = tree[v * 2] & tree[v * 2 + 1];
    }

    int query(int v, int l, int r, int L, int R) {
     	if (l == L && r == R) {
     	 	return tree[v];
     	}
     	int mid = (L + R) >> 1;
     	int ans = (1<< 30) - 1;

     	if (l < mid) 
     		ans &= query(v * 2, l, Math.min(r, mid), L, mid);
     	if (mid < r) 
     		ans &= query(v * 2 + 1, Math.max(l, mid), r, mid, R);

     	return ans;
    }

   
    /////////////////////////////////////////////
    void solve() throws IOException {
    	int n = s.nextInt();
    	int m = s.nextInt();
    	int N=1000000;
    	int l[] = new int[N];
    	int r[] = new int[N];
    	int q[] = new int[N];
    	
    	for(int i = 0;i < m;i++){
    		l[i] = s.nextInt()-1;
    		r[i] = s.nextInt();
    		q[i] = s.nextInt();
    	}
    	
    	dp = new int[N];
    	arr = new int[N];
    	int power = (int) Math.floor(Math.log(N) / Math.log(2)) + 1;
        power = (int) ((int) 2 * Math.pow(2, power));
        
    	tree = new int[power];
    	
    	for(int bit = 0;bit <= 30;bit++){
    		for(int i=0;i<n;i++)
    			dp[i]=0;
    	
    		for(int i=0;i<m;i++){
    			if (((q[i] >> bit) & 1)==1) {
    				dp[l[i]]++;
    				dp[r[i]]--;
    			}
    		}
    		
    		for(int i=0;i<n;i++){
    			if(i>0)
    				dp[i]+= dp[i-1];
    			
    			if(dp[i]>0)
    				arr[i]|=(1<<bit);
    		}
    	}
    	
    	build(1,0,n);
    	//for(int i=0;i<n;i++)
    		//System.out.println(arr[i]+" ");
    	
    	for(int i=0;i<m;i++){
    		if (query(1, l[i], r[i], 0, n) != q[i]){
    			ww.println("NO");
    			return;
    		}
    	}
    	
    	ww.println("YES");
    	for(int i=0;i<n;i++)
    		ww.print(arr[i]+" ");
     }//solve
  }