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.BufferedReader;
  import java.io.FileReader;
  import java.io.IOException;
  import java.io.InputStreamReader;
  import java.util.StringTokenizer;
  import java.util.Arrays;
  import java.util.Random;
  import java.io.FileWriter;
  import java.io.PrintWriter;
  /*
      Solution Created: 21:30:34 30/07/2021
      Custom Competitive programming helper.
  */
  public class Main {
  	static Segment[] a;
  	static int n,m;
  	static SegmentTree st;
  	public static void solve() {
  		n = in.nextInt(); m = in.nextInt();
  		a = new Segment[n];
  		for(int i = 0; i<n; i++) a[i] = new Segment(in.nextInt(), in.nextInt()-1, in.nextInt());
  		Util.sortArray(a);
  		st = new SegmentTree(m+1);
  		int j = 0;
  		long ans = Long.MAX_VALUE/2;
  		for(int i = 0; i<n; i++) {
  			while(j<n && (!covered())) {
  				add(a[j].l, a[j].r);
  				j++;
  			}
  			if(covered()) ans = Math.min(ans, a[j-1].w-a[i].w);
  			rem(a[i].l, a[i].r);
  		}
  		out.println(ans);
  	}
  	public static boolean covered() {
  		return st.query(1, m-1) > 0;
  	}
  	public static void add(int l, int r) {
  		st.update(l, r, 1);
  	}
  	public static void rem(int l, int r) {
  		st.update(l, r, -1);
  	}
  	
  	public static class Segment implements Comparable<Segment>{
  		int l, r, w;
  		public Segment(int l, int r, int w) {
  			this.l = l;
  			this.r = r;
  			this.w = w;
  		}
  		public String toString() {
  			return this.l+" "+this.r+" "+this.w;
  		}
  		@Override
  		public int compareTo(Main.Segment o) {
  			return this.w - o.w;
  		}
  	}
  	static class SegmentTree{
  		private long[] tree;
  		private long[] lazy;
  		int n;
  		public SegmentTree(int[] a) { //Initialize by given array
  			this.n = a.length;
  			this.tree = new long[4*n];
  			this.lazy = new long[4*n];
  			build(0, 0, n-1, a);
  		}
  		
  		public SegmentTree(int n) { //Initialize by size
  			this.n = n;
  			this.tree = new long[4*n];
  			this.lazy = new long[4*n];
  		}
  		
  		private void build(int idx, int l, int r, int[] a) {
  			if(l==r) tree[idx] = a[l];
  			else {
  				int m = (l+r)/2;
  				build(2*idx+1, l, m, a);
  				build(2*idx+2,m+1,r, a);
  				tree[idx] = Math.min(tree[2*idx+1], tree[2*idx+2]); //Min
  			}
  		}
  		
  		public void prop(int idx) {
  		    tree[idx*2+1] += lazy[idx];
  		    lazy[idx*2+1] += lazy[idx];
  		    tree[idx*2+2] += lazy[idx];
  		    lazy[idx*2+2] += lazy[idx];
  		    lazy[idx] = 0;
  		}
  
  		public void update(int l, int r, int val) {
  			updateUtil(0, l, r, 0, n-1, val);
  		}
  		
  		private void updateUtil(int idx, int lBound, int rBound, int l, int r , int v) {
  			if(lBound<=l && r<=rBound) {
  				tree[idx] += v;
  				lazy[idx] += v;
  				return;
  			}
  			if(r<lBound || rBound<l) return;
  			int md = (l+r)/2;
  			prop(idx);
  			updateUtil(2*idx+1, lBound, rBound, l, md, v);
  			updateUtil(2*idx+2, lBound, rBound, md+1, r, v);
  			tree[idx] = Math.min(tree[2*idx+1], tree[2*idx+2]);
  		}
  		
  		public long query(int l, int r) {
  			return queryUtil(0, l, r, 0, n-1);
  		}
  		
  		private long queryUtil(int idx, int lBound, int rBound, int l, int r) {
  			if(rBound < l || r < lBound) return Integer.MAX_VALUE; //Min
  			if(lBound <= l && r<= rBound) return tree[idx];
  			prop(idx);
  			int md = (l+r)/2;
  			return Math.min(queryUtil(2*idx+1, lBound, rBound, l, md), queryUtil(2*idx+2, lBound, rBound, md+1, r)); //Min
  		}
  	}
  	public static void main(String[] args) {
  		in = new Reader();
  		out = new Writer();
  		int t = 1;
  		while(t-->0) solve();
  		out.exit();
  	}
  	static Reader in; static Writer out;
  
  static class Reader {
  	static BufferedReader br;
  	static StringTokenizer st;
  	
  	public Reader() {
  		this.br = new BufferedReader(new InputStreamReader(System.in));
  	}
  	
  	public Reader(String f){
  		try {
  			this.br = new BufferedReader(new FileReader(f));
  		} catch (IOException e) {
  			e.printStackTrace();
  		}
  	}
  	
  	public int[] na(int n) {
  		int[] a = new int[n];
  		for (int i = 0; i < n; i++) a[i] = nextInt();
  		return a;
  	}
  
  	public double[] nd(int n) {
  		double[] a = new double[n];
  		for (int i = 0; i < n; i++) a[i] = nextDouble();
  		return a;
  	}
  	
  	public long[] nl(int n) {
  		long[] a = new long[n];
  		for (int i = 0; i < n; i++) a[i] = nextLong();
  		return a;
  	}
  
  	public char[] nca() {
  		return next().toCharArray();
  	}
  
  	public String[] ns(int n) {
  		String[] a = new String[n];
  		for (int i = 0; i < n; i++) a[i] = next();
  		return a;
  	}
  
  	public int nextInt() {
  		ensureNext();
  		return Integer.parseInt(st.nextToken());
  	}
  
  	public double nextDouble() {
  		ensureNext();
  		return Double.parseDouble(st.nextToken());
  	}
  
  	public Long nextLong() {
  		ensureNext();
  		return Long.parseLong(st.nextToken());
  	}
  
  	public String next() {
  		ensureNext();
  		return st.nextToken();
  	}
  	
  	public String nextLine() {
  		try {
  			return br.readLine();
  		} catch (Exception e) {
  			e.printStackTrace();
  			return null;
  		}
  	}
  	
  	private void ensureNext() {
  		if (st == null || !st.hasMoreTokens()) {
  			try {
  				st = new StringTokenizer(br.readLine());
  			} catch (IOException e) {
  				e.printStackTrace();
  			}
  		}
  	}
  }
  
  static class Util{
  		private static Random random = new Random();
  		static long[] fact;
  		
  		public static void initFactorial(int n, long mod) {
  			fact = new long[n+1];
  			fact[0] = 1;
  			for (int i = 1; i < n+1; i++) fact[i] = (fact[i - 1] * i) % mod;
  		}
  		
  		public static long modInverse(long a, long MOD) {
  			long[] gcdE = gcdExtended(a, MOD);
  			if (gcdE[0] != 1) return -1; // Inverted doesn't exist
  			long x = gcdE[1];
  			return (x % MOD + MOD) % MOD;
  		}
  		
  		public static long[] gcdExtended(long p, long q) {
  			if (q == 0) return new long[] { p, 1, 0 };
  			long[] vals = gcdExtended(q, p % q);
  			long tmp = vals[2];
  			vals[2] = vals[1] - (p / q) * vals[2];
  			vals[1] = tmp;
  			return vals;
  		}
  		
  		public static long nCr(int n, int r, long MOD) {
  			if (r == 0) return 1;
  			return (fact[n] * modInverse(fact[r], MOD) % MOD * modInverse(fact[n - r], MOD) % MOD) % MOD;
  		}
  		
  		public static long nCr(int n, int r) {
  			return (fact[n]/fact[r])/fact[n-r];
  		}
  		
  		public static long nPr(int n, int r, long MOD) {
  			if (r == 0) return 1;
  			return (fact[n] * modInverse(fact[n - r], MOD) % MOD) % MOD;
  		}
  		public static long nPr(int n, int r) {
  			return fact[n]/fact[n-r];
  		}
  		
  		public static boolean isPrime(int n) { 
  	        if (n <= 1) return false; 
  	        if (n <= 3) return true; 
  	        if (n % 2 == 0 || n % 3 == 0) return false; 
  	        for (int i = 5; i * i <= n; i = i + 6) 
  	            if (n % i == 0 || n % (i + 2) == 0) 
  	            return false; 
  	        return true; 
  	    }
  		
  	    public static boolean[] getSieve(int n) {
  	        boolean[] isPrime = new boolean[n+1];
  	        for (int i = 2; i <= n; i++) isPrime[i] = true;
  	        for (int i = 2; i*i <= n; i++) if (isPrime[i]) 
  	                for (int j = i; i*j <= n; j++) isPrime[i*j] = false;
  	        return isPrime;
  	    }
  	    
  	    public static int gcd(int a, int b) { 
  	    	int tmp = 0;
  	    	while(b != 0) {
  	    		tmp = b;
  	    		b = a%b;
  	    		a = tmp;
  	    	}
  	    	return a;
  	    }
  	    
  	    public static long gcd(long a, long b) { 
  	    	long tmp = 0;
  	    	while(b != 0) {
  	    		tmp = b;
  	    		b = a%b;
  	    		a = tmp;
  	    	}
  	    	return a;
  	    }
  	    
  	    public static int random(int min, int max) {
  	    	return random.nextInt(max-min+1)+min;
  	    }
  	    
  		public static void dbg(Object... o) { 
  			System.out.println(Arrays.deepToString(o)); 
  		}
  		
  		public static void reverse(int[] s, int l , int r) {
  			for(int i = l; i<=(l+r)/2; i++) {
  				int tmp = s[i];
  				s[i] = s[r+l-i];
  				s[r+l-i] = tmp;
  			}
  	    }
  		
  		public static void reverse(int[] s) {
  			reverse(s, 0, s.length-1);
  	    }
  		
  		public static void reverse(long[] s, int l , int r) {
  			for(int i = l; i<=(l+r)/2; i++) {
  				long tmp = s[i];
  				s[i] = s[r+l-i];
  				s[r+l-i] = tmp;
  			}
  	    }
  		
  		public static void reverse(long[] s) {
  			reverse(s, 0, s.length-1);
  	    }
  		
  		public static void reverse(float[] s, int l , int r) {
  			for(int i = l; i<=(l+r)/2; i++) {
  				float tmp = s[i];
  				s[i] = s[r+l-i];
  				s[r+l-i] = tmp;
  			}
  	    }
  		
  		public static void reverse(float[] s) {
  			reverse(s, 0, s.length-1);
  	    }
  		
  		public static void reverse(double[] s, int l , int r) {
  			for(int i = l; i<=(l+r)/2; i++) {
  				double tmp = s[i];
  				s[i] = s[r+l-i];
  				s[r+l-i] = tmp;
  			}
  	    }
  		
  		public static void reverse(double[] s) {
  			reverse(s, 0, s.length-1);
  	    }
  		
  		public static void reverse(char[] s, int l , int r) {
  			for(int i = l; i<=(l+r)/2; i++) {
  				char tmp = s[i];
  				s[i] = s[r+l-i];
  				s[r+l-i] = tmp;
  			}
  	    }
  		
  		public static void reverse(char[] s) {
  			reverse(s, 0, s.length-1);
  	    }
  		
  		public static <T> void reverse(T[] s, int l , int r) {
  			for(int i = l; i<=(l+r)/2; i++) {
  				T tmp = s[i];
  				s[i] = s[r+l-i];
  				s[r+l-i] = tmp;
  			}
  	    }
  		
  		public static <T> void reverse(T[] s) {
  			reverse(s, 0, s.length-1);
  	    }
  		
  		public static void shuffle(int[] s) {
  	        for (int i = 0; i < s.length; ++i) {
  	            int j = random.nextInt(i + 1);
  	            int t = s[i];
  	            s[i] = s[j];
  	            s[j] = t;
  	        }
  	    }
  		
  	    public static void shuffle(long[] s) {
  	        for (int i = 0; i < s.length; ++i) {
  	            int j = random.nextInt(i + 1);
  	            long t = s[i];
  	            s[i] = s[j];
  	            s[j] = t;
  	        }
  	    }
  	    
  	    public static void shuffle(float[] s) {
  	        for (int i = 0; i < s.length; ++i) {
  	            int j = random.nextInt(i + 1);
  	            float t = s[i];
  	            s[i] = s[j];
  	            s[j] = t;
  	        }
  	    }
  	    
  	    public static void shuffle(double[] s) {
  	        for (int i = 0; i < s.length; ++i) {
  	            int j = random.nextInt(i + 1);
  	            double t = s[i];
  	            s[i] = s[j];
  	            s[j] = t;
  	        }
  	    }
  	    
  	    public static void shuffle(char[] s) {
  	        for (int i = 0; i < s.length; ++i) {
  	            int j = random.nextInt(i + 1);
  	            char t = s[i];
  	            s[i] = s[j];
  	            s[j] = t;
  	        }
  	    }
  	    
  	    public static <T> void shuffle(T[] s) {
  	        for (int i = 0; i < s.length; ++i) {
  	            int j = random.nextInt(i + 1);
  	            T t = s[i];
  	            s[i] = s[j];
  	            s[j] = t;
  	        }
  	    }
  	    
  		public static void sortArray(int[] a) {
  	        shuffle(a);
  	        Arrays.sort(a);
  	    }
  		
  		public static void sortArray(long[] a) {
  			shuffle(a);
  	        Arrays.sort(a);
  	    }
  		
  		public static void sortArray(float[] a) {
  			shuffle(a);
  	        Arrays.sort(a);
  	    }
  		
  		public static void sortArray(double[] a) {
  			shuffle(a);
  	        Arrays.sort(a);
  	    }
  		
  		public static void sortArray(char[] a) {
  			shuffle(a);
  	        Arrays.sort(a);
  	    }
  		
  		public static <T extends Comparable<T>> void sortArray(T[] a) {
  	        Arrays.sort(a);
  	    }
  	}
  
  static class Writer {
  	private PrintWriter pw;
  	public Writer(){
  		pw = new PrintWriter(System.out);
  	}
  	
  	public Writer(String f){
  		try {
  			pw = new PrintWriter(new FileWriter(f));
  		} catch (IOException e) {
  			e.printStackTrace();
  		}
  	}
  	
  	public void yesNo(boolean condition) {
  		println(condition?"YES":"NO");
  	}
  	
  	public void printArray(int[] a) {
  		for(int i = 0; i<a.length; i++) print(a[i]+" ");
  	}
  	
  	public void printlnArray(int[] a) {
  		for(int i = 0; i<a.length; i++) print(a[i]+" ");
  		pw.println();
  	}
  	
  	public void printArray(long[] a) {
  		for(int i = 0; i<a.length; i++) print(a[i]+" ");
  	}
  	
  	public void printlnArray(long[] a) {
  		for(int i = 0; i<a.length; i++) print(a[i]+" ");
  		pw.println();
  	}
  	
  	public void print(Object o) {
  		pw.print(o.toString());
  	}
  	
  	public void println(Object o) {
  		pw.println(o.toString());
  	}
  	
  	public void println() {
  		pw.println();
  	}
  	
  	public void flush() {
  		pw.flush();
  	}
  	public void exit() {
  		pw.close();
  	}
  }
  }
  