#include <stdio.h> 
#include <stdio.h> 
#include <math.h>
#include <string.h>
#include <algorithm>
using namespace std;
#define eps 1e-6
struct Pt {
    double x, y;
    Pt(double a = 0, double b = 0):
    	x(a), y(b) {}
    bool operator<(const Pt &a) const {
        if(fabs(x-a.x) > eps)
            return x < a.x;
        return y < a.y;
    }
	Pt operator-(const Pt &a) const {
		Pt ret;
		ret.x = x - a.x;
		ret.y = y - a.y;
        return ret;
    }
};
enum LINE_TYPE {LINE, SEGMENT};
struct LINE2D {
    Pt s, e;
    LINE_TYPE type;
};
double dist(Pt a, Pt b) {
	return hypot(a.x - b.x, a.y - b.y);
}
double dot(Pt a, Pt b) {
	return a.x * b.x + a.y * b.y;
}
double cross2(Pt a, Pt b) {
	return a.x * b.y - a.y * b.x;
}
double cross(Pt o, Pt a, Pt b) {
    return (a.x-o.x)*(b.y-o.y)-(a.y-o.y)*(b.x-o.x);
}
int between(Pt a, Pt b, Pt c) {
	return dot(c - a, b - a) >= 0 && dot(c - b, a - b) >= 0;
}
double onSeg(Pt a, Pt b, Pt c) {
	return between(a, b, c) && fabs(cross(a, b, c)) < eps;
}
int intersection(Pt as, Pt at, Pt bs, Pt bt) {
    if(cross(as, at, bs) * cross(as, at, bt) < 0 &&
       cross(at, as, bs) * cross(at, as, bt) < 0 &&
       cross(bs, bt, as) * cross(bs, bt, at) < 0 &&
       cross(bt, bs, as) * cross(bt, bs, at) < 0)
        return 1;
    return 0;
}
double distProjection(Pt as, Pt at, Pt s) {
	int a, b, c;
	a = at.y - as.y;
	b = as.x - at.x;
	c = - (a * as.x + b * as.y);
	return fabs(a * s.x + b * s.y + c) / hypot(a, b);
}
double closest(LINE2D l1, LINE2D l2) {
	if(l1.type == SEGMENT && l2.type == SEGMENT) {
		if(intersection(l1.s, l1.e, l2.s, l2.e))
			return 0;
		double c = 1e+30;
		if(between(l1.s, l1.e, l2.s))
			c = min(c, distProjection(l1.s, l1.e, l2.s));
		else
			c = min(c, min(dist(l1.s, l2.s), dist(l1.e, l2.s)));
			
		if(between(l1.s, l1.e, l2.e))
			c = min(c, distProjection(l1.s, l1.e, l2.e));
		else
			c = min(c, min(dist(l1.s, l2.e), dist(l1.e, l2.e)));
		
		if(between(l2.s, l2.e, l1.s))
			c = min(c, distProjection(l2.s, l2.e, l1.s));
		else
			c = min(c, min(dist(l1.s, l2.s), dist(l1.e, l2.s)));
			
		if(between(l2.s, l2.e, l1.e))
			c = min(c, distProjection(l2.s, l2.e, l1.e));
		else
			c = min(c, min(dist(l2.s, l1.e), dist(l2.e, l1.e)));
		return c;
	}
	if(l1.type == LINE && l2.type == LINE) {
		double a1, a2, b1, b2, c1, c2;
		a1 = l1.s.y - l1.e.y;
		b1 = l1.e.x - l1.s.x;
		c1 = - (a1 * l1.s.x + b1 * l1.s.y);
		a2 = l2.s.y - l2.e.y;
		b2 = l2.e.x - l2.s.x;
		c2 = - (a2 * l2.s.x + b2 * l2.s.y);
		if(a1 * b2 - a2 * b1 != 0)
			return 0;
		return distProjection(l1.s, l1.e, l2.s);
	}
	if(l1.type != l2.type) {
		if(l1.type == SEGMENT)
			swap(l1, l2);
		
		double a1, b1, c1;
		a1 = l1.s.y - l1.e.y;
		b1 = l1.e.x - l1.s.x;
		c1 = - (a1 * l1.s.x + b1 * l1.s.y);
		int v1, v2;
		v1 = a1 * l2.s.x + b1 * l2.s.y + c1;
		v2 = a1 * l2.e.x + b1 * l2.e.y + c1;
		if(v1 * v2 <= 0)
			return 0; 
		return min(distProjection(l1.s, l1.e, l2.s), distProjection(l1.s, l1.e, l2.e));
	}
	return -1;
}
int main() {
	int n;
	double L, H;
	LINE2D D[1024];
	while(scanf("%d", &n) == 1) {
		scanf("%lf %lf", &L, &H);
		for(int i = 0; i < n; i++) {
			D[i].s.x = i&1 ? L : 0;
			scanf("%lf %lf %lf", &D[i].s.y, &D[i].e.x, &D[i].e.y);
			D[i].type = SEGMENT;
		}
		
		LINE2D wall1, wall2;
		wall1.type = wall2.type = LINE;
		wall1.s.x = wall1.e.x = 0;
		wall1.s.y = 1, wall1.e.y = 0;
		
		wall2.s.x = wall2.e.x = L;
		wall2.s.y = 1, wall2.e.y = 0;
		
		double r = L;
		for(int i = 0; i < n; i++) {
			if(i&1)
				r = min(r, closest(wall1, D[i]));
			else
				r = min(r, closest(wall2, D[i]));
			if(i + 1 < n) {
				r = min(r, closest(D[i], D[i+1]));
			}
		}
		printf("%.2lf\n", r);
	}
	return 0;
}