Problem:
Anchored Balloon
A balloon placed on the ground is connected to one or more anchors on the ground with ropes.
Each rope is long enough to connect the balloon and the anchor.
No two ropes cross each other.
Figure E-1 shows such a situation.
Figure E-1: A balloon and ropes on the ground
Now the balloon takes off, and your task is to find how high 
the balloon can go up with keeping the rope connections.
The positions of the anchors are fixed.
The lengths of the ropes and the positions of the anchors are given.
You may assume that these ropes have no weight and
thus can be straightened up when pulled to
whichever directions.
Figure E-2 shows the highest position of the balloon for
the situation shown in Figure E-1.
Figure E-2: The highest position of the balloon
Input
The input consists of multiple datasets, each in the following format.
n
x
1
y
1
l
1
...
x
n
y
n
l
n
The first line of a dataset contains an integer
n
(1 ≤
n
≤ 10) representing the number of the ropes.
Each of the following
n
lines contains three integers,
x
i
,
y
i
, and
l
i
, separated by a single space.
P
i
= 
(
x
i
,
y
i
) represents
the position of the anchor connecting the
i
-th rope,
and
l
i
represents the length of the rope.
You can assume that 
−100 ≤
x
i
≤ 100, 
−100 ≤
y
i
≤ 100, and
1 ≤
l
i
≤ 300.
The balloon is initially placed at (0, 0) on the ground.
You can ignore the size of the balloon and the anchors.
You can assume that
P
i
and
P
j
represent different positions if
i
≠
j
.
You can also assume that the distance between
P
i
and (0, 0) is less than or equal to
l
i
−1.
This means that the balloon can go up at least 1 unit high.
Figures E-1 and E-2 correspond to the first dataset of Sample Input below.
The end of the input is indicated by a line containing a zero.
Output
For each dataset, 
output a single line containing the maximum height that the balloon can go up.
The error of the value should be no greater than 0.00001. 
No extra characters should appear in the output.
Sample Input
3
10 10 20
10 -10 20
-10 10 120
1
10 10 16
2
10 10 20
10 -10 20
2
100 0 101
-90 0 91
2
0 0 53
30 40 102
3
10 10 20
10 -10 20
-10 -10 20
3
1 5 13
5 -3 13
-3 -3 13
3
98 97 168
-82 -80 193
-99 -96 211
4
90 -100 160
-80 -80 150
90 80 150
80 80 245
4
85 -90 290
-80 -80 220
-85 90 145
85 90 170
5
0 0 4
3 0 5
-3 0 5
0 3 5
0 -3 5
10
95 -93 260
-86 96 211
91 90 177
-81 -80 124
-91 91 144
97 94 165
-90 -86 194
89 85 167
-93 -80 222
92 -84 218
0
Output for the Sample Input
17.3205081
16.0000000
17.3205081
13.8011200
53.0000000
14.1421356
12.0000000
128.3928757
94.1879092
131.1240816
4.0000000
72.2251798

Submitted solutions:

code_snippet: #include <bits/stdc++.h>

using namespace std;
using ll = long long;

typedef complex<double> Point;
const double EPS = 1e-8;

struct Circle {
    Point p;
    double r;
};

// 円の交点を求めるメソッド
pair<Point, Point> cc_cross(const Circle& c1, const Circle& c2) {
    double d   = abs(c1.p - c2.p);
    double rc  = (d * d + c1.r * c1.r - c2.r * c2.r) / (2 * d);
    double h2  = c1.r * c1.r - rc * rc;
    double rs  = sqrt(max(0.0, h2));
    Point diff = (c2.p - c1.p) / d;
    return make_pair(c1.p + diff * Point(rc, rs), c1.p + diff * Point(rc, -rs));
}

bool ok(double z, vector<Point>& points, vector<double>& len) {
    int n = (int) points.size();
    vector<Circle> C(n);

    // 高さをもとに円を作成
    for (int i = 0; i < n; i++) {
        if (z > len[i]) {
            return false; // ロープより高いならfalse
        }

        double rr = sqrt(max(0.0, len[i] * len[i] - z * z));
        C[i]      = Circle(points[i], rr);
    }

    // 交点があるかの判定
    for (int i = 0; i < n; i++) {
        bool ok = true;
        for (int j = 0; j < n; j++) {
            if (i == j) {
                continue;
            }

            double d2 = norm(C[i].p - C[j].p);
            if (d2 > C[j].r * C[j].r + EPS) {
                ok = false;
            }
        }
        if (ok) {
            return true;
        }
    }

    // 交点と、その他の円が重なっているかの判定
    for (int i = 0; i < n; i++) {
        for (int j = i + 1; j < n; j++) {
            auto [p1, p2] = cc_cross(C[i], C[j]);
            for (Point cp : {p1, p2}) {
                bool all = true;
                for (int k = 0; k < n; k++) {
                    if (norm(cp - C[k].p) > C[k].r * C[k].r + EPS) {
                        all = false;
                        break;
                    }
                }
                if (all) {
                    return true;
                }
            }
        }
    }

    return false;
}

int main() {
    while (true) {
        int n;
        cin >> n;
        if (n == 0) {
            break;
        }

        vector<Point> points(n);
        vector<double> len(n);
        for (int i = 0; i < n; i++) {
            double x, y, l;
            cin >> x >> y >> l;
            points[i] = Point(x, y);
            len[i]    = l;
        }

        double left = 0, right = 300;
        while (right - left > EPS) {
            double mid = (right + left) / 2;
            if (ok(mid, points, len)) {
                left = mid;
            } else {
                right = mid;
            }
        }
        printf("%.7f\n", left);
    }
}
accuracy: 1
time_ms: 10
memory_kb: 3840
final_rank: 10

code_snippet: #include <bits/stdc++.h>

using namespace std;
using ll = long long;

typedef complex<double> Point;
const double EPS = 1e-8;

struct Circle {
    Point p;
    double r;
};

// 円の交点を求めるメソッド
pair<Point, Point> cc_cross(const Circle& c1, const Circle& c2) {
    double d   = abs(c1.p - c2.p);
    double rc  = (d * d + c1.r * c1.r - c2.r * c2.r) / (2 * d);
    double h2  = c1.r * c1.r - rc * rc;
    double rs  = sqrt(max(0.0, h2));
    Point diff = (c2.p - c1.p) / d;
    return make_pair(c1.p + diff * Point(rc, rs), c1.p + diff * Point(rc, -rs));
}

bool ok(double z, vector<Point>& points, vector<double>& len) {
    int n = (int) points.size();
    vector<Circle> C(n);

    // 高さをもとに円を作成
    for (int i = 0; i < n; i++) {
        if (z > len[i]) {
            return false; // ロープより高いならfalse
        }

        double rr = sqrt(max(0.0, len[i] * len[i] - z * z));
        C[i]      = Circle(points[i], rr);
    }

    // 交点があるかの判定
    for (int i = 0; i < n; i++) {
        bool ok = true;
        for (int j = 0; j < n; j++) {
            if (i == j) {
                continue;
            }

            double d2 = norm(C[i].p - C[j].p);
            if (d2 > C[j].r * C[j].r + EPS) {
                ok = false;
            }
        }
        if (ok) {
            return true;
        }
    }

    // 交点と、その他の円が重なっているかの判定
    for (int i = 0; i < n; i++) {
        for (int j = i + 1; j < n; j++) {
            auto [p1, p2] = cc_cross(C[i], C[j]);
            for (Point cp : {p1, p2}) {
                bool all = true;
                for (int k = 0; k < n; k++) {
                    if (norm(cp - C[k].p) > C[k].r * C[k].r + EPS) {
                        all = false;
                        break;
                    }
                }
                if (all) {
                    return true;
                }
            }
        }
    }

    return false;
}

int main() {
    while (true) {
        int n;
        cin >> n;
        if (n == 0) {
            break;
        }

        vector<Point> points(n);
        vector<double> len(n);
        for (int i = 0; i < n; i++) {
            double x, y, l;
            cin >> x >> y >> l;
            points[i] = Point(x, y);
            len[i]    = l;
        }

        double left = 0, right = 300;
        while (right - left > EPS) {
            double mid = (right + left) / 2;
            if (ok(mid, points, len)) {
                left = mid;
            } else {
                right = mid;
            }
        }
        printf("%.10f\n", left);
    }
}
accuracy: 1
time_ms: 10
memory_kb: 3840
final_rank: 10

code_snippet: #include <bits/stdc++.h>

using namespace std;
using ll = long long;

typedef complex<double> Point;
const double EPS = 1e-8;

struct Circle {
    Point p;
    double r;
};

// 円の交点を求めるメソッド
pair<Point, Point> cc_cross(const Circle& c1, const Circle& c2) {
    double d   = abs(c1.p - c2.p);
    double rc  = (d * d + c1.r * c1.r - c2.r * c2.r) / (2 * d);
    double h2  = c1.r * c1.r - rc * rc;
    double rs  = sqrt(max(0.0, h2));
    Point diff = (c2.p - c1.p) / d;
    return make_pair(c1.p + diff * Point(rc, rs), c1.p + diff * Point(rc, -rs));
}

bool ok(double z, vector<Point>& points, vector<double>& len) {
    int n = (int) points.size();
    vector<Circle> C(n);

    for (int i = 0; i < n; i++) {
        if (z > len[i]) {
            return false; // ロープより高いならfalse
        }

        double rr = sqrt(max(0.0, len[i] * len[i] - z * z));
        C[i]      = Circle(points[i], rr);
    }

    // 交点があるかの判定
    for (int i = 0; i < n; i++) {
        bool ok = true;
        for (int j = 0; j < n; j++) {
            if (i == j) {
                continue;
            }

            double d2 = norm(C[i].p - C[j].p);
            if (d2 > C[j].r * C[j].r + EPS) {
                ok = false;
            }
        }
        if (ok) {
            return true;
        }
    }

    // 交点と、その他の円が重なっているかの判定
    for (int i = 0; i < n; i++) {
        for (int j = i + 1; j < n; j++) {
            auto [p1, p2] = cc_cross(C[i], C[j]);
            for (Point cp : {p1, p2}) {
                bool all = true;
                for (int k = 0; k < n; k++) {
                    if (norm(cp - C[k].p) > C[k].r * C[k].r + EPS) {
                        all = false;
                        break;
                    }
                }
                if (all) {
                    return true;
                }
            }
        }
    }

    return false;
}

int main() {
    while (true) {
        int n;
        cin >> n;
        if (n == 0) {
            break;
        }

        vector<Point> points(n);
        vector<double> len(n);
        for (int i = 0; i < n; i++) {
            double x, y, l;
            cin >> x >> y >> l;
            points[i] = Point(x, y);
            len[i]    = l;
        }

        double left = 0, right = 300;
        while (right - left > EPS) {
            double mid = (right + left) / 2;
            if (ok(mid, points, len)) {
                left = mid;
            } else {
                right = mid;
            }
        }
        printf("%.10f\n", left);
    }
}
accuracy: 1
time_ms: 10
memory_kb: 3840
final_rank: 10

code_snippet: #include <bits/stdc++.h>

using namespace std;
using ll = long long;

typedef complex<double> Point;
const double EPS = 1e-8;

struct Circle {
    Point p;
    double r;
};

pair<Point, Point> cc_cross(const Circle& c1, const Circle& c2) {
    double d   = abs(c1.p - c2.p);
    double rc  = (d * d + c1.r * c1.r - c2.r * c2.r) / (2 * d);
    double h2  = c1.r * c1.r - rc * rc;
    double rs  = sqrt(max(0.0, h2));
    Point diff = (c2.p - c1.p) / d;
    return make_pair(c1.p + diff * Point(rc, rs), c1.p + diff * Point(rc, -rs));
}

bool ok(double z, vector<Point>& points, vector<double>& len) {
    int n = (int) points.size();
    vector<Circle> C(n);

    for (int i = 0; i < n; i++) {
        if (z > len[i]) {
            return false; // ロープより高いならfalse
        }

        double rr = sqrt(max(0.0, len[i] * len[i] - z * z));
        C[i]      = Circle(points[i], rr);
    }

    for (int i = 0; i < n; i++) {
        bool ok = true;
        for (int j = 0; j < n; j++) {
            if (i == j) {
                continue;
            }
            double d2 = norm(C[i].p - C[j].p);
            if (d2 > C[j].r * C[j].r + EPS) {
                ok = false;
                break;
            }
        }
        if (ok) {
            return true;
        }
    }

    for (int i = 0; i < n; i++) {
        for (int j = i + 1; j < n; j++) {
            double d = abs(C[i].p - C[j].p);
            if (d > C[i].r + C[j].r + EPS) {
                continue;
            }
            if (d < (C[i].r - C[j].r) - EPS) {
                continue;
            }

            auto [p1, p2] = cc_cross(C[i], C[j]);
            for (Point pp : {p1, p2}) {
                bool all = true;
                for (int k = 0; k < n; k++) {
                    if (norm(pp - C[k].p) > C[k].r * C[k].r + EPS) {
                        all = false;
                        break;
                    }
                }
                if (all) {
                    return true;
                }
            }
        }
    }

    return false;
}

int main() {
    while (true) {
        int n;
        cin >> n;
        if (n == 0) {
            break;
        }

        vector<Point> points(n);
        vector<double> len(n);
        for (int i = 0; i < n; i++) {
            double x, y, l;
            cin >> x >> y >> l;
            points[i] = Point(x, y);
            len[i]    = l;
        }

        double left = 0, right = 300;
        while (right - left > EPS) {
            double mid = (right + left) / 2;
            if (ok(mid, points, len)) {
                left = mid;
            } else {
                right = mid;
            }
        }
        printf("%.10f\n", left);
    }
}
accuracy: 1
time_ms: 10
memory_kb: 3840
final_rank: 10

code_snippet: #include <bits/stdc++.h>

using namespace std;
using ll = long long;

typedef complex<double> Point;
const double EPS = 1e-8;

struct Circle {
    Point p;
    double r;
};

pair<Point, Point> cc_cross(const Circle& c1, const Circle& c2) {
    double d   = abs(c1.p - c2.p);
    double rc  = (d * d + c1.r * c1.r - c2.r * c2.r) / (2 * d);
    double h2  = c1.r * c1.r - rc * rc;
    double rs  = sqrt(max(0.0, h2));
    Point diff = (c2.p - c1.p) / d;
    return make_pair(c1.p + diff * Point(rc, rs), c1.p + diff * Point(rc, -rs));
}

bool ok(double z, vector<Point>& points, vector<double>& len) {
    int n = (int) points.size();
    vector<Circle> C(n);

    for (int i = 0; i < n; i++) {
        if (z > len[i]) {
            return false; // ロープより高いならfalse
        }

        double rr = sqrt(max(0.0, len[i] * len[i] - z * z));
        C[i]      = Circle(points[i], rr);
    }

    for (int i = 0; i < n; i++) {
        bool ok = true;
        for (int j = 0; j < n; j++) {
            if (i == j) {
                continue;
            }
            double d2 = norm(C[i].p - C[j].p);
            if (d2 > C[j].r * C[j].r + EPS) {
                ok = false;
                break;
            }
        }
        if (ok) {
            return true;
        }
    }

    for (int i = 0; i < n; i++) {
        for (int j = i + 1; j < n; j++) {
            double d = abs(C[i].p - C[j].p);
            if (d > C[i].r + C[j].r + EPS) {
                continue;
            }
            if (d < (C[i].r - C[j].r) - EPS) {
                continue;
            }

            auto [p1, p2] = cc_cross(C[i], C[j]);
            for (Point cand : {p1, p2}) {
                bool all = true;
                for (int k = 0; k < n; k++) {
                    if (norm(cand - C[k].p) > C[k].r * C[k].r + EPS) {
                        all = false;
                        break;
                    }
                }
                if (all) {
                    return true;
                }
            }
        }
    }

    return false;
}

int main() {
    while (true) {
        int n;
        cin >> n;
        if (n == 0) {
            break;
        }

        vector<Point> points(n);
        vector<double> len(n);
        for (int i = 0; i < n; i++) {
            double x, y, l;
            cin >> x >> y >> l;
            points[i] = Point(x, y);
            len[i]    = l;
        }

        double left = 0, right = 300;
        while (right - left > EPS) {
            double mid = (right + left) / 2;
            if (ok(mid, points, len)) {
                left = mid;
            } else {
                right = mid;
            }
        }
        printf("%.10f\n", left);
    }
}
accuracy: 1
time_ms: 10
memory_kb: 3840
final_rank: 10

code_snippet: #include <bits/stdc++.h>

using namespace std;
using ll = long long;

typedef complex<double> Point;
const double EPS = 1e-8;

struct Circle {
    Point p;
    double r;
};

pair<Point, Point> cc_cross(const Circle& c1, const Circle& c2) {
    double d   = abs(c1.p - c2.p);
    double rc  = (d * d + c1.r * c1.r - c2.r * c2.r) / (2 * d);
    double h2  = c1.r * c1.r - rc * rc;
    double rs  = sqrt(max(0.0, h2));
    Point diff = (c2.p - c1.p) / d;
    return make_pair(c1.p + diff * Point(rc, rs), c1.p + diff * Point(rc, -rs));
}

bool ok(double z, vector<Point>& points, vector<double>& len) {
    int n = (int) points.size();
    vector<Circle> C(n);

    for (int i = 0; i < n; i++) {
        if (z > len[i]) {
            return false; // ロープより高いならfalse
        }

        double rr = sqrt(max(0.0, len[i] * len[i] - z * z));
        C[i]      = Circle(points[i], rr);
    }

    for (int i = 0; i < n; i++) {
        bool ok = true;
        for (int j = 0; j < n; j++) {
            if (i == j) {
                continue;
            }
            double d2 = norm(C[i].p - C[j].p);
            if (d2 > C[j].r * C[j].r + EPS) {
                ok = false;
                break;
            }
        }
        if (ok) {
            return true;
        }
    }

    for (int i = 0; i < n; i++) {
        for (int j = i + 1; j < n; j++) {
            double d = abs(C[i].p - C[j].p);
            if (d > C[i].r + C[j].r + EPS) {
                continue;
            }
            if (d < fabs(C[i].r - C[j].r) - EPS) {
                continue;
            }

            auto [p1, p2] = cc_cross(C[i], C[j]);
            for (Point cand : {p1, p2}) {
                bool all = true;
                for (int k = 0; k < n; k++) {
                    if (norm(cand - C[k].p) > C[k].r * C[k].r + EPS) {
                        all = false;
                        break;
                    }
                }
                if (all) {
                    return true;
                }
            }
        }
    }

    return false;
}

