#include <bits/stdc++.h>
using namespace std;

const int MAXN = 100 + 10;

typedef double flt;
const flt eps = 1e-8, PI = M_PI, S = 100.0;

inline flt sqr(flt x) {return x * x;}

struct Point {
    flt x, y;
    Point() {}
    Point(flt a, flt b) : x(a), y(b) {}
    Point operator + (const Point &rhs) const {
        return Point(x + rhs.x, y + rhs.y);
    }
    Point operator - (const Point &rhs) const {
        return Point(x - rhs.x, y - rhs.y);
    }
    Point operator * (const flt k) const {
        return Point(x * k, y * k);
    }
    flt abs() {
        return hypot(x, y);
    }
    flt sqr() {
        return x * x + y * y;
    }
};

Point operator ~(const Point &rhs) {
    return Point(-rhs.y, rhs.x);
}

Point C[MAXN];
flt H[MAXN], R[MAXN], D;
int N, W;

bool ok(Point o) {
    if (o.x < D || o.x > S - D || o.y < D || o.y > S - D) return false;
    for (int i = 0; i < N; ++ i) {
        if ((o - C[i]).abs() + eps < R[i]) return false;
    }
    return true;
}

bool check_line(Point o, flt r, flt a, flt b, flt c) {
    flt dis = a * o.x + b * o.y + c;
    if (fabs(dis) >= r) return false;
    flt u = sqrt(r * r - dis * dis);
    Point v = Point(o.x - a * dis, o.y - b * dis);
    return ok(Point(v.x + b * u, v.y - a * u)) ||
           ok(Point(v.x - b * u, v.y + a * u));
}

bool check() {
    if (ok(Point(D, D)) || ok(Point(D, S - D)) || ok(Point(S - D, D)) || ok(Point(S - D, S - D))) return true;
    for (int i = 0; i < N; ++ i) {
        if (check_line(C[i], R[i], 1, 0, -D)) return true;
        if (check_line(C[i], R[i], 0, 1, -D)) return true;
        if (check_line(C[i], R[i], 1, 0, D - S)) return true;
        if (check_line(C[i], R[i], 0, 1, D - S)) return true;
    }
    for (int i = 0; i < N; ++ i) {
        for (int j = i + 1; j < N; ++ j) {
            flt dis = (C[i] - C[j]).sqr();
            if (dis > sqr(R[i] + R[j]) || dis < sqr(R[i] - R[j])) continue;
            flt w = (1 + (R[i] * R[i] - R[j] * R[j]) / dis) * 0.5;
            flt e = R[i] * R[i] / dis - w * w;
            Point t = (~(C[j] - C[i])) * sqrt(e);
            Point s = C[i] + ((C[j] - C[i]) * w);
            if (ok(s + t) || ok(s - t)) return true;
        }
    }
    return false;
}

int main() {
    while (scanf("%d%d", &N, &W) == 2 && (N || W)) {
        for (int i = 0; i < N; ++ i) scanf("%lf%lf%lf", &C[i].x, &C[i].y, &H[i]);
        flt left = 0, right = 200;
        for (int _ = 0; _ < 50; ++ _) {
            double mid = (left + right) * 0.5;
            D = W > mid ? mid : sqrt(2 * W * mid - W * W);
            for (int i = 0; i < N; ++ i) {
                R[i] = H[i] > mid ? mid : sqrt(2 * H[i] * mid - H[i] * H[i]);
            }
            if (check()) left = mid;
            else right = mid;
        }
        printf("%.10f\n", left);
    }
}
### Prompt

In Cpp, your task is to solve the following 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

### Response

```cpp
#include <bits/stdc++.h>
using namespace std;

const int MAXN = 100 + 10;

typedef double flt;
const flt eps = 1e-8, PI = M_PI, S = 100.0;

inline flt sqr(flt x) {return x * x;}

struct Point {
    flt x, y;
    Point() {}
    Point(flt a, flt b) : x(a), y(b) {}
    Point operator + (const Point &rhs) const {
        return Point(x + rhs.x, y + rhs.y);
    }
    Point operator - (const Point &rhs) const {
        return Point(x - rhs.x, y - rhs.y);
    }
    Point operator * (const flt k) const {
        return Point(x * k, y * k);
    }
    flt abs() {
        return hypot(x, y);
    }
    flt sqr() {
        return x * x + y * y;
    }
};

Point operator ~(const Point &rhs) {
    return Point(-rhs.y, rhs.x);
}

Point C[MAXN];
flt H[MAXN], R[MAXN], D;
int N, W;

bool ok(Point o) {
    if (o.x < D || o.x > S - D || o.y < D || o.y > S - D) return false;
    for (int i = 0; i < N; ++ i) {
        if ((o - C[i]).abs() + eps < R[i]) return false;
    }
    return true;
}

bool check_line(Point o, flt r, flt a, flt b, flt c) {
    flt dis = a * o.x + b * o.y + c;
    if (fabs(dis) >= r) return false;
    flt u = sqrt(r * r - dis * dis);
    Point v = Point(o.x - a * dis, o.y - b * dis);
    return ok(Point(v.x + b * u, v.y - a * u)) ||
           ok(Point(v.x - b * u, v.y + a * u));
}

bool check() {
    if (ok(Point(D, D)) || ok(Point(D, S - D)) || ok(Point(S - D, D)) || ok(Point(S - D, S - D))) return true;
    for (int i = 0; i < N; ++ i) {
        if (check_line(C[i], R[i], 1, 0, -D)) return true;
        if (check_line(C[i], R[i], 0, 1, -D)) return true;
        if (check_line(C[i], R[i], 1, 0, D - S)) return true;
        if (check_line(C[i], R[i], 0, 1, D - S)) return true;
    }
    for (int i = 0; i < N; ++ i) {
        for (int j = i + 1; j < N; ++ j) {
            flt dis = (C[i] - C[j]).sqr();
            if (dis > sqr(R[i] + R[j]) || dis < sqr(R[i] - R[j])) continue;
            flt w = (1 + (R[i] * R[i] - R[j] * R[j]) / dis) * 0.5;
            flt e = R[i] * R[i] / dis - w * w;
            Point t = (~(C[j] - C[i])) * sqrt(e);
            Point s = C[i] + ((C[j] - C[i]) * w);
            if (ok(s + t) || ok(s - t)) return true;
        }
    }
    return false;
}

int main() {
    while (scanf("%d%d", &N, &W) == 2 && (N || W)) {
        for (int i = 0; i < N; ++ i) scanf("%lf%lf%lf", &C[i].x, &C[i].y, &H[i]);
        flt left = 0, right = 200;
        for (int _ = 0; _ < 50; ++ _) {
            double mid = (left + right) * 0.5;
            D = W > mid ? mid : sqrt(2 * W * mid - W * W);
            for (int i = 0; i < N; ++ i) {
                R[i] = H[i] > mid ? mid : sqrt(2 * H[i] * mid - H[i] * H[i]);
            }
            if (check()) left = mid;
            else right = mid;
        }
        printf("%.10f\n", left);
    }
}
```