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.OutputStream;
  import java.io.IOException;
  import java.io.InputStream;
  import java.io.PrintWriter;
  import java.util.StringTokenizer;
  import java.io.IOException;
  import java.io.BufferedReader;
  import java.util.Comparator;
  import java.io.InputStreamReader;
  import java.util.ArrayList;
  import java.io.InputStream;
  
  /**
   * Built using CHelper plug-in
   * Actual solution is at the top
   *
   * @author xwchen
   */
  public class Main {
      public static void main(String[] args) {
          InputStream inputStream = System.in;
          OutputStream outputStream = System.out;
          InputReader in = new InputReader(inputStream);
          PrintWriter out = new PrintWriter(outputStream);
          TaskE solver = new TaskE();
          solver.solve(1, in, out);
          out.close();
      }
  
      static class TaskE {
          public void solve(int testNumber, InputReader in, PrintWriter out) {
              int n = in.nextInt();
              int m = in.nextInt();
              ArrayList<Segment> segments = new ArrayList<>();
              for (int i = 0; i < n; i++) {
                  int left = in.nextInt();
                  int right = in.nextInt() - 1;
                  int weight = in.nextInt();
                  Segment segment = new Segment(left, right, weight);
                  segments.add(segment);
              }
              segments.sort(Comparator.comparingInt(o -> o.weight));
              SegmentTree segmentTree = new SegmentTree(m);
              int[] a = new int[m + 1];
              segmentTree.build(a);
  
              int best = 1000000;
              int ed = -1;
              for (int st = 0; st < n; st++) {
                  while (ed + 1 < n && segmentTree.query(1, m - 1) == 0) {
                      ++ed;
                      segmentTree.update(segments.get(ed).left, segments.get(ed).right, 1);
                  }
                  if (segmentTree.query(1, m - 1) > 0) {
                      best = Math.min(best, segments.get(ed).weight - segments.get(st).weight);
                  } else {
                      break;
                  }
                  segmentTree.update(segments.get(st).left, segments.get(st).right, -1);
              }
              out.println(best);
          }
  
          class Segment {
              int left;
              int right;
              int weight;
  
              public Segment(int left, int right, int weight) {
                  this.left = left;
                  this.right = right;
                  this.weight = weight;
              }
  
          }
  
      }
  
      static class SegmentTree {
          int n;
          Node[] nodes = null;
          int[] a = null;
          int[] rev = null;
  
          public SegmentTree(int n) {
              int m = n * 4;
              this.n = n;
              nodes = new Node[m];
              //rNodes = new Node[m];
              rev = new int[m];
              for (int i = 0; i < m; ++i) {
                  nodes[i] = new Node();
                  //rNodes[i] = new Node();
              }
          }
  
          public void build(int[] a) {
              this.a = a;
              build(1, 1, n, a);
          }
  
          public void build(int root, int nodeLeft, int nodeRight, int[] a) {
              nodes[root].left = nodeLeft;
              nodes[root].right = nodeRight;
              //rNodes[root].left = nodeLeft;
              //rNodes[root].right = nodeRight;
              //nodes[root].lazy_value = rNodes[root].lazy_value = 0;
  //      System.out.println(String.format("node[%d] [%d,%d]", cur, left[cur], right[cur]));
              if (nodeLeft == nodeRight) {
                  nodes[root].val = a[nodeLeft];
                  nodes[root].lazy_value = 0;
                  //System.out.println(" L:"+cur.left);
  //            if (a[nodeLeft - 1] == '<') {
  //                rNodes[root].leftRight = nodes[root].leftLeft = 1;
  //                rNodes[root].leftLeft = nodes[root].leftRight = 0;
  //                rNodes[root].rightRight = nodes[root].rightLeft = 1;
  //                rNodes[root].rightLeft = nodes[root].rightRight = 0;
  //                rNodes[root].maxValue = nodes[root].maxValue = 1;
  //            } else {
  //                rNodes[root].leftRight = nodes[root].leftLeft = 0;
  //                rNodes[root].leftLeft = nodes[root].leftRight = 1;
  //                rNodes[root].rightRight = nodes[root].rightLeft = 0;
  //                rNodes[root].rightLeft = nodes[root].rightRight = 1;
  //                rNodes[root].maxValue = nodes[root].maxValue = 1;
  //            }
  //          System.out.println(String.format("node[%d] [%d,%d] sum =%d", cur, left[cur], right[cur], sum[cur]));
              } else {
                  int leftChild = root * 2;
                  int rightChild = root * 2 + 1;
                  int mid = (nodeLeft + nodeRight) / 2;
                  build(leftChild, nodeLeft, mid, a);
                  build(rightChild, mid + 1, nodeRight, a);
                  pull_up(nodes[root], nodes[leftChild], nodes[rightChild]);
                  //pull_up(rNodes[root], rNodes[leftChild], rNodes[rightChild]);
                  //System.out.println(String.format("node[%d] [%d,%d] leftLeft = %d leftRight = %d rightLeft = %d rightRight = %d %s", root, nodeLeft, nodeRight, nodes[root].leftLeft, nodes[root].leftRight, nodes[root].rightLeft, nodes[root].rightRight, subString(a, nodeLeft, nodeRight + 1)));
              }
          }
  
          void pull_up(Node cur, Node left, Node right) {
              cur.val = Math.min(left.val, right.val);
              //int pair = Math.min(left.rightBracket, right.leftBracket);
              //cur.val = Math.max(left.val, right.val);
              //cur.maxValue = Math.max(left.maxValue, right.maxValue);
  //        cur.leftRight = left.leftRight;
  //        if (left.leftLeft > 0) {
  //            cur.leftLeft = left.leftLeft;
  //            if (left.leftLeft + left.leftRight == left.right - left.left + 1) {
  //                if (right.leftRight == 0) {
  //                    cur.leftLeft += right.leftLeft;
  //                }
  //            }
  //        } else {
  //            cur.leftRight += right.leftRight;
  //            cur.leftLeft = right.leftLeft;
  //        }
  //        cur.maxValue = Math.max(cur.maxValue, cur.leftRight + cur.leftLeft);
  //
  //        cur.rightLeft = right.rightLeft;
  //        if (right.rightRight > 0) {
  //            cur.rightRight = right.rightRight;
  //            if (right.rightLeft + right.rightRight == right.right - right.left + 1) {
  //                if (left.rightLeft == 0) {
  //                    cur.rightRight += left.rightRight;
  //                }
  //            }
  //        } else {
  //            cur.rightLeft += left.rightLeft;
  //            cur.rightRight = left.rightRight;
  //        }
  //        cur.maxValue = Math.max(cur.maxValue, cur.rightRight + cur.rightLeft);
  //        if (left.rightLeft == 0) {
  //            cur.maxValue = Math.max(cur.maxValue, left.rightRight + right.leftRight + right.leftLeft);
  //        }
  //        if (right.leftRight == 0) {
  //            cur.maxValue = Math.max(cur.maxValue, right.leftLeft + left.rightLeft + left.rightRight);
  //        }
              //cur.leftBracket = left.leftBracket + right.leftBracket - pair;
              //cur.rightBracket = right.rightBracket + left.rightBracket - pair;
          }
  
          void push_down(int root) {
              if (nodes[root].lazy_value != 0) {
                  op(root * 2, nodes[root].lazy_value);
                  op(root * 2 + 1, nodes[root].lazy_value);
                  nodes[root].lazy_value = 0;
              }
          }
  
          void op(int root, int value) {
              nodes[root].val += value;
              nodes[root].lazy_value += value;
          }
  
          public void update(int queryLeft, int queryRight, int value) {
              //System.out.println(String.format("%d->%d += %d", from, to, value));
              update(1, 1, n, queryLeft, queryRight, value);
          }
  
          public void update(int root, int nodeLeft, int nodeRight, int queryLeft, int queryRight, int value) {
              //System.out.println(String.format("enter node[%d] range[%d,%d] query[%d,%d]", root, nodeLeft, nodeRight, queryLeft, queryRight));
              //System.out.println(String.format("enter node[%d] lazy = %d [%d,%d] leftLeft = %d leftRight = %d rightLeft = %d rightRight = %d %s", root, nodes[root].lazy_value, nodeLeft, nodeRight, nodes[root].leftLeft, nodes[root].leftRight, nodes[root].rightLeft, nodes[root].rightRight, subString(a, nodeLeft, nodeRight + 1)));
  
              if (queryLeft <= nodeLeft && nodeRight <= queryRight) {
                  //flip(root);
                  op(root, value);
                  //System.out.println(String.format("exit node[%d] lazy = %d [%d,%d] leftLeft = %d leftRight = %d rightLeft = %d rightRight = %d %s", root, nodes[root].lazy_value, nodeLeft, nodeRight, nodes[root].leftLeft, nodes[root].leftRight, nodes[root].rightLeft, nodes[root].rightRight, subString(a, nodeLeft, nodeRight + 1)));
              } else {
                  push_down(root);
                  int leftChild = root * 2;
                  int rightChild = root * 2 + 1;
                  int mid = (nodeLeft + nodeRight) / 2;
                  if (queryLeft <= mid) {
                      update(leftChild, nodeLeft, mid, queryLeft, queryRight, value);
                  }
                  if (queryRight >= mid + 1) {
                      update(rightChild, mid + 1, nodeRight, queryLeft, queryRight, value);
                  }
                  pull_up(nodes[root], nodes[leftChild], nodes[rightChild]);
                  //pull_up(rNodes[root], rNodes[leftChild], rNodes[rightChild]);
                  //System.out.println(String.format("exit node[%d] lazy = %d [%d,%d] leftLeft = %d leftRight = %d rightLeft = %d rightRight = %d %s", root, nodes[root].lazy_value, nodeLeft, nodeRight, nodes[root].leftLeft, nodes[root].leftRight, nodes[root].rightLeft, nodes[root].rightRight, subString(a, nodeLeft, nodeRight + 1)));
  
                  //System.out.println(String.format("after node [%d,%d] max =%d  add %d", cur.left, cur.right, cur.val, value));
              }
          }
  
          public int query(int queryLeft, int queryRight) {
              Node qNode = query(1, 1, n, queryLeft, queryRight);
              return qNode.val;
          }
  
          public Node query(int root, int nodeLeft, int nodeRight, int queryLeft, int queryRight) {
  //        System.out.println(String.format("node[%d] [%d,%d] sum =%d", cur, left[cur], right[cur], sum[cur]));
  
              if (queryLeft <= nodeLeft && nodeRight <= queryRight) {
                  return nodes[root];
              } else {
                  push_down(root);
                  int leftChild = root * 2;
                  int rightChild = root * 2 + 1;
                  int mid = (nodeLeft + nodeRight) / 2;
                  if (queryRight <= mid) {
                      return query(leftChild, nodeLeft, mid, queryLeft, queryRight);
                  }
                  if (queryLeft >= mid + 1) {
                      return query(rightChild, mid + 1, nodeRight, queryLeft, queryRight);
                  }
                  Node ql = query(leftChild, nodeLeft, mid, queryLeft, queryRight);
                  Node qr = query(rightChild, mid + 1, nodeRight, queryLeft, queryRight);
                  Node qNode = new Node();
                  pull_up(qNode, ql, qr);
                  return qNode;
              }
          }
  
          class Node {
              int left;
              int right;
              int val;
              int lazy_value;
  
          }
  
      }
  
      static class InputReader {
          private BufferedReader reader;
          private StringTokenizer tokenizer = new StringTokenizer("");
  
          public InputReader(InputStream inputStream) {
              this.reader = new BufferedReader(
                      new InputStreamReader(inputStream));
          }
  
          public String next() {
              while (!tokenizer.hasMoreTokens()) {
                  try {
                      tokenizer = new StringTokenizer(reader.readLine());
                  } catch (IOException e) {
                      e.printStackTrace();
                  }
              }
              return tokenizer.nextToken();
          }
  
          public int nextInt() {
              return Integer.parseInt(next());
          }
  
      }
  }
  
  