int main() {
    while (true) {
        int n;
        cin >> n;
        if (n == 0) {
            break;
        }

        vector<Point> points(n);
        vector<double> len(n);
        for (int i = 0; i < n; i++) {
            double x, y, l;
            cin >> x >> y >> l;
            points[i] = Point(x, y);
            len[i]    = l;
        }

        double left = 0, right = 300;
        while (right - left > EPS) {
            double mid = (right + left) / 2;
            if (ok(mid, points, len)) {
                left = mid;
            } else {
                right = mid;
            }
        }
        printf("%.10f\n", left);
    }
}
accuracy: 1
time_ms: 10
memory_kb: 3840
final_rank: 10

code_snippet: #include <bits/stdc++.h>
using namespace std;
using ll = long long;
typedef complex<double> Point;

const double EPS = 1e-7;


struct Circle {
    Point p;
    double r;
};



pair<Point, Point> cc_cross(const Circle& c1, const Circle& c2) {
    double d = abs(c1.p - c2.p);
    
    double rc = (d*d + c1.r*c1.r - c2.r*c2.r) / (2*d);
    double h2 = c1.r*c1.r - rc*rc;
    
    double rs = sqrt(max(0.0, h2));
    Point diff = (c2.p - c1.p) / d;
    return make_pair(
        c1.p + diff * Point(rc,  rs),
        c1.p + diff * Point(rc, -rs)
    );
}


bool centerContained(int i, const vector<Circle>& C) {
    for (int j = 0; j < (int)C.size(); j++) {
        if (i == j) continue;
        double d2 = norm(C[i].p - C[j].p);
        if (d2 > C[j].r*C[j].r + EPS) return false;
    }
    return true;
}


bool ok(double z,
        const vector<Point>& points,
        const vector<double>& len)
{
    int n = points.size();
    vector<Circle> C(n);

    for (int i = 0; i < n; i++) {
        if (z > len[i]) return false;
        double rr = sqrt(max(0.0, len[i]*len[i] - z*z));
        C[i] = { points[i], rr };
    }
    
    for (int i = 0; i < n; i++) {
        if (centerContained(i, C)) return true;
    }
    
    for (int i = 0; i < n; i++) {
        for (int j = i+1; j < n; j++) {
            double d = abs(C[i].p - C[j].p);
            
            if (d > C[i].r + C[j].r + EPS) continue;        
            if (d < fabs(C[i].r - C[j].r) - EPS) continue;   
            
            auto [p1, p2] = cc_cross(C[i], C[j]);
            
            
            for (Point cand : {p1, p2}) {
                bool insideAll = true;
                for (int k = 0; k < n; k++) {
                    if (norm(cand - C[k].p) > C[k].r*C[k].r + EPS) {
                        insideAll = false;
                        break;
                    }
                }
                if (insideAll) return true;
            }
        }
    }
    return false;
}

int main(){
    while (true) {
        int n;
        cin >> n;
        if (!cin || n == 0) break;

        vector<Point> points(n);
        vector<double> len(n);
        for (int i = 0; i < n; i++) {
            double x, y, l;
            cin >> x >> y >> l;
            points[i] = Point(x, y);
            len[i] = l;
        }

        double left = 0.0, right = 0.0;
        
        for (double l : len) right = max(right, l);

        
        while (right - left > EPS) {
            double mid = (left + right) / 2;
            if (ok(mid, points, len)) {
                left = mid;
            } else {
                right = mid;
            }
        }

        
        cout << fixed << setprecision(7) << left << "\n";
    }

}
accuracy: 1
time_ms: 20
memory_kb: 3576
final_rank: 4

code_snippet: #include <bits/stdc++.h>
using namespace std;
using ll = long long;
typedef complex<double> Point;

const double EPS = 1e-7;


struct Circle {
    Point p;
    double r;
};



pair<Point, Point> cc_cross(const Circle& c1, const Circle& c2) {
    double d = abs(c1.p - c2.p);
    
    double rc = (d*d + c1.r*c1.r - c2.r*c2.r) / (2*d);
    double h2 = c1.r*c1.r - rc*rc;
    
    double rs = sqrt(max(0.0, h2));
    Point diff = (c2.p - c1.p) / d;
    return make_pair(
        c1.p + diff * Point(rc,  rs),
        c1.p + diff * Point(rc, -rs)
    );
}


bool centerContained(int i, const vector<Circle>& C) {
    for (int j = 0; j < (int)C.size(); j++) {
        if (i == j) continue;
        double d2 = norm(C[i].p - C[j].p);
        if (d2 > C[j].r*C[j].r + EPS) return false;
    }
    return true;
}


bool ok(double z,
        const vector<Point>& points,
        const vector<double>& len)
{
    int n = points.size();
    vector<Circle> C(n);

    for (int i = 0; i < n; i++) {
        if (z > len[i]) return false;  // ロープ長より高い
        double rr = sqrt(max(0.0, len[i]*len[i] - z*z));
        C[i] = { points[i], rr };
    }
    
    for (int i = 0; i < n; i++) {
        if (centerContained(i, C)) return true;
    }
    
    for (int i = 0; i < n; i++) {
        for (int j = i+1; j < n; j++) {
            double d = abs(C[i].p - C[j].p);
            
            if (d > C[i].r + C[j].r + EPS) continue;        
            if (d < fabs(C[i].r - C[j].r) - EPS) continue;   
            
            auto [p1, p2] = cc_cross(C[i], C[j]);
            
            
            for (Point cand : {p1, p2}) {
                bool insideAll = true;
                for (int k = 0; k < n; k++) {
                    if (norm(cand - C[k].p) > C[k].r*C[k].r + EPS) {
                        insideAll = false;
                        break;
                    }
                }
                if (insideAll) return true;
            }
        }
    }
    return false;
}

int main(){
    while (true) {
        int n;
        cin >> n;
        if (!cin || n == 0) break;

        vector<Point> points(n);
        vector<double> len(n);
        for (int i = 0; i < n; i++) {
            double x, y, l;
            cin >> x >> y >> l;
            points[i] = Point(x, y);
            len[i] = l;
        }

        double left = 0.0, right = 0.0;
        
        for (double l : len) right = max(right, l);

        
        while (right - left > EPS) {
            double mid = (left + right) / 2;
            if (ok(mid, points, len)) {
                left = mid;
            } else {
                right = mid;
            }
        }

        
        cout << fixed << setprecision(7) << left << "\n";
    }

}
accuracy: 1
time_ms: 20
memory_kb: 3492
final_rank: 1

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

struct Point {
    double x, y;
};

const double EPS = 1e-7;

int circleIntersections(const Point& p1, double r1,
                        const Point& p2, double r2,
                        vector<Point>& points) {
    double dx = p2.x - p1.x;
    double dy = p2.y - p1.y;
    double d2 = dx*dx + dy*dy;
    if (d2 < EPS) return 0;
    double d = sqrt(d2);
    if (d > r1 + r2 + EPS) return 0;
    if (d < fabs(r1 - r2) - EPS) return 0; 
    double a = (r1*r1 - r2*r2 + d2) / (2*d);
    double h2 = r1*r1 - a*a;
    if (h2 < -EPS) return 0;
    h2 = max(h2, 0.0);
    double xm = p1.x + a * dx / d;
    double ym = p1.y + a * dy / d;
    if (h2 < EPS) {
        points.push_back({xm, ym});
        return 1;
    } else {
        double h = sqrt(h2);
        double rx = -dy * (h / d);
        double ry =  dx * (h / d);
        points.push_back({xm + rx, ym + ry});
        points.push_back({xm - rx, ym - ry});
        return 2;
    }
}

bool centerContained(int i, const vector<Point>& centers,
                     const vector<double>& radii) {
    for (int j = 0; j < (int)centers.size(); j++) {
        if (i == j) continue;
        double dx = centers[i].x - centers[j].x;
        double dy = centers[i].y - centers[j].y;
        if (dx*dx + dy*dy > radii[j]*radii[j] + EPS) {
            return false;
        }
    }
    return true;
}

bool feasible(double z,
              const vector<Point>& stakes,
              const vector<double>& lengths) {
    int n = stakes.size();
    vector<double> r(n);
    for (int i = 0; i < n; i++) {
        if (z > lengths[i]) return false;
        r[i] = sqrt(max(0.0, lengths[i]*lengths[i] - z*z));
    }
    for (int i = 0; i < n; i++) {
        if (centerContained(i, stakes, r)) return true;
    }
    for (int i = 0; i < n; i++) {
        for (int j = i+1; j < n; j++) {
            vector<Point> pts;
            int cnt = circleIntersections(stakes[i], r[i], stakes[j], r[j], pts);
            for (auto& p : pts) {
                bool insideAll = true;
                for (int k = 0; k < n; k++) {
                    double dx = p.x - stakes[k].x;
                    double dy = p.y - stakes[k].y;
                    if (dx*dx + dy*dy > r[k]*r[k] + EPS) {
                        insideAll = false;
                        break;
                    }
                }
                if (insideAll) return true;
            }
        }
    }
    return false;
}

int main(){
    ios::sync_with_stdio(false);
    cin.tie(nullptr);

    while (true) {
        int n;
        cin >> n;
        if (!cin || n == 0) break;

        vector<Point> stakes(n);
        vector<double> lengths(n);
        for (int i = 0; i < n; i++) {
            cin >> stakes[i].x >> stakes[i].y >> lengths[i];
        }

        double low = 0, high = 0;
        for (double l : lengths) high = max(high, l);

        for (int iter = 0; iter < 60; iter++) {
            double mid = (low + high) / 2;
            if (feasible(mid, stakes, lengths)) low = mid;
            else                 high = mid;
        }

        cout << fixed << setprecision(7) << low << "\n";
    }
    return 0;
}
accuracy: 1
time_ms: 20
memory_kb: 3840
final_rank: 16

code_snippet: #include <bits/stdc++.h>
using namespace std;
using ll = long long;
using P = pair<long long, long long>;
#define rep(i, a, b) for(long long i = (a); i < (b); ++i)
#define rrep(i, a, b) for(long long i = (a); i >= (b); --i)
constexpr long long inf = 4e18;
struct SetupIO {
    SetupIO() {
        ios::sync_with_stdio(0);
        cin.tie(0);
        cout << fixed << setprecision(30);
    }
} setup_io;
using Real = long double;
constexpr Real EPS = Real(1e-8), PI = 3.141592653589793238462643383279L;
int sign(const Real& r) {
    if(r <= -EPS) return -1;
    if(r >= +EPS) return +1;
    return 0;
}
bool eq(const Real& a, const Real& b) {
    return sign(a - b) == 0;
}
using Point = complex<Real>;
istream& operator>>(istream& is, Point& p) {
    Real a, b;
    is >> a >> b;
    p = Point(a, b);
    return is;
}
ostream& operator<<(ostream& os, const Point& p) {
    return os << p.real() << " " << p.imag();
}
Point operator*(const Point& p, const Real& d) {
    return Point(p.real() * d, p.imag() * d);
}
Point operator/(const Point& p, const Real& d) {
    return Point(p.real() / d, p.imag() / d);
}
Point rot(const Point& p, const Real& theta) {
    return p * Point(cos(theta), sin(theta));
}
Real dot(const Point& p1, const Point& p2) {
    return (conj(p1) * p2).real();
}
Real cross(const Point& p1, const Point& p2) {
    return (conj(p1) * p2).imag();
}
Real dist(const Point& p1, const Point& p2) {
    return abs(p1 - p2);
}
bool comp_x(const Point& p1, const Point& p2) {
    return eq(p1.real(), p2.real()) ? p1.imag() < p2.imag() : p1.real() < p2.real();
}
bool comp_y(const Point& p1, const Point& p2) {
    return eq(p1.imag(), p2.imag()) ? p1.real() < p2.real() : p1.imag() < p2.imag();
}
bool comp_arg(const Point& p1, const Point& p2) {
    return arg(p1) < arg(p2);
}
int ccw(const Point& a, Point b, Point c) {
    b -= a;
    c -= a;
    if(sign(cross(b, c)) == 1) return 1;
    if(sign(cross(b, c)) == -1) return -1;
    if(sign(dot(b, c)) == -1) return +2;
    if(norm(b) < norm(c)) return -2;
    return 0;
}
Real closest_pair(vector<Point> ps) {
    if((int)ps.size() <= 1) return Real(1e18);
    sort(ps.begin(), ps.end(), comp_x);
    vector<Point> memo(ps.size());
    auto func = [&](const auto& func, const int l, const int r) -> Real {
        if(r - l <= 1) return Real(1e18);
        const int m = (l + r) >> 1;
        const Real x = ps[m].real();
        Real res = min(func(func, l, m), func(func, m, r));
        inplace_merge(ps.begin() + l, ps.begin() + m, ps.begin() + r, comp_y);
        int cnt = 0;
        for(int i = l; i < r; ++i) {
            if(abs(ps[i].real() - x) >= res) continue;
            for(int j = 0; j < cnt; ++j) {
                const Point d = ps[i] - memo[cnt - j - 1];
                if(d.imag() >= res) break;
                res = min(res, abs(d));
            }
            memo[cnt++] = ps[i];
        }
        return res;
    };
    return func(func, 0, (int)ps.size());
}
struct Line {
    Point a, b;
    Line() = default;
    Line(const Point& a, const Point& b)
        : a(a), b(b) {}
};
using Segment = Line;
bool is_parallel(const Line& a, const Line& b) {
    return eq(cross(a.b - a.a, b.b - b.a), 0.0);
}
bool is_orthogonal(const Line& a, const Line& b) {
    return eq(dot(a.b - a.a, b.b - b.a), 0.0);
}
Point projection(const Line& l, const Point& p) {
    Real t = dot(p - l.a, l.b - l.a) / norm(l.b - l.a);
    return l.a + (l.b - l.a) * t;
}
Point reflection(const Line& l, const Point& p) {
    return p + (projection(l, p) - p) * 2.0;
}
bool is_intersect_lp(const Line& l, const Point& p) {
    return abs(ccw(l.a, l.b, p)) != 1;
}
bool is_intersect_sp(const Segment& s, const Point& p) {
    return ccw(s.a, s.b, p) == 0;
}
bool is_intersect_ll(const Line& l1, const Line& l2) {
    if(!eq(cross(l1.b - l1.a, l2.b - l2.a), 0.0)) return true;
    return eq(cross(l1.b - l1.a, l2.b - l1.a), 0.0);
}
bool is_intersect_ls(const Line& l, const Segment& s) {
    return sign(cross(l.b - l.a, s.a - l.a) * cross(l.b - l.a, s.b - l.a)) <= 0;
}
bool is_intersect_sl(const Segment& s, const Line& l) {
    return is_intersect_ls(l, s);
}
bool is_intersect_ss(const Segment& s1, const Segment& s2) {
    if(ccw(s1.a, s1.b, s2.a) * ccw(s1.a, s1.b, s2.b) > 0) return false;
    return ccw(s2.a, s2.b, s1.a) * ccw(s2.a, s2.b, s1.b) <= 0;
}
vector<Point> intersection_ll(const Line& l1, const Line& l2) {
    vector<Point> res;
    if(!is_intersect_ll(l1, l2)) return res;
    Real a = cross(l1.b - l1.a, l2.b - l2.a);
    Real b = cross(l1.b - l1.a, l1.b - l2.a);
    if(eq(a, 0.0) and eq(b, 0.0)) {
        res.emplace_back(l2.a);
    } else {
        res.emplace_back(l2.a + (l2.b - l2.a) * b / a);
    }
    return res;
}
vector<Point> intersection_ss(const Segment& s1, const Segment& s2) {
    return is_intersect_ss(s1, s2) ? intersection_ll(Line(s1), Line(s2)) : vector<Point>();
}
Real dist_lp(const Line& l, const Point& p) {
    return abs(p - projection(l, p));
}
Real dist_sp(const Segment& s, const Point& p) {
    const Point h = projection(s, p);
    if(is_intersect_sp(s, h)) return abs(h - p);
    return min(abs(s.a - p), abs(s.b - p));
}
Real dist_ll(const Line& l1, const Line& l2) {
    if(is_intersect_ll(l1, l2)) return 0.0;
    return dist_lp(l1, l2.a);
}
Real dist_ss(const Segment& s1, const Segment& s2) {
    if(is_intersect_ss(s1, s2)) return 0.0;
    return min({dist_sp(s1, s2.a), dist_sp(s1, s2.b), dist_sp(s2, s1.a), dist_sp(s2, s1.b)});
}
Real dist_ls(const Line& l, const Segment& s) {
    if(is_intersect_ls(l, s)) return 0.0;
    return min(dist_lp(l, s.a), dist_lp(l, s.b));
}
Real dist_sl(const Segment& s, const Line& l) {
    return dist_ls(l, s);
}
struct Circle {
    Point p;
    Real r;
    Circle() = default;
    Circle(const Point& p, const Real& r)
        : p(p), r(r) {}
};
bool is_intersect_cp(const Circle& c, const Point& p) {
    return eq(abs(p - c.p), c.r);
}
bool is_intersect_cl(const Circle& c, const Line& l) {
    return sign(c.r - dist_lp(l, c.p)) >= 0;
}
int is_intersect_cc(Circle c1, Circle c2) {
    if(c1.r < c2.r) swap(c1, c2);
    const Real d = abs(c1.p - c2.p);
    const int a = sign(d - c1.r - c2.r);
    if(a >= 0) return a + 3;
    return sign(d - c1.r + c2.r) + 1;
}
vector<Point> intersection_cl(const Circle& c, const Line& l) {
    const Point h = projection(l, c.p);
    const Point e = (l.b - l.a) / abs(l.b - l.a);
    vector<Point> res;
    if(!is_intersect_cl(c, l)) return res;
    if(eq(dist_lp(l, c.p), c.r)) {
        res.emplace_back(h);
    } else {
        const Real b = sqrt(c.r * c.r - norm(h - c.p));
        res.emplace_back(h - e * b);
        res.emplace_back(h + e * b);
    }
    return res;
}
vector<Point> intersection_cs(const Circle& c, const Segment& s) {
    const vector<Point> cand = intersection_cl(c, Line(s));
    vector<Point> res;
    for(const Point& p : cand) {
        if(ccw(s.a, s.b, p) == 0) {
            res.emplace_back(p);
        }
    }
    return res;
}
vector<Point> intersection_cc(const Circle& c1, const Circle& c2) {
    const Real d = abs(c1.p - c2.p);
    const Real a = acos((c1.r * c1.r + d * d - c2.r * c2.r) / (Real(2.0) * c1.r * d));
    const Real t = atan2(c2.p.imag() - c1.p.imag(), c2.p.real() - c1.p.real());
    vector<Point> res;
    if(is_intersect_cc(c1, c2) % 4 == 0) return res;
    if(eq(a, 0.0)) {
        res.emplace_back(c1.p + rot(Point(c1.r, 0.0), t));
    } else {
        res.emplace_back(c1.p + rot(Point(c1.r, 0.0), t + a));
        res.emplace_back(c1.p + rot(Point(c1.r, 0.0), t - a));
    }
    return res;
}
vector<Point> tangent_cp(const Circle& c, const Point& p) {
    return intersection_cc(c, Circle(p, sqrt(norm(p - c.p) - c.r * c.r)));
}
vector<Line> tangent_cc(Circle c1, Circle c2) {
    vector<Line> res;
    if(c1.r < c2.r) swap(c1, c2);
    const Real r = abs(c2.p - c1.p);
    if(eq(r, 0.0)) return res;
    const Point u = (c2.p - c1.p) / r;
    const Point v = rot(u, PI * 0.5);
    for(const Real s : {Real(1.0), Real(-1.0)}) {
        const Real h = (c1.r + c2.r * s) / r;
        if(eq(abs(h), Real(1.0))) {
            res.emplace_back(c1.p + u * c1.r, c1.p + (u + v) * c1.r);
        } else if(abs(h) < Real(1.0)) {
            const Point uu = u * h, vv = v * sqrt(Real(1.0) - h * h);
            res.emplace_back(c1.p + (uu + vv) * c1.r, c2.p - (uu + vv) * c2.r * s);
            res.emplace_back(c1.p + (uu - vv) * c1.r, c2.p - (uu - vv) * c2.r * s);
        }
    }
    return res;
}
Circle inscribed_circle(const Point& a, const Point& b, const Point& c) {
    const Real A = abs(b - c), B = abs(c - a), C = abs(a - b);
    const Point x = Point((a * A + b * B + c * C) / (A + B + C));
    const Real r = dist_sp(Segment(a, b), x);
    return Circle(x, r);
}
Circle circumscribed_circle(const Point& a, const Point& b, const Point& c) {
    const Point m1((a + b) / 2.0), m2((b + c) / 2.0);
    const Point v((b - a).imag(), (a - b).real()), w((b - c).imag(), (c - b).real());
    const Line s(m1, Point(m1 + v)), t(m2, Point(m2 + w));
    const Point x = intersection_ll(s, t)[0];
    return Circle(x, abs(a - x));
}
Circle appollonius(const Point& p1, const Point& p2, const Real& a, const Real& b) {
    const Point q1 = (p1 * b + p2 * a) / (a + b), q2 = (-p1 * b + p2 * a) / (a - b);
    return Circle((q1 + q2) * 0.5, abs(q1 - q2) * 0.5);
}
Real area_cc(const Circle& c1, const Circle& c2) {
    const Real d = abs(c1.p - c2.p);
    if(c1.r + c2.r <= d + EPS) return 0.0;
    if(d <= abs(c1.r - c2.r) + EPS) {
        const Real r = min(c1.r, c2.r);
        return r * r * PI;
    }
    const Real rc = (d * d + c1.r * c1.r - c2.r * c2.r) / (Real(2.0) * d);
    const Real theta = acos(rc / c1.r);
    const Real phi = acos((d - rc) / c2.r);
    return c1.r * c1.r * theta + c2.r * c2.r * phi - d * c1.r * sin(theta);
}
Real area_pc(const vector<Point>& ps, const Circle& c) {
    auto calc_element = [&](const Point& a, const Point& b, const Real& r, const bool triangle) -> Real {
        if(triangle) return cross(a, b) / 2.0;
        const Point tmp = b * Point(a.real(), -a.imag());
        const Real ang = atan2(tmp.imag(), tmp.real());
        return r * r * ang / 2.0;
    };
    auto cross_area = [&](const Circle& c, const Point& ia, const Point& ib) -> Real {
        const Point a = ia - c.p, b = ib - c.p;
        if(abs(a - b) < EPS) return 0;
        const bool isin_a = (abs(a) < c.r + EPS);
        const bool isin_b = (abs(b) < c.r + EPS);
        if(isin_a and isin_b) return calc_element(a, b, c.r, true);
        const Circle oc(Point(0.0, 0.0), c.r);
        const Segment seg(a, b);
        const vector<Point> cr = intersection_cs(oc, seg);
        if(cr.empty()) return calc_element(a, b, c.r, false);
        const Point s = cr[0], t = cr.back();
        return calc_element(s, t, c.r, true) + calc_element(a, s, c.r, isin_a) + calc_element(t, b, c.r, isin_b);
    };
    const int n = (int)ps.size();
    if(n < 3) return 0.0;
    Real S = 0;
    for(int i = 0; i < n; ++i) {
        S += cross_area(c, ps[i], ps[(i + 1) % n]);
    }
    return S;
}
int main(void) {
    while(1) {
        int n;
        cin >> n;
        if(n == 0) break;
        vector<Point> ps(n);
        vector<Real> l(n);
        rep(i, 0, n) {
            cin >> ps[i] >> l[i];
        }
        Real lower = 0.0, upper = *ranges::min_element(l);
        rep(_, 0, 100) {
            Real mid = (lower + upper) / 2.0;
            vector<Circle> c(n);
            rep(i, 0, n) {
                c[i] = {ps[i], sqrtl(l[i] * l[i] - mid * mid)};
            }
            vector<Point> cand;
            rep(i, 0, n) cand.push_back(c[i].p);
            rep(i, 0, n) {
                rep(j, i + 1, n) {
                    vector<Point> intersect = intersection_cc(c[i], c[j]);
                    rep(k, 0, ssize(intersect)) {
                        cand.push_back(intersect[k]);
                    }
                }
            }
            bool res = false;
            for(const Point& p : cand) {
                bool flag = true;
                rep(i, 0, n) {
                    if(dist(p, c[i].p) - EPS > c[i].r) {
                        flag = false;
                    }
                }
                if(flag) res = true;
            }
            if(res) {
                lower = mid;
            } else {
                upper = mid;
            }
        }
        cout << lower << '\n';
    }
}
accuracy: 1
time_ms: 1040
memory_kb: 4096
final_rank: 19

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

