#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <climits>
#include <cfloat>
#include <cstring>
#include <map>
#include <utility>
#include <set>
#include <iostream>
#include <memory>
#include <string>
#include <vector>
#include <list>
#include <algorithm>
#include <functional>
#include <sstream>
#include <complex>
#include <stack>
#include <queue>
#include <unordered_set>
#include <unordered_map>
#include <array>
#include <cassert>
#include <bitset>
using namespace std;
using LL = long long;

//P????????°(????????????)x,y???????????????(c=?????°)
//x+y,x-y???????????????
//x*c,x/c???????????????
//?????????abs(x)????????¢???abs(x-y)
//?????????????????????x/abs(x)
//?????????????????????x*P(0,?±1)(+??????-)
//x?????¨???????§????arg(v)???u??¨v??????????§????arg(u/v)
//u??¨v???2?????¨??????????§???¢?????¢??????cross(u,v)*0.5

//complex???????§????
//real?????¨???imag?????¨???abs??¶?????????arg????§????norm??¶???????????????
//conj??±??????proj?????????????????¢???????°???±(?)???polar(r,t)?\???¢??????????????????
using FLOAT = double;
const FLOAT EPS = 1e-8;
const FLOAT INF = 1e12;
typedef complex<FLOAT> P;//????????????
namespace std {
	bool operator < (const P& a, const P& b) {
		return real(a) != real(b) ? real(a) < real(b) : imag(a) < imag(b);
	}
}
//FLOAT????£?????????????
inline bool EQ(FLOAT a, FLOAT b) { return abs(a - b) < EPS; }
//P????£?????????????
inline bool EQV(P a, P b) { return EQ(a.real(), b.real()) && EQ(a.imag(), b.imag()); }
//??????(a.x*b.y-a.y*b.x)
double cross(const P& a, const P& b) {
	return imag(conj(a)*b);
}
//??????(a.x*b.x+a.y*b.y)
double dot(const P& a, const P& b) {
	return real(conj(a)*b);
}
//????????????(?????????[0],[1])
struct L : public vector<P> {
	L(const P &a, const P &b) {
		push_back(a); push_back(b);
	}
};
typedef vector<P> G;//????§???¢?????????
					//????????????
struct C {
	P p; FLOAT r;
	C(const P &p, FLOAT r) : p(p), r(r) { }
};
//?¬???¢??°(?????????????????§??????)
//?????????EPS???????????????????????¨????????????(FLOAT?????´?????????????????????????????????)
int ccw(P a, P b, P c) {
	b -= a; c -= a;
	if (cross(b, c) > 0)   return +1;       // counter clockwise
	if (cross(b, c) < 0)   return -1;       // clockwise
	if (dot(b, c) < 0)     return +2;       // c--a--b on line
	if (norm(b) < norm(c)) return -2;       // a--b--c on line
	return 0;
}

//??´?????????????????????
//??´????????´??????????????????
bool intersectLL(const L &l, const L &m) {
	return abs(cross(l[1] - l[0], m[1] - m[0])) > EPS || // non-parallel
		abs(cross(l[1] - l[0], m[0] - l[0])) < EPS;   // same line
}
//??´???????????????????????????
bool intersectLS(const L &l, const L &s) {
	return cross(l[1] - l[0], s[0] - l[0])*       // s[0] is left of l
		cross(l[1] - l[0], s[1] - l[0]) < EPS; // s[1] is right of l
}
//??´????????????????????????
bool intersectLP(const L &l, const P &p) {
	return abs(cross(l[1] - p, l[0] - p)) < EPS;
}
//??????????????????????????????
bool intersectSS(const L &s, const L &t) {
	return ccw(s[0], s[1], t[0])*ccw(s[0], s[1], t[1]) <= 0 &&
		ccw(t[0], t[1], s[0])*ccw(t[0], t[1], s[1]) <= 0;
}
//???????????????????????????
bool intersectSP(const L &s, const P &p) {
	return abs(s[0] - p) + abs(s[1] - p) - abs(s[1] - s[0]) < EPS; // triangle inequality
}

//?????¢????????????
//???????????????????°???±(??????????????????????¶?)
P projection(const L &l, const P &p) {
	FLOAT t = dot(p - l[0], l[0] - l[1]) / norm(l[0] - l[1]);
	return l[0] + t*(l[0] - l[1]);
}
//????????¨????§°??????
P reflection(const L &l, const P &p) {
	return p + (projection(l, p) - p) * 2.;
}
//?????¨??´???????????¢
FLOAT distanceLP(const L &l, const P &p) {
	return abs(p - projection(l, p));
}
//??´?????¨??´???????????¢???????????§????????¨??????0???
FLOAT distanceLL(const L &l, const L &m) {
	return intersectLL(l, m) ? 0 : distanceLP(l, m[0]);
}
//??´?????¨??????????????¢(???????????¨??????0)
FLOAT distanceLS(const L &l, const L &s) {
	if (intersectLS(l, s)) return 0;
	return min(distanceLP(l, s[0]), distanceLP(l, s[1]));
}
//????????¨???????????¢
FLOAT distanceSP(const L &s, const P &p) {
	const P r = projection(s, p);
	if (intersectSP(s, r)) return abs(r - p);
	return min(abs(s[0] - p), abs(s[1] - p));
}
//????????¨??????????????¢(???????????¨??????0)
FLOAT distanceSS(const L &s, const L &t) {
	if (intersectSS(s, t)) return 0;
	return min(min(distanceSP(s, t[0]), distanceSP(s, t[1])),
		min(distanceSP(t, s[0]), distanceSP(t, s[1])));
}
//
P crosspoint(const L &l, const L &m) {
	FLOAT A = cross(l[1] - l[0], m[1] - m[0]);
	FLOAT B = cross(l[1] - l[0], l[1] - m[0]);
	if (abs(A) < EPS && abs(B) < EPS) return m[0]; // same line
	if (abs(A) < EPS) assert(false); // !!!PRECONDITION NOT SATISFIED!!!
	return m[0] + B / A * (m[1] - m[0]);
}

