#include <iostream>
#include <cstring>
#include <cstdio>
#include <string>
#include <sstream>
#include <vector>
#include <deque>
#include <queue>
#include <stack>
#include <set>
#include <map>
#include <algorithm>
#include <cmath>
  
using namespace std;
  
#define EPS 1e-9
  
struct point{
    double x, y;
    point(){x = 0;y = 0;}
    point(double a, double b) : x(a), y(b) {}
} P[11], cP[11],nP[11];
   
double dis(point &p1,point &p2){
    return sqrt((p1.x-p2.x)*(p1.x-p2.x)+(p1.y-p2.y)*(p1.y-p2.y));
} 
point intersection(point &u1,point &u2,point &v1,point &v2){
    point ret=u1;
    double t=((u1.x-v1.x)*(v1.y-v2.y)-(u1.y-v1.y)*(v1.x-v2.x))
    /((u1.x-u2.x)*(v1.y-v2.y)-(u1.y-u2.y)*(v1.x-v2.x));
    ret.x+=(u2.x-u1.x)*t;
    ret.y+=(u2.y-u1.y)*t;
    return ret;
}
   
void intersection_line_circle(point c, double r,point &l1,point &l2,point& p1,point&p2){
    point p=c;
    double t;
    p.x+=l1.y-l2.y;
    p.y+=l2.x-l1.x;
    p=intersection(p,c,l1,l2);
    t=sqrt(r*r-dis(p,c)*dis(p,c))/dis(l1,l2);
    p1.x=p.x+(l2.x-l1.x)*t;
    p1.y=p.y+(l2.y-l1.y)*t;
    p2.x=p.x-(l2.x-l1.x)*t;
    p2.y=p.y-(l2.y-l1.y)*t;
}
   
void intersection_circle_circle(point c1, double r1,point c2,double r2,point& p1, point& p2){
    point u,v;
    double t;
    t=(1+(r1*r1-r2*r2)/dis(c1,c2)/dis(c1,c2))/2;
    u.x=c1.x+(c2.x-c1.x)*t;
    u.y=c1.y+(c2.y-c1.y)*t;
    v.x=u.x+c1.y-c2.y;
    v.y=u.y-c1.x+c2.x;
    intersection_line_circle(c1,r1,u,v,p1,p2);
}
  
int n;
double x[11],y[11],r[11];
double cx[11],cy[11];
double sqr(double x) { return x*x; }
  
point rot(point p, double a) {
    point ret;
    double C = cos(a), S = sin(a);
    ret.x = p.x*C - p.y*S;
    ret.y = p.x*S + p.y*C;
    return ret;
}
  
double aaa[1111111];
int cs=0;
  
int main() {
#ifdef LOCAL
    freopen("input.txt","r",stdin);
#endif
    while(1) {
        scanf("%d",&n); 
        if(n==0) break;
        for(int i=0;i<n;++i) scanf("%lf%lf%lf",x+i,y+i,r+i), P[i] = point(x[i],y[i]);
  
        double ans = -1e20;
        for(int i=0;i<n;++i) {
            double tmp = r[i];
            bool can = 1;
            for(int j=0;j<n;++j) if(sqr(x[i]-x[j])+sqr(y[i]-y[j])+r[i]*r[i] > r[j]*r[j] + EPS) can = 0;
            if(can) ans = max(ans, tmp);
        }
  
        for(int i=0;i<n;++i) {
            memcpy(cP,P,sizeof(cP));
            for(int j=0;j<n;++j) cP[j].x -= P[i].x,cP[j].y -= P[i].y;
            for(int j=i+1;j<n;++j) if(j!=i) {
                double d = dis(cP[i],cP[j]);
                if(r[i]+r[j] < d-EPS) continue;
                if(abs(r[i]-r[j]) > d+EPS) continue;
  
                memcpy(nP,cP,sizeof(nP));
                double a = atan2(cP[j].y,cP[j].x);
                for(int k=0;k<n;++k) nP[k] = rot(cP[k],-a);
  
                bool can = 1;
                point p1,p2;
                intersection_circle_circle(point(nP[j].x,nP[j].y),r[j],point(nP[i].x,nP[i].y),r[i],p1,p2);
                double zz = max(p1.y,p2.y), yy = 0;
                double xx = p1.x;
                for(int k=0;k<n;++k) if(sqr(nP[k].x-xx)+sqr(nP[k].y-yy)+sqr(zz) > r[k]*r[k] + EPS) can = 0;
                if(can)
                    ans = max(ans, zz);
  
                double rr = zz;
                for(int k=0;k<n;++k) nP[k].x -= xx;
                for(int k=j+1;k<n;++k) if(k!=i && k!=j && abs(nP[k].x) <= r[k]+EPS){
                    double nr = sqrt(sqr(r[k])-sqr(nP[k].x));
                    double d = abs(nP[k].y);
                    if(nr+rr < d-EPS) continue;
                    if(abs(nr-rr) > d+EPS) continue;
  
                    bool can = 1;
                    point p1,p2;
                    intersection_circle_circle(point(0,0),rr,point(nP[k].y,0),nr,p1,p2);
                    double zz = max(p1.y,p2.y), xx = 0;
                    double yy = p1.x;
                    for(int h=0;h<n;++h) if(sqrt(sqr(nP[h].x-xx)+sqr(nP[h].y-yy)+sqr(zz)) > r[h] + EPS) can = 0;
                    if(can)
                        ans = max(ans, zz);
                }
            }
        } printf("%.10lf\n",ans);
    }
}

Measured memory_bytes: 1352