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.util.*;
  import java.io.*;
  
  public class _1555_E {
      public static void main(String[] args) throws IOException {
          BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
          PrintWriter out = new PrintWriter(System.out);
          StringTokenizer line = new StringTokenizer(in.readLine());
          int n = Integer.parseInt(line.nextToken());
          int m = Integer.parseInt(line.nextToken());
          int[][] segs = new int[n][3];
          for(int i = 0; i < n; i++) {
              line = new StringTokenizer(in.readLine());
              segs[i][0] = Integer.parseInt(line.nextToken());
              segs[i][1] = Integer.parseInt(line.nextToken());
              segs[i][2] = Integer.parseInt(line.nextToken());
              if(segs[i][1] < m) {
                  segs[i][1]--;
              }
          }
          Arrays.sort(segs, new Comparator<int[]>() {
              @Override
              public int compare(int[] a, int[] b) {
                  return a[2] - b[2];
              }
          });
          Segtree st = new Segtree(new int[m + 1]);
          int res = Integer.MAX_VALUE;
          int l = 0;
          boolean first = true;
          for(int r = 0; r < n; r++) {
              st.update(1, 0, m, segs[r][0], segs[r][1], 1);
              int min = st.min(1, 0, m, 1, m);
              if(first && min == 0) {
                  continue;
              }
              first = false;
              while(min > 0) {
                  st.update(1, 0, m, segs[l][0], segs[l][1], -1);
                  min = st.min(1, 0, m, 1, m);
                  l++;
              }
              l--;
              res = Math.min(res, segs[r][2] - segs[l][2]);
              st.update(1, 0, m, segs[l][0], segs[l][1], 1);
          }
          out.println(res);
          in.close();
          out.close();
      }
      static class Segtree {
          int[] a, min, lazy;
          Segtree(int[] aa) {
              a = aa;
              min = new int[a.length * 4];
              lazy = new int[a.length * 4];
              construct(1, 0, a.length - 1);
          }
          void construct(int v, int l, int r) {
              if(l == r) {
                  min[v] = a[l];
              }else {
                  int m = (l + r) / 2;
                  construct(v * 2, l, m);
                  construct(v * 2 + 1, m + 1, r);
                  min[v] = Math.min(min[v * 2], min[v * 2 + 1]);
              }
          }
          void push(int v) {
              lazy[v * 2] += lazy[v];
              min[v * 2] += lazy[v];
              lazy[v * 2 + 1] += lazy[v];
              min[v * 2 + 1] += lazy[v];
              lazy[v] = 0;
          }
          void update(int v, int l, int r, int ql, int qr, int add) {
              if(ql > qr) {
                  return;
              }else if(l == ql && r == qr) {
                  lazy[v] += add;
                  min[v] += add;
              }else {
                  push(v);
                  int m = (l + r) / 2;
                  update(v * 2, l, m, ql, Math.min(m, qr), add);
                  update(v * 2 + 1, m + 1, r, Math.max(ql, m + 1), qr, add);
                  min[v] = Math.min(min[v * 2], min[v * 2 + 1]);
              }
          }
          int min(int v, int l, int r, int ql, int qr) {
              if(ql > qr) {
                  return Integer.MAX_VALUE;
              }else if(l == ql && r == qr) {
                  return min[v];
              }else {
                  push(v);
                  int m = (l + r) / 2;
                  int minl = min(v * 2, l, m, ql, Math.min(m, qr));
                  int minr = min(v * 2 + 1, m + 1, r, Math.max(ql, m + 1), qr);
                  return Math.min(minl, minr);
              }
          }
      }
  }
  