//????§???¢???
//??????????§???¢????????¨/?¢????/?????¨????????????????????????????????????(O(n))
//???????§???¢?????´???????????????????????¢??°?????????
enum { OUT, ON, IN };
int contains(const G& poly, const P& point) {
	bool in = false;
	for (int i = 0; i < poly.size(); ++i) {
		P a = poly[i] - point, b = poly[(i + 1) % poly.size()] - point;
		if (imag(a) > imag(b)) swap(a, b);
		if (imag(a) <= 0 && 0 < imag(b))
			if (cross(a, b) < 0) in = !in;
		if (cross(a, b) == 0 && dot(a, b) <= 0) return ON;
	}
	return in ? IN : OUT;
}
//????§???¢?????¢???
FLOAT areaOfG(const G& poly) {
	FLOAT A = 0;
	for (int i = 0; i < poly.size(); ++i)
		A += cross(poly[i], poly[(i + 1) % poly.size()]);
	return A / 2;
}

//???????§???¢???
//??????????§????????????????????????°?????????????????£??????????¨???§?±???????
G convexHull(G ps) {
	int n = ps.size(), k = 0;
	assert(n >= 3);//??????????¶??????????
	sort(ps.begin(), ps.end());
	G ch(2 * n);
	for (int i = 0; i < n; ch[k++] = ps[i++]) // lower-hull
		while (k >= 2 && ccw(ch[k - 2], ch[k - 1], ps[i]) <= 0) --k;
	for (int i = n - 2, t = k + 1; i >= 0; ch[k++] = ps[i--]) // upper-hull
		while (k >= t && ccw(ch[k - 2], ch[k - 1], ps[i]) <= 0) --k;
	ch.resize(k - 1);
	return ch;
}
//???????????????????§???¢?????????????????????
bool isConvex(const G& poly) {
	for (int i = 0; i < poly.size(); ++i)
		if (ccw(poly[(i + poly.size() - 1) % poly.size()], poly[i], poly[(i + 1) % poly.size()]))
			return false;
	return true;
}
//???????§???¢?????´???????????£??????????????§?±???????(O(n log n))
FLOAT convexDiameter(const G& poly) {
	const int n = poly.size();
	int is = 0, js = 0;
	for (int i = 1; i < n; ++i) {
		if (imag(poly[i]) > imag(poly[is]))is = i;
		if (imag(poly[i]) < imag(poly[js]))js = i;
	}
	FLOAT maxd = norm(poly[is] - poly[js]);
	int i = is, maxi = is;
	int j = js, maxj = js;
	auto diff = [](const G&pol, int i) {
		return pol[(i + 1) % pol.size()] - pol[i];
	};
	do {
		if (cross(diff(poly, i), diff(poly, j)) >= 0)j = (j + 1) % n;
		else i = (i + 1) % n;
		if (norm(poly[i] - poly[j]) > maxd) {
			maxd = norm(poly[i] - poly[j]);
			maxi = i; maxj = j;
		}
	} while (i != is || j != js);
	return maxd;
}
//???????§???¢????????????????????´??????????????????????????????????????¢?´¢??§?±???????(O(log n))
//?????¬??????????§???¢???????????????????????´?????????????????????????????§?????¨????????¨??????
P convexExtreme(const G&poly, const L&l) {
	const int n = poly.size();
	int a = 0, b = n;
	auto d = [&](int k) {
		return dot(poly[k], l[1] - l[0]);
	};
	if (d(0) >= d(n - 1) && d(0) >= d(1))return poly[0];
	while (a < b) {
		int c = (a + b) / 2;
		if (d(c) >= d(c - 1) && d(c) >= d(c + 1))return poly[c];
		if (d(a + 1) > d(a)) {
			if (d(c + 1) <= d(c) || d(a) > d(c))b = c;
			else a = c;
		}
		else {
			if (d(c + 1) > d(c) || d(a) >= d(c))a = c;
			else b = c;
		}
	}
	assert(false);
}
//?????????????§???¢????????¨/?¢????/?????¨????????????????????????????????¢?´¢?????¨??????????????????(O(log n))
//enum { OUT, ON, IN };
int convexContains(const G&poly, const P&p) {
	const int n = poly.size();
	P g = (poly[0] + poly[n / 3] + poly[2 * n / 3]) / 3.;//?????????????????????????????¨???
	int a = 0, b = n;
	while (a + 1 < b) {
		int c = (a + b) / 2;
		if (cross(poly[a] - g, poly[c] - g) > 0) {
			if (cross(poly[a] - g, p - g) > 0 && cross(poly[c] - g, p - g) < 0)b = c;
			else a = c;
		}
		else {
			if (cross(poly[a] - g, p - g) < 0 && cross(poly[c] - g, p - g) > 0)a = c;
			else b = c;
		}
	}
	b %= n;
	if (cross(poly[a] - p, poly[b] - p) < 0)return OUT;
	if (cross(poly[a] - p, poly[b] - p) > 0)return IN;
	return ON;
}

