#include<bits/stdc++.h>

#define REP(i,s,n) for(int i=s;i<n;i++)
#define rep(i,n) REP(i,0,n)
#define EPS (1e-8)
#define equals(a,b) (fabs((a)-(b)) < EPS)
#define COUNTER_CLOCKWISE 1
#define CLOCKWISE -1 
#define ONLINE_BACK 2
#define ONLINE_FRONT -2
#define ON_SEGMENT 0

using namespace std;

class Point{
public:
  double x,y;

  Point(double x = 0,double y = 0): x(x),y(y){}

  Point operator + (Point p){return Point(x+p.x,y+p.y);}
  Point operator - (Point p){return Point(x-p.x,y-p.y);}
  Point operator * (double a){return Point(a*x,a*y);}
  Point operator / (double a){return Point(x/a,y/a);}
  Point operator * (Point a){ return Point(x * a.x - y * a.y, x * a.y + y * a.x); }

  bool operator < (const Point& p) const{ return !equals(x,p.x)?x<p.x:(!equals(y,p.y)&&y<p.y); }

  bool operator == (const Point& p)const{ return fabs(x-p.x) < EPS && fabs(y-p.y) < EPS; }

};

struct Segment{
  Point p1,p2;
  Segment(Point p1 = Point(),Point p2 = Point()):p1(p1),p2(p2){}
  bool operator <  (const Segment& s) const { return ( p2 == s.p2 ) ? p1 < s.p1 : p2 < s.p2; }
  bool operator == (const Segment& s) const { return ( s.p1 == p1 && s.p2 == p2 ) || ( s.p1 == p2 && s.p2 == p1 ); }

};

typedef Point Vector;
typedef Segment Line;
typedef vector<Point> Polygon;

ostream& operator << (ostream& os,const Point& a){ os << "(" << a.x << "," << a.y << ")"; }

ostream& operator << (ostream& os,const Segment& a){ os << "( " << a.p1 << " , " << a.p2 << " )"; }

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

double cross(Point a,Point b){ return a.x*b.y - a.y*b.x; }

double norm(Point a){ return a.x*a.x+a.y*a.y; }

double abs(Point a){ return sqrt(norm(a)); }

//rad ????§???????????????¢?????§?????????????????¨
Point rotate(Point a,double rad){ return Point(cos(rad)*a.x - sin(rad)*a.y,sin(rad)*a.x + cos(rad)*a.y); }

// ??????????????¢????????????
double toRad(double agl){ return agl*M_PI/180.0; }

int ccw(Point p0,Point p1,Point p2){
  Point a = p1-p0;
  Point b = p2-p0;
  if(cross(a,b) > EPS)return COUNTER_CLOCKWISE;
  if(cross(a,b) < -EPS)return CLOCKWISE;
  if(dot(a,b) < -EPS)return ONLINE_BACK;
  if(norm(a) < norm(b))return ONLINE_FRONT;
  return ON_SEGMENT;
}

pair<Point, Point> crosspointCC( Point C1, double r1, Point C2, double r2) {
  complex<double> c1(C1.x,C1.y);
  complex<double> c2(C2.x,C2.y);
  complex<double> A = conj(c2-c1), B = (r2*r2-r1*r1-(c2-c1)*conj(c2-c1)), C = r1*r1*(c2-c1);
  complex<double> D = B*B-4.0*A*C;
  complex<double> z1 = (-B+sqrt(D))/(2.0*A)+c1, z2 = (-B-sqrt(D))/(2.0*A)+c1;
  return pair<Point, Point>(Point(z1.real(),z1.imag()),Point(z2.real(),z2.imag()));
}

bool intersectLL(Line l, Line m) {
  return abs(cross(l.p2-l.p1, m.p2-m.p1)) > EPS || // non-parallel
         abs(cross(l.p2-l.p1, m.p1-l.p1)) < EPS;   // same line
}
bool intersectLS(Line l, Line s) {
  return cross(l.p2-l.p1, s.p1-l.p1)*       // s[0] is left of l
         cross(l.p2-l.p1, s.p2-l.p1) < EPS; // s[1] is right of l
}
bool intersectLP(Line l,Point p) {
  return abs(cross(l.p2-p, l.p1-p)) < EPS;
}
bool intersectSS(Line s, Line t) {
  return ccw(s.p1,s.p2,t.p1)*ccw(s.p1,s.p2,t.p2) <= 0 &&
         ccw(t.p1,t.p2,s.p1)*ccw(t.p1,t.p2,s.p2) <= 0;
}
bool intersectSP(Line s, Point p) {
  return abs(s.p1-p)+abs(s.p2-p)-abs(s.p2-s.p1) < EPS; // triangle inequality
}

Point projection(Line l,Point p) {
  double t = dot(p-l.p1, l.p1-l.p2) / norm(l.p1-l.p2);
  return l.p1 + (l.p1-l.p2)*t;
}
Point reflection(Line l,Point p) {
  return p + (projection(l, p) - p) * 2;
}
double distanceLP(Line l, Point p) {
  return abs(p - projection(l, p));
}
double distanceLL(Line l, Line m) {
  return intersectLL(l, m) ? 0 : distanceLP(l, m.p1);
}

double distanceLS(Line l, Line s) {
  if (intersectLS(l, s)) return 0;
  return min(distanceLP(l, s.p1), distanceLP(l, s.p2));
}
double distanceSP(Line s, Point p) {
  Point r = projection(s, p);
  if (intersectSP(s, r)) return abs(r - p);
  return min(abs(s.p1 - p), abs(s.p2 - p));
}