int x[11], y[11], l[11];
int n;

double findH(double X, double Y) {
    double mn = 1e9;
    for (int i = 1;i <= n;i++) {
        double cur = l[i] * l[i] - (X - x[i]) * (X - x[i]) - (Y - y[i]) * (Y - y[i]);
        if (cur < mn) mn = cur;
    }
    return mn;
}

double findY(double X) {
    double l = -100, r = 100; 
    for (int i = 1;i <= 100;i++) {
        double m1 = l + (r - l) / 3;
        double m2 = r - (r - l) / 3;
        if (findH(X, m1) < findH(X, m2)) {
            l = m1;
        } else {
            r = m2;
        }
    }
    return findH(X, l);
}

int main() {
    ios_base::sync_with_stdio(false); cin.tie(NULL);
    while (cin >> n) {
        if (n == 0) return 0;
        for (int i = 1;i <= n;i++) {
            cin >> x[i] >> y[i] >> l[i];
        }
        double l = -100, r = 100; 
        for (int i = 1;i <= 100;i++) {
            double m1 = l + (r - l) / 3;
            double m2 = r - (r - l) / 3;
            if (findY(m1) < findY(m2)) {
                l = m1;
            } else {
                r = m2;
            }
        }
        cout << fixed << setprecision(5) << sqrt(findY(l)) << "\n";
    }
}
accuracy: 1
time_ms: 210
memory_kb: 3496
final_rank: 5

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

int n;
int l[10], x[10], y[10];

double H(double Y, double X) {
    double min_val = 1e18;
    for (int i = 0; i < n; ++i) {
        double dx = X - x[i];
        double dy = Y - y[i];
        double val = l[i] * l[i] - dx*dx - dy*dy;
        if (val < min_val) min_val = val;
    }
    return min_val;
}

double optimizeY(double X) {
    double left = -100.0, right = 100.0;
    for (int i = 0; i < 100; ++i) {
        double m1 = left + (right - left) / 3;
        double m2 = right - (right - left) / 3;
        if (H(m1, X) < H(m2, X))
            left = m1;
        else
            right = m2;
    }
    return H(left, X);
}

double optimizeX() {
    double left = -100.0, right = 100.0;
    for (int i = 0; i < 100; ++i) {
        double m1 = left + (right - left) / 3;
        double m2 = right - (right - left) / 3;
        if (optimizeY(m1) < optimizeY(m2))
            left = m1;
        else
            right = m2;
    }
    return optimizeY(left);
}

int main() {
    ios::sync_with_stdio(false);
    cin.tie(0);
    while (cin >> n && n != 0) {
        for (int i = 0; i < n; ++i)
            cin >> x[i] >> y[i] >> l[i];
        double max_h_squared = optimizeX();
        double max_h = sqrt(max_h_squared);
        cout << fixed << setprecision(7) << max_h << '\n';
    }
    return 0;
}
accuracy: 1
time_ms: 210
memory_kb: 3588
final_rank: 8

code_snippet: #include <iostream>
#include <vector>
#include <cmath>
#include <iomanip>
#include <algorithm>

using namespace std;

struct Anchor {
    double x, y, l;
};

struct Circle {
    double x, y, r;
    Circle(double x_, double y_, double r_) : x(x_), y(y_), r(r_) {}
};

const double EPS = 1e-8;

bool isPossible(double z, const vector<Anchor>& anchors) {
    vector<Circle> circles;
    for (const auto& a : anchors) {
        if (z > a.l + EPS) return false;
        double r = sqrt(max(a.l * a.l - z * z, 0.0));
        circles.emplace_back(a.x, a.y, r);
    }

    // Check if any circle's center is inside all others
    for (int i = 0; i < circles.size(); ++i) {
        bool valid = true;
        for (int j = 0; j < circles.size(); ++j) {
            if (i == j) continue;
            double dx = circles[i].x - circles[j].x;
            double dy = circles[i].y - circles[j].y;
            double dist_sq = dx * dx + dy * dy;
            if (dist_sq > circles[j].r * circles[j].r + EPS) {
                valid = false;
                break;
            }
        }
        if (valid) return true;
    }

    // Check all pairs of circles for intersection points
    for (int i = 0; i < circles.size(); ++i) {
        for (int j = i + 1; j < circles.size(); ++j) {
            const Circle& c1 = circles[i];
            const Circle& c2 = circles[j];

            double dx = c2.x - c1.x;
            double dy = c2.y - c1.y;
            double d_sq = dx * dx + dy * dy;
            double d = sqrt(d_sq);

            if (d > c1.r + c2.r + EPS) continue;
            if (d + EPS < abs(c1.r - c2.r)) continue;

            double a = (c1.r * c1.r - c2.r * c2.r + d_sq) / (2 * d);
            double h_sq = c1.r * c1.r - a * a;
            if (h_sq < -EPS) continue;
            h_sq = max(h_sq, 0.0);
            double h = sqrt(h_sq);

            double xm = c1.x + (a * dx) / d;
            double ym = c1.y + (a * dy) / d;

            pair<double, double> points[2];
            points[0] = {xm - (h * dy) / d, ym + (h * dx) / d};
            points[1] = {xm + (h * dy) / d, ym - (h * dx) / d};

            for (const auto& p : points) {
                double x = p.first;
                double y = p.second;
                bool inside = true;
                for (int k = 0; k < circles.size(); ++k) {
                    if (k == i || k == j) continue;
                    const Circle& c = circles[k];
                    double dxk = x - c.x;
                    double dyk = y - c.y;
                    double dist_sq = dxk * dxk + dyk * dyk;
                    if (dist_sq > c.r * c.r + EPS) {
                        inside = false;
                        break;
                    }
                }
                if (inside) return true;
            }
        }
    }

    return false;
}

double findMaxHeight(const vector<Anchor>& anchors) {
    double low = 0.0;
    double high = 0.0;
    for (const auto& a : anchors) {
        high = max(high, a.l);
    }
    high = 1e9; // Set a large initial upper bound

    // Binary search with sufficient iterations for precision
    double max_z = 0.0;
    for (int iter = 0; iter < 100; ++iter) {
        double mid = (low + high) / 2;
        if (isPossible(mid, anchors)) {
            max_z = mid;
            low = mid;
        } else {
            high = mid;
        }
    }
    return max_z;
}

int main() {
    ios::sync_with_stdio(false);
    cin.tie(0);

    int n;
    while (cin >> n && n != 0) {
        vector<Anchor> anchors(n);
        for (int i = 0; i < n; ++i) {
            cin >> anchors[i].x >> anchors[i].y >> anchors[i].l;
        }
        double maxHeight = findMaxHeight(anchors);
        cout << fixed << setprecision(7) << maxHeight << '\n';
    }

    return 0;
}
accuracy: 1
time_ms: 10
memory_kb: 3560
final_rank: 2

code_snippet: #include <bits/stdc++.h>

using namespace std;

#define rep(i, a, b) for (int i = (int)(a); i < (int)(b); i++)
#define rrep(i, a, b) for (int i = (int)(b)-1; i >= (int)(a); i--)
#define ALL(v) (v).begin(), (v).end()
#define UNIQUE(v) sort(ALL(v)), (v).erase(unique(ALL(v)), (v).end())
#define SZ(v) (int)v.size()
#define MIN(v) *min_element(ALL(v))
#define MAX(v) *max_element(ALL(v))
#define LB(v, x) int(lower_bound(ALL(v), (x)) - (v).begin())
#define UB(v, x) int(upper_bound(ALL(v), (x)) - (v).begin())

using uint = unsigned int;
using ll = long long int;
using ull = unsigned long long;
using i128 = __int128_t;
using u128 = __uint128_t;
const int inf = 0x3fffffff;
const ll INF = 0x1fffffffffffffff;

template <typename T> inline bool chmax(T &a, T b) {
    if (a < b) {
        a = b;
        return 1;
    }
    return 0;
}
template <typename T> inline bool chmin(T &a, T b) {
    if (a > b) {
        a = b;
        return 1;
    }
    return 0;
}
template <typename T, typename U> T ceil(T x, U y) {
    assert(y != 0);
    if (y < 0)
        x = -x, y = -y;
    return (x > 0 ? (x + y - 1) / y : x / y);
}
template <typename T, typename U> T floor(T x, U y) {
    assert(y != 0);
    if (y < 0)
        x = -x, y = -y;
    return (x > 0 ? x / y : (x - y + 1) / y);
}
template <typename T> int popcnt(T x) {
    return __builtin_popcountll(x);
}
template <typename T> int topbit(T x) {
    return (x == 0 ? -1 : 63 - __builtin_clzll(x));
}
template <typename T> int lowbit(T x) {
    return (x == 0 ? -1 : __builtin_ctzll(x));
}

template <class T, class U>
ostream &operator<<(ostream &os, const pair<T, U> &p) {
    os << "P(" << p.first << ", " << p.second << ")";
    return os;
}
template <typename T> ostream &operator<<(ostream &os, const vector<T> &vec) {
    os << "{";
    for (int i = 0; i < vec.size(); i++) {
        os << vec[i] << (i + 1 == vec.size() ? "" : ", ");
    }
    os << "}";
    return os;
}
template <typename T, typename U>
ostream &operator<<(ostream &os, const map<T, U> &map_var) {
    os << "{";
    for (auto itr = map_var.begin(); itr != map_var.end(); itr++) {
        os << "(" << itr->first << ", " << itr->second << ")";
        itr++;
        if (itr != map_var.end())
            os << ", ";
        itr--;
    }
    os << "}";
    return os;
}
template <typename T> ostream &operator<<(ostream &os, const set<T> &set_var) {
    os << "{";
    for (auto itr = set_var.begin(); itr != set_var.end(); itr++) {
        os << *itr;
        ++itr;
        if (itr != set_var.end())
            os << ", ";
        itr--;
    }
    os << "}";
    return os;
}
#ifdef LOCAL
#define show(...) _show(0, #__VA_ARGS__, __VA_ARGS__)
#else
#define show(...) true
#endif
template <typename T> void _show(int i, T name) {
    cerr << '\n';
}
template <typename T1, typename T2, typename... T3>
void _show(int i, const T1 &a, const T2 &b, const T3 &...c) {
    for (; a[i] != ',' && a[i] != '\0'; i++)
        cerr << a[i];
    cerr << ":" << b << " ";
    _show(i + 1, a, c...);
}

#include <unistd.h>

