description: You are given n segments on a number line, numbered from 1 to n. The i-th segments covers all integer points from l_i to r_i and has a value w_i.
  
  You are asked to select a subset of these segments (possibly, all of them). Once the subset is selected, it's possible to travel between two integer points if there exists a selected segment that covers both of them. A subset is good if it's possible to reach point m starting from point 1 in arbitrary number of moves.
  
  The cost of the subset is the difference between the maximum and the minimum values of segments in it. Find the minimum cost of a good subset.
  
  In every test there exists at least one good subset.
  
  Input
  
  The first line contains two integers n and m (1 ≤ n ≤ 3 ⋅ 10^5; 2 ≤ m ≤ 10^6) — the number of segments and the number of integer points.
  
  Each of the next n lines contains three integers l_i, r_i and w_i (1 ≤ l_i < r_i ≤ m; 1 ≤ w_i ≤ 10^6) — the description of the i-th segment.
  
  In every test there exists at least one good subset.
  
  Output
  
  Print a single integer — the minimum cost of a good subset.
  
  Examples
  
  Input
  
  
  5 12
  1 5 5
  3 4 10
  4 10 6
  11 12 5
  10 12 3
  
  
  Output
  
  
  3
  
  
  Input
  
  
  1 10
  1 10 23
  
  
  Output
  
  
  0
