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.io.PrintStream;
  import java.util.Arrays;
  import java.io.InputStream;
  
  /**
   * Built using CHelper plug-in
   * Actual solution is at the top
   *
   * @author sarthakmanna
   */
  public class Main {
      public static void main(String[] args) {
          InputStream inputStream = System.in;
          OutputStream outputStream = System.out;
          FastReader in = new FastReader(inputStream);
          PrintWriter out = new PrintWriter(outputStream);
          EBoringSegments solver = new EBoringSegments();
          solver.solve(1, in, out);
          out.close();
      }
  
      static class EBoringSegments {
          public void solve(int testNumber, FastReader in, PrintWriter out) {
              int i, j, k;
  
              int N = in.nextInt(), M = in.nextInt();
              int[][] P = new int[N][3];
              for (i = 0; i < N; ++i) {
                  P[i][0] = in.nextInt() - 1;
                  P[i][1] = in.nextInt() - 1;
                  P[i][2] = in.nextInt();
              }
              Arrays.sort(P, (a, b) -> Integer.compare(a[2], b[2]));
  
              SegmentTree segmentTree = new SegmentTree(new long[M - 1], Integer.MAX_VALUE, 0) {
                  public long nodeToNode(long a, long b) {
                      return Math.min(a, b);
                  }
  
                  public long lazyToLazy(long a, long b) {
                      return a + b;
                  }
  
                  public long lazyToNode(long val, int l, int r) {
                      return val;
                  }
              };
  
  //        for (int idx = 0; idx < M - 1; ++idx)
  //            System.err.print(segmentTree.rangeQuery(idx, idx) + ", ");
  //        System.err.println();
  
              long ans = Long.MAX_VALUE;
              int p = 0;
              for (i = 0; i < N; ++i) {
                  while (p < N && segmentTree.rangeQuery(0, M - 1) == 0) {
                      segmentTree.rangeUpdate(P[p][0], P[p][1] - 1, +1);
                      ++p;
                  }
  
  //            for (int idx = 0; idx < M - 1; ++idx)
  //                System.err.print(segmentTree.rangeQuery(idx, idx) + ", ");
  //            System.err.println("**** " + p);
  
                  if (segmentTree.rangeQuery(0, M - 1) > 0) {
                      ans = Math.min(ans, P[p - 1][2] - P[i][2]);
                  } else {
                      break;
                  }
  
                  segmentTree.rangeUpdate(P[i][0], P[i][1] - 1, -1);
              }
              out.println(ans);
          }
  
      }
  
      static class FastReader {
          static final int BUFSIZE = 1 << 20;
          static byte[] buf;
          static int index;
          static int total;
          static InputStream in;
  
          public FastReader(InputStream is) {
              try {
                  in = is;
                  buf = new byte[BUFSIZE];
              } catch (Exception e) {
              }
          }
  
          private int scan() {
              try {
                  if (index >= total) {
                      index = 0;
                      total = in.read(buf);
                      if (total <= 0)
                          return -1;
                  }
                  return buf[index++];
              } catch (Exception | Error e) {
                  System.err.println(e.getMessage());
                  return 13 / 0;
              }
          }
  
          public int nextInt() {
              int c, val = 0;
              for (c = scan(); c <= 32; c = scan()) ;
              boolean neg = c == '-';
              if (c == '-' || c == '+')
                  c = scan();
              for (; c >= '0' && c <= '9'; c = scan())
                  val = (val << 3) + (val << 1) + (c & 15);
              return neg ? -val : val;
          }
  
      }
  
      static class SegmentTree {
          private int N;
          private long[] tree;
          private long[] lazy;
          public final long DEFAULT_NODE;
          public final long DEFAULT_LAZY;
  
          public SegmentTree(long[] ar, long def_node, long def_lazy) {
              DEFAULT_NODE = def_node;
              DEFAULT_LAZY = def_lazy;
              N = 1;
              while (N < ar.length) N <<= 1;
              tree = new long[N * 2 - 1];
              Arrays.fill(tree, DEFAULT_NODE);
              lazy = new long[N * 2 - 1];
              Arrays.fill(lazy, DEFAULT_LAZY);
  
              for (int i = 0; i < ar.length; ++i) tree[i + N - 1] = ar[i];
              for (int i = N - 2; i >= 0; --i) {
                  tree[i] = nodeToNode(tree[i * 2 + 1], tree[i * 2 + 2]);
              }
          }
  
          public long nodeToNode(long a, long b) {
              return a + b;
          }
  
          public long lazyToLazy(long a, long b) {
              return a + b;
          }
  
          public void pushDown(int i, int l, int r) {
              //tree[i] = nodeToNode(tree[i], lazyToNode(lazy[i], l, r));
              tree[i] += lazy[i];
              if (i * 2 + 1 < tree.length) {
                  lazy[i * 2 + 1] = lazyToLazy(lazy[i * 2 + 1], lazy[i]);
                  lazy[i * 2 + 2] = lazyToLazy(lazy[i * 2 + 2], lazy[i]);
              }
              lazy[i] = DEFAULT_LAZY;
          }
  
          public void rangeUpdate(int l, int r, long val) {
              update(0, 0, N - 1, l, r, val);
          }
  
          public long rangeQuery(int l, int r) {
              return query(0, 0, N - 1, l, r);
          }
  
          private void update(int i, int l, int r, int ql, int qr, long val) {
              pushDown(i, l, r);
              int mid = l + r >> 1, i2 = i << 1;
              if (l > qr || r < ql) return;
              else if (l >= ql && r <= qr) {
                  lazy[i] = lazyToLazy(lazy[i], val);
                  pushDown(i, l, r);
              } else {
                  update(i2 + 1, l, mid, ql, qr, val);
                  update(i2 + 2, mid + 1, r, ql, qr, val);
  
                  // Rebuild tree[i] if necessary
                  tree[i] = nodeToNode(tree[i2 + 1], tree[i2 + 2]);
              }
          }
  
          private long query(int i, int l, int r, int ql, int qr) {
              pushDown(i, l, r);
              int mid = l + r >> 1, i2 = i << 1;
              if (l > qr || r < ql) return DEFAULT_NODE;
              else if (l >= ql && r <= qr) return tree[i];
              else {
                  return nodeToNode(query(i2 + 1, l, mid, ql, qr),
                          query(i2 + 2, mid + 1, r, ql, qr));
              }
          }
  
      }
  }
  
  