namespace fastio {
static constexpr uint32_t SZ = 1 << 17;
char ibuf[SZ];
char obuf[SZ];
char out[100];
// pointer of ibuf, obuf


uint32_t pil = 0, pir = 0, por = 0;

struct Pre {
    char num[10000][4];
    constexpr Pre() : num() {
        for (int i = 0; i < 10000; i++) {
            int n = i;
            for (int j = 3; j >= 0; j--) {
                num[i][j] = n % 10 | '0';
                n /= 10;
            }
        }
    }
} constexpr pre;

inline void load() {
    memmove(ibuf, ibuf + pil, pir - pil);
    pir = pir - pil + fread(ibuf + pir - pil, 1, SZ - pir + pil, stdin);
    pil = 0;
    if (pir < SZ)
        ibuf[pir++] = '\n';
}

inline void flush() {
    fwrite(obuf, 1, por, stdout);
    por = 0;
}

void rd(char &c) {
    do {
        if (pil + 1 > pir)
            load();
        c = ibuf[pil++];
    } while (isspace(c));
}

void rd(string &x) {
    x.clear();
    char c;
    do {
        if (pil + 1 > pir)
            load();
        c = ibuf[pil++];
    } while (isspace(c));
    do {
        x += c;
        if (pil == pir)
            load();
        c = ibuf[pil++];
    } while (!isspace(c));
}

template <typename T> void rd_real(T &x) {
    string s;
    rd(s);
    x = stod(s);
}

template <typename T> void rd_integer(T &x) {
    if (pil + 100 > pir)
        load();
    char c;
    do
        c = ibuf[pil++];
    while (c < '-');
    bool minus = 0;
    if constexpr (is_signed<T>::value || is_same_v<T, i128>) {
        if (c == '-') {
            minus = 1, c = ibuf[pil++];
        }
    }
    x = 0;
    while ('0' <= c) {
        x = x * 10 + (c & 15), c = ibuf[pil++];
    }
    if constexpr (is_signed<T>::value || is_same_v<T, i128>) {
        if (minus)
            x = -x;
    }
}

void rd(int &x) {
    rd_integer(x);
}
void rd(ll &x) {
    rd_integer(x);
}
void rd(i128 &x) {
    rd_integer(x);
}
void rd(uint &x) {
    rd_integer(x);
}
void rd(ull &x) {
    rd_integer(x);
}
void rd(u128 &x) {
    rd_integer(x);
}
void rd(double &x) {
    rd_real(x);
}
void rd(long double &x) {
    rd_real(x);
}

template <class T, class U> void rd(pair<T, U> &p) {
    return rd(p.first), rd(p.second);
}
template <size_t N = 0, typename T> void rd_tuple(T &t) {
    if constexpr (N < std::tuple_size<T>::value) {
        auto &x = std::get<N>(t);
        rd(x);
        rd_tuple<N + 1>(t);
    }
}
template <class... T> void rd(tuple<T...> &tpl) {
    rd_tuple(tpl);
}

template <size_t N = 0, typename T> void rd(array<T, N> &x) {
    for (auto &d : x)
        rd(d);
}
template <class T> void rd(vector<T> &x) {
    for (auto &d : x)
        rd(d);
}

void read() {}
template <class H, class... T> void read(H &h, T &...t) {
    rd(h), read(t...);
}

void wt(const char c) {
    if (por == SZ)
        flush();
    obuf[por++] = c;
}
void wt(const string s) {
    for (char c : s)
        wt(c);
}
void wt(const char *s) {
    size_t len = strlen(s);
    for (size_t i = 0; i < len; i++)
        wt(s[i]);
}

template <typename T> void wt_integer(T x) {
    if (por > SZ - 100)
        flush();
    if (x < 0) {
        obuf[por++] = '-', x = -x;
    }
    int outi;
    for (outi = 96; x >= 10000; outi -= 4) {
        memcpy(out + outi, pre.num[x % 10000], 4);
        x /= 10000;
    }
    if (x >= 1000) {
        memcpy(obuf + por, pre.num[x], 4);
        por += 4;
    } else if (x >= 100) {
        memcpy(obuf + por, pre.num[x] + 1, 3);
        por += 3;
    } else if (x >= 10) {
        int q = (x * 103) >> 10;
        obuf[por] = q | '0';
        obuf[por + 1] = (x - q * 10) | '0';
        por += 2;
    } else
        obuf[por++] = x | '0';
    memcpy(obuf + por, out + outi + 4, 96 - outi);
    por += 96 - outi;
}

template <typename T> void wt_real(T x) {
    ostringstream oss;
    oss << fixed << setprecision(15) << double(x);
    string s = oss.str();
    wt(s);
}

void wt(int x) {
    wt_integer(x);
}
void wt(ll x) {
    wt_integer(x);
}
void wt(i128 x) {
    wt_integer(x);
}
void wt(uint x) {
    wt_integer(x);
}
void wt(ull x) {
    wt_integer(x);
}
void wt(u128 x) {
    wt_integer(x);
}
void wt(double x) {
    wt_real(x);
}
void wt(long double x) {
    wt_real(x);
}

template <class T, class U> void wt(const pair<T, U> val) {
    wt(val.first);
    wt(' ');
    wt(val.second);
}
template <size_t N = 0, typename T> void wt_tuple(const T t) {
    if constexpr (N < std::tuple_size<T>::value) {
        if constexpr (N > 0) {
            wt(' ');
        }
        const auto x = std::get<N>(t);
        wt(x);
        wt_tuple<N + 1>(t);
    }
}
template <class... T> void wt(tuple<T...> tpl) {
    wt_tuple(tpl);
}
template <class T, size_t S> void wt(const array<T, S> val) {
    auto n = val.size();
    for (size_t i = 0; i < n; i++) {
        if (i)
            wt(' ');
        wt(val[i]);
    }
}
template <class T> void wt(const vector<T> val) {
    auto n = val.size();
    for (size_t i = 0; i < n; i++) {
        if (i)
            wt(' ');
        wt(val[i]);
    }
}

void print() {
    wt('\n');
}
template <class Head, class... Tail> void print(Head &&head, Tail &&...tail) {
    wt(head);
    if (sizeof...(Tail))
        wt(' ');
    print(forward<Tail>(tail)...);
}
void __attribute__((destructor)) _d() {
    flush();
}
} // namespace fastio


using fastio::flush;
using fastio::print;
using fastio::read;

inline void first(bool i = true) {
    print(i ? "first" : "second");
}
inline void Alice(bool i = true) {
    print(i ? "Alice" : "Bob");
}
inline void Takahashi(bool i = true) {
    print(i ? "Takahashi" : "Aoki");
}
inline void yes(bool i = true) {
    print(i ? "yes" : "no");
}
inline void Yes(bool i = true) {
    print(i ? "Yes" : "No");
}
inline void No() {
    print("No");
}
inline void YES(bool i = true) {
    print(i ? "YES" : "NO");
}
inline void NO() {
    print("NO");
}
inline void Yay(bool i = true) {
    print(i ? "Yay!" : ":(");
}
inline void Possible(bool i = true) {
    print(i ? "Possible" : "Impossible");
}
inline void POSSIBLE(bool i = true) {
    print(i ? "POSSIBLE" : "IMPOSSIBLE");
}

/**
 * @brief Fast IO
 */

using T = double;
const T eps = 1e-12;
using Point = complex<T>;
using Poly = vector<Point>;
#define X real()
#define Y imag()
template <typename T> inline bool eq(const T &a, const T &b) {
    return fabs(a - b) < eps;
}
bool cmp(const Point &a, const Point &b) {
    auto sub = [&](Point a) {
        return (a.Y < 0 ? -1 : (a.Y == 0 && a.X >= 0 ? 0 : 1));
    };
    if (sub(a) != sub(b))
        return sub(a) < sub(b);
    return a.Y * b.X < a.X * b.Y;
}
struct Line {
    Point a, b, dir;
    Line() {}
    Line(Point _a, Point _b) : a(_a), b(_b), dir(b - a) {}
    Line(T A, T B, T C) {
        if (eq(A, .0)) {
            a = Point(0, C / B), b = Point(1 / C / B);
        } else if (eq(B, .0)) {
            a = Point(C / A, 0), b = Point(C / A, 1);
        } else {
            a = Point(0, C / B), b = Point(C / A, 0);
        }
    }
};
struct Segment : Line {
    Segment() {}
    Segment(Point _a, Point _b) : Line(_a, _b) {}
};
struct Circle {
    Point p;
    T r;
    Circle() {}
    Circle(Point _p, T _r) : p(_p), r(_r) {}
};

istream &operator>>(istream &is, Point &p) {
    T x, y;
    is >> x >> y;
    p = Point(x, y);
    return is;
}
ostream &operator<<(ostream &os, Point &p) {
    os << fixed << setprecision(12) << p.X << ' ' << p.Y;
    return os;
}
Point unit(const Point &a) {
    return a / abs(a);
}
T dot(const Point &a, const Point &b) {
    return a.X * b.X + a.Y * b.Y;
}
T cross(const Point &a, const Point &b) {
    return a.X * b.Y - a.Y * b.X;
}
Point rot(const Point &a, const T &theta) {
    return Point(cos(theta) * a.X - sin(theta) * a.Y,
                 sin(theta) * a.X + cos(theta) * a.Y);
}
Point rot90(const Point &a) {
    return Point(-a.Y, a.X);
}
T arg(const Point &a, const Point &b, const Point &c) {
    double ret = acos(dot(a - b, c - b) / abs(a - b) / abs(c - b));
    if (cross(a - b, c - b) < 0)
        ret = -ret;
    return ret;
}

Point Projection(const Line &l, const Point &p) {
    T t = dot(p - l.a, l.a - l.b) / norm(l.a - l.b);
    return l.a + (l.a - l.b) * t;
}
Point Projection(const Segment &l, const Point &p) {
    T t = dot(p - l.a, l.a - l.b) / norm(l.a - l.b);
    return l.a + (l.a - l.b) * t;
}
Point Reflection(const Line &l, const Point &p) {
    return p + (Projection(l, p) - p) * 2.;
}
int ccw(const Point &a, Point b, Point c) {
    b -= a;
    c -= a;
    if (cross(b, c) > eps)
        return 1; // ccw

    if (cross(b, c) < -eps)
        return -1; // cw

    if (dot(b, c) < 0)
        return 2; // c,a,b

    if (norm(b) < norm(c))
        return -2; // a,b,c

    return 0;      // a,c,b

}
bool isOrthogonal(const Line &a, const Line &b) {
    return eq(dot(a.b - a.a, b.b - b.a), .0);
}
bool isParallel(const Line &a, const Line &b) {
    return eq(cross(a.b - a.a, b.b - b.a), .0);
}
bool isIntersect(const Segment &a, const Segment &b) {
    return ccw(a.a, a.b, b.a) * ccw(a.a, a.b, b.b) <= 0 and
           ccw(b.a, b.b, a.a) * ccw(b.a, b.b, a.b) <= 0;
}
int isIntersect(const Circle &a, const Circle &b) {
    T d = abs(a.p - b.p);
    if (d > a.r + b.r + eps)
        return 4;
    if (eq(d, a.r + b.r))
        return 3;
    if (eq(d, abs(a.r - b.r)))
        return 1;
    if (d < abs(a.r - b.r) - eps)
        return 0;
    return 2;
}
T Dist(const Line &a, const Point &b) {
    Point c = Projection(a, b);
    return abs(c - b);
}
T Dist(const Segment &a, const Point &b) {
    if (dot(a.b - a.a, b - a.a) < eps)
        return abs(b - a.a);
    if (dot(a.a - a.b, b - a.b) < eps)
        return abs(b - a.b);
    return abs(cross(a.b - a.a, b - a.a)) / abs(a.b - a.a);
}
T Dist(const Segment &a, const Segment &b) {
    if (isIntersect(a, b))
        return .0;
    T res = min({Dist(a, b.a), Dist(a, b.b), Dist(b, a.a), Dist(b, a.b)});
    return res;
}
Point Intersection(const Line &a, const Line &b) {
    T d1 = cross(a.b - a.a, b.b - b.a);
    T d2 = cross(a.b - a.a, a.b - b.a);
    if (eq(d1, 0.) and eq(d2, 0.))
        return b.a;
    return b.a + (b.b - b.a) * (d2 / d1);
}
Poly Intersection(const Circle &a, const Line &b) {
    Poly res;
    T d = Dist(b, a.p);
    if (d > a.r + eps)
        return res;
    Point h = Projection(b, a.p);
    if (eq(d, a.r)) {
        res.push_back(h);
        return res;
    }
    Point e = unit(b.b - b.a);
    T ph = sqrt(a.r * a.r - d * d);
    res.push_back(h - e * ph);
    res.push_back(h + e * ph);
    return res;
}
Poly Intersection(const Circle &a, const Segment &b) {
    Line c(b.a, b.b);
    Poly sub = Intersection(a, c);
    double xmi = min(b.a.X, b.b.X), xma = max(b.a.X, b.b.X);
    double ymi = min(b.a.Y, b.b.Y), yma = max(b.a.Y, b.b.Y);
    Poly res;
    rep(i, 0, sub.size()) {
        if (xmi <= sub[i].X + eps and sub[i].X - eps <= xma and
            ymi <= sub[i].Y + eps and sub[i].Y - eps <= yma) {
            res.push_back(sub[i]);
        }
    }
    return res;
}
Poly Intersection(const Circle &a, const Circle &b) {
    Poly res;
    int mode = isIntersect(a, b);
    T d = abs(a.p - b.p);
    if (mode == 4 or mode == 0)
        return res;
    if (mode == 3) {
        T t = a.r / (a.r + b.r);
        res.push_back(a.p + (b.p - a.p) * t);
        return res;
    }
    if (mode == 1) {
        if (b.r < a.r - eps) {
            res.push_back(a.p + (b.p - a.p) * (a.r / d));
        } else {
            res.push_back(b.p + (a.p - b.p) * (b.r / d));
        }
        return res;
    }
    T rc = (a.r * a.r + d * d - b.r * b.r) / d / 2.;
    T rs = sqrt(a.r * a.r - rc * rc);
    if (a.r - abs(rc) < eps)
        rs = 0;
    Point e = unit(b.p - a.p);
    res.push_back(a.p + rc * e + rs * e * Point(0, 1));
    res.push_back(a.p + rc * e + rs * e * Point(0, -1));
    return res;
}
Poly HalfplaneIntersection(vector<Line> &H) {
    sort(ALL(H), [&](Line &l1, Line &l2) { return cmp(l1.dir, l2.dir); });
    auto outside = [&](Line &L, Point p) -> bool {
        return cross(L.dir, p - L.a) < -eps;
    };
    deque<Line> deq;
    int sz = 0;
    rep(i, 0, SZ(H)) {
        while (sz > 1 and
               outside(H[i], Intersection(deq[sz - 1], deq[sz - 2]))) {
            deq.pop_back();
            sz--;
        }
        while (sz > 1 and outside(H[i], Intersection(deq[0], deq[1]))) {
            deq.pop_front();
            sz--;
        }
        if (sz > 0 and fabs(cross(H[i].dir, deq[sz - 1].dir)) < eps) {
            if (dot(H[i].dir, deq[sz - 1].dir) < 0) {
                return {};
            }
            if (outside(H[i], deq[sz - 1].a)) {
                deq.pop_back();
                sz--;
            } else
                continue;
        }
        deq.push_back(H[i]);
        sz++;
    }

    while (sz > 2 and outside(deq[0], Intersection(deq[sz - 1], deq[sz - 2]))) {
        deq.pop_back();
        sz--;
    }
    while (sz > 2 and outside(deq[sz - 1], Intersection(deq[0], deq[1]))) {
        deq.pop_front();
        sz--;
    }
    if (sz < 3)
        return {};
    deq.push_back(deq.front());
    Poly ret;
    rep(i, 0, sz) ret.push_back(Intersection(deq[i], deq[i + 1]));
    return ret;
}

T Area(const Poly &a) {
    T res = 0;
    int n = a.size();
    rep(i, 0, n) res += cross(a[i], a[(i + 1) % n]);
    return fabs(res / 2.);
}
T Area(const Poly &a, const Circle &b) {
    int n = a.size();
    if (n < 3)
        return .0;
    auto rec = [&](auto self, const Circle &c, const Point &p1,
                   const Point &p2) {
        Point va = c.p - p1, vb = c.p - p2;
        T f = cross(va, vb), res = .0;
        if (eq(f, .0))
            return res;
        if (max(abs(va), abs(vb)) < c.r + eps)
            return f;
        if (Dist(Segment(p1, p2), c.p) > c.r - eps)
            return c.r * c.r * arg(vb * conj(va));
        auto u = Intersection(c, Segment(p1, p2));
        Poly sub;
        sub.push_back(p1);
        for (auto &x : u)
            sub.push_back(x);
        sub.push_back(p2);
        rep(i, 0, sub.size() - 1) res += self(self, c, sub[i], sub[i + 1]);
        return res;
    };
    T res = .0;
    rep(i, 0, n) res += rec(rec, b, a[i], a[(i + 1) % n]);
    return fabs(res / 2.);
}
T Area(const Circle &a, const Circle &b) {
    T d = abs(a.p - b.p);
    if (d >= a.r + b.r - eps)
        return .0;
    if (d <= abs(a.r - b.r) + eps) {
        T r = min(a.r, b.r);
        return M_PI * r * r;
    }
    T ath = acos((a.r * a.r + d * d - b.r * b.r) / d / a.r / 2.);
    T res = a.r * a.r * (ath - sin(ath * 2) / 2.);
    T bth = acos((b.r * b.r + d * d - a.r * a.r) / d / b.r / 2.);
    res += b.r * b.r * (bth - sin(bth * 2) / 2.);
    return fabs(res);
}
bool isConvex(const Poly &a) {
    int n = a.size();
    int cur, pre, nxt;
    rep(i, 0, n) {
        pre = (i - 1 + n) % n;
        nxt = (i + 1) % n;
        cur = i;
        if (ccw(a[pre], a[cur], a[nxt]) == -1)
            return 0;
    }
    return 1;
}
int isContained(const Poly &a,
                const Point &b) { // 0:not contain,1:on edge,2:contain

    bool res = 0;
    int n = a.size();
    rep(i, 0, n) {
        Point p = a[i] - b, q = a[(i + 1) % n] - b;
        if (p.Y > q.Y)
            swap(p, q);
        if (p.Y < eps and eps < q.Y and cross(p, q) > eps)
            res ^= 1;
        if (eq(cross(p, q), .0) and dot(p, q) < eps)
            return 1;
    }
    return (res ? 2 : 0);
}
Poly ConvexHull(Poly &a) {
    sort(ALL(a), [](const Point &p, const Point &q) {
        return (eq(p.Y, q.Y) ? p.X < q.X : p.Y < q.Y);
    });
    a.erase(unique(ALL(a)), a.end());
    int n = a.size(), k = 0;
    Poly res(n * 2);
    for (int i = 0; i < n; res[k++] = a[i++]) {
        while (k >= 2 and
               cross(res[k - 1] - res[k - 2], a[i] - res[k - 1]) < eps)
            k--;
    }
    for (int i = n - 2, t = k + 1; i >= 0; res[k++] = a[i--]) {
        while (k >= t and
               cross(res[k - 1] - res[k - 2], a[i] - res[k - 1]) < eps)
            k--;
    }
    res.resize(k - 1);
    return res;
}
T Diam(const Poly &a) {
    int n = a.size();
    int x = 0, y = 0;
    rep(i, 1, n) {
        if (a[i].Y > a[x].Y)
            x = i;
        if (a[i].Y < a[y].Y)
            y = i;
    }
    T res = abs(a[x] - a[y]);
    int i = x, j = y;
    do {
        if (cross(a[(i + 1) % n] - a[i], a[(j + 1) % n] - a[j]) < 0)
            i = (i + 1) % n;
        else
            j = (j + 1) % n;
        chmax(res, abs(a[i] - a[j]));
    } while (i != x or j != y);
    return res;
}
Poly Cut(const Poly &a, const Line &l) {
    int n = a.size();
    Poly res;
    rep(i, 0, n) {
        Point p = a[i], q = a[(i + 1) % n];
        if (ccw(l.a, l.b, p) != -1)
            res.push_back(p);
        if (ccw(l.a, l.b, p) * ccw(l.a, l.b, q) < 0)
            res.push_back(Intersection(Line(p, q), l));
    }
    return res;
}

