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;

const double INF = 1e+9;
const double EPS = 1e-6;
const double EPS2 = 1e-6;
const int N = 10;
const double H = 100.0;
const double W = H;

typedef complex<double> P;
typedef pair<P,P> L;

struct P3{
  double x,y,z;
  P3(double x=0, double y=0, double z=0):x(x),y(y),z(z){}
  P3(P p, double z):x(real(p)),y(imag(p)),z(z){}
  P3 operator + (const P3 &a) const{ return P3(x+a.x, y+a.y, z+a.z); }
  P3 operator - (const P3 &a) const{ return P3(x-a.x, y-a.y, z-a.z); }
  P3 operator * (const double &c) const{ return P3(x*c, y*c, z*c); }
};
P3 operator * (double c, const P3 &a){ return P3(c * a.x, c * a.y, c * a.z); }

struct L3{
  P3 a,b;
  L3(P3 a=P3(), P3 b=P3()):a(a),b(b){}
};

struct Stick{
  P p;
  double h;
  Stick(P p=P(), double h=0):p(p),h(h){}
};

struct Circle{
  P c;
  double r;
  Circle(P c=P(), double r=0):c(c),r(r){}
};

double dot(P a, P b){ return real(conj(a)*b); }

P proj(P p, L l){
    return l.first + dot(p - l.first, l.second - l.first) / norm(l.second - l.first) * (l.second - l.first);
}

double abs(P3 a){ return sqrt(a.x*a.x + a.y*a.y + a.z*a.z); }

double dot(P3 a, P3 b){ return a.x*b.x + a.y*b.y + a.z*b.z; }

double distSP(L3 S, P3 p){
  double a = dot(S.b - S.a, S.b - S.a);
  double b = dot(S.b - S.a, S.a - p);
  double c = dot(S.a - p, S.a - p);
  double t = -b / a;

  if(t < -EPS) return abs(S.a - p);
  if(t > 1.0 + EPS) return abs(S.b - p);
  return sqrt(max(0.0, (a * t * t + 2.0 * b * t + c)));
}

bool isIntersectSP(L s, P p){ 
  return abs(s.first-p) + abs(s.second-p) - abs(s.second-s.first) < EPS; 
}

vector<P> getIntersectCS(Circle c, L s){
  vector<P> res;
  P h = proj(c.c, s);
  double d = abs(c.c - h);
  if(d > c.r + EPS);
  else if(d > c.r - EPS){
    if(isIntersectSP(s,h)) res.push_back(h);
  }
  else {
    P v = s.second - s.first;
    v = (sqrt(c.r*c.r - d*d) / abs(v)) * v;
    if(isIntersectSP(s, h+v)) res.push_back(h+v);
    if(isIntersectSP(s, h-v)) res.push_back(h-v);
  }
  return res;
}

vector<P> getIntersectCC(Circle c1, Circle c2){
  vector<P> res;
  double r1 = c1.r, r2 = c2.r, d;
  P p1 = c1.c, p2 = c2.c;
  d = abs(p1-p2);

  if(d < EPS && abs(r1-r2) < EPS) return res; //????????¨?????????????????´???????????????????????????????????????
  if(r1 + r2< d - EPS || d + EPS < abs(r1-r2)) return res; //???????????????

  double a = (r1*r1 - r2*r2 + d*d) / (2*d);
  double h = sqrt(max(r1*r1 - a*a, 0.0));
  P tmp1 = p1 + a / d * (p2-p1);
  P tmp2 = h / d * (p2-p1);

  if(abs(tmp2) < EPS) res.push_back(tmp1);
  else {
    res.push_back(P(real(tmp1) - imag(tmp2), imag(tmp1) + real(tmp2)));
    res.push_back(P(real(tmp1) + imag(tmp2), imag(tmp1) - real(tmp2)));
  }
  return res;
}

double getIntersectStC(Stick s, Circle c){
  return distSP(L3(P3(s.p, 0), P3(s.p, s.h)), P3(c.c, c.r));
}

bool isIntersectStC(Stick s, Circle c){
  return distSP(L3(P3(s.p, 0), P3(s.p, s.h)), P3(c.c, c.r)) < c.r - EPS;
}

