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: //package newpackage;
  
  import java.util.Arrays;
  import java.util.Scanner;
  
  public class Main {
  
      static class Segment implements Comparable<Segment>{
          public int l, r, w;
          public Segment(int l, int r, int w) {
              this.l = l;
              this.r = r;
              this.w = w;
          }
  
          public int compareTo(Segment o) {
              return Integer.compare(w, o.w);
          }
      }
  
      static class SegmentTree {
          public SegmentTree leftChild, rightChild;
          public int left, right, val, propVal;
          public SegmentTree(int left, int right) {
              this.val = 0;
              this.left = left;
              this.right = right;
              if (left != right) {
                  int mid = (left + right) / 2;
                  this.leftChild = new SegmentTree(left, mid);
                  this.rightChild = new SegmentTree(mid + 1, right);
              }
          }
          public void addSeg(int low, int high, int delta) {
              if (left > right)
                  return;
              // check if propagated value is added and every thing is up to date or not.
              if (propVal != 0){
                  val += propVal;
                  if (leftChild != null && rightChild != null){
                      leftChild.propVal += propVal;
                      rightChild.propVal += propVal;
                  }
                  propVal = 0;
              }
              // case No overlap.
              if (low > right || high < left)
                  return;
              // case total overlap.
              if (low <= left && high >= right){
                  val += delta;
                  if (leftChild != null && rightChild != null){
                      leftChild.propVal += delta;
                      rightChild.propVal += delta;
                  }
                  return;
              }
              // case partial overlap (recurse left and right).
              if (leftChild == null || rightChild == null)
                  return;
              int mid = (left + right)/2;
              leftChild.right = mid;
              rightChild.left = mid + 1;
              leftChild.addSeg(low, high, delta);
              rightChild.addSeg(low, high, delta);
              val = Math.min(leftChild.val, rightChild.val);
          }
  
          public int min() {
              return this.val + this.propVal;
          }
      }
  
      public static void main(String[] args) {
          Scanner input = new Scanner(System.in);
          int n = input.nextInt();
          int m = input.nextInt();
          Segment[] segments = new Segment[n];
          for (int i = 0; i < n; i++)
              segments[i] = new Segment(input.nextInt() - 1, input.nextInt() - 1, input.nextInt());
          Arrays.sort(segments);
          SegmentTree st = new SegmentTree(0, 2*(m - 1));
  
          // main algorithm.
          int ans = Integer.MAX_VALUE;
          for (int i = 0, j = 0; i < n && j < n; i++) {
              st.addSeg(2 * segments[i].l, 2 * segments[i].r, 1);
              while (st.min() > 0){
                  ans = Math.min(ans, segments[i].w - segments[j].w);
                  st.addSeg(2 * segments[j].l, 2 * segments[j].r, -1);
                  j++;
              }
          }
          System.out.println(ans);
      }
  }
  