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< (n);i++)
using namespace std;
typedef long long ll;
typedef pair<double,double> P;
const double EPS = 1e-8;

//補助用演算関数を作っとく.
double dist(P x,P y){
    double x1=x.first,x2=x.second,y1=y.first,y2=y.second;
    double tmp=(x1-y1)*(x1-y1)+(x2-y2)*(x2-y2);
    return sqrt(tmp);
}
double grp(double x,double y){
    //斜辺と一辺が与えられたときにもう一個の辺の長さを返す関数。
    //初めから作っておくべきであった.
    //xを斜辺とする.
    double ans = x*x-y*y;
    if(ans<0){
        cout<<"error!"<<endl;
        cout<<x<<' '<<y<<endl;
        //円同士の交点の演算の時にerrorが出ていた.おそらくすっぽり入ってるときか？
        //やはり円の交点のところを直したらerrorが出なかったので元凶は円.
        //円と壁のバグなしたのにまだ駄目だ。。。
    }
    return sqrt(ans);
}

int main(){
    while(true){
        int n,w;cin>>n>>w;
        if(n==0 && w==0)break;
        vector<pair<P,double>> lst(n);
        rep(i,n){
            double x,y,h;cin>>x>>y>>h;
            lst[i] = make_pair(make_pair(x,y),h);
        }
        //まずは交点を全て求める.
        //これらは全てt_midを与えられて計算する.
        //つまりjudge内で書く必要がある.
        auto judge=[&](double t_mid){
            vector<P> cross_lst;
            double w_now;
            if(w < t_mid)w_now=grp(t_mid,(t_mid-w));
            else w_now=t_mid;
            //円同士の交点を求める
            for(int i=0;i<n-1;i++){
                for(int j=i+1;j<n;j++){
                    //円の全ての組み合わせを試す.
                    pair<P,double> r1 = lst[i];
                    pair<P,double> r2 = lst[j];
                    //半径は修正.
                    double r1_now;
                    if(r1.second < t_mid)r1_now=grp(t_mid,(t_mid-r1.second));
                    else r1_now=t_mid;
                    double r2_now;
                    if(r2.second < t_mid)r2_now=grp(t_mid,(t_mid-r2.second));
                    else r2_now=t_mid;
                    //交点を持たない場合はここでcontinue↓
                    double dis = dist(r1.first,r2.first);
                    //判定します.
                    if(abs(r1_now-r2_now) > dis || (r1_now+r2_now) < dis)continue;
                    double a = (dis*dis+r1_now*r1_now-r2_now*r2_now)/2;
                    double b = dis*dis*r1_now*r1_now-a*a;
                    double x1 = r2.first.first,x0 = r1.first.first,y1=r2.first.second,y0=r1.first.second;
                    P tg1 = make_pair(((a*(x1-x0)+(y1-y0)*sqrt(b))/(dis*dis)+x0),((a*(y1-y0)-(x1-x0)*sqrt(b))/(dis*dis)+y0));
                    P tg2 = make_pair(((a*(x1-x0)-(y1-y0)*sqrt(b))/(dis*dis)+x0),((a*(y1-y0)+(x1-x0)*sqrt(b))/(dis*dis)+y0));
                    cross_lst.push_back(tg1);
                    cross_lst.push_back(tg2);
                    //done
                }
            }
            
            //次、壁と円の交点を求める.
            rep(i,n){
                pair<P,double> r=lst[i];
                //下の壁との交点
                double r_now;
                if(r.second < t_mid)r_now=grp(t_mid,(t_mid-r.second));
                else r_now=t_mid;
                double distwithwall = abs(r.first.second-w_now);
                if(distwithwall<=r_now){
                P tg1 = make_pair((r.first.first+grp(r_now,distwithwall)),w_now);
                P tg2 = make_pair((r.first.first-grp(r_now,distwithwall)),w_now);
                cross_lst.push_back(tg1);
                cross_lst.push_back(tg2);
                }
                //上の壁との交点
                distwithwall = abs(r.first.second-(100-w_now));
                if(distwithwall<=r_now){
                P tg1 = make_pair((r.first.first+grp(r_now,distwithwall)),100-w_now);
                P tg2 = make_pair((r.first.first-grp(r_now,distwithwall)),100-w_now);
                cross_lst.push_back(tg1);
                cross_lst.push_back(tg2);
                }
                //左の壁との交点
                distwithwall = abs(r.first.first-w_now);
                if(distwithwall<=r_now){
                P tg1 = make_pair(w_now,(r.first.second+grp(r_now,distwithwall)));
                P tg2 = make_pair(w_now,(r.first.second-grp(r_now,distwithwall)));
                cross_lst.push_back(tg1);
                cross_lst.push_back(tg2);
                }
                //右の壁との交点
                distwithwall = abs(r.first.first-(100-w_now));
                if(distwithwall<=r_now){
                P tg1 = make_pair(100-w_now,(r.first.second+grp(r_now,distwithwall)));
                P tg2 = make_pair(100-w_now,(r.first.second-grp(r_now,distwithwall)));
                cross_lst.push_back(tg1);
                cross_lst.push_back(tg2);
                }
            }
            //最後に、壁同士の交点を入れておく.
            cross_lst.push_back(make_pair(w_now,w_now));
            cross_lst.push_back(make_pair(100-w_now,w_now));
            cross_lst.push_back(make_pair(w_now,100-w_now));
            cross_lst.push_back(make_pair(100-w_now,100-w_now));

            //次に、交点が存在できるかチェック!!
            int cnt = 0;//ダメだった交点数.これが全部ならout.
            for(P target : cross_lst){
                //壁の内側に入っているかcheck!
                if(w_now>target.first+EPS || target.first>(100-w_now)+EPS || w_now>target.second+EPS || target.second+EPS>(100-w_now)){
                    cnt++;
                    continue;
                }
                //円の内部に入らないかチェック!
                rep(i,n){
                    pair<P,double> r = lst[i];
                    double r_now;
                    if(r.second < t_mid)r_now=grp(t_mid,(t_mid-r.second));
                    else r_now=t_mid;
                    if(dist(r.first,target)+EPS<r_now){
                        cnt++;
                        break;
                    }
                }
            }
            if(cnt == cross_lst.size())return false;
            return true;
        };
        //judgeが描き終わったので二分探索をする.
        double t_min = 0;//ok
        double t_max = (1e+9)+5;//絶対out
        const double D = 1e-6;
        while(t_min+D<t_max){
            double t_mid=(t_min+t_max)/2;
            if(judge(t_mid)){
                t_min = t_mid;
            }else{
                t_max = t_mid;
            }
        }
        cout<<fixed<<setprecision(6)<<t_min<<endl;
    }
    return 0;
}