double getIntersectR(Stick s, double cr){
  double le = 0, ri = INF, mid;
  
  while(fabs(ri - le) > EPS2){
    mid = (le + ri) / 2.0;
    if(isIntersectStC(s, Circle(P(real(s.p)+mid, imag(s.p)), cr))) le = mid;
    else ri = mid;
  }

  return ri;
}


int n;
double w;
vector<Stick> v;

bool check(P p){
  double x = real(p);
  double y = imag(p);
  if(x < -EPS || x > W + EPS) return false;
  if(y < -EPS || y > H + EPS) return false;
  return true;
}

bool is_hit(double cr){
  vector<L> vl;
  vector<Circle> vc;
  vector<P> resv;

  for(int i=0;i<n;i++){
    vc.push_back(Circle(P(v[i].p), getIntersectR(v[i], cr)));
  }

  double rr = getIntersectR(Stick(P(0,0), w), cr);
  vl.push_back(L(P(0, rr), P(W, rr)));
  vl.push_back(L(P(W-rr, 0), P(W-rr, H)));
  vl.push_back(L(P(W, H-rr), P(0, H-rr)));
  vl.push_back(L(P(rr, H), P(rr, 0)));

  for(int i=0;i<n;i++){
    for(int j=i+1;j<n;j++){
      vector<P> res = getIntersectCC(vc[i], vc[j]);
      for(int k=0;k<res.size();k++){
        if(check(res[k])) resv.push_back(res[k]);
      }
      if(res.size() == 2){
        if(check((res[0]+res[1])/2.0)){
          resv.push_back((res[0]+res[1])/2.0);
        }
      }
    }
    for(int j=0;j<4;j++){
      vector<P> res = getIntersectCS(vc[i], vl[j]);
      for(int k=0;k<res.size();k++){
        if(check(res[k])) resv.push_back(res[k]);
      }
      if(res.size() == 2){
        if(check(res[0]+res[1])/2.0){
          resv.push_back((res[0]+res[1])/2.0);
        }
      }
    }
  }

  if(rr < H + EPS) {
    resv.push_back(P(rr, rr));
  }

  for(int i=0;i<resv.size();i++){
    bool f = true;
    Circle c = Circle(resv[i], cr);
    for(int j=0;j<n;j++){
      if(isIntersectStC(v[j], c)){
        f = false;
        break;
      }
    }
    if(f && 
       !isIntersectStC(Stick(P(0, imag(c.c)), w), c) &&
       !isIntersectStC(Stick(P(real(c.c), 0), w), c) &&
       !isIntersectStC(Stick(P(W, imag(c.c)), w), c) &&
       !isIntersectStC(Stick(P(real(c.c), H), w), c)){
      /*
      cout << c.c << " : " << endl;
      for(int j=0;j<n;j++) {
        cout << cr << ": " << v[j].p << ' ' << getIntersectStC(v[j], c) << endl;
      }
      cout << P(0, imag(c.c)) << ' ' << getIntersectStC(Stick(P(0, imag(c.c)), w), c) << endl;
      cout << P(W, imag(c.c)) << ' ' << getIntersectStC(Stick(P(W, imag(c.c)), w), c) << endl;
      cout << P(real(c.c), 0) << ' ' << getIntersectStC(Stick(P(real(c.c), 0), w), c) << endl;
      cout << P(real(c.c), H) << ' ' << getIntersectStC(Stick(P(real(c.c), H), w), c) << endl;
      */
      return false;
    }
  }
  
  return true;
}

double solve(){
  double le = 0, ri = INF, mid;
  
  while(fabs(ri - le) > EPS2){
    mid = (le + ri) / 2.0;
    if(is_hit(mid)) ri = mid;
    else le = mid;
  }
  return (le + ri) / 2.0;
}

int main(){
  double x, y, h;
  while(cin >> n >> w && n){
    v.clear();
    for(int i=0;i<n;i++){
      cin >> x >> y >> h;
      v.push_back(Stick(P(x, y), h));
    }
    printf("%.5f\n", solve());
  }
}