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;
typedef long long ll;
typedef pair<int,int> Pii;
typedef pair<ll,ll> Pll;
typedef complex<double> Point;
#define rep(i,n) for (ll i=0;i<n;++i)
#define rep2(i,a,b) for (ll i=a;i<b;++i)
#define X real()
#define Y imag()
#define LE(n,m) (n<m+EPS)
#define GE(n,m) (n+EPS>m)
#define EQ(n,m) (abs(n-m)<EPS)
const ll MOD=1000000007;
const ll INF=1e9;
const ll IINF=1e18;
const double EPS=1e-9;
struct Line{Point a,b;};
struct Circle{Point center;double r;};

double dot(Point a,Point b){
    return (conj(a)*b).X;
}

double cross(Point a,Point b){
    return (conj(a)*b).Y;
}

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

vector<Point> crosspointLC(Line l,Circle c){
    vector<Point> ps;
    Point p=proj(l,c.center);
    if (!GE(c.r*c.r,norm(p-c.center))){
        return ps;
    }
    Point dir=sqrt(max(0.0,c.r*c.r-norm(p-c.center)))/abs(l.b-l.a)*(l.b-l.a);
    ps.push_back(p+dir);
    if (!EQ(c.r*c.r,norm(p-c.center))){
        ps.push_back(p-dir);
    }
    return ps;
}

vector<Point> crosspointCC(Circle c1,Circle c2){
    vector<Point> ps;
    Point d=c2.center-c1.center;
    double len=abs(d);
    double crL=(norm(d)+c1.r*c1.r-c2.r*c2.r)/(2*len);
    if (EQ(len,0.0)||c1.r<abs(crL)){
        return ps;
    }
    Point dir=d*Point(0,sqrt(c1.r*c1.r-crL*crL)/len);
    Point cp=c1.center+crL/len*d;
    ps.push_back(cp+dir);
    if (!EQ(norm(dir),0.0)){
        ps.push_back(cp-dir);
    }
    return ps;
}

int n,w;
double wall;
vector<int> x(11),y(11),h(11);
vector<Circle> cs(11);
vector<Point> cors(4);
vector<Line> ls(4);
bool uncovered(Point p){
    if (p.X<wall||100.0-wall<p.X||p.Y<wall||100.0-wall<p.Y){
        return false;
    }
    rep(i,n){
        if (!GE(abs(p-cs[i].center),cs[i].r)){
            return false;
        }
    }
    return true;
}

int main(){
    while(cin >> n >> w,n){
        rep(i,n){
            cin >> x[i] >> y[i] >> h[i];
        }
        double lb=0.0,ub=1000.0;
        while(ub-lb>1e-4){
            double mid=(ub+lb)/2.0;
            rep(i,n){
                double r=mid;
                if (h[i]<mid){
                    r=sqrt(2*mid*h[i]-h[i]*h[i]);
                }
                cs[i]=Circle{Point(x[i],y[i]),r};
            }
            wall=mid;
            if (w<mid){
                wall=sqrt(2*mid*w-w*w);
            }
            if (wall>50.0){
                ub=mid;
                continue;
            }
            cors[0]=Point(wall,wall);
            cors[1]=Point(100.0-wall,wall);
            cors[2]=Point(100.0-wall,100.0-wall);
            cors[3]=Point(wall,100.0-wall);
            rep(i,4){
                ls[i]=Line{cors[i],cors[(i+1)%4]};
            }
            vector<Point> check;
            rep(i,n){
                rep2(j,i+1,n){
                    for (Point p:crosspointCC(cs[i],cs[j])){
                        check.push_back(p);
                    }
                }
                rep(j,4){
                    for (Point p:crosspointLC(ls[j],cs[i])){
                        check.push_back(p);
                    }
                }
            }

            for (auto p:cors){
                check.push_back(p);
            }
            bool can=false;
            for (Point p:check){
                if (uncovered(p)){
                    can=true;
                }
            }
            if (can){
                lb=mid;
            }
            else {
                ub=mid;
            }
        }
        cout << fixed << setprecision(10);
        cout << lb << endl;
    }
}