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 <vector>
#include <complex>
#include <cstdio>
#include <utility>
using namespace std;
typedef complex<double>P;
typedef pair<P,P> L;
typedef pair<P,double> C;
const double EPS = (1e-10);
#define X real()
#define Y imag()

double dot(P a, P b){ return a.X*b.X+a.Y*b.Y;}
double cross(P a, P b){ return a.X*b.Y - a.Y*b.X;}
P projection(P a, P b){ return dot(a,b)/norm(b)*b;}
double p_to_l_dist(P a, L s){
  return abs(cross(s.first-s.second,a-s.second))/abs(s.first-s.second);
}
vector<P> cpcl(C c, L l){
  double d = p_to_l_dist(c.first, l), r = c.second;
  P m = l.first + projection(c.first-l.first,l.second-l.first);
  P x = sqrt(r*r-d*d)/abs(l.second-l.first)*(l.second-l.first);
  vector<P> ret(2,m);
  ret[0] -= x;
  ret[1] += x;
  return ret;
}

L cpcc(C a, C b){
  double d = abs(a.first-b.first), ra = a.second, rb = b.second;
  double t = (ra*ra-rb*rb+d*d)/2/d, h = sqrt(ra*ra-t*t);
  P m = t/abs(b.first-a.first)*(b.first-a.first)+a.first;
  P n = (a.first-b.first)*P(0,1);
  n /= abs(n);
  return make_pair(m-n*h, m+n*h);
}

int main(){
  int n;
  double w;
  while(cin >> n >> w, n){
    vector<P> V;
    vector<double> H;
    for(int i = 0; i < n; ++i){
      double x, y, h;
      cin >> x >> y >> h;
      V.emplace_back(x,y);
      H.emplace_back(h);
    }
    double ok = 0, ng = 1000;
    for(int _ = 0; _ < 100; ++_){
      double r = (ok + ng)/2;
      vector<C> Cs;
      for(int i = 0; i < n; ++i){
        Cs.emplace_back(V[i], sqrt(r*r - max(0.0, r-H[i])*max(0.0, r-H[i])));
      }
      vector<P> cps;
      vector<P> R;
      cps.emplace_back(sqrt(r*r - max(0.0, r-w)*max(0.0, r-w)), sqrt(r*r - max(0.0, r-w)*max(0.0, r-w)));
      R.push_back(cps.back());
      cps.emplace_back(100 - sqrt(r*r - max(0.0, r-w)*max(0.0, r-w)), sqrt(r*r - max(0.0, r-w)*max(0.0, r-w)));
      R.push_back(cps.back());
      cps.emplace_back(sqrt(r*r - max(0.0, r-w)*max(0.0, r-w)), 100 - sqrt(r*r - max(0.0, r-w)*max(0.0, r-w)));
      R.push_back(cps.back());
      cps.emplace_back(100 - sqrt(r*r - max(0.0, r-w)*max(0.0, r-w)), 100 - sqrt(r*r - max(0.0, r-w)*max(0.0, r-w)));
      R.push_back(cps.back());

      for(int i = 0; i < n; ++i){
        for(int j = 0; j < 4; ++j){
          vector<P> cp = cpcl(Cs[i], L(R[j], R[(j+1)%4]));
          for(int k = 0; k < (int)cp.size(); ++k) cps.push_back(cp[k]);
        }

        for(int j = 0; j < i; ++j){
          L cp = cpcc(Cs[i], Cs[j]);
          if(abs(Cs[i].first-Cs[j].first) > Cs[i].second+Cs[j].second ||
             abs(Cs[i].first-Cs[j].first) < abs(Cs[i].second-Cs[j].second)) continue;
          
          cps.push_back(cp.first);
          cps.push_back(cp.second);
        }
      }

      int m = cps.size();
      if(!m){
        ok = r;
        continue;
      }
      for(int i = 0; i < m; ++i){
        P p = cps[i];
        if(sqrt(r*r - max(0.0, r-w)*max(0.0, r-w)) > p.real() ||
           100 - sqrt(r*r - max(0.0, r-w)*max(0.0, r-w)) < p.real() ||
           sqrt(r*r - max(0.0, r-w)*max(0.0, r-w)) > p.imag() ||
           100 - sqrt(r*r - max(0.0, r-w)*max(0.0, r-w)) < p.imag()){
          continue;
        }
        bool f = true;
        for(int j = 0; j < n; ++j) f &= max(0.0, r-H[j])*max(0.0, r-H[j])+norm(V[j]-p)-r*r > -EPS;
        if(f){
          ok = r;
          break;
        }
      }
      if(abs(ok - r) > EPS) ng = r;
    }
    printf("%.12f\n", ok);
  }
  return 0;
}