//????????????
//???(a,b)??¨??´???(y=a*x-b)??????????????§???????????????
//?¨??????????????????£????§£?????????????????????????????????
//????°???§????????¢?????????(p??¨l????????¢??¨l*??¨p*????????¢????????????)???
//???????????????(p???l??????/???/???????????????l*???p*??????/???/????????????)???????????????
L dual(const P&p) {
	return L(P(0, -imag(p)), P(1, real(p) - imag(p)));
}
P dual(const L&l) {
	const P&p = l[0], &q = l[1];
	return P(imag(p - q) / real(p - q), cross(p, q) / real(q - p));
}



//?????????(??¢????????????)
//?????¨??´??????2??????(?????????????????¨??¨???????????????)
L crosspointLC(const L& l, const C&c) {
	P v = l[1] - l[0];
	P u = l[0] - c.p;
	FLOAT A = norm(v);
	FLOAT B = 2 * dot(u, v);
	FLOAT C = norm(u) - c.r * c.r;
	assert(B*B - 4 * A*C >= 0);
	FLOAT S = -B / (A * 2);
	FLOAT T = sqrt(B*B - 4 * A*C) / (A * 2);
	return L(l[0] + v*(S + T), l[0] + v*(S - T));
}

//????§???¢?????¢????????????
FLOAT areaOfTriangle(P p1, P p2, P p3) {
	return abs(cross(p1, p2) + cross(p2, p3) + cross(p3, p1)) / 2.;
}

//?????¨???????????????????????¨??????????§???¢?????±?????¢???
FLOAT areaCT(C c, P p1, P p2) {
	//if (abs(p1 - p2) < EPS)return 0.;
	if (distanceSP(L(p1, p2), c.p) >= c.r - EPS) {
		return c.r * c.r * abs(arg((p1 - c.p) / (p2 - c.p))) / 2.;
	}
	FLOAT d1 = abs(p1 - c.p);
	FLOAT d2 = abs(p2 - c.p);
	if (d1 > d2) {
		swap(d1, d2); swap(p1, p2);
	}
	if (d2 <= c.r + EPS) {
		return areaOfTriangle(c.p, p1, p2);
	}
	auto pp = crosspointLC(L(p1, p2), c);
	if (d1 <= c.r) {
		P cr = pp[0];
		if (!intersectSP(L(p1, p2), cr)) {
			cr = pp[1];
		}
		return areaCT(c, p1, cr) + areaCT(c, cr, p2);
	}
	if (!intersectSP(L(p1, pp[1]), pp[0])) {
		swap(pp[0], pp[1]);
	}
	return areaCT(c, p1, pp[0]) + areaCT(c, pp[0], pp[1]) + areaCT(c, pp[1], p2);
}

//?????¨????§???¢?????±?????¢???
FLOAT areaCG(C c, G g) {
	FLOAT res = 0.;
	for (int i = 0; i < g.size(); ++i) {
		P p1 = g[i], p2 = g[(i + 1) % g.size()];
		FLOAT a = areaCT(c, p1, p2);
		if (cross(p1 - c.p, p2 - c.p) <= 0)a = -a;
		res += a;
	}
	return abs(res);
}

int N, R;
vector<G>rect;
FLOAT PI = acos(-1);
//??????????????§????????????
bool cond(FLOAT x) {
	FLOAT area = 0.;
	C c(P(0, x), R);
	for (auto&r : rect) {
		area += areaCG(c, r);
	}
	area /= (PI * R*R);
	return area > 0.5;
}

int main() {
	cin >> N >> R;
	for (int i = 0; i < N; ++i) {
		int x, w, h;
		cin >> x >> w >> h;
		G g = { P(x,0),P(x + w,0),P(x + w,h),P(x,h) };
		rect.push_back(g);
	}
	G ground = { P(R * 2,0),P(-R * 2,0),P(-R * 2,-R * 4),P(R * 2,-R * 4) };
	rect.push_back(ground);
	FLOAT lo = 0, hi = R * N * 2;
	for (int loop = 0; loop < 100; ++loop) {
		FLOAT mid = (lo + hi) / 2;
		if (cond(mid)) {
			lo = mid;
		}
		else {
			hi = mid;
		}
	}
	cout.precision(15);
	cout << lo << endl;
	return 0;
}

Measured memory_bytes: 3608