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

public class InterestingArray {
	public static void main(String[] args) throws IOException {
		Scanner s = new Scanner(System.in);
		int n = s.nextInt();
		int m = s.nextInt();
		SegmentTree st = new SegmentTree(n);
		Query[] qs = new Query[m];
		for (int i = 0; i < qs.length; i++) {
			int x = s.nextInt();
			int y = s.nextInt();
			int v = s.nextInt();
			st.update(x, y, v);
			qs[i] = new Query(x, y, v);
		}
		
		
		for (int i = 0; i < qs.length; i++) {
			Query q = qs[i];
			if(st.get(q.i, q.j)!= q.val){
				System.out.println("NO");
				return;
			}
		}
		System.out.println("YES");
		for (int i = 1; i < st.n; i++) {
			st.propagate(i);
		}
		int i = st.n;
		while(n-- >0) {
			System.out.print(st.stree[i]+" ");
			i++;
			
		}
		System.out.println();
		
	}
   
	
	static class Query{
		int i,j,val;
		public Query(int x, int y, int v){
			i =x;
			j = y;
			val =v;
		}
	}
	
	
	static class SegmentTree{
		int n;
		int[] stree;
		int[] lazy;
		public SegmentTree(int s){
			n = 1; while(n <s) n<<=1;
			stree = new int[n<<1];
			lazy = new int[n<<1];
			//Arrays.fill(lazy, 1);
		}
		
		public void update(int i, int j, int val){
			update(1,1,n,i,j,val);
		}
		public void update(int node, int b, int e, int i, int j, int val){
			if(i > e || j < b)		
				return;
			if(b >= i && e <= j)		
			{
				stree[node] |= val;			
				lazy[node] |= val;				
			}
			else{
				int mid = b + e >>1;
			propagate(node, b, mid, e);
			update(node<<1,b,mid,i,j,val);
			update(node<<1|1,mid+1,e,i,j,val);
			stree[node] = stree[node<<1] & stree[node<<1|1];
			 
			}
		}
		
		void propagate(int node, int b, int mid, int e)		
		{
			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 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;
		}
		
		public int get(int i, int j){
			return get(1,1,n,i,j);
		}
		public int get(int node, int b, int e,int i, int j){
			if(e < i || b > j)
				return -1;
			if(b>= i && e <= j)
				return stree[node];
			int mid = b + e >> 1;
			propagate(node, b, mid, e);
			int q1 = get(node<<1,b,mid,i,j);
			int q2 = get(node<<1|1,mid+1,e,i,j);
			return q1 & q2;	
			
		}
	}
	
	
	static class Scanner
 	{
 	    StringTokenizer st;
 	    BufferedReader br;

 	    public Scanner(InputStream system) {br = new BufferedReader(new InputStreamReader(system));}
 	    public String next() throws IOException
 	    {
 	        while (st == null || !st.hasMoreTokens())
 	            st = new StringTokenizer(br.readLine());
 	        return st.nextToken();
 	    }
 	    public String nextLine()throws IOException{return br.readLine();}
 	    public int nextInt() throws IOException {return Integer.parseInt(next());}
 	    public double nextDouble() throws IOException {return Double.parseDouble(next());}
 	    public char nextChar()throws IOException{return next().charAt(0);}
 	    public Long nextLong()throws IOException{return Long.parseLong(next());}
 	    public boolean ready() throws IOException{return br.ready();}
 	    public void waitForInput() throws InterruptedException {Thread.sleep(4000);}
 	}
	
	
	
}