solution: import java.io.*;
  import java.util.*;
  
  public class Main{
  	static class segmentTree {
  		int[]arr,sTree,lazy;
  		int N;
  		public segmentTree(int[]in) {//in array is 1-based array
  			arr=in;
  			int n=in.length;
  			N=1;
  			while(N<n) {
  				N<<=1;
  			}
  			sTree=new int[N<<1];
  			lazy=new int[N<<1];
  			build(1,1,N);
  		}
  		void build(int node,int left,int right) {
  			if(left==right) {
  				if(left>=arr.length) {
  					sTree[node]=1000000000;//the value that won't affect the required operation
  				}
  				else {
  					sTree[node]=arr[left];
  				}
  				return;
  			}
  			int mid=(left+right)>>1;
  			int leftChild=node<<1,rightChild=node<<1|1;
  			build(leftChild, left, mid);
  			build(rightChild, mid+1, right);
  			sTree[node]=Math.min(sTree[leftChild],sTree[rightChild]);
  		}		
  		
  		
  		void update_range(int i, int j, int val){
  			update_range(1,1,N,i,j,val);
  		}
  		
  		void update_range(int node,int curLeft,int curRight,int left,int right,int val) {
  			if(curLeft>right || curRight<left)return;
  			
  			if(curLeft>=left && curRight<=right) {
  				sTree[node] += val;			
  				lazy[node] += val;
  				return;
  			}
  			int mid=(curLeft+curRight)>>1;
  			int leftChild=node<<1,rightChild=node<<1|1;
  			propagate(node, curLeft, mid, curRight);
  			update_range(leftChild, curLeft, mid, left, right,val);
  			update_range(rightChild, mid+1, curRight, left, right,val);
  
  			sTree[node]=Math.min(sTree[leftChild],sTree[rightChild]);
  			
  		}
  		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;//the value that won't affect the required operation
  		}
  		
  	}
  	static void main() throws Exception{
  		int n=sc.nextInt(),m=sc.nextInt()-1;
  		int[][]in=new int[n][3];
  		for(int i=0;i<n;i++) {
  			in[i]=sc.intArr(3);
  			in[i][1]--;
  		}
  		Arrays.sort(in,(x,y)->x[2]-y[2]);
  		int i=0,j=0;
  		segmentTree st=new segmentTree(new int[m+1]);
  		int ans=1000000000;
  		while(j<n) {
  			while(j<n && st.sTree[1]==0) {
  //				System.out.println(in[j][0]+" "+in[j][1]);
  				st.update_range(in[j][0], in[j][1], 1);
  				j++;
  			}
  			if(st.sTree[1]>0) {
  				ans=Math.min(ans, in[j-1][2]-in[i][2]);
  //				if(ans==1) {
  //					System.out.println(i+" "+j+" "+st.sTree[1]+" "+m);
  //					dbg(in[i]);
  //					dbg(in[j-1]);
  //				}
  			}
  
  			st.update_range(in[i][0], in[i][1], -1);
  //			System.out.println(in[i][0]+" "+in[i][1]+" -1");
  			i++;
  		}
  		while(i<n) {
  			if(st.sTree[1]>0) {
  				ans=Math.min(ans, in[j-1][2]-in[i][2]);
  			}
  			st.update_range(in[i][0], in[i][1], -1);
  			i++;
  		}
  		pw.println(ans);
  	}
  	public static void main(String[] args) throws Exception{
  		sc=new MScanner(System.in);
  		pw = new PrintWriter(System.out);
  		int tc=1;
  //        tc=sc.nextInt();
  		for(int i=1;i<=tc;i++) {
  //			pw.printf("Case #%d: ", i);
  			main();
  		}
  		pw.flush();
  	}
  	static PrintWriter pw;
  	static MScanner sc;
  	static class MScanner {
  		StringTokenizer st;
  		BufferedReader br;
  		public MScanner(InputStream system) {
  			br = new BufferedReader(new InputStreamReader(system));
  		}
  	 
  		public MScanner(String file) throws Exception {
  			br = new BufferedReader(new FileReader(file));
  		}
  	 
  		public String next() throws IOException {
  			while (st == null || !st.hasMoreTokens())
  				st = new StringTokenizer(br.readLine());
  			return st.nextToken();
  		}
  		public int[] intArr(int n) throws IOException {
  	        int[]in=new int[n];for(int i=0;i<n;i++)in[i]=nextInt();
  	        return in;
  		}
  		public long[] longArr(int n) throws IOException {
  	        long[]in=new long[n];for(int i=0;i<n;i++)in[i]=nextLong();
  	        return in;
  		}
  		public int[] intSortedArr(int n) throws IOException {
  	        int[]in=new int[n];for(int i=0;i<n;i++)in[i]=nextInt();
  	        shuffle(in);
  	        Arrays.sort(in);
  	        return in;
  		}
  		public long[] longSortedArr(int n) throws IOException {
  	        long[]in=new long[n];for(int i=0;i<n;i++)in[i]=nextLong();
  	        shuffle(in);
  	        Arrays.sort(in);
  	        return in;
  		}
  		public Integer[] IntegerArr(int n) throws IOException {
  	        Integer[]in=new Integer[n];for(int i=0;i<n;i++)in[i]=nextInt();
  	        return in;
  		}
  		public Long[] LongArr(int n) throws IOException {
  	        Long[]in=new Long[n];for(int i=0;i<n;i++)in[i]=nextLong();
  	        return in;
  		}
  		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(3000);
  		}
  		
  	}
  	static void dbg(int[]in) {
  		System.out.println(Arrays.toString(in));
  	}
  	static void dbg(long[]in) {
  		System.out.println(Arrays.toString(in));
  	}
  	static void sort(int[]in) {
  		shuffle(in);
  		Arrays.sort(in);
  	}
  	static void sort(long[]in) {
  		shuffle(in);
  		Arrays.sort(in);
  	}
  	static void shuffle(int[]in) {
  		for(int i=0;i<in.length;i++) {
  			int idx=(int)(Math.random()*in.length);
  			int tmp=in[i];
  			in[i]=in[idx];
  			in[idx]=tmp;
  		}
  	}
  	static void shuffle(long[]in) {
  		for(int i=0;i<in.length;i++) {
  			int idx=(int)(Math.random()*in.length);
  			long tmp=in[i];
  			in[i]=in[idx];
  			in[idx]=tmp;
  		}
  	}
  }