#include <iostream>
#include <algorithm>
#include <vector>
#include <queue>
#include <cstring>
#include <string>
#include <cstdlib>
#include <cstdio>
#include <set>
#include <map>
#include <complex>
#include <cmath>
using namespace std;

#define EPS 1.0e-8
#define PI 3.1415926535897932384 
#define REP(i,n) for(int i = 0; i < (int)(n); i++)
#define FOR(it,c) for(__typeof((c).begin()) it = (c).begin(); it != (c).end(); ++it)
#define ALLOF(c) (c).begin(), (c).end()
// 実数の符号関数
inline int signum(double x) { return (abs(x) < EPS ? 0 : x > 0 ? 1 : -1); }
//XY座標
#define X real()
#define Y imag()
// 点
typedef complex<double> P;
 

// 線分・半直線・直線
struct L { P pos, dir; };


// 円
struct C { P p; double r; };

// 二つのベクトルの内積を計算する
inline double inp(const P& a, const P& b) {
    return (conj(a)*b).real();
}
 
// 二つのベクトルの外積を計算する
inline double outp(const P& a, const P& b) {
    return (conj(a)*b).imag();
}
inline int ccw(const P& p, const P& r, const P& s) {
    P a(r-p), b(s-p);
    int sgn = signum(outp(a, b));
    if (sgn != 0)
        return sgn;
    if (a.real()*b.real() < -EPS || a.imag()*b.imag() < -EPS)
        return -1;
    if (norm(a) < norm(b) - EPS)
        return 1;
    return 0;
}
// ベクトルpをベクトルbに射影したベクトルを計算する
inline P proj(const P& p, const P& b) {
    return b*inp(p,b)/norm(b);
}
 
// 点pから直線lに引いた垂線の足となる点を計算する
inline P perf(const L& l, const P& p) {
    L m = {l.pos - p, l.dir};
    return (p + (m.pos - proj(m.pos, m.dir)));
}
 
// 線分sを直線bに射影した線分を計算する
inline L proj(const L& s, const L& b) {
     return (L){perf(b, s.pos), proj(s.dir, b.dir)};
}

pair<P, P> cc_cross(const C& c1, const C& c2) {
	if(c1.r+c2.r < abs(c1.p-c2.p) || abs(c1.p-c2.p) < abs(c1.r-c2.r)+EPS){
		printf("cc_cross error\n");
		exit(0);
	}

    double d = abs(c1.p - c2.p);
    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.p - c1.p) / d;
    return make_pair(c1.p + diff * P(rc, rs), c1.p + diff * P(rc, -rs));
}

int n;

bool check(vector<C> Cs, double z){
	int i,j,k;

	vector<P> intersects;
	for(i=0;i<Cs.size();i++){
		Cs[i].r = sqrt(Cs[i].r*Cs[i].r - z*z);
//		printf("circle(%f, %f, %f)\n", Cs[i].p.X+100, Cs[i].p.Y+100, Cs[i].r);
		intersects.push_back(Cs[i].p);
	}
	for(i=0;i<Cs.size();i++){
		for(j=0;j<i;j++){
			C a=Cs[i], b=Cs[j];
			if(abs(a.p-b.p) < EPS) continue;
			if(abs(a.p-b.p) > a.r+b.r) continue;
			if(abs(a.p-b.p) < abs(a.r-b.r)) continue;
			pair<P, P> c = cc_cross(a, b);
			intersects.push_back(c.first);
			intersects.push_back(c.second);
		}
	}
//	printf("%d %d\n", intersects.size(), Cs.size());
	for(i=0;i<intersects.size();i++){
//		printf("circle(%f, %f, 2)\n", intersects[i].X+100, intersects[i].Y+100);
		for(j=0;j<Cs.size();j++){
			if(abs(Cs[j].p - intersects[i]) > Cs[j].r + EPS) break;
		}
		if(j==Cs.size()) return true;
	}
	return false;
}
main(){
	int h,w,i,j;
	
	while(cin >> n, n){
		vector<C> Cs;
		double minl=300;
		for(i=0;i<n;i++){
			double x,y,l;
			cin >> x >> y >> l;
			Cs.push_back((C){P(x,y),l});
			minl = min(minl, l);
		}
//		check(Cs, 20);
//		return 0;
		double high = minl, low=0;
//		printf("high = %f\n", high);
		while(high-low > EPS){
			double mid = (high+low)/2;
//			printf("mid = %f\n", mid);
			if(check(Cs, mid)) low = mid;
			else high = mid;
		}
		printf("%.7f\n", high);
	}
	return 0;
}

Measured memory_bytes: 1280