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 sys
  import io, os
  input = io.BytesIO(os.read(0,os.fstat(0).st_size)).readline
  from operator import itemgetter
  
  n,m=map(int,input().split())
  A=[tuple(map(int,input().split())) for i in range(n)]
  A.sort(key=itemgetter(2))
  
  seg_el=1<<((m+5).bit_length())
  SEG=[0]*(2*seg_el)
  LAZY=[0]*(2*seg_el)
  
  def indexes(L,R):
      INDLIST=[]
  
      R-=1
      
      L>>=1
      R>>=1
  
      while L!=R:
          if L>R:
              INDLIST.append(L)
              L>>=1
          else:
              INDLIST.append(R)
              R>>=1
  
      while L!=0:
          INDLIST.append(L)
          L>>=1
  
      return INDLIST
          
  
  def adds(l,r,x):
          
      L=l+seg_el
      R=r+seg_el
  
      L//=(L & (-L))
      R//=(R & (-R))
  
      UPIND=indexes(L,R)
      
      for ind in UPIND[::-1]:
          if LAZY[ind]!=0:
              plus_lazy=LAZY[ind]
              
              SEG[ind<<1]+=plus_lazy
              SEG[1+(ind<<1)]+=plus_lazy
              
              LAZY[ind<<1]+=plus_lazy
              LAZY[1+(ind<<1)]+=plus_lazy
              
              LAZY[ind]=0
      
      while L!=R:
          if L > R:
              SEG[L]+=x
              LAZY[L]+=x
              L+=1
              L//=(L & (-L))
  
          else:
              R-=1
              SEG[R]+=x
              LAZY[R]+=x
              R//=(R & (-R))
  
      for ind in UPIND:
          SEG[ind]=min(SEG[ind<<1],SEG[1+(ind<<1)])
          
  def getvalues(l,r):
  
      L=l+seg_el
      R=r+seg_el
  
      L//=(L & (-L))
      R//=(R & (-R))
  
      UPIND=indexes(L,R)
      
      for ind in UPIND[::-1]:
          if LAZY[ind]!=0:
              plus_lazy=LAZY[ind]
              
              SEG[ind<<1]+=plus_lazy
              SEG[1+(ind<<1)]+=plus_lazy
              
              LAZY[ind<<1]+=plus_lazy
              LAZY[1+(ind<<1)]+=plus_lazy
              
              LAZY[ind]=0
              
      ANS=1<<28
  
      while L!=R:
          if L > R:
              ANS=min(ANS , SEG[L])
              L+=1
              L//=(L & (-L))
  
          else:
              R-=1
              ANS=min(ANS , SEG[R])
              R//=(R & (-R))
  
      return ANS
  
  ind=0
  ANS=1<<28
  for i in range(n):
      while ind<n and getvalues(1,m)==0:
          x,y,z=A[ind]
          adds(x,y,1)
          ind+=1
  
      if getvalues(1,m)!=0:
          ANS=min(ANS,A[ind-1][2]-A[i][2])
  
      x,y,z=A[i]
      adds(x,y,-1)
  
  print(ANS)
  
      
          
  