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>
#define REP(i,n) for(int i=0; i<(int)(n); ++i)

using namespace std;

typedef complex<double> Point;
typedef vector<Point> Pol;
struct Circle{Point p;double r;};
const double EPS = 1e-8;
const double LEN = 100;
int sign(double x) {
    if(x > EPS) return 1;
    if(x < -EPS) return -1;
    return 0;
}

double calc(double h, double x) {
    if(x >= h) {
        double rad = sqrt(2 * x * h - h * h);
        return rad;
    } else {
        return x;
    }
}

enum{
    OUT,
    ON,
    IN
};

int contains(Circle c, Point p){
    double d = abs(c.p - p);
    if(sign(d - c.r) > 0) return OUT;
    if(sign(d - c.r) == 0) return ON;
    return IN;
}

vector<Point> pCC(Circle a, Circle b) {
    vector<Point> res;
 
    double d = abs(b.p - a.p);
    double l1 = abs(a.r - b.r);
    double l2 = a.r + b.r; 
 
    if(sign(d) == 0 && sign(l1) == 0) assert(false); // 円が等しい
    if(sign(d - l1) < 0 || sign(d - l2) > 0) return res; // 交わらない
 
    double th1 = arg(b.p - a.p);
 
    if(sign(d - l1) == 0 || sign(d - l2) == 0) { // 一点で交わる
        res.push_back(a.p + polar(a.r, th1));
    } else { // 二点で交わる
        double th2 = acos( (a.r * a.r - b.r * b.r + d * d) / (2 * a.r * d) );
        res.push_back(a.p + polar(a.r, th1 - th2));
        res.push_back(a.p + polar(a.r, th1 + th2));
    }
 
    return res;
}
typedef vector<Point> L;
Point vec(L l){return l[1] - l[0];}
double dot(Point a, Point b){return real(conj(a) * b);}
double cross(Point a, Point b){return imag(conj(a) * b);}
Point proj(L l, Point p){
    double t = dot(p - l[0], vec(l)) / norm(vec(l));
    return l[0] + t * vec(l);
}
vector<Point> pCL(Circle c, L l) {
    vector<Point> res;
    Point center = proj(l, c.p);
    double d = abs(center - c.p);
    double tt = c.r * c.r - d * d;
    if(tt < 0 && tt > -EPS) tt = 0;
    if(tt < 0) return res;
    double t = sqrt(tt);
    Point vect = vec(l);
    vect /= abs(vect);
    res.push_back(center - vect * t);
    if (t > EPS) {
        res.push_back(center + vect * t);
    }
    return res;
}

int main(){
    int n, w;
    while(cin >> n >> w && n > 0) {
        vector<Point> vp(n);
        vector<double> h(n);
        REP(i, n) {
            double x, y;
            cin >> x >> y;
            vp[i] = Point(x, y);
            cin >> h[i];
        }

        double l = 0, r = 100000;
        REP(_, 80) {
            double x = (l + r) / 2;
            double width = calc(w, x);
            if(2.0 * width >= LEN){
                r = x;
                continue;
            }
            
            Pol box;
            box.push_back({0 + width, 0 + width});
            box.push_back({LEN - width, 0 + width});
            box.push_back({LEN - width, LEN - width});
            box.push_back({0 + width, LEN - width});

            vector<Point> cand;
            for(Point p : box) {
                cand.push_back(p);
            }

            vector<Circle> cs(n);
            REP(i, n) {
                cs[i] = {vp[i], calc(h[i], x)};
            }

            // for(Point p : box) {
            //      cout << p << endl;
            // }
            // REP(i, n) {
            //     cout << cs[i].p << " " << cs[i].r << endl;
            // }

            for(int i = 0; i < n; i++) {
                for(int j = i + 1; j < n; j++) {
                    for(Point p : pCC(cs[i], cs[j])) {
                        cand.push_back(p);
                    }
                }

                for(int j = 0; j < 4; j++) {
                    L ll = {box[j], box[(j+1) % 4]};
                    for(Point p : pCL(cs[i], ll)) {
                        cand.push_back(p);
                    }
                }
            }

            bool exist = false;

            for(Point p : cand) {
                if(sign(p.real() - width) < 0) continue;
                if(sign(p.imag() - width) < 0) continue;
                if(sign(p.real() - (LEN - width)) > 0) continue;
                if(sign(p.imag() - (LEN - width)) > 0) continue;
                bool ok = true;
                REP(i, n) {
                    // cout << "x: " << x << endl;
                    // cout << "r: " << cs[i].r << endl;
                    // cout << "d: " << abs(cs[i].p - p) << endl;
                    if(contains(cs[i], p) == IN) {
                        ok = false;
                        break;
                    }
                }
                if(ok) {
                    exist = true;
                    break;
                }
            }

            if(exist) {
                l = x;
            } else {
                r = x;
            }
        }

        printf("%.12f\n", l);
    }
    return 0;
}