#include <cstdio>
#include <vector>
#include <iostream>
#include <set>
#include <algorithm>

using namespace std;

#define MAXN 100005

int inf = 2000000000;

struct segment {
    int h, l, r;
	segment(){}
	segment(int h, int l, int r) : h(h), l(l), r(r) {}
	bool operator < (const segment &s) const {
		return h < s.h;
	}
};

struct part {
	int l, r, f;
	segment s;
	part(int l, int r, int f, segment s) : l(l), r(r), f(f), s(s) {}
	bool operator < (const part &p) const {
		return l < p.l;
	}
};

set<part> sweep;
segment s[MAXN];

int main()
{	
	int n, t; scanf("%d %d", &n, &t);
	for(int i = 0; i < n; i++) {
		int h, l, r; scanf("%d %d %d", &h, &l, &r);
		s[i] = segment(h, l, r);
	}
	s[n] = segment(t, -inf, inf);
	sort(s, s+n);
	
	part bottom(-inf, inf, inf, segment(0, -inf, inf));
	part left(-inf-1, -inf, 0, segment(0, -inf-1, -inf));
	part right(inf, inf+1, 0, segment(0, inf, inf+1));
	sweep.insert(bottom);
	sweep.insert(left);
	sweep.insert(right);
	for(int i = 0; i <= n; i++) {
		int h = s[i].h, l = s[i].l, r = s[i].r;
		
		part p(l, r, 0, s[i]);
		set<part>::iterator it = sweep.upper_bound(p), jt, kt;
		it--;
		jt = it;
		set<part>::iterator lt = jt, rt = jt;
		lt--;
		rt++;
		while(jt->l < r) {
			if(!(lt->s.r > max(jt->s.l, l) && jt->s.h < lt->s.h && lt->s.h < h) &&
				!(rt->s.l < min(jt->s.r, r) && jt->s.h < rt->s.h && rt->s.h < h)) {
				p.f = max(p.f, min(jt->f, min(jt->s.r, r)-max(jt->s.l, l)));
			}
			lt++;
			jt++;
			rt++;
		}
		
		kt = jt; kt--;
		part start = *it, end = *kt;
		
		sweep.erase(it, jt);
		if(start.l<l) {
			sweep.insert(part(start.l, l, start.f, start.s));
		}
		if(end.r>r) {
			sweep.insert(part(r, end.r, end.f, end.s));
		}
		sweep.insert(p);
	}
	
	set<part>::iterator it = sweep.begin();
	it++;
	printf("%d\n", it->f);
}