T Closest(Poly &a) {
    int n = a.size();
    if (n <= 1)
        return 0;
    sort(ALL(a), [&](Point a, Point b) {
        return (eq(a.X, b.X) ? a.Y < b.Y : a.X < b.X);
    });
    Poly buf(n);
    auto rec = [&](auto self, int lb, int rb) -> T {
        if (rb - lb <= 1)
            return (T)INF;
        int mid = (lb + rb) >> 1;
        auto x = a[mid].X;
        T res = min(self(self, lb, mid), self(self, mid, rb));
        inplace_merge(a.begin() + lb, a.begin() + mid, a.begin() + rb,
                      [&](auto p, auto q) { return p.Y < q.Y; });
        int ptr = 0;
        rep(i, lb, rb) {
            if (abs(a[i].X - x) >= res)
                continue;
            rep(j, 0, ptr) {
                auto sub = a[i] - buf[ptr - 1 - j];
                if (sub.Y >= res)
                    break;
                chmin(res, abs(sub));
            }
            buf[ptr++] = a[i];
        }
        return res;
    };
    return rec(rec, 0, n);
}

Circle Incircle(const Point &a, const Point &b, const Point &c) {
    T A = abs(b - c), B = abs(c - a), C = abs(a - b);
    Point p(A * a.X + B * b.X + C * c.X, A * a.Y + B * b.Y + C * c.Y);
    p /= (A + B + C);
    T r = Dist(Line(a, b), p);
    return Circle(p, r);
}
Circle Circumcircle(const Point &a, const Point &b, const Point &c) {
    Line l1((a + b) / 2., (a + b) / 2. + (b - a) * Point(0, 1));
    Line l2((b + c) / 2., (b + c) / 2. + (c - b) * Point(0, 1));
    Point p = Intersection(l1, l2);
    return Circle(p, abs(p - a));
}
Poly tangent(const Point &a, const Circle &b) {
    return Intersection(b, Circle(a, sqrt(norm(b.p - a) - b.r * b.r)));
}
vector<Line> tangent(const Circle &a, const Circle &b) {
    vector<Line> res;
    T d = abs(a.p - b.p);
    if (eq(d, 0.))
        return res;
    Point u = unit(b.p - a.p);
    Point v = u * Point(0, 1);
    for (int t : {-1, 1}) {
        T h = (a.r + b.r * t) / d;
        if (eq(h * h, 1.)) {
            res.push_back(Line(a.p + (h > 0 ? u : -u) * a.r,
                               a.p + (h > 0 ? u : -u) * a.r + v));
        } else if (1 > h * h) {
            Point U = u * h, V = v * sqrt(1 - h * h);
            res.push_back(Line(a.p + (U + V) * a.r, b.p - (U + V) * (b.r * t)));
            res.push_back(Line(a.p + (U - V) * a.r, b.p - (U - V) * (b.r * t)));
        }
    }
    return res;
}

/**
 * @brief Geometry
 */

int main() {
while(1) {
    int N;
    cin >> N;
    if (N == 0) return 0;
    vector<Point> P(N);
    vector<double> L(N);
    double OK = 0.0, NG = 300.0;
    rep(i,0,N) {
        double PX, PY;
        cin >> PX >> PY >> L[i];
        P[i] = Point(PX,PY);
        chmin(NG, L[i]);
    }
    while(NG - OK > eps) {
        double MID = (OK + NG) / 2.0;
        vector<Circle> C(N);
        rep(i,0,N) C[i].p = P[i], C[i].r = sqrt(L[i]*L[i]-MID*MID);
        vector<Point> V;
        rep(i,0,N) V.push_back(C[i].p);
        rep(i,0,N) {
            rep(j,i+1,N) {
                Poly Ret = Intersection(C[i],C[j]);
                for (Point IntP : Ret) V.push_back(IntP);
            }
        }
        bool check = false;
        for (Point A : V) {
            bool check2 = true;
            rep(i,0,N) {
                if (abs(A-C[i].p)>C[i].r+0.0000001) check2 = false;
            }
            if (check2) check = true;
        }
        if (check) OK = MID;
        else NG = MID;
    }
    print(OK);
}
}
accuracy: 1
time_ms: 110
memory_kb: 3724
final_rank: 9

code_snippet: #include <bits/stdc++.h>

using namespace std;

#define rep(i, a, b) for (int i = (int)(a); i < (int)(b); i++)
#define rrep(i, a, b) for (int i = (int)(b)-1; i >= (int)(a); i--)
#define ALL(v) (v).begin(), (v).end()
#define UNIQUE(v) sort(ALL(v)), (v).erase(unique(ALL(v)), (v).end())
#define SZ(v) (int)v.size()
#define MIN(v) *min_element(ALL(v))
#define MAX(v) *max_element(ALL(v))
#define LB(v, x) int(lower_bound(ALL(v), (x)) - (v).begin())
#define UB(v, x) int(upper_bound(ALL(v), (x)) - (v).begin())

using uint = unsigned int;
using ll = long long int;
using ull = unsigned long long;
using i128 = __int128_t;
using u128 = __uint128_t;
const int inf = 0x3fffffff;
const ll INF = 0x1fffffffffffffff;

template <typename T> inline bool chmax(T &a, T b) {
    if (a < b) {
        a = b;
        return 1;
    }
    return 0;
}
template <typename T> inline bool chmin(T &a, T b) {
    if (a > b) {
        a = b;
        return 1;
    }
    return 0;
}
template <typename T, typename U> T ceil(T x, U y) {
    assert(y != 0);
    if (y < 0)
        x = -x, y = -y;
    return (x > 0 ? (x + y - 1) / y : x / y);
}
template <typename T, typename U> T floor(T x, U y) {
    assert(y != 0);
    if (y < 0)
        x = -x, y = -y;
    return (x > 0 ? x / y : (x - y + 1) / y);
}
template <typename T> int popcnt(T x) {
    return __builtin_popcountll(x);
}
template <typename T> int topbit(T x) {
    return (x == 0 ? -1 : 63 - __builtin_clzll(x));
}
template <typename T> int lowbit(T x) {
    return (x == 0 ? -1 : __builtin_ctzll(x));
}

template <class T, class U>
ostream &operator<<(ostream &os, const pair<T, U> &p) {
    os << "P(" << p.first << ", " << p.second << ")";
    return os;
}
template <typename T> ostream &operator<<(ostream &os, const vector<T> &vec) {
    os << "{";
    for (int i = 0; i < vec.size(); i++) {
        os << vec[i] << (i + 1 == vec.size() ? "" : ", ");
    }
    os << "}";
    return os;
}
template <typename T, typename U>
ostream &operator<<(ostream &os, const map<T, U> &map_var) {
    os << "{";
    for (auto itr = map_var.begin(); itr != map_var.end(); itr++) {
        os << "(" << itr->first << ", " << itr->second << ")";
        itr++;
        if (itr != map_var.end())
            os << ", ";
        itr--;
    }
    os << "}";
    return os;
}
template <typename T> ostream &operator<<(ostream &os, const set<T> &set_var) {
    os << "{";
    for (auto itr = set_var.begin(); itr != set_var.end(); itr++) {
        os << *itr;
        ++itr;
        if (itr != set_var.end())
            os << ", ";
        itr--;
    }
    os << "}";
    return os;
}
#ifdef LOCAL
#define show(...) _show(0, #__VA_ARGS__, __VA_ARGS__)
#else
#define show(...) true
#endif
template <typename T> void _show(int i, T name) {
    cerr << '\n';
}
template <typename T1, typename T2, typename... T3>
void _show(int i, const T1 &a, const T2 &b, const T3 &...c) {
    for (; a[i] != ',' && a[i] != '\0'; i++)
        cerr << a[i];
    cerr << ":" << b << " ";
    _show(i + 1, a, c...);
}

#include <unistd.h>

namespace fastio {
static constexpr uint32_t SZ = 1 << 17;
char ibuf[SZ];
char obuf[SZ];
char out[100];
// pointer of ibuf, obuf


uint32_t pil = 0, pir = 0, por = 0;

struct Pre {
    char num[10000][4];
    constexpr Pre() : num() {
        for (int i = 0; i < 10000; i++) {
            int n = i;
            for (int j = 3; j >= 0; j--) {
                num[i][j] = n % 10 | '0';
                n /= 10;
            }
        }
    }
} constexpr pre;

inline void load() {
    memmove(ibuf, ibuf + pil, pir - pil);
    pir = pir - pil + fread(ibuf + pir - pil, 1, SZ - pir + pil, stdin);
    pil = 0;
    if (pir < SZ)
        ibuf[pir++] = '\n';
}

inline void flush() {
    fwrite(obuf, 1, por, stdout);
    por = 0;
}

void rd(char &c) {
    do {
        if (pil + 1 > pir)
            load();
        c = ibuf[pil++];
    } while (isspace(c));
}

void rd(string &x) {
    x.clear();
    char c;
    do {
        if (pil + 1 > pir)
            load();
        c = ibuf[pil++];
    } while (isspace(c));
    do {
        x += c;
        if (pil == pir)
            load();
        c = ibuf[pil++];
    } while (!isspace(c));
}

template <typename T> void rd_real(T &x) {
    string s;
    rd(s);
    x = stod(s);
}

template <typename T> void rd_integer(T &x) {
    if (pil + 100 > pir)
        load();
    char c;
    do
        c = ibuf[pil++];
    while (c < '-');
    bool minus = 0;
    if constexpr (is_signed<T>::value || is_same_v<T, i128>) {
        if (c == '-') {
            minus = 1, c = ibuf[pil++];
        }
    }
    x = 0;
    while ('0' <= c) {
        x = x * 10 + (c & 15), c = ibuf[pil++];
    }
    if constexpr (is_signed<T>::value || is_same_v<T, i128>) {
        if (minus)
            x = -x;
    }
}

void rd(int &x) {
    rd_integer(x);
}
void rd(ll &x) {
    rd_integer(x);
}
void rd(i128 &x) {
    rd_integer(x);
}
void rd(uint &x) {
    rd_integer(x);
}
void rd(ull &x) {
    rd_integer(x);
}
void rd(u128 &x) {
    rd_integer(x);
}
void rd(double &x) {
    rd_real(x);
}
void rd(long double &x) {
    rd_real(x);
}

template <class T, class U> void rd(pair<T, U> &p) {
    return rd(p.first), rd(p.second);
}
template <size_t N = 0, typename T> void rd_tuple(T &t) {
    if constexpr (N < std::tuple_size<T>::value) {
        auto &x = std::get<N>(t);
        rd(x);
        rd_tuple<N + 1>(t);
    }
}
template <class... T> void rd(tuple<T...> &tpl) {
    rd_tuple(tpl);
}

template <size_t N = 0, typename T> void rd(array<T, N> &x) {
    for (auto &d : x)
        rd(d);
}
template <class T> void rd(vector<T> &x) {
    for (auto &d : x)
        rd(d);
}

void read() {}
template <class H, class... T> void read(H &h, T &...t) {
    rd(h), read(t...);
}

void wt(const char c) {
    if (por == SZ)
        flush();
    obuf[por++] = c;
}
void wt(const string s) {
    for (char c : s)
        wt(c);
}
void wt(const char *s) {
    size_t len = strlen(s);
    for (size_t i = 0; i < len; i++)
        wt(s[i]);
}

template <typename T> void wt_integer(T x) {
    if (por > SZ - 100)
        flush();
    if (x < 0) {
        obuf[por++] = '-', x = -x;
    }
    int outi;
    for (outi = 96; x >= 10000; outi -= 4) {
        memcpy(out + outi, pre.num[x % 10000], 4);
        x /= 10000;
    }
    if (x >= 1000) {
        memcpy(obuf + por, pre.num[x], 4);
        por += 4;
    } else if (x >= 100) {
        memcpy(obuf + por, pre.num[x] + 1, 3);
        por += 3;
    } else if (x >= 10) {
        int q = (x * 103) >> 10;
        obuf[por] = q | '0';
        obuf[por + 1] = (x - q * 10) | '0';
        por += 2;
    } else
        obuf[por++] = x | '0';
    memcpy(obuf + por, out + outi + 4, 96 - outi);
    por += 96 - outi;
}

template <typename T> void wt_real(T x) {
    ostringstream oss;
    oss << fixed << setprecision(15) << double(x);
    string s = oss.str();
    wt(s);
}

void wt(int x) {
    wt_integer(x);
}
void wt(ll x) {
    wt_integer(x);
}
void wt(i128 x) {
    wt_integer(x);
}
void wt(uint x) {
    wt_integer(x);
}
void wt(ull x) {
    wt_integer(x);
}
void wt(u128 x) {
    wt_integer(x);
}
void wt(double x) {
    wt_real(x);
}
void wt(long double x) {
    wt_real(x);
}

template <class T, class U> void wt(const pair<T, U> val) {
    wt(val.first);
    wt(' ');
    wt(val.second);
}
template <size_t N = 0, typename T> void wt_tuple(const T t) {
    if constexpr (N < std::tuple_size<T>::value) {
        if constexpr (N > 0) {
            wt(' ');
        }
        const auto x = std::get<N>(t);
        wt(x);
        wt_tuple<N + 1>(t);
    }
}
template <class... T> void wt(tuple<T...> tpl) {
    wt_tuple(tpl);
}
template <class T, size_t S> void wt(const array<T, S> val) {
    auto n = val.size();
    for (size_t i = 0; i < n; i++) {
        if (i)
            wt(' ');
        wt(val[i]);
    }
}
template <class T> void wt(const vector<T> val) {
    auto n = val.size();
    for (size_t i = 0; i < n; i++) {
        if (i)
            wt(' ');
        wt(val[i]);
    }
}

void print() {
    wt('\n');
}
template <class Head, class... Tail> void print(Head &&head, Tail &&...tail) {
    wt(head);
    if (sizeof...(Tail))
        wt(' ');
    print(forward<Tail>(tail)...);
}
void __attribute__((destructor)) _d() {
    flush();
}
} // namespace fastio


using fastio::flush;
using fastio::print;
using fastio::read;

inline void first(bool i = true) {
    print(i ? "first" : "second");
}
inline void Alice(bool i = true) {
    print(i ? "Alice" : "Bob");
}
inline void Takahashi(bool i = true) {
    print(i ? "Takahashi" : "Aoki");
}
inline void yes(bool i = true) {
    print(i ? "yes" : "no");
}
inline void Yes(bool i = true) {
    print(i ? "Yes" : "No");
}
inline void No() {
    print("No");
}
inline void YES(bool i = true) {
    print(i ? "YES" : "NO");
}
inline void NO() {
    print("NO");
}
inline void Yay(bool i = true) {
    print(i ? "Yay!" : ":(");
}
inline void Possible(bool i = true) {
    print(i ? "Possible" : "Impossible");
}
inline void POSSIBLE(bool i = true) {
    print(i ? "POSSIBLE" : "IMPOSSIBLE");
}

/**
 * @brief Fast IO
 */

using T = double;
const T eps = 1e-12;
using Point = complex<T>;
using Poly = vector<Point>;
#define X real()
#define Y imag()
template <typename T> inline bool eq(const T &a, const T &b) {
    return fabs(a - b) < eps;
}
bool cmp(const Point &a, const Point &b) {
    auto sub = [&](Point a) {
        return (a.Y < 0 ? -1 : (a.Y == 0 && a.X >= 0 ? 0 : 1));
    };
    if (sub(a) != sub(b))
        return sub(a) < sub(b);
    return a.Y * b.X < a.X * b.Y;
}
struct Line {
    Point a, b, dir;
    Line() {}
    Line(Point _a, Point _b) : a(_a), b(_b), dir(b - a) {}
    Line(T A, T B, T C) {
        if (eq(A, .0)) {
            a = Point(0, C / B), b = Point(1 / C / B);
        } else if (eq(B, .0)) {
            a = Point(C / A, 0), b = Point(C / A, 1);
        } else {
            a = Point(0, C / B), b = Point(C / A, 0);
        }
    }
};
struct Segment : Line {
    Segment() {}
    Segment(Point _a, Point _b) : Line(_a, _b) {}
};
struct Circle {
    Point p;
    T r;
    Circle() {}
    Circle(Point _p, T _r) : p(_p), r(_r) {}
};

