Problem: An open-top box having a square bottom is placed on the floor. You see a number of needles vertically planted on its bottom.

You want to place a largest possible spheric balloon touching the box bottom, interfering with none of the side walls nor the needles.

Java Specific: Submitted Java programs may not use "java.awt.geom.Area". You may use it for your debugging purposes.

Figure H.1 shows an example of a box with needles and the corresponding largest spheric balloon. It corresponds to the first dataset of the sample input below.

<image>
Figure H.1. The upper shows an example layout and the lower shows the largest spheric balloon that can be placed.



Input

The input is a sequence of datasets. Each dataset is formatted as follows.


n w
x1 y1 h1
:
xn yn hn


The first line of a dataset contains two positive integers, n and w, separated by a space. n represents the number of needles, and w represents the height of the side walls.

The bottom of the box is a 100 × 100 square. The corners of the bottom face are placed at positions (0, 0, 0), (0, 100, 0), (100, 100, 0), and (100, 0, 0).

Each of the n lines following the first line contains three integers, xi, yi, and hi. (xi, yi, 0) and hi represent the base position and the height of the i-th needle. No two needles stand at the same position.

You can assume that 1 ≤ n ≤ 10, 10 ≤ w ≤ 200, 0 < xi < 100, 0 < yi < 100 and 1 ≤ hi ≤ 200. You can ignore the thicknesses of the needles and the walls.

The end of the input is indicated by a line of two zeros. The number of datasets does not exceed 1000.

Output

For each dataset, output a single line containing the maximum radius of a balloon that can touch the bottom of the box without interfering with the side walls or the needles. The output should not contain an error greater than 0.0001.

Example

Input

5 16
70 66 40
38 52 20
40 35 10
70 30 10
20 60 10
1 100
54 75 200
1 10
90 10 1
1 11
54 75 200
3 10
53 60 1
61 38 1
45 48 1
4 10
20 20 10
20 80 10
80 20 10
80 80 10
0 0


Output

26.00000
39.00000
130.00000
49.49777
85.00000
95.00000

Solution (in CPP):

Solution:
#include<iostream>
#include<string>
#include<cstdio>
#include<vector>
#include<cmath>
#include<algorithm>
#include<functional>
#include<iomanip>
#include<queue>
#include<ciso646>
#include<random>
#include<map>
#include<set>
#include<bitset>
#include<stack>
#include<unordered_map>
#include<utility>
#include<cassert>
#include<complex>
using namespace std;

//#define int long long
typedef long long ll;

typedef unsigned long long ul;
typedef unsigned int ui;
const ll mod = 1000000007;
const ll INF = (1e+18) + 7;
typedef pair<int, int>P;
#define stop char nyaa;cin>>nyaa;
#define rep(i,n) for(int i=0;i<n;i++)
#define per(i,n) for(int i=n-1;i>=0;i--)
#define Rep(i,sta,n) for(int i=sta;i<n;i++)
#define rep1(i,n) for(int i=1;i<=n;i++)
#define per1(i,n) for(int i=n;i>=1;i--)
#define Rep1(i,sta,n) for(int i=sta;i<=n;i++)
#define all(v) (v).begin(),(v).end()
typedef pair<ll, ll> LP;
typedef long double ld;
typedef pair<ld, ld> LDP;
const ld eps = 1e-6;
const ld pi = acos(-1.0);
//typedef vector<vector<ll>> mat;
typedef vector<int> vec;

ll mod_pow(ll a, ll n) {
	ll res = 1;
	while (n) {
		if (n & 1)res = res * a%mod;
		a = a * a%mod; n >>= 1;
	}
	return res;
}

struct modint {
	ll n;
	modint() :n(0) { ; }
	modint(ll m) :n(m) {
		if (n >= mod)n %= mod;
		else if (n < 0)n = (n%mod + mod) % mod;
	}
	operator int() { return n; }
};
bool operator==(modint a, modint b) { return a.n == b.n; }
modint operator+=(modint &a, modint b) { a.n += b.n; if (a.n >= mod)a.n -= mod; return a; }
modint operator-=(modint &a, modint b) { a.n -= b.n; if (a.n < 0)a.n += mod; return a; }
modint operator*=(modint &a, modint b) { a.n = ((ll)a.n*b.n) % mod; return a; }
modint operator+(modint a, modint b) { return a += b; }
modint operator-(modint a, modint b) { return a -= b; }
modint operator*(modint a, modint b) { return a *= b; }
modint operator^(modint a, int n) {
	if (n == 0)return modint(1);
	modint res = (a*a) ^ (n / 2);
	if (n % 2)res = res * a;
	return res;
}

