#include<bits/stdc++.h>
using namespace std;
typedef complex<double> P;
#define EPS (1e-10)    //誤差
const double INF = 10000;

struct cercle{
    P point;
    double r;
};

pair<P, P> cc_cross(cercle c1, cercle c2){
    double d = abs(c1.point - c2.point);
    double rc = (d * d + c1.r * c1.r - c2.r * c2.r) / (2 * d);
    double rs = sqrt(c1.r * c1.r - rc * rc);
    P diff = (c2.point - c1.point) / d;
    return make_pair(c1.point + diff * P(rc, rs), c1.point + diff * P(rc, -rs));
}

bool C(vector<cercle> vec){

    int n = (int)vec.size();

    //調べる点の集合
    vector<P> point_set;
    
    //中点をpoint_setに追加
    for(int i = 0; i < n; i++){
        //cout << "add" << endl;
        point_set.push_back(vec[i].point);
    }

    //任意の二頂点間の交点をpoint_setに追加
    for(int i = 0; i < n; i++){
        for(int j = i + 1; j < n; j++){

            double d = abs(vec[i].point - vec[j].point);
            
            if(abs(vec[i].r - vec[j].r) <= d && d <= vec[i].r + vec[j].r){
                //cout << "ADD" << endl;
                pair<P, P> sec = cc_cross(vec[i], vec[j]);
                //cout << "f" << endl;
                //point_set.push_back(sec.first);
                //cout << "f" << endl;
                point_set.push_back(sec.first);
                //cout << "s" << endl;
                point_set.push_back(sec.second);
                //cout << sec.first << " " << sec.second << endl;
            }
        }
    }

    //point_setを全てためす
    bool flag = false;
    //cout << point_set.size() << endl;
    for(auto po : point_set){

        //cout << "po" << endl;
        //cout << po << endl;

        bool ok = true;
        for(int i = 0; i < n; i++){
            double d = abs(po - vec[i].point);
            if(d > vec[i].r + 1e-9){
                ok = false;
                i += n;
            }
        }

        //cout << "ok " << ok << endl;
        if(ok){
            flag = true;
            break;
        }

    }

    //cout << "flag" << flag << endl;
    return flag;
}

int main(){

    while(1){

        int n; cin >> n;
        if(!n) break;

        vector<double> x(n);
        vector<double> y(n);
        vector<double> l(n);
        double ub = INF;
        for(int i = 0; i < n; i++){
            cin >> x[i] >> y[i] >> l[i];
            ub = min(ub, l[i]);
        }

        double lb = 0;
        
        //cout << lb << " " << ub << endl;

        for(int i = 0; i < 100; i++){
            double d = (lb + ub) / 2;

            vector<cercle> vec(n);            
            for(int i = 0; i < n; i++){

                vec[i].point = P(x[i], y[i]);
                vec[i].r = sqrt(l[i] * l[i] - d * d);

            }

            //cout << d << endl;
            for(int i = 0; i < n; i++){

                //cout << vec[i].point.real() << " " << vec[i].point.imag() << " " << vec[i].r << endl;
            }

            //cout << d << " " << C(vec) << endl;

            if(C(vec)) lb = d;
            else ub = d;
        }
        
        /*double d = 17.0;
        cout << d << endl;
        vector<cercle> vec(n);            
        for(int i = 0; i < n; i++){

            vec[i].point = P(x[i], y[i]);
            vec[i].r = sqrt(l[i] * l[i] - d * d);
        
        }

        for(int i = 0; i < n; i++){
            cout << vec[i].point.real() << " " << vec[i].point.imag() << " " << vec[i].r << endl;
        }

        cout << C(vec) << endl;
        */
        printf("%f\n", lb);
    }


    return 0;
}


Measured memory_bytes: 3340