istream &operator>>(istream &is, Point &p) {
    T x, y;
    is >> x >> y;
    p = Point(x, y);
    return is;
}
ostream &operator<<(ostream &os, Point &p) {
    os << fixed << setprecision(12) << p.X << ' ' << p.Y;
    return os;
}
Point unit(const Point &a) {
    return a / abs(a);
}
T dot(const Point &a, const Point &b) {
    return a.X * b.X + a.Y * b.Y;
}
T cross(const Point &a, const Point &b) {
    return a.X * b.Y - a.Y * b.X;
}
Point rot(const Point &a, const T &theta) {
    return Point(cos(theta) * a.X - sin(theta) * a.Y,
                 sin(theta) * a.X + cos(theta) * a.Y);
}
Point rot90(const Point &a) {
    return Point(-a.Y, a.X);
}
T arg(const Point &a, const Point &b, const Point &c) {
    double ret = acos(dot(a - b, c - b) / abs(a - b) / abs(c - b));
    if (cross(a - b, c - b) < 0)
        ret = -ret;
    return ret;
}

Point Projection(const Line &l, const Point &p) {
    T t = dot(p - l.a, l.a - l.b) / norm(l.a - l.b);
    return l.a + (l.a - l.b) * t;
}
Point Projection(const Segment &l, const Point &p) {
    T t = dot(p - l.a, l.a - l.b) / norm(l.a - l.b);
    return l.a + (l.a - l.b) * t;
}
Point Reflection(const Line &l, const Point &p) {
    return p + (Projection(l, p) - p) * 2.;
}
int ccw(const Point &a, Point b, Point c) {
    b -= a;
    c -= a;
    if (cross(b, c) > eps)
        return 1; // ccw

    if (cross(b, c) < -eps)
        return -1; // cw

    if (dot(b, c) < 0)
        return 2; // c,a,b

    if (norm(b) < norm(c))
        return -2; // a,b,c

    return 0;      // a,c,b

}
bool isOrthogonal(const Line &a, const Line &b) {
    return eq(dot(a.b - a.a, b.b - b.a), .0);
}
bool isParallel(const Line &a, const Line &b) {
    return eq(cross(a.b - a.a, b.b - b.a), .0);
}
bool isIntersect(const Segment &a, const Segment &b) {
    return ccw(a.a, a.b, b.a) * ccw(a.a, a.b, b.b) <= 0 and
           ccw(b.a, b.b, a.a) * ccw(b.a, b.b, a.b) <= 0;
}
int isIntersect(const Circle &a, const Circle &b) {
    T d = abs(a.p - b.p);
    if (d > a.r + b.r + eps)
        return 4;
    if (eq(d, a.r + b.r))
        return 3;
    if (eq(d, abs(a.r - b.r)))
        return 1;
    if (d < abs(a.r - b.r) - eps)
        return 0;
    return 2;
}
T Dist(const Line &a, const Point &b) {
    Point c = Projection(a, b);
    return abs(c - b);
}
T Dist(const Segment &a, const Point &b) {
    if (dot(a.b - a.a, b - a.a) < eps)
        return abs(b - a.a);
    if (dot(a.a - a.b, b - a.b) < eps)
        return abs(b - a.b);
    return abs(cross(a.b - a.a, b - a.a)) / abs(a.b - a.a);
}
T Dist(const Segment &a, const Segment &b) {
    if (isIntersect(a, b))
        return .0;
    T res = min({Dist(a, b.a), Dist(a, b.b), Dist(b, a.a), Dist(b, a.b)});
    return res;
}
Point Intersection(const Line &a, const Line &b) {
    T d1 = cross(a.b - a.a, b.b - b.a);
    T d2 = cross(a.b - a.a, a.b - b.a);
    if (eq(d1, 0.) and eq(d2, 0.))
        return b.a;
    return b.a + (b.b - b.a) * (d2 / d1);
}
Poly Intersection(const Circle &a, const Line &b) {
    Poly res;
    T d = Dist(b, a.p);
    if (d > a.r + eps)
        return res;
    Point h = Projection(b, a.p);
    if (eq(d, a.r)) {
        res.push_back(h);
        return res;
    }
    Point e = unit(b.b - b.a);
    T ph = sqrt(a.r * a.r - d * d);
    res.push_back(h - e * ph);
    res.push_back(h + e * ph);
    return res;
}
Poly Intersection(const Circle &a, const Segment &b) {
    Line c(b.a, b.b);
    Poly sub = Intersection(a, c);
    double xmi = min(b.a.X, b.b.X), xma = max(b.a.X, b.b.X);
    double ymi = min(b.a.Y, b.b.Y), yma = max(b.a.Y, b.b.Y);
    Poly res;
    rep(i, 0, sub.size()) {
        if (xmi <= sub[i].X + eps and sub[i].X - eps <= xma and
            ymi <= sub[i].Y + eps and sub[i].Y - eps <= yma) {
            res.push_back(sub[i]);
        }
    }
    return res;
}
Poly Intersection(const Circle &a, const Circle &b) {
    Poly res;
    int mode = isIntersect(a, b);
    T d = abs(a.p - b.p);
    if (mode == 4 or mode == 0)
        return res;
    if (mode == 3) {
        T t = a.r / (a.r + b.r);
        res.push_back(a.p + (b.p - a.p) * t);
        return res;
    }
    if (mode == 1) {
        if (b.r < a.r - eps) {
            res.push_back(a.p + (b.p - a.p) * (a.r / d));
        } else {
            res.push_back(b.p + (a.p - b.p) * (b.r / d));
        }
        return res;
    }
    T rc = (a.r * a.r + d * d - b.r * b.r) / d / 2.;
    T rs = sqrt(a.r * a.r - rc * rc);
    if (a.r - abs(rc) < eps)
        rs = 0;
    Point e = unit(b.p - a.p);
    res.push_back(a.p + rc * e + rs * e * Point(0, 1));
    res.push_back(a.p + rc * e + rs * e * Point(0, -1));
    return res;
}
Poly HalfplaneIntersection(vector<Line> &H) {
    sort(ALL(H), [&](Line &l1, Line &l2) { return cmp(l1.dir, l2.dir); });
    auto outside = [&](Line &L, Point p) -> bool {
        return cross(L.dir, p - L.a) < -eps;
    };
    deque<Line> deq;
    int sz = 0;
    rep(i, 0, SZ(H)) {
        while (sz > 1 and
               outside(H[i], Intersection(deq[sz - 1], deq[sz - 2]))) {
            deq.pop_back();
            sz--;
        }
        while (sz > 1 and outside(H[i], Intersection(deq[0], deq[1]))) {
            deq.pop_front();
            sz--;
        }
        if (sz > 0 and fabs(cross(H[i].dir, deq[sz - 1].dir)) < eps) {
            if (dot(H[i].dir, deq[sz - 1].dir) < 0) {
                return {};
            }
            if (outside(H[i], deq[sz - 1].a)) {
                deq.pop_back();
                sz--;
            } else
                continue;
        }
        deq.push_back(H[i]);
        sz++;
    }

    while (sz > 2 and outside(deq[0], Intersection(deq[sz - 1], deq[sz - 2]))) {
        deq.pop_back();
        sz--;
    }
    while (sz > 2 and outside(deq[sz - 1], Intersection(deq[0], deq[1]))) {
        deq.pop_front();
        sz--;
    }
    if (sz < 3)
        return {};
    deq.push_back(deq.front());
    Poly ret;
    rep(i, 0, sz) ret.push_back(Intersection(deq[i], deq[i + 1]));
    return ret;
}

T Area(const Poly &a) {
    T res = 0;
    int n = a.size();
    rep(i, 0, n) res += cross(a[i], a[(i + 1) % n]);
    return fabs(res / 2.);
}
T Area(const Poly &a, const Circle &b) {
    int n = a.size();
    if (n < 3)
        return .0;
    auto rec = [&](auto self, const Circle &c, const Point &p1,
                   const Point &p2) {
        Point va = c.p - p1, vb = c.p - p2;
        T f = cross(va, vb), res = .0;
        if (eq(f, .0))
            return res;
        if (max(abs(va), abs(vb)) < c.r + eps)
            return f;
        if (Dist(Segment(p1, p2), c.p) > c.r - eps)
            return c.r * c.r * arg(vb * conj(va));
        auto u = Intersection(c, Segment(p1, p2));
        Poly sub;
        sub.push_back(p1);
        for (auto &x : u)
            sub.push_back(x);
        sub.push_back(p2);
        rep(i, 0, sub.size() - 1) res += self(self, c, sub[i], sub[i + 1]);
        return res;
    };
    T res = .0;
    rep(i, 0, n) res += rec(rec, b, a[i], a[(i + 1) % n]);
    return fabs(res / 2.);
}
T Area(const Circle &a, const Circle &b) {
    T d = abs(a.p - b.p);
    if (d >= a.r + b.r - eps)
        return .0;
    if (d <= abs(a.r - b.r) + eps) {
        T r = min(a.r, b.r);
        return M_PI * r * r;
    }
    T ath = acos((a.r * a.r + d * d - b.r * b.r) / d / a.r / 2.);
    T res = a.r * a.r * (ath - sin(ath * 2) / 2.);
    T bth = acos((b.r * b.r + d * d - a.r * a.r) / d / b.r / 2.);
    res += b.r * b.r * (bth - sin(bth * 2) / 2.);
    return fabs(res);
}
bool isConvex(const Poly &a) {
    int n = a.size();
    int cur, pre, nxt;
    rep(i, 0, n) {
        pre = (i - 1 + n) % n;
        nxt = (i + 1) % n;
        cur = i;
        if (ccw(a[pre], a[cur], a[nxt]) == -1)
            return 0;
    }
    return 1;
}
int isContained(const Poly &a,
                const Point &b) { // 0:not contain,1:on edge,2:contain

    bool res = 0;
    int n = a.size();
    rep(i, 0, n) {
        Point p = a[i] - b, q = a[(i + 1) % n] - b;
        if (p.Y > q.Y)
            swap(p, q);
        if (p.Y < eps and eps < q.Y and cross(p, q) > eps)
            res ^= 1;
        if (eq(cross(p, q), .0) and dot(p, q) < eps)
            return 1;
    }
    return (res ? 2 : 0);
}
Poly ConvexHull(Poly &a) {
    sort(ALL(a), [](const Point &p, const Point &q) {
        return (eq(p.Y, q.Y) ? p.X < q.X : p.Y < q.Y);
    });
    a.erase(unique(ALL(a)), a.end());
    int n = a.size(), k = 0;
    Poly res(n * 2);
    for (int i = 0; i < n; res[k++] = a[i++]) {
        while (k >= 2 and
               cross(res[k - 1] - res[k - 2], a[i] - res[k - 1]) < eps)
            k--;
    }
    for (int i = n - 2, t = k + 1; i >= 0; res[k++] = a[i--]) {
        while (k >= t and
               cross(res[k - 1] - res[k - 2], a[i] - res[k - 1]) < eps)
            k--;
    }
    res.resize(k - 1);
    return res;
}
T Diam(const Poly &a) {
    int n = a.size();
    int x = 0, y = 0;
    rep(i, 1, n) {
        if (a[i].Y > a[x].Y)
            x = i;
        if (a[i].Y < a[y].Y)
            y = i;
    }
    T res = abs(a[x] - a[y]);
    int i = x, j = y;
    do {
        if (cross(a[(i + 1) % n] - a[i], a[(j + 1) % n] - a[j]) < 0)
            i = (i + 1) % n;
        else
            j = (j + 1) % n;
        chmax(res, abs(a[i] - a[j]));
    } while (i != x or j != y);
    return res;
}
Poly Cut(const Poly &a, const Line &l) {
    int n = a.size();
    Poly res;
    rep(i, 0, n) {
        Point p = a[i], q = a[(i + 1) % n];
        if (ccw(l.a, l.b, p) != -1)
            res.push_back(p);
        if (ccw(l.a, l.b, p) * ccw(l.a, l.b, q) < 0)
            res.push_back(Intersection(Line(p, q), l));
    }
    return res;
}

T Closest(Poly &a) {
    int n = a.size();
    if (n <= 1)
        return 0;
    sort(ALL(a), [&](Point a, Point b) {
        return (eq(a.X, b.X) ? a.Y < b.Y : a.X < b.X);
    });
    Poly buf(n);
    auto rec = [&](auto self, int lb, int rb) -> T {
        if (rb - lb <= 1)
            return (T)INF;
        int mid = (lb + rb) >> 1;
        auto x = a[mid].X;
        T res = min(self(self, lb, mid), self(self, mid, rb));
        inplace_merge(a.begin() + lb, a.begin() + mid, a.begin() + rb,
                      [&](auto p, auto q) { return p.Y < q.Y; });
        int ptr = 0;
        rep(i, lb, rb) {
            if (abs(a[i].X - x) >= res)
                continue;
            rep(j, 0, ptr) {
                auto sub = a[i] - buf[ptr - 1 - j];
                if (sub.Y >= res)
                    break;
                chmin(res, abs(sub));
            }
            buf[ptr++] = a[i];
        }
        return res;
    };
    return rec(rec, 0, n);
}

Circle Incircle(const Point &a, const Point &b, const Point &c) {
    T A = abs(b - c), B = abs(c - a), C = abs(a - b);
    Point p(A * a.X + B * b.X + C * c.X, A * a.Y + B * b.Y + C * c.Y);
    p /= (A + B + C);
    T r = Dist(Line(a, b), p);
    return Circle(p, r);
}
Circle Circumcircle(const Point &a, const Point &b, const Point &c) {
    Line l1((a + b) / 2., (a + b) / 2. + (b - a) * Point(0, 1));
    Line l2((b + c) / 2., (b + c) / 2. + (c - b) * Point(0, 1));
    Point p = Intersection(l1, l2);
    return Circle(p, abs(p - a));
}
Poly tangent(const Point &a, const Circle &b) {
    return Intersection(b, Circle(a, sqrt(norm(b.p - a) - b.r * b.r)));
}
vector<Line> tangent(const Circle &a, const Circle &b) {
    vector<Line> res;
    T d = abs(a.p - b.p);
    if (eq(d, 0.))
        return res;
    Point u = unit(b.p - a.p);
    Point v = u * Point(0, 1);
    for (int t : {-1, 1}) {
        T h = (a.r + b.r * t) / d;
        if (eq(h * h, 1.)) {
            res.push_back(Line(a.p + (h > 0 ? u : -u) * a.r,
                               a.p + (h > 0 ? u : -u) * a.r + v));
        } else if (1 > h * h) {
            Point U = u * h, V = v * sqrt(1 - h * h);
            res.push_back(Line(a.p + (U + V) * a.r, b.p - (U + V) * (b.r * t)));
            res.push_back(Line(a.p + (U - V) * a.r, b.p - (U - V) * (b.r * t)));
        }
    }
    return res;
}

/**
 * @brief Geometry
 */

int main() {
while(1) {
    int N;
    cin >> N;
    if (N == 0) return 0;
    vector<Point> P(N);
    vector<double> L(N);
    double OK = 0.0, NG = 300.0;
    rep(i,0,N) {
        double PX, PY;
        cin >> PX >> PY >> L[i];
        P[i] = Point(PX,PY);
        chmin(NG, L[i]);
    }
    while(NG - OK > eps) {
        double MID = (OK + NG) / 2;
        vector<Circle> C(N);
        rep(i,0,N) C[i].p = P[i], C[i].r = sqrt(L[i]*L[i]-MID*MID);
        vector<Point> V;
        rep(i,0,N) V.push_back(C[i].p);
        rep(i,0,N) {
            rep(j,i+1,N) {
                Poly Ret = Intersection(C[i],C[j]);
                for (Point IntP : Ret) V.push_back(IntP);
            }
        }
        bool check = false;
        for (Point A : V) {
            bool check2 = true;
            rep(i,0,N) {
                if (sqrt(norm(A-C[i].p))>C[i].r+eps) check2 = false;
            }
            if (check2) check = true;
        }
        if (check) OK = MID;
        else NG = MID;
    }
    print(OK);
}
}
accuracy: 0.5
time_ms: 120
memory_kb: 3728
final_rank: 20

code_snippet: #include <bits/stdc++.h>

#include <algorithm>
#include <cmath>
#include <iostream>
#include <iterator>
#include <utility>
#include <vector>

using Real = long double;
constexpr Real EPS = 1e-10;
const Real PI = std::acos(-1);

int sign(Real x) {
    return x < -EPS ? -1 : x > EPS ? 1 : 0;
}

bool eq(Real lhs, Real rhs) {
    return sign(rhs - lhs) == 0;
}

bool lte(Real lhs, Real rhs) {
    return sign(rhs - lhs) >= 0;
}

bool lt(Real lhs, Real rhs) {
    return sign(rhs - lhs) > 0;
}

bool gte(Real lhs, Real rhs) {
    return lte(rhs, lhs);
}

bool gt(Real lhs, Real rhs) {
    return lt(rhs, lhs);
}

struct Point {
    Real x;
    Real y;
    Point(Real x = 0, Real y = 0): x(x), y(y) {}
    Point& operator+=(Point rhs) {
        this->x += rhs.x;
        this->y += rhs.y;
        return *this;
    }
    Point& operator-=(Point rhs) {
        this->x -= rhs.x;
        this->y -= rhs.y;
        return *this;
    }
    Point& operator*=(Real k) {
        this->x *= k;
        this->y *= k;
        return *this;
    }
    Point& operator/=(Real k) {
        this->x /= k;
        this->y /= k;
        return *this;
    }
    friend Point operator+(Point lhs, Point rhs) {
        return lhs += rhs;
    }
    friend Point operator-(Point lhs, Point rhs) {
        return lhs -= rhs;
    }
    friend Point operator*(Point p, Real k) {
        return p *= k;
    }
    friend Point operator/(Point p, Real k) {
        return p /= k;
    }
    friend Point operator*(Real k, Point p) {
        return p * k;
    }
    friend Point operator/(Real k, Point p) {
        return p / k;
    }
    friend bool operator==(Point lhs, Point rhs) {
        return eq(lhs.x, rhs.x) && eq(lhs.y, rhs.y);
    }
    friend bool operator!=(Point lhs, Point rhs) {
        return !(lhs == rhs);
    }
    friend bool operator<(Point lhs, Point rhs) {
        if (eq(lhs.x, rhs.x)) return lt(lhs.y, rhs.y);
        return lt(lhs.x, rhs.x);
    }
    friend bool operator<=(Point lhs, Point rhs) {
        return lhs == rhs || lhs < rhs;
    }
    friend bool operator>(Point lhs, Point rhs) {
        return rhs < lhs;
    }
    friend bool operator>=(Point lhs, Point rhs) {
        return rhs <= lhs;
    }
    friend std::istream& operator>>(std::istream& is, Point& p) {
        is >> p.x >> p.y;
        return is;
    }
    friend std::ostream& operator<<(std::ostream& os, Point& p) {
        os << p.x << ' ' << p.y;
        return os;
    }
};