//ll inv(ll a, ll p) {
//	return (a == 1 ? 1 : (1 - p * inv(p%a, a)) / a + p);
//}
//modint operator/(modint a, modint b) { return a * modint(inv(b, mod)); }

int dx[4] = { 1,0,-1,0 };
int dy[4] = { 0,1,0,-1 };

using Point = complex<ld>;
ld dot(Point a, Point b) { return real(conj(a)*b); }
ld cross(Point a, Point b) { return imag(conj(a)*b); }
struct Line {
	Point a, b;
};
struct Circle {
	Point p; ld r;
};

Point proj(Line l, Point p) {
	ld t = dot(p - l.a, l.a - l.b) / norm(l.a - l.b);
	return l.a + t * (l.a - l.b);
}
ld dist_lp(Line l, Point p) {
	return abs(p - proj(l, p));
}

vector<Point> is_lc(Circle c, Line l) {
	vector<Point> res;
	ld d = dist_lp(l, c.p);
	if (d > c.r + eps)return res;
	ld len = (d > c.r) ? 0.0 : sqrt(c.r*c.r - d * d);
	Point nor = (l.a - l.b) / abs(l.a - l.b);
	res.push_back(proj(l, c.p) + len * nor);
	res.push_back(proj(l, c.p) - len * nor);
	return res;
}
vector<Point> is_cc(Circle c1, Circle c2) {
	vector<Point> res;
	ld d = abs(c1.p - c2.p);
	ld rc = (d*d + c1.r*c1.r - c2.r*c2.r) / (2 * d);
	ld dfr = c1.r*c1.r - rc * rc;
	if (abs(dfr) < eps)dfr = 0.0;
	if (dfr < 0.0)return res;
	ld rs = sqrt(dfr);
	Point diff = (c2.p - c1.p) / d;
	res.push_back(c1.p + diff * Point(rc, rs));
	if (dfr != 0.0)res.push_back(c1.p + diff * Point(rc, -rs));
	return res;
}

bool is_in(Circle c, Point p) {
	ld dist = abs(c.p - p);
	return dist < c.r;
}

int n;ld w;
int x[10], y[10], h[10];
Circle c[10];

bool can(ld r) {
	ld le;
	if (r < w)le = r;
	else {
		le = sqrt(pow(r, 2) - pow(r - w, 2));
	}
	if (le >= 50)return false;
	rep(i, n) {
		c[i].p = { (ld)x[i],(ld)y[i] };
		if (r < h[i])c[i].r = r;
		else c[i].r = sqrt(pow(r, 2) - pow(r - h[i], 2));
	}

	ld ri = 100 - le;
	Point p[4] = { {le,le},{le,ri},{ri,le},{ri,ri} };
	Line l[4] = { {p[0],p[1]},{p[0],p[2]},{p[3],p[1]},{p[3],p[2]} };
	rep(i, 4) {
		bool f = true;
		rep(j, n) {
			if (is_in(c[j], p[i])) {
				f = false; break;
			}
		}
		if (f)return true;
	}
	rep(i, 4) {
		rep(j, n) {
			vector<Point> v = is_lc(c[j], l[i]);
			rep(k, v.size()) {
				
				if (real(v[k]) < le || real(v[k])>ri)continue;
				if (imag(v[k]) < le || imag(v[k]) > ri)continue;
				bool f = true;
				rep(l, n) {
					if (l == j)continue;
					if (is_in(c[l], v[k])) {
						f = false; break;
					}
				}
				if (f)return true;
			}
		}
	}
	rep(i, n)Rep(j,i+1, n) {
		vector<Point> v = is_cc(c[i], c[j]);
		rep(k, v.size()) {
			if (real(v[k]) < le || real(v[k])>ri)continue;
			if (imag(v[k]) < le || imag(v[k]) > ri)continue;
			bool f = true;
			rep(l, n) {
				if (l == i || l == j)continue;
				if (is_in(c[l], v[k])) {
					f = false; break;
				}
			}
			if (f)return true;
		}
	}
	return false;
}
void solve() {
	cin >> w;
	rep(i, n) {
		cin >> x[i] >> y[i] >> h[i];
	}
	ld le = 0, ri = (w*w+2500)/(2*w);
	rep (aa,100) {
		ld mid = (le + ri) / 2;
		if (can(mid))le = mid;
		else ri = mid;
	}
	cout << le << endl;
}

signed main() {
	ios::sync_with_stdio(false);
	cin.tie(0);
	cout << fixed << setprecision(5);
	//init();
	//int t; cin >> t; rep(i, t)solve();
	while (cin >> n, n)solve();
	//solve();
	stop
		return 0;
}