#ifndef _WIN32
#include<iostream>
#endif 
#include<cmath>
#include<iomanip>
#include<algorithm>
#include<vector>
#include<string>
#include<map>
#include<tuple>
#include<complex>
#include<queue>
#include<functional>
using namespace std;
typedef long long LL;
#define FOR(i,bg,ed) for(int i=(bg);i<(ed);i++)
#define REP(i,n) FOR(i,0,n)
template<typename T> bool chmin(T &l, T r) {
	bool res = l > r;
	if (res) {
		l = r;
	}
	return res;
}
#define IL inline
#define X real()
#define Y imag()
typedef double D;

typedef complex<double> P;
typedef pair<P, P> LS;
typedef pair<P, D> C;
const D EPS = 1e-8;
IL D dot(P a, P b) {
	return a.X*b.X + a.Y*b.Y;
}
IL D cross(P a, P b) {
	return a.X*b.Y - a.Y*b.X;
}



struct cww {
	cww() {
		cout << fixed;
		cout << setprecision(10);
	}
}star;
IL D signed_distance_P_L(P p, LS l) {
	P a, b, c = p;
	tie(a, b) = l;
	return cross(b - a, c - a) / abs(b - a);
}
IL D distance_P_LS(P p, LS ls) {
	P a, b, c = p;
	tie(a, b) = ls;
	if (dot(b - a, c - a) < EPS)return abs(c - a);
	if (dot(a - b, c - b) < EPS)return abs(c - b);
	return abs(cross(b - a, c - a)) / abs(b - a);
}

IL bool isintersected_LS_LS(LS p, LS q) {
	P a, b, c, d;
	tie(a, b) = p;
	tie(c, d) = q;
	if (abs(cross(b - a, d - c))<EPS) {
		if (abs(abs(b - c) + abs(a - c) - abs(a - b)) < EPS)return true;
		if (abs(abs(b - d) + abs(a - d) - abs(a - b)) < EPS)return true;
		if (abs(abs(a - c) + abs(a - d) - abs(c - d)) < EPS)return true;
		if (abs(abs(b - c) + abs(b - d) - abs(c - d)) < EPS)return true;

		return false;
	}
	return cross(b - a, c - a)*cross(b - a, d - a) < EPS && cross(d - c, a - c)*cross(d - c, b - c) < EPS;
}
IL D distance_LS_LS(LS p, LS q) {
	if (isintersected_LS_LS(p, q))return 0;
	P a, b, c, d;
	tie(a, b) = p;
	tie(c, d) = q;
	double e, f, g, h;
	e = distance_P_LS(a, q);
	f = distance_P_LS(b, q);
	g = distance_P_LS(c, p);
	h = distance_P_LS(d, p);
	return min({ e,f,g,h });
}
P rot(P p, double r) {
	return P(p.X*cos(r) - p.Y*sin(r), p.X*sin(r) + p.Y*cos(r));
}
IL bool isintersected_C_C(C p, C q) {
	P cp, cq;
	D rp, rq;
	tie(cp, rp) = p;
	tie(cq, rq) = q;
	D d = abs(cp - cq);
	return abs(rp - rq) < d + EPS&&d < rp + rq + EPS;
}
IL LS cross_C_C(C p, C q) {
	P cp, cq;
	D rp, rq;
	tie(cp, rp) = p;
	tie(cq, rq) = q;
	D d = abs(cp - cq);
	D rc = (d*d +rp*rp - rq*rq)/(2*d);
	D rs = sqrt(rp*rp - rc*rc);
	P diff = (cq - cp) / d;
	return LS(cp + P(rc, rs)*diff, cp + P(rc, -rs)*diff);
}

const D PI = acos(-1);
typedef pair<double, int> pp;
typedef priority_queue<pp, vector<pp>, greater<pp>> QUE;
int main() {
	int N;
	while (cin >> N, N) {
		vector<P> xy(N);
		vector<D> len(N);
		REP(i, N) {
			double x, y;
			cin >> x >> y>>len[i];
			xy[i] = P(x, y);
		}
		double lb = 0;
		double ub = 400;
		REP(loop, 100) {
			const D mid = (lb + ub) / 2;
			vector<C> cir(N);
			bool flag = true;
			REP(i, N) {
				double l = len[i] * len[i] - mid*mid;
				if (l < 0) { flag = false; break; }
				cir[i] = C(xy[i], sqrt(l));
			}
			if (flag == false) {
				ub = mid; continue;
			}
			vector<P> nobu;
			REP(i, N)nobu.push_back(xy[i]);
			REP(i, N) {
				REP(j, N) {
					if (i != j) {
						if (!isintersected_C_C(cir[i], cir[j]))continue;
						auto hiro = cross_C_C(cir[i], cir[j]);
						nobu.push_back(hiro.first);
						nobu.push_back(hiro.second);
					}
				}
			}
			flag = false;
			for (auto &p : nobu) {
				bool btk=true;
				REP(i, N) {
					auto d = abs(p - xy[i]);
					if (d*d + mid*mid >EPS+ len[i] * len[i])
						btk = false;
				}
				if (btk)flag = true;
			}


			if (flag)lb = mid;
			else ub = mid;
		}
		cout << lb << endl;
	}
	return 0;
}

Measured memory_bytes: 3360