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.IOException;
  import java.io.InputStream;
  import java.io.InputStreamReader;
  import java.io.PrintWriter;
  import java.util.ArrayList;
  import java.util.Arrays;
  import java.util.Collections;
  import java.util.LinkedList;
  import java.util.Queue;
  import java.util.Scanner;
  import java.util.StringTokenizer;
  import java.util.TreeSet;
  
  public class E {
  
  	public static void main(String[] args) throws IOException {
  		Scanner sc = new Scanner(System.in);
  		PrintWriter pw = new PrintWriter(System.out);
  
  		int t = 1;
  		while (t-- > 0) {
  			int n = sc.nextInt();
  			int m = sc.nextInt();
  
  			int[][] arr = new int[n][3];
  			for (int i = 0; i < n; i++) {
  				int l = sc.nextInt();
  				int r = sc.nextInt() - 1;
  				int w = sc.nextInt();
  				arr[i] = new int[] { l, r, w };
  			}
  			Arrays.sort(arr, (x, y) -> x[2] - y[2]);
  			
  			m--;
  			SegmentTree seg = new SegmentTree(m);
  
  			int ans = Integer.MAX_VALUE;
  			int i = 0;
  			int j = 0;
  			while (i < n) {
  				if (seg.query(1, m) == 0) {
  					if (j == n)
  						break;
  
  					seg.update_range(arr[j][0], arr[j][1], 1);
  					j++;
  				} else {
  					ans = Math.min(ans, arr[j - 1][2] - arr[i][2]);
  					seg.update_range(arr[i][0], arr[i][1], -1);
  					i++;
  				}
  			}
  
  			pw.println(ans);
  
  		}
  
  		pw.flush();
  	}
  
  	static class SegmentTree { // 1-based DS, OOP
  
  		int N; // the number of elements in the array as a power of 2 (i.e. after padding)
  		int[] sTree, lazy;
  
  		SegmentTree(int n) {
  			N = 1;
  			while (N < n)
  				N <<= 1;
  			sTree = new int[N << 1]; // no. of nodes = 2*N - 1, we add one to cross out index zero
  			lazy = new int[N << 1];
  		}
  
  		void update_range(int i, int j, int val) // O(log n)
  		{
  			update_range(1, 1, N, i, j, val);
  		}
  
  		void update_range(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_range(node << 1, b, mid, i, j, val);
  				update_range(node << 1 | 1, mid + 1, e, i, j, val);
  				sTree[node] = Math.min(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;
  		}
  
  		int query(int i, int j) {
  			return query(1, 1, N, i, j);
  		}
  
  		int query(int node, int b, int e, int i, int j) // O(log n)
  		{
  			if (i > e || j < b)
  				return (int) 1e9;
  			if (b >= i && e <= j)
  				return sTree[node];
  			int mid = b + e >> 1;
  			propagate(node, b, mid, e);
  			int q1 = query(node << 1, b, mid, i, j);
  			int q2 = query(node << 1 | 1, mid + 1, e, i, j);
  			return Math.min(q1, q2);
  
  		}
  
  	}
  
  	static long[] fac;
  	static int mod = 998244353;
  
  	static void fac() {
  		fac[0] = 1;
  		for (int j = 1; j < fac.length; j++) {
  			fac[j] = fac[j - 1] * j;
  			fac[j] %= mod;
  		}
  	}
  
  	static long inverse(long n) {
  		return modPow(n, mod - 2, mod);
  	}
  
  	static long nc(int n, int r) {
  		return ((fac[n] * inverse(fac[r])) % mod) * inverse(fac[n - r]) % mod;
  	}
  
  	static long modPow(long a, long e, int mod) // O(log e)
  	{
  		a %= mod;
  		long res = 1;
  		while (e > 0) {
  			if ((e & 1) == 1)
  				res = (res * a) % mod;
  			a = (a * a) % mod;
  			e >>= 1;
  		}
  		return res;
  	}
  
  	static class Scanner {
  		StringTokenizer st;
  		BufferedReader br;
  
  		public Scanner(InputStream s) {
  			br = new BufferedReader(new InputStreamReader(s));
  		}
  
  		public String next() throws IOException {
  			while (st == null || !st.hasMoreTokens())
  				st = new StringTokenizer(br.readLine());
  			return st.nextToken();
  		}
  
  		public int nextInt() throws IOException {
  			return Integer.parseInt(next());
  		}
  
  		public long nextLong() throws IOException {
  			return Long.parseLong(next());
  		}
  
  		public String nextLine() throws IOException {
  			return br.readLine();
  		}
  
  		public double nextDouble() throws IOException {
  			String x = next();
  			StringBuilder sb = new StringBuilder("0");
  			double res = 0, f = 1;
  			boolean dec = false, neg = false;
  			int start = 0;
  			if (x.charAt(0) == '-') {
  				neg = true;
  				start++;
  			}
  			for (int i = start; i < x.length(); i++)
  				if (x.charAt(i) == '.') {
  					res = Long.parseLong(sb.toString());
  					sb = new StringBuilder("0");
  					dec = true;
  				} else {
  					sb.append(x.charAt(i));
  					if (dec)
  						f *= 10;
  				}
  			res += Long.parseLong(sb.toString()) / f;
  			return res * (neg ? -1 : 1);
  		}
  
  		public boolean ready() throws IOException {
  			return br.ready();
  		}
  
  	}
  
  }
  