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: def naiveSolve():
      
      
      
      return
  
  
  
  def solve():
      
      
      
      return
  
  class Lazysegtree:
      #RAQ
      def __init__(self, A, defaultVal, initialize = True, segf = min):
          #区間は 1-indexed で管理
          intv=defaultVal
          self.N = len(A)
          self.N0 = 2**(self.N-1).bit_length()
          self.intv = intv
          self.segf = segf
          self.lazy = [0]*(2*self.N0)
          if initialize:
              self.data = [intv]*self.N0 + A + [intv]*(self.N0 - self.N)
              for i in range(self.N0-1, 0, -1):
                  self.data[i] = self.segf(self.data[2*i], self.data[2*i+1]) 
          else:
              self.data = [intv]*(2*self.N0)
   
      def _ascend(self, k):
          k = k >> 1
          c = k.bit_length()
          for j in range(c):
              idx = k >> j
              self.data[idx] = self.segf(self.data[2*idx], self.data[2*idx+1]) \
              + self.lazy[idx]
              
      def _descend(self, k):
          k = k >> 1
          idx = 1
          c = k.bit_length()
          for j in range(1, c+1):
              idx = k >> (c - j)
              ax = self.lazy[idx]
              if not ax:
                  continue
              self.lazy[idx] = 0
              self.data[2*idx] += ax
              self.data[2*idx+1] += ax
              self.lazy[2*idx] += ax
              self.lazy[2*idx+1] += ax
      
      def query(self, l, r):
          r+=1
          L = l+self.N0
          R = r+self.N0
          Li = L//(L & -L)
          Ri = R//(R & -R)
          self._descend(Li)
          self._descend(Ri - 1)
          
          s = self.intv                                                              
          while L < R:
              if R & 1:
                  R -= 1
                  s = self.segf(s, self.data[R])
              if L & 1:
                  s = self.segf(s, self.data[L])
                  L += 1
              L >>= 1
              R >>= 1
          return s
      
      def add(self, l, r, x):
          r+=1
          L = l+self.N0
          R = r+self.N0
   
          Li = L//(L & -L)
          Ri = R//(R & -R)
          
          while L < R :
              if R & 1:
                  R -= 1
                  self.data[R] += x
                  self.lazy[R] += x
              if L & 1:
                  self.data[L] += x
                  self.lazy[L] += x
                  L += 1
              L >>= 1
              R >>= 1
          
          self._ascend(Li)
          self._ascend(Ri-1)
      
      def binsearch(self, l, r, check, reverse = False):
          r+=1
          L = l+self.N0
          R = r+self.N0
          Li = L//(L & -L)
          Ri = R//(R & -R)
          self._descend(Li)
          self._descend(Ri-1)
          SL, SR = [], []
          while L < R:
              if R & 1:
                  R -= 1
                  SR.append(R)
              if L & 1:
                  SL.append(L)
                  L += 1
              L >>= 1
              R >>= 1
          
          if reverse:
              for idx in (SR + SL[::-1]):
                  if check(self.data[idx]):
                      break
              else:
                  return -1
              while idx < self.N0:
                  ax = self.lazy[idx]
                  self.lazy[idx] = 0
                  self.data[2*idx] += ax
                  self.data[2*idx+1] += ax
                  self.lazy[2*idx] += ax
                  self.lazy[2*idx+1] += ax
                  idx = idx << 1
                  if check(self.data[idx+1]):
                      idx += 1
              return idx - self.N0
          else:
              for idx in (SL + SR[::-1]):
                  if check(self.data[idx]):
                      break
              else:
                  return -1
              while idx < self.N0:
                  ax = self.lazy[idx]
                  self.lazy[idx] = 0
                  self.data[2*idx] += ax
                  self.data[2*idx+1] += ax
                  self.lazy[2*idx] += ax
                  self.lazy[2*idx+1] += ax
                  idx = idx << 1
                  if not check(self.data[idx]):
                      idx += 1
              return idx - self.N0
  
  def main():
      
      n,m=readIntArr()
      wlr=[]
      for _ in range(n):
          l,r,w=readIntArr() # 1<=l<r<=m
          r-=1 # reduce all the rights by 1 so that each count needs to be only 1 (no need to overlap)
          wlr.append((w,l,r))
      wlr.sort()
      
      arr=[0]*(m+1)
      lst=Lazysegtree(arr,inf,initialize=True,segf=min)
      ans=inf
      left=0
      # print(wlr)
      for right in range(n):
          lst.add(wlr[right][1],wlr[right][2],1)
          while lst.query(1,m-1)>=1:
              ans=min(ans,wlr[right][0]-wlr[left][0])
              lst.add(wlr[left][1],wlr[left][2],-1)
              left+=1
      print(ans)
      
      return
  
  
  
  import sys
  input=sys.stdin.buffer.readline #FOR READING PURE INTEGER INPUTS (space separation ok)
  # input=lambda: sys.stdin.readline().rstrip("\r\n") #FOR READING STRING/TEXT INPUTS.
  
  def oneLineArrayPrint(arr):
      print(' '.join([str(x) for x in arr]))
  def multiLineArrayPrint(arr):
      print('\n'.join([str(x) for x in arr]))
  def multiLineArrayOfArraysPrint(arr):
      print('\n'.join([' '.join([str(x) for x in y]) for y in arr]))
   
  def readIntArr():
      return [int(x) for x in input().split()]
  # def readFloatArr():
  #     return [float(x) for x in input().split()]
   
  def makeArr(defaultValFactory,dimensionArr): # eg. makeArr(lambda:0,[n,m])
      dv=defaultValFactory;da=dimensionArr
      if len(da)==1:return [dv() for _ in range(da[0])]
      else:return [makeArr(dv,da[1:]) for _ in range(da[0])]
   
  def queryInteractive(x):
      print('{}'.format(x))
      sys.stdout.flush()
      return int(input())
   
  def answerInteractive(ans):
      print('! {}'.format(ans))
      sys.stdout.flush()
   
  inf=float('inf')
  # MOD=10**9+7
  MOD=998244353
  
  from math import gcd,floor,ceil
  # from math import floor,ceil # for Python2
   
  for _abc in range(1):
      main()