#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=0;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);
				if(abs(nP[j].x) < 1e-9) continue;

				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=0;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;
					if(d < 1e-9) 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;
					if(nP[k].y < 0) yy *= -1;
					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: 1348