double distanceSS(Line s, Line t) {
  if (intersectSS(s, t)) return 0;
  return min(min(distanceSP(s, t.p1), distanceSP(s, t.p2)),
             min(distanceSP(t, s.p1), distanceSP(t, s.p2)));
}

Point crosspoint(Line l,Line m){
  double A = cross(l.p2-l.p1,m.p2-m.p1);
  double B = cross(l.p2-l.p1,l.p2-m.p1);
  if(abs(A) < EPS && abs(B) < EPS){
    vector<Point> vec;
    vec.push_back(l.p1),vec.push_back(l.p2),vec.push_back(m.p1),vec.push_back(m.p2);
    sort(vec.begin(),vec.end());
    assert(vec[1] == vec[2]); //???????????°??????????????????
    return vec[1];
    //return m.p1;
  }
  if(abs(A) < EPS)assert(false);
  return m.p1 + (m.p2-m.p1)*(B/A);
}

// <----- Library ----->

bool LT(double a,double b) { return !equals(a,b) && a < b; }
bool LTE(double a,double b) { return equals(a,b) || a < b; }

const int MAX_N = 11;
int n;
double w;
Point ps[MAX_N];
double h[MAX_N];
Segment walls[] = {(Segment){Point(0,0),Point(100,0)},
                         (Segment){Point(100,0),Point(100,100)},
                         (Segment){Point(100,100),Point(0,100)},
                         (Segment){Point(0,100),Point(0,0)}};
Vector walls_v[] = {(Vector){0,1},
                          (Vector){-1,0},
                          (Vector){0,-1},
                          (Vector){1,0}};

pair<Point,Point> crosspointSC(Segment seg,Point cp,double r) {
  Point op = projection(seg,cp);
  double dist = abs(op-cp);
  double x = sqrt(r*r-dist*dist);
  Vector e = ( seg.p1 - seg.p2 ) / abs( seg.p1 - seg.p2 );
  return pair<Point,Point>(op+e*x,op+e*(-x));
}

//index???????????????????????\?????????????????????r????????????????????????????????????????????¨????????°?????¨??\???????????¨????????¢
double calcX(int index,double r){
  if( LTE(r,h[index]) ) {
    return r;
  } else {
    return sqrt( 2.0 * r * h[index] - h[index] * h[index] );
  }
}

double calcX(double r){
  if( LTE(r,w) ) {
    return r;
  } else {
    return sqrt( 2.0 * r * w - w * w );
  }
}

bool isValid(Point p) {
  return LTE(0,p.x) && LTE(p.x,100) && LTE(0,p.y) && LTE(p.y,100);
}
//???p?????\?????????????????????r?????????????????????
#define pow2(x) ((x)*(x))
bool canPut(Point p,double r){
  if( !isValid(p) ) return false;
  rep(i,n){
    double H = h[i];
    if( LT(r,h[i]) ) {
      H = r;
    }
    double dist = sqrt(pow2(ps[i].x-p.x)+pow2(ps[i].y-p.y)+pow2(H-r));
    if( LT(dist,r) ) return false;
  }
  rep(i,4){
    Point op = projection(walls[i],p);
    double H = w;
    if( LT(r,w) ) {
      H = r;
    }
    double dist = sqrt(pow2(op.x-p.x)+pow2(op.y-p.y)+pow2(H-r));
    if( LT(dist,r) ) return false;
  }
  return true;
}

bool check(double r){
  if( canPut(Point(50,50),r) ) return true;
  double x_w = calcX(r);
  rep(i,n) {
    double x_i = calcX(i,r);
    REP(j,i+1,n) {
      double x_j = calcX(j,r);
      if( LT(x_i+x_j,abs(ps[i]-ps[j])) ) continue;
      pair<Point,Point> pp = crosspointCC(ps[i],x_i,ps[j],x_j);
      if( canPut(pp.first,r) ) {
        //cout << "P1 " << pp.first << " " << r << endl;
        return true;
      }
      if( canPut(pp.second,r) ) {
        //cout << "P2 " << pp.second << " " << r << endl;
        return true;
      }
    }
    rep(j,4){
      Point owp = projection(walls[j],ps[i]);
      if( LT(x_w+x_i,abs(owp-ps[i])) ) continue;
      Segment XYZ = Segment(walls[j].p1+walls_v[j]*x_w,walls[j].p2+walls_v[j]*x_w);
      pair<Point,Point> pp = crosspointSC(XYZ,ps[i],x_i);
      if( canPut(pp.first,r) ) {
        //cout << "P3 " << pp.first << " " << r << endl;
        return true;
      }
      if( canPut(pp.second,r) ) {
        //cout << "P4 " << pp.second << " " << r << endl;
        return true;
      }
    }
  }
  return false;
}

void compute(){
  double L = 0, R = 500000;
  rep(_,120){
    double M = ( L + R ) * 0.5;
    if( check(M) ) L = M;
    else           R = M;
  }
  printf("%.10f\n",L);
}

int main(){
  int _w_;
  while( scanf("%d %d",&n,&_w_), n|_w_ ){
    w = _w_;
    rep(i,n) cin >> ps[i].x >> ps[i].y >> h[i];
    compute();
  }
  return 0;
}

Measured memory_bytes: 1324