using Points = std::vector<Point>;
using Polygon = Points;
using Vector = Point;

Real norm(Vector p) {
    return p.x * p.x + p.y * p.y;
}

Real abs(Vector p) {
    return std::sqrt(norm(p));
}

Real dot(Vector lhs, Vector rhs) {
    return lhs.x * rhs.x + lhs.y * rhs.y;
}

Real cross(Vector lhs, Vector rhs) {
    return lhs.x * rhs.y - lhs.y * rhs.x;
}

int ccw(Point p0, Point p1, Point p2) {
    Vector a = p1 - p0;
    Vector b = p2 - p0;

    if (cross(a, b) > EPS) return 1;

    if (cross(a, b) < -EPS) return -1;

    if (dot(a, b) < 0) return 2;

    if (norm(a) < norm(b)) return -2;

    return 0;
}

struct Circle {
    Real r;
    Point c;
    Circle() {}
    Circle(Real r, Point c): r(r), c(c) {}
};

struct Segment {
    Segment() {}
    Segment(Point p0, Point p1): p0(p0), p1(p1) {}
    Point p0, p1;
};

struct Line {
    Line() {}
    Line(Point p0, Point p1): p0(p0), p1(p1) {}
    explicit Line(Segment s): p0(s.p0), p1(s.p1) {}
    Point p0, p1;
};

Real distance(Point lhs, Point rhs) {
    return abs(rhs - lhs);
}

Real distance(Line l, Point p) {
    return std::abs(cross(l.p1 - l.p0, p - l.p0)) / abs(l.p1 - l.p0);
}

Real distance(Segment s, Point p) {
    if (dot(s.p1 - s.p0, p - s.p0) < 0) {
        return distance(p, s.p0);
    }
    if (dot(s.p0 - s.p1, p - s.p1) < 0) {
        return distance(p, s.p1);
    }
    return distance(Line(s), p);
}

bool intersect(Segment lhs, Segment rhs) {
    return ccw(lhs.p0, lhs.p1, rhs.p0) * ccw(lhs.p0, lhs.p1, rhs.p1) <= 0
           && ccw(rhs.p0, rhs.p1, lhs.p0) * ccw(rhs.p0, rhs.p1, lhs.p1) <= 0;
}

bool intersect(Segment s, Point p) {
    return ccw(s.p0, s.p1, p) == 0;
}

Real distance(Segment lhs, Segment rhs) {
    if (intersect(lhs, rhs)) {
        return Real(0);
    }
    return std::min({distance(lhs, rhs.p0), distance(lhs, rhs.p1), distance(rhs, lhs.p0), distance(rhs, lhs.p1)});
}

bool parallel(Vector lhs, Vector rhs) {
    return eq(cross(lhs, rhs), 0);
}

bool parallel(Segment lhs, Segment rhs) {
    return parallel(lhs.p0 - lhs.p1, rhs.p0 - rhs.p1);
}

bool parallel(Line lhs, Line rhs) {
    return parallel(lhs.p0 - lhs.p1, rhs.p0 - rhs.p1);
}

Point crosspoint(Line lhs, Line rhs) {
    Real a = cross(lhs.p1 - lhs.p0, rhs.p1 - rhs.p0);
    Real b = cross(lhs.p1 - lhs.p0, lhs.p1 - rhs.p0);
    return rhs.p0 + (rhs.p1 - rhs.p0) * b / a;
}

bool intersect(Line l, Segment s) {
    return ccw(l.p0, l.p1, s.p0) * ccw(l.p0, l.p1, s.p1) <= 0;
}

bool intersect(Circle c, Line l) {
    return lte(distance(l, c.c), c.r);
}

bool contain(Circle c, Point p) {
    return lt(distance(c.c, p), c.r);
}

bool intersect(Circle c, Point p) {
    return eq(distance(c.c, p), c.r);
}

bool internal(Circle c, Point p) {
    return lt(distance(c.c, p), c.r);
}

bool intersect(Circle c, Segment s) {
    return lte(distance(s, c.c), c.r);
}

int intersect(Circle lhs, Circle rhs) {
    if (gt(lhs.r, rhs.r)) std::swap(lhs, rhs);
    Real d = distance(lhs.c, rhs.c);
    if (lt(lhs.r + rhs.r, d)) return 4;
    if (eq(lhs.r + rhs.r, d)) return 3;
    if (gt(lhs.r + d, rhs.r)) return 2;
    if (eq(lhs.r + d, rhs.r)) return 1;
    return 0;
}

bool orthogonal(Vector lhs, Vector rhs) {
    return eq(dot(lhs, rhs), 0);
}

bool orthogonal(Segment lhs, Segment rhs) {
    return orthogonal(lhs.p0 - lhs.p1, rhs.p0 - rhs.p1);
}

bool orthogonal(Line lhs, Line rhs) {
    return orthogonal(lhs.p0 - lhs.p1, rhs.p0 - rhs.p1);
}

Point crosspoint(Segment lhs, Segment rhs) {
    Real d0 = distance(Line(lhs.p0, lhs.p1), rhs.p0);
    Real d1 = distance(Line(lhs.p0, lhs.p1), rhs.p1);
    return rhs.p0 + (rhs.p1 - rhs.p0) * (d0 / (d0 + d1));
}

Real arg(Vector p) {
    return std::atan2(p.y, p.x);
}

Vector polar(Real a, Real r) {
    return Point(std::cos(r) * a, std::sin(r) * a);
}

Point rotate(Point p, Real t) {
    Point v = polar(1, t);
    return Point(p.x * v.x - p.y * v.y, p.x * v.y + p.y * v.x);
}

Real angle(Point p0, Point p1, Point p2) {
    Real a = arg(p0 - p1);
    Real b = arg(p2 - p1);
    if (gt(a, b)) std::swap(a, b);
    return std::min(b - a, 2 * PI - (b - a));
}

Points crosspoint(Circle lhs, Circle rhs) {
    Real d = abs(lhs.c - rhs.c);
    if (eq(d, lhs.r + rhs.r)) return {lhs.c + lhs.r * (rhs.c - lhs.c) / d};
    Real a = std::acos((lhs.r * lhs.r + d * d - rhs.r * rhs.r) / (2 * lhs.r * d));
    Real t = arg(rhs.c - lhs.c);
    return {lhs.c + polar(lhs.r, t + a), lhs.c + polar(lhs.r, t - a)};
}

Point projection(Segment s, Point p) {
    Vector a = p - s.p0;
    Vector b = s.p1 - s.p0;
    Real t = dot(a, b) / norm(b);
    return s.p0 + t * b;
}

Point projection(Line l, Point p) {
    Vector a = p - l.p0;
    Vector b = l.p1 - l.p0;
    Real t = dot(a, b) / norm(b);
    return l.p0 + t * b;
}

Point reflection(Segment s, Point p) {
    return p + (projection(s, p) - p) * Real(2);
}

Point reflection(Line l, Point p) {
    return p + (projection(l, p) - p) * Real(2);
}

Points crosspoint(Circle c, Line l) {
    Vector p = projection(l, c.c);
    Real t = std::sqrt(c.r * c.r - norm(c.c - p));
    if (eq(t, 0)) return {p};
    Vector e = (l.p1 - l.p0) / abs(l.p1 - l.p0);
    return {p + t * e, p + -t * e};
}

Real area(Polygon poly) {
    int n = poly.size();
    Real result = 0;
    for (int i = 0; i < n; i++) {
        result += cross(poly[i], poly[(i + 1) % n]);
    }
    return result / 2;
}

Real perimeter(Polygon poly) {
    int n = poly.size();
    Real result = 0;
    for (int i = 0; i < n; i++) {
        result += abs(poly[i] - poly[(i + 1) % n]);
    }
    return result;
}

bool convex(Polygon poly) {
    int n = poly.size();
    for (int i = 0; i < n; i++) {
        if (ccw(poly[i], poly[(i + 1) % n], poly[(i + 2) % n]) == -1) return false;
    }
    return true;
}

int contain(Polygon poly, Point p) {
    int n = poly.size();
    bool parity = false;
    for (int i = 0; i < n; i++) {
        Point a = poly[i] - p;
        Point b = poly[(i + 1) % n] - p;
        if (gt(a.y, b.y)) std::swap(a, b);
        if (lte(a.y, 0) && lt(0, b.y) && lt(cross(a, b), 0)) parity ^= true;
        if (eq(cross(a, b), 0) && lte(dot(a, b), 0)) return 1;
    }
    return (parity ? 2 : 0);
}

Polygon convex_hull(Points points) {
    std::sort(points.begin(), points.end());
    if (points.size() < 3) return points;
    int n = points.size();
    Points lower, upper;
    lower.push_back(points[n - 1]);
    lower.push_back(points[n - 2]);
    upper.push_back(points[0]);
    upper.push_back(points[1]);
    for (int i = n - 3; i >= 0; i--) {
        for (int m = lower.size(); m >= 2 && ccw(lower[m - 2], lower[m - 1], points[i]) >= 0; m--) {
            lower.pop_back();
        }
        lower.push_back(points[i]);
    }
    for (int i = 2; i < n; i++) {
        for (int m = upper.size(); m >= 2 && ccw(upper[m - 2], upper[m - 1], points[i]) >= 0; m--) {
            upper.pop_back();
        }
        upper.push_back(points[i]);
    }
    std::reverse(lower.begin(), lower.end());
    std::copy(std::next(upper.rbegin()), std::prev(upper.rend()), std::back_inserter(lower));
    return lower;
}

Polygon convex_cut(Polygon poly, Line l) {
    int n = poly.size();
    Polygon res;
    for (int i = 0; i < n; i++) {
        Point a = poly[i];
        Point b = poly[(i + 1) % n];
        if (ccw(l.p0, l.p1, a) != -1) res.push_back(a);
        if (ccw(l.p0, l.p1, a) * ccw(l.p0, l.p1, b) == -1) {
            res.push_back(crosspoint(l, Line(a, b)));
        }
    }
    return res;
}

Line bisector(Point p0, Point p1, Point p2) {
    return Line(p1, p1 + polar(1, angle(p0, p1, p2) / 2));
}

Circle incircle(Point p0, Point p1, Point p2) {
    Point c = crosspoint(bisector(p0, p1, p2), bisector(p1, p2, p0));
    Real r = std::abs(2 * area({p0, p1, p2}) / perimeter({p0, p1, p2}));
    return Circle(r, c);
}

Line perpendicular(Line l, Point p) {
    Vector v = l.p1 - l.p0;
    return Line(p, p + Vector(-v.y, v.x));
}

Line perpendicular_bisector(Segment s) {
    return perpendicular(Line(s), (s.p0 + s.p1) / 2);
}

Circle circumscribed_circle(Point p0, Point p1, Point p2) {
    Point c = crosspoint(perpendicular_bisector(Segment(p0, p1)), perpendicular_bisector(Segment(p0, p2)));
    return Circle(distance(p0, c), c);
}

Real area(Circle c) {
    return c.r * c.r * PI;
}

Points tangent(Circle c, Point p) {
    return crosspoint(c, Circle(std::sqrt(norm(c.c - p) - c.r * c.r), p));
}

bool contain(Polygon ps, Segment s) {
    if (contain(ps, s.p0) == 0 || contain(ps, s.p1) == 0) return false;
    int n = ps.size();
    Points cps;
    cps.push_back(s.p0);
    cps.push_back(s.p1);
    for (int i = 0; i < n; i++) {
        Segment t(ps[i], ps[(i + 1) % n]);
        if (parallel(s, t)) continue;
        if (!intersect(s, t)) continue;
        Point cp = crosspoint(s, t);
        if (cp != s.p0 && cp != s.p1 && cp != t.p0 && cp != t.p1) return false;
        cps.push_back(cp);
    }
    std::sort(cps.begin(), cps.end());
    int m = cps.size();
    for (int i = 0; i + 1 < m; i++) {
        if (contain(ps, (cps[i] + cps[i + 1]) / 2) == 0) return false;
    }
    return true;
}

std::pair<Points, Points> lower_and_upper_convex_hull(Polygon ps) {
    auto it = std::max_element(ps.begin(), ps.end());
    Points lower(ps.begin(), it + 1);
    Points upper(it, ps.end());
    upper.push_back(ps.front());
    std::reverse(upper.begin(), upper.end());
    return {lower, upper};
}

Real y(Line l, Real x) {
    if (eq(l.p0.x, l.p1.x)) return std::min(l.p0.y, l.p1.y);
    return x * (l.p1.y - l.p0.y) / (l.p1.x - l.p0.x);
}

Polygon common_polygon(Polygon lhs, Polygon rhs) {
    if (lhs.size() < 3 || rhs.size() < 3) return {};
    auto [ll, lu] = lower_and_upper_convex_hull(lhs);
    auto [rl, ru] = lower_and_upper_convex_hull(rhs);
    constexpr Real INF = 1e18;
    ll.push_back(Point(INF, INF));
    lu.push_back(Point(INF, INF));
    rl.push_back(Point(INF, INF));
    ru.push_back(Point(INF, INF));

    Points lower, upper;
    for (int i = 0, j = 0, k = 0, l = 0;;) {
        if (ll[i] <= lu[j] && ll[i] <= rl[k] && ll[i] <= ru[l]) {
            if (0 < k && 0 < l) {
                if (lte(y(Line(rl[k - 1], rl[k]), ll[i].x), ll[i].y)
                    && lte(ll[i].y, y(Line(ru[l - 1], ru[l]), ll[i].x))) {
                    lower.push_back(ll[i]);
                }
            }
            if (i + 2 < (int)ll.size()) {
                Segment lls(ll[i], ll[i + 1]);
                if (0 < k) {
                    Segment rls(rl[k - 1], rl[k]);
                    if (intersect(lls, rls) && !parallel(lls, rls)) {
                        lower.push_back(crosspoint(lls, rls));
                    }
                }
                if (0 < l) {
                    Segment rus(ru[l - 1], ru[l]);
                    if (intersect(lls, rus) && !parallel(lls, rus)) {
                        lower.push_back(crosspoint(lls, rus));
                        upper.push_back(crosspoint(lls, rus));
                    }
                }
            }
            i++;
            if (i + 1 == (int)ll.size() && j + 1 == (int)lu.size()) break;
        } else if (lu[j] <= ll[i] && lu[j] <= rl[k] && lu[j] <= ru[l]) {
            if (0 < k && 0 < l) {
                if (lte(y(Line(rl[k - 1], rl[k]), lu[j].x), lu[j].y)
                    && lte(lu[j].y, y(Line(ru[l - 1], ru[l]), lu[j].x))) {
                    upper.push_back(lu[j]);
                }
            }
            if (j + 2 < (int)lu.size()) {
                Segment lus(lu[j], lu[j + 1]);
                if (0 < l) {
                    Segment rus(ru[l - 1], ru[l]);
                    if (intersect(lus, rus) && !parallel(lus, rus)) {
                        upper.push_back(crosspoint(lus, rus));
                    }
                }
                if (0 < k) {
                    Segment rls(rl[k - 1], rl[k]);
                    if (intersect(lus, rls) && !parallel(lus, rls)) {
                        lower.push_back(crosspoint(lus, rls));
                        upper.push_back(crosspoint(lus, rls));
                    }
                }
            }
            j++;
            if (i + 1 == (int)ll.size() && j + 1 == (int)lu.size()) break;
        } else if (rl[k] <= ll[i] && rl[k] <= lu[j] && rl[k] <= ru[l]) {
            if (0 < i && 0 < j) {
                if (lte(y(Line(ll[i - 1], ll[i]), rl[k].x), rl[k].y)
                    && lte(rl[k].y, y(Line(lu[j - 1], lu[j]), rl[k].x))) {
                    lower.push_back(rl[k]);
                }
            }
            if (k + 2 < (int)rl.size()) {
                Segment rls(rl[k], rl[k + 1]);
                if (0 < i) {
                    Segment lls(ll[i - 1], ll[i]);
                    if (intersect(rls, lls) && !parallel(rls, lls)) {
                        lower.push_back(crosspoint(rls, lls));
                    }
                }
                if (0 < j) {
                    Segment lus(lu[j - 1], lu[j]);
                    if (intersect(rls, lus) && !parallel(rls, lus)) {
                        lower.push_back(crosspoint(rls, lus));
                        upper.push_back(crosspoint(rls, lus));
                    }
                }
            }
            k++;
            if (k + 1 == (int)rl.size() && l + 1 == (int)ru.size()) break;
        } else {
            if (0 < i && 0 < j) {
                if (lte(y(Line(ll[i - 1], ll[i]), ru[l].x), ru[l].y)
                    && lte(ru[l].y, y(Line(lu[j - 1], lu[j]), ru[l].x))) {
                    upper.push_back(ru[l]);
                }
            }
            if (l + 2 < (int)ru.size()) {
                Segment rus(ru[l], ru[l + 1]);
                if (0 < j) {
                    Segment lus(lu[j - 1], lu[j]);
                    if (intersect(rus, lus) && !parallel(rus, lus)) {
                        upper.push_back(crosspoint(rus, lus));
                    }
                }
                if (0 < i) {
                    Segment lls(ll[i - 1], ll[i]);
                    if (intersect(rus, lls) && !parallel(rus, lls)) {
                        lower.push_back(crosspoint(rus, lls));
                        upper.push_back(crosspoint(rus, lls));
                    }
                }
            }
            l++;
            if (k + 1 == (int)rl.size() && l + 1 == (int)ru.size()) break;
        }
    }
    if (lower.empty() && upper.empty()) return {};
    std::cerr << lhs.size() << ' ' << rhs.size() << ' ' << lower.size() << ' ' << upper.size() << std::endl;

    std::copy(std::next(upper.rbegin()), std::prev(upper.rend()), std::back_inserter(lower));
    return lower;
}

