#include <iostream>
#include <vector>
#include <cmath>
#define repeat(i,n) for (int i = 0; (i) < (n); ++(i))
#define repeat_from(i,m,n) for (int i = (m); (i) < (n); ++(i))
using namespace std;
const double eps = 1e-7;

double sq(double x) { return x * x; }

struct point {
    double x, y;
};
point operator + (point const & a, point const & b) { return { a.x + b.x, a.y + b.y }; }
point operator - (point const & a, point const & b) { return { a.x - b.x, a.y - b.y }; }
double   dot(point const & a, point const & b) { return a.x * b.x + a.y * b.y; }
double cross(point const & a, point const & b) { return a.x * b.y - a.y * b.x; }
double length_squared(point const & a) { return dot(a,a); }
double length(point const & a) { return sqrt(length_squared(a)); }
point operator * (double a, point const & b) { return { a * b.x, a * b.y }; }
point normalize(point const & a) { return (1 / length(a)) * a; }
point rot90( point const & a) { return { - a.y, a.x }; }
point rot270(point const & a) { return { a.y, - a.x }; }
ostream & operator << (ostream & output, point const & a) {
    return output << "( " << a.x << ", " << a.y << " )";
}

struct circle {
    point p;
    double r;
};
vector<point> cross_point(circle const & a, circle const & b) {
    point d = b.p - a.p;
    double r = min(a.r, b.r);
    double R = max(a.r, b.r);
    if (length(d) + r <= R) {
        // ???????????????
        return vector<point>();
    } else if (r + R < length(d)) {
        // ????????????
        return vector<point>();
    } else {
        // 1,2?????§
        double x = ( sq(a.r) - sq(b.r) + length_squared(d) ) / ( 2 * length(d) );
        double y = sqrt( sq(a.r) - sq(x) );
        point e = normalize(d);
        point h = x * e + a.p;
        vector<point> result(2);
        result[0] = h + y * rot90(e);
        result[1] = h + y * rot270(e);
        return result;
    }
}
// ?????¨??? ????????????
bool is_include(circle const & a, point const & b) {
    return length_squared(b - a.p) <= sq(a.r) + eps;
}
// ?????¨??? ?????\??????
bool is_include(circle a, circle const & b) {
    a.r += b.r;
    return is_include(a, b.p);
}
bool has_intersection(circle const & a, circle const & b) {
    return length(a.p - b.p) <= a.r + b.r + eps;
}

// ??±?????¨????????????
bool has_intersection(vector<circle> const & cs) {
    int n = cs.size();
    vector<point> ps;
    repeat (i,n) {
        ps.push_back(cs[i].p);
        repeat_from (j,i+1,n) {
            if (not has_intersection(cs[i], cs[j])) return false;
            for (auto p : cross_point(cs[i], cs[j])) {
                ps.push_back(p);
            }
        }
    }
    for (auto p : ps) {
        bool ok = true;
        repeat (k,n) {
            ok = ok and is_include(cs[k], p);
        }
        if (ok) return true;
    }
    return false;
}

double solve(vector<circle> const & cs) {
    int n = cs.size();
    double l = 1;
    double r = 300+1;
    repeat (trial,400) {
        double m = (l + r) / 2;
        vector<circle> ds(n);
        repeat (i,n) {
            ds[i].p = cs[i].p;
            if (cs[i].r < m) {
                r = m;
                goto next;
            }
            ds[i].r = sqrt( sq(cs[i].r) - sq(m) );
        }
        (has_intersection(ds) ? l : r) = m;
next: ;
    }
    return l;
}

int main() {
    while (true) {
        int n; cin >> n;
        if (n == 0) break;
        vector<circle> cs(n);
        repeat (i,n) cin >> cs[i].p.x >> cs[i].p.y >> cs[i].r;
        printf("%.9lf\n", solve(cs));
    }
    return 0;
}

Measured memory_bytes: 1276