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 <bits/stdc++.h>
using namespace std;

using Float = double;
using Point = complex<Float>;
struct Line{ Point a,b; };
struct Circle{ Point center; Float r; };

const Float INF = 200;
const Float EPS = 1e-8;
const Float width = 100;

inline bool eq(Float a,Float b) { return abs(a - b) < EPS; }
inline Float dot(const Point &p1,const Point &p2){ return real(conj(p1) * p2); }

Point projection(const Line &l,const Point &p){
	Float t = dot(l.b - l.a,p - l.a) / norm(l.b - l.a);
	return l.a + (l.b - l.a) * t;
}

vector<Point> crosspoint(const Circle &c,const Line &l){
	vector<Point> ret;
	Point p = projection(l,c.center),vect = (l.b - l.a) / abs(l.b - l.a);
	if(abs(p - c.center) > c.r) return ret;
	Float d = sqrt(c.r * c.r - norm(p - c.center));
	ret.push_back(p + vect * d);
	if(!eq(abs(p - c.center),c.r)) ret.push_back(p - vect * d);
	return ret;
}

vector<Point> crosspoint(const Circle &c1,const Circle &c2){
	vector<Point> ret;
	Point d = c2.center - c1.center;
	Float rcosa = (c1.r * c1.r + norm(d) - c2.r * c2.r) / (abs(d) * 2);
	if(eq(0,abs(d)) || abs(rcosa) > c1.r) return ret;
	Float rsina = sqrt(c1.r * c1.r - rcosa * rcosa);
	ret.push_back(c1.center + d / abs(d) * Point(rcosa,rsina));
	if(!eq(rcosa,c1.r)) ret.push_back(c1.center + d / abs(d) * Point(rcosa,-rsina));
	return ret;
}

int n;
Float w,x[15],y[15],h[15];

bool bisearch(Float r){
	Float margin = (w > r ? r : sqrt(r * r - (r - w) * (r - w)));
	Circle cs[10];
	for(int i = 0;i < n;i++){
		Float cr = (h[i] > r ? r : sqrt(r * r - (r - h[i]) * (r - h[i])));
		cs[i] = {Point(x[i],y[i]),cr};
	}
	vector<Point> corner = {
		Point(margin,margin),
		Point(margin,width - margin),
		Point(width - margin,width - margin),
		Point(width - margin,margin)
	};
	Line ls[4];
	for(int i = 0;i < 4;i++) ls[i] = {corner[i],corner[(i + 1) % 4]};
	vector<Point> candidate = corner;
	for(int i = 0;i < n;i++){
		for(int j = 0;j < 4;j++){
			vector<Point> inters = crosspoint(cs[i],ls[j]);
			for(const auto &p : inters) candidate.push_back(p);
		}
		for(int j = i + 1;j < n;j++){
			vector<Point> inters = crosspoint(cs[i],cs[j]);
			for(const auto &p : inters) candidate.push_back(p);
		}
	}
	for(const auto &p : candidate){
		if(!(margin - EPS <= imag(p) && imag(p) <= width - margin + EPS
		&& margin - EPS <= real(p) && real(p) <= width - margin + EPS)) continue;
		bool isOK = true;
		for(int i = 0;i < n;i++){
			if(abs(p - cs[i].center) <= cs[i].r - EPS) isOK = false;
		}
		if(isOK) return true;
	}
	return false;
}

signed main(){
	while(cin >> n >> w,n){
		for(int i = 0;i < n;i++) cin >> x[i] >> y[i] >> h[i];
		Float ng = INF,ok = 0;
		for(int i = 0;i < 100;i++){
			Float mid = (ng + ok) / 2;
			if(bisearch(mid)) ok = mid;
			else ng = mid;
		}
		printf("%.9lf\n",ok);
	}
}