bool intersect(Polygon lhs, Polygon rhs) {
    return lt(0, area(common_polygon(lhs, rhs)));
}

using ll = long long;

#define rep(i, l, r) for (ll i = (l); i < (r); i++)
#define rrep(i, r, l) for (ll i = (r); i-- > (l);)
template <class T, class U>
bool chmin(T& lhs, U rhs) {
    return lhs > rhs ? (lhs = rhs, true) : false;
}
template <class T, class U>
bool chmax(T& lhs, U rhs) {
    return lhs < rhs ? (lhs = rhs, true) : false;
}
using namespace std;

struct Sphere {
    Real r;
    Point c;
    Sphere() {}
    Sphere(Real r, Point c): r(r), c(c) {}
};

int solve() {
    int n;
    cin >> n;
    if (n == 0) return 1;
    vector<Sphere> ss;
    rep(i, 0, n) {
        Sphere s;
        cin >> s.c >> s.r;
        ss.push_back(s);
    }

    auto satisfy = [&](Real h) {
        vector<Circle> cs;
        rep(i, 0, n) {
            if (lt(ss[i].r, h)) {
                return false;
            }
            Real r = sqrt(max(Real(0), ss[i].r * ss[i].r - h * h));
            cs.push_back(Circle(r, ss[i].c));
        }

        vector<bool> removed(n);
        int valid = n;
        rep(i, 0, n) rep(j, 0, n) if (i != j) {
            if (intersect(cs[i], cs[j]) == 0 && gt(cs[i].r, cs[j].r)) {
                removed[i] = true;
                valid--;
                break;
            }
        }

        Points cps;
        rep(i, 0, n) if (!removed[i]) {
            auto a = cs[i];
            rep(j, i + 1, n) if (!removed[i]) {
                auto b = cs[j];
                if (intersect(a, b) != 0 && intersect(a, b) != 4) {
                    auto temp = crosspoint(a, b);
                    copy(temp.begin(), temp.end(), back_inserter(cps));
                }
            }
        }

        for (auto cp: cps) {
            bool ok = true;
            for (auto c: cs) {
                ok &= contain(c, cp) || intersect(c, cp);
            }
            if (ok) return true;
        }

        return valid == 1;
    };

    Real ok = 0;
    Real ng = 500;
    const int LOOP = 100;
    rep(loop, 0, LOOP) {
        Real key = (ok + ng) / 2;
        (satisfy(key) ? ok : ng) = key;
    }
    cout << fixed << setprecision(10);
    cout << ok << endl;
    return 0;
}

int main() {
    while (!solve())
        ;
}
accuracy: 1
time_ms: 250
memory_kb: 3796
final_rank: 17

code_snippet: #include <bits/stdc++.h>
using namespace std;
using ll = long long;
using vll = vector<ll>;
using vvll = vector<vll>;
using vvvll = vector<vvll>;
using vb = vector<bool>;
using vvb = vector<vb>;
using vvvb = vector<vvb>;
#define all(A) A.begin(),A.end()
#define rep(i, n) for (int i = 0; i < (int) (n); i++)
template<class T>
void chmax(T& p, T q) { if (p < q)p = q; };

ll N;
using point = pair<double, double>;
const double eps = 1e-6;

pair<point, point> CC(point P, double R, point Q, double S) {
    Q.first -= P.first;
    Q.second -= P.second;
    double a = Q.first * Q.first + Q.second * Q.second + R * R - S * S;
    a /= 2.0;
    double d = Q.first * Q.first + Q.second * Q.second;
    double b = sqrt(d * R * R - a * a);
    point res1, res2;
    res1 = { (a * Q.first + Q.second * b) / d,(a * Q.second - Q.first * b) / d };
    res2 = { (a * Q.first - Q.second * b) / d,(a * Q.second + Q.first * b) / d };
    res1.first += P.first;
    res2.first += P.first;
    res1.second += P.second;
    res2.second += P.second;
    return { res1,res2 };
}

void solve() {
    vector<point> P(N);
    vector<double> R(N);
    rep(i, N)cin >> P[i].first >> P[i].second >> R[i];
    double down = 0.5, up = 305.0;
    rep(_, 100) {
        double M = (up + down) / 2.0;
        bool OK = 1;
        vector<double> T(N);
        rep(i, N) {
            if (R[i] * R[i] < M * M) {
                OK = 0;
                break;
            }
            T[i] = sqrt(R[i] * R[i] - M * M);
        }
        vector<point> CP;
        rep(i, N)CP.push_back(P[i]);
        rep(i, N)rep(j, i) {
            double dx = P[i].first - P[j].first;
            double dy = P[i].second - P[j].second;
            double dr = T[i] + T[j];
            if (dx * dx + dy * dy >= dr * dr) {
                continue;
            }
            auto [p1, p2] = CC(P[i], T[i], P[j], T[j]);
            CP.push_back(p1);
            CP.push_back(p2);
        }
        bool EG = 0;
        for (auto p : CP) {
            ll cnt = 0;
            rep(i, N) {
                double dx = p.first - P[i].first;
                double dy = p.second - P[i].second;
                if (dx * dx + dy * dy <= T[i] * T[i] + eps)cnt++;
            }
            if (cnt == N)EG = 1;
        }
        if (!EG)OK = 0;
        if (OK)down = M;
        else up = M;
    }
    cout << fixed << setprecision(15) << up << endl;

}

int main() {
    cin.tie(nullptr);
    ios::sync_with_stdio(false);

    while (cin >> N) {
        if (N == 0)return 0;
        solve();
    }

}
accuracy: 1
time_ms: 40
memory_kb: 3644
final_rank: 6

code_snippet: #include <bits/stdc++.h>

using R = long double;
using Interval = std::pair<R, R>;

const R EPS{1e-12l};
const R PI{acosl(-1.0l)};
bool Negative(R v) {
    return v < -EPS;
}
bool Positive(R v) {
    return v > EPS;
}
bool Zero(R v) {
    return !Negative(v) and !Positive(v);
}
bool Smaller(R a, R b) {
    return Negative(a - b);
}
bool Bigger(R a, R b) {
    return Positive(a - b);
}
bool Equal(R a, R b) {
    return !Smaller(a, b) and !Bigger(a, b);
}

R Square(R v) {
    return Zero(v) ? 0.0l : v * v;
}

struct Point {
    R x, y;
    Point() = default;
    Point(R x, R y) : x{x}, y{y} {}
    Point(const Point& p) : x{p.x}, y{p.y} {}
    R normSquare() const {
        return Square(x) + Square(y);
    }
    R norm() const {
        return sqrtl(normSquare());
    }
    Point normalized() const {
        assert(!Zero(x) or !Zero(y));
        R v{norm()};
        return Point{x / v, y / v};
    }
    Point rotatedByRad(R rad) const {
        return Point{
            x * cosl(rad) - y * sinl(rad),
            x * sinl(rad) + y * cosl(rad)
        };
    }
    Point rotaedByArc(R arc) const {
        return rotatedByRad((arc * PI) / 180.0l);
    }
    friend std::ostream& operator<<(std::ostream& os, const Point& p) {
        os << '(' << p.x << ',' << p.y << ')';
        return os;
    }
    friend Point operator*(const Point& p, R v) {
        return Point{p.x * v, p.y * v};
    }
    friend Point operator+(const Point& p, const Point& q) {
        return Point{p.x + q.x, p.y + q.y};
    }
    friend Point operator-(const Point& p, const Point& q) {
        return Point{p.x - q.x, p.y - q.y};
    }
    friend R DistanceSquare(const Point& p, const Point& q) {
        Point diff{p - q};
        return diff.normSquare();
    }
    friend R Distance(const Point& p, const Point& q) {
        return sqrtl(DistanceSquare(p, q));
    }
};

struct Circle {
    Point p;
    R r;
    Circle() = default;
    Circle(R x, R y, R r) : p{x, y}, r{r} {}
    R x() const { return p.x; };
    R y() const { return p.y; }
    friend int NumberCommonTangent(const Circle& c0, const Circle& c1) {
        R dist{DistanceSquare(c0.p, c1.p)};
        R down{Square(std::abs(c0.r - c1.r))};
        if (Smaller(dist, down)) return 0;
        if (Equal(dist, down)) return 1;
        R up{Square(c0.r + c1.r)};
        if (Smaller(dist, up)) return 2;
        if (Equal(dist, up)) return 3;
        return 4;
    }
    bool contains(const Circle& c) const {
        return Bigger(r, c.r) and NumberCommonTangent(*this, c) == 0;
    }
    friend bool Intersect(const Circle& c0, const Circle& c1) {
        int num{NumberCommonTangent(c0, c1)};
        return 0 < num and num < 4;
    }
    friend std::vector<Point> CrossPoint(const Circle& l, const Circle& r) {
        assert(Intersect(l, r));
        R d{Distance(l.p, r.p)};
        R cosine{(Square(l.r) + Square(d) - Square(r.r)) / (2.0l * l.r * d)};
        R rc{l.r * cosine};
        R rs{sqrtl(Square(l.r) - Square(rc))};
        Point lr{Point{r.p - l.p}.normalized()};
        Point h{l.p + lr * rc};
        std::vector<Point> res;
        res.push_back(h + lr.rotaedByArc(90.0l) * rs);
        res.push_back(h + lr.rotaedByArc(-90.0l) * rs);
        return res;
    }
};

bool HasCommonInterval(const std::vector<Interval>& I) {
    R l{-9e18}, r{9e18};
    for (auto [L, R] : I) {
        l = std::max(l, L);
        r = std::min(r, R);
    }
    return !Bigger(l, r);
}

bool HasCommonArea(const std::vector<Circle>& C) {
    std::vector<bool> ignore(C.size());
    for (int i{} ; i < (int)C.size() ; i++) {
        for (int j{} ; j < (int)C.size() ; j++) {
            if (i == j) continue;
            if (C[i].contains(C[j])) {
                ignore[i] = true;
            }
        }
    }
    int cnt{};
    for (int i{} ; i < (int)C.size() ; i++) {
        if (!ignore[i]) {
            // std::cout << C[i].p << ' ' << C[i].r << std::endl;
            cnt++;
        }
    }
    if (cnt <= 1) return true;
    for (int i{} ; i < (int)C.size() ; i++) {
        if (ignore[i]) continue;
        for (int j{i + 1} ; j < (int)C.size() ; j++) {
            if (ignore[j]) continue;
            if (!Intersect(C[i], C[j])) return false;
            for (const auto& p : CrossPoint(C[i], C[j])) {
                // std::cout << p << std::endl;
                std::vector<Interval> I;
                bool ok{true};
                for (int k{} ; k < (int)C.size() ; k++) {
                    R d{Square(C[k].y() - p.y)};
                    if (Bigger(d, Square(C[k].r))) {
                        ok = false;
                    }
                    else {
                        R len{sqrtl(Square(C[k].r) - d)};
                        I.emplace_back(C[k].x() - len, C[k].x() + len);
                    }
                }
                if (ok) ok &= HasCommonInterval(I);
                if (ok) return true;
            }
        }
    }
    return false;
}

bool solve() {
    int N;
    std::cin >> N;
    if (N == 0) return false;
    std::vector<R> X(N), Y(N), L(N);
    for (int i{} ; i < N ; i++) {
        std::cin >> X[i] >> Y[i] >> L[i];
    }
    if (N == 1) {
        std::cout << L[0] << '\n';
        return true;
    }
    auto f{[&](R z) -> bool {
        std::vector<Circle> C(N);
        for (int i{} ; i < N ; i++) {
            if (!Smaller(z, L[i])) return false;
            C[i] = Circle{X[i], Y[i], sqrtl(Square(L[i]) - Square(z))};
        }
        return HasCommonArea(C);
    }};
    // std::cout << f(0) << std::endl;
    // return true;
    R ok{1.0l}, ng{301.0l};
    for (int _{} ; _ < 40 ; _++) {
        R mid{(ok + ng) / 2};
        if (f(mid)) ok = mid;
        else ng = mid;
    }
    std::cout << ok << '\n';
    return true;
}

int main() {
    std::cin.tie(nullptr)->sync_with_stdio(false);
    std::cout << std::fixed << std::setprecision(8);
    while (solve()) ;
}
accuracy: 1
time_ms: 40
memory_kb: 3648
final_rank: 7

code_snippet: #include <iostream>
#include <vector>
#include <complex>
#include <cstdio>
#include <cmath>

using namespace std;

const double EPS = 1e-10;

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

double cross(P a, P b) { return imag(conj(a)*b); }

bool containPoint(const circle& c, const P& p){
    double dist = abs(c.first-p);
    return dist < c.second+EPS;
}

bool crossCircle(const circle& c1, const circle& c2){
    double r1 = c1.second;
    double r2 = c2.second;
    double d = abs(c1.first-c2.first);
    if(d<r1||d<r2)
        return d-abs(r1-r2)>EPS;
    return r1+r2-d>-EPS;
}

void crossPoint(vector<P> &res, const circle& c1, const circle& c2){
    double r1 = c1.second;
    double r2 = c2.second;
    double r3 = abs(c1.first-c2.first);
    double rc = (r3*r3+r1*r1-r2*r2)/(2*r3);
    double rs = sqrt(r1*r1-rc*rc);
    P dif = (c2.first-c1.first)/r3;
    res.push_back(c1.first+dif*P(rc, rs));
    res.push_back(c1.first+dif*P(rc,-rs));
}

bool valid(const vector<circle>& vc){
    vector<P> vp;
    for(int i=0;i<vc.size();i++){
        vp.push_back(vc[i].first);
        for(int j=i+1;j<vc.size();j++){
            if(crossCircle(vc[i], vc[j]))
                crossPoint(vp, vc[i], vc[j]);
        }
    }
    for(int i=0;i<vp.size();i++){
        bool ok = true;
        for(int j=0;j<vc.size();j++)
            if(!containPoint(vc[j], vp[i])) ok = false;
        if(ok) return true;
    }
    return false;
}

int main(){
    int n;
    int x[10], y[10], l[10]; 
    while(cin >> n &&  n){
        int minL = 100000;
        for(int i=0;i<n;i++){
            cin >> x[i] >> y[i] >> l[i];
            minL = min(minL, l[i]);
        }
        double low = 1.0, high = minL;
        for(int i=0;i<200;i++){
            double mid = 0.5*(low+high);
            vector<circle> vc;
            for(int j=0;j<n;j++){
                double r = sqrt(l[j]*l[j]-mid*mid);
                vc.push_back(make_pair(P(x[j], y[j]), r));
            }
            if(valid(vc)) low  = mid;
            else          high = mid;
        }
        printf("%.8lf\n", 0.5*(low+high));
    }
}
accuracy: 1
time_ms: 370
memory_kb: 3272
final_rank: 2

code_snippet: #include <bits/stdc++.h>
using namespace std;
#define ALL(v) v.begin(),v.end()
#define dbg(x) cerr << #x << ": " << x << endl
template<class F, class S>
ostream& operator<<(ostream& os, pair<F,S> p) {
    os << '(' << p.first << ',' << p.second << ')';
    return os;
}
template<class Iter>
void print(Iter beg, Iter end) {
    for (auto itr = beg; itr != end; ++itr) {
        cerr << *itr << ' ';
    }
    cerr << '\n';
}
using ld = long double;
const ld EPS = 1e-7;
using Point = pair<ld,ld>;
Point operator+(const Point& a, const Point& b) {
    return {a.first+b.first, a.second+b.second};
}
Point operator-(const Point& a, const Point& b) {
    return {a.first-b.first, a.second-b.second};
}
ld abs(Point a) {
    return sqrtl(a.first*a.first + a.second*a.second);
}

struct Circle {
    Point c;
    ld r;
};
ld ar(Point p) {
    return atan2(p.second, p.first);
}
Point polar(ld a, ld r) {
    return Point(cos(r) * a, sin(r) * a);
}
vector<Point> getCrossPoints(Circle c1, Circle c2) {
    ld d = abs(c1.c - c2.c);
    if (d > c1.r + c2.r) return vector<Point>();
    if (!((d + c1.r >= c2.r) && (d + c2.r >= c1.r) && (c1.r + c2.r >= d))) return vector<Point>();
    ld a = acos((c1.r * c1.r + d * d - c2.r * c2.r) / (2 * c1.r * d));
    ld t = ar(c2.c - c1.c);
    vector<Point> v;
    v.push_back(c1.c + polar(c1.r, t + a));
    v.push_back(c1.c + polar(c1.r, t - a));
    return v;
}

int main() {
    while (true) {
        int n;
        cin >> n;
        if (n == 0) break;
        vector<int> x(n), y(n), l(n);
        for (int i = 0; i < n; ++i) {
            cin >> x[i] >> y[i] >> l[i];
        }
        auto isOk = [&](ld mid) -> bool {
            vector<Circle> circle(n);
            for (int i = 0; i < n; ++i) {
                ld z = l[i]*l[i] - mid*mid;
                if (z < 0) return false;
                circle[i] = {Point(x[i], y[i]), sqrtl(z)};
            }
            vector<Point> points;
            for (int i = 0; i < n; ++i) {
                for (int j = i+1; j < n; ++j) {
                    for (auto y : getCrossPoints(circle[i], circle[j])) {
                        points.push_back(y);
                    }
                }
            }
            for (int i = 0; i < n; ++i) {
                points.push_back({x[i], y[i]});
            }
            for (auto point : points) {
                bool ok = true;
                for (int i = 0; i < n; ++i) {
                    auto d = abs(point - Point(x[i], y[i]));
                    if (d > circle[i].r + EPS) {
                        ok = false;
                        break;
                    }
                }
                if (ok) return true;
            }
            return false;
        };
        ld ok = 0;
        ld ng = *max_element(ALL(l)) + 1;
        for (int t = 0; t < 100; ++t) {
            ld mid = (ok + ng) / 2;
            // cerr << mid << ' ' << isOk(mid) << '\n';
            (isOk(mid) ? ok : ng) = mid;
        }
        cout << fixed << setprecision(20) << ok << '\n';
    }
}
accuracy: 1
time_ms: 360
memory_kb: 3924
final_rank: 18