#include <bits/stdc++.h>
using namespace std;

typedef long double Real;
typedef complex<Real> Point;
typedef vector<Point> Polygon;
struct Line {
	Line(){}
	Line(Point p, Point q): p(p), q(q){}
	Point p, q;
};
typedef Line Segment;
struct Circle {
	Circle(){}
	Circle(Point p, Real r): p(p), r(r){}
	Point p;
	Real r;
};

#define X real
#define Y imag

const Real PI = acos(Real(-1));
const Real EPS = 1e-12;

inline int sgn(Real a){
	if (abs(a) < EPS) return 0;
	return a < 0.0 ? -1 : 1;
}

inline bool eq(Real a, Real b){ return sgn(a - b) == 0; }
inline bool neq(Real a, Real b){ return sgn(a - b) != 0; }
inline bool lt(Real a, Real b){ return sgn(a - b) == -1; }
inline bool leq(Real a, Real b){ return sgn(a - b) <= 0; }
inline bool gt(Real a, Real b){ return sgn(a - b) == 1; }
inline bool geq(Real a, Real b){ return sgn(a - b) >= 0; }

Real sq(Real a){ return a * a; }

Real dot(Point a, Point b){ return X(conj(a) * b); }
Real cross(Point a, Point b){ return Y(conj(a) * b); }

bool orthogonal(Line l, Line m){
	return sgn(dot(l.q - l.p, m.q - m.p)) == 0;
}

bool parallel(Line l, Line m){
	return sgn(cross(l.q - l.p, m.q - m.p)) == 0;
}

Point project(Line l, Point p){
	Point t = l.q - l.p;
	Real r = dot(p - l.p, t) / norm(t);
	return l.p + t * r;
}

Point reflect(Line l, Point p){
	return p + (project(l, p) - p) * Real(2.0);
}

int ccw(Point a, Point b, Point c){
	Point u = b - a, v = c - a;
	if (sgn(cross(u, v)) == 1) return 1;		// ccw
	if (sgn(cross(u, v)) == -1) return -1;	// cw
	if (sgn(dot(a, b)) == -1) return 2;			// back
	if (lt(norm(a), norm(b))) return -2;		// front
	return 0;																// on
}

bool intersectLL(Line l, Line m){
	if (!parallel(l, m)) return true;
	return parallel(l, Line(l.p, m.p));
}

bool intersectLS(Line l, Segment s){
	return sgn(cross(l.q - l.p, s.p - l.p)) * sgn(cross(l.q - l.p, s.q - l.p)) <= 0;
}

bool intersectLP(Line l, Point p){
	return parallel(l, Line(l.p, p));
}

bool intersectSS(Segment s, Segment t){
	return ccw(s.p, s.q, t.p) * ccw(s.p, s.q, t.q) <= 0
		&& ccw(t.p, t.q, s.p) * ccw(t.p, t.q, s.q) <= 0;
}

Real distanceLP(Line l, Point p){
	return abs(cross(l.q - l.p, p - l.p) / abs(l.q - l.p));
}

Real distanceLL(Line l, Line m){
	if (intersectLL(l, m)) return 0.0;
	return distanceLP(l, m.p);
}

Real distanceLS(Line l, Segment s){
	if (intersectLS(l, s)) return 0.0;
	return min(distanceLP(l, s.p), distanceLP(l, s.q));
}

Real distanceSP(Segment s, Point p){
	if (sgn(dot(s.q - s.p, p - s.p)) <= 0) return abs(p - s.p);
	if (sgn(dot(s.p - s.q, p - s.q)) <= 0) return abs(p - s.q);
	return distanceLP(s, p);
}

Real distanceSS(Segment s, Segment t){
	if (intersectSS(s, t)) return 0.0;
	return min(
		min(distanceSP(s, t.p), distanceSP(s, t.q)),
		min(distanceSP(t, s.p), distanceSP(t, s.q))
	);
}

bool intersectCL(Circle c, Line l){
	return leq(distanceLP(l, c.p), c.r);
}

bool intersectCS(Circle c, Segment s){
	return leq(distanceSP(s, c.p), c.r);
}

bool intersectCP(Circle c, Point p){
	return leq(norm(c.p - p), sq(c.r));
}

bool intersectCC(Circle c, Circle d){
	return leq(norm(c.p - d.p), sq(c.r + d.r));
}

pair<Point, Point> crossPointsCL(Circle c, Line l){
	Point pr = project(l, c.p);
	Point e = (l.q - l.p) / abs(l.q - l.p);
	Real t = sqrt(sq(c.r) - norm(pr - c.r));
	return make_pair(pr + e * t, pr - e * t);
}

pair<Point, Point> crossPointsCC(Circle c, Circle d){
	Real ds = abs(d.p - c.p);
	Real a = acos((sq(c.r) + sq(ds) - sq(d.r)) / (2 * c.r * ds));
	Real t = arg(d.p - c.p);
	return make_pair(c.p + polar(c.r, t + a), c.p + polar(c.r, t - a));
}

bool contains(Circle c, Circle d){ // d in c
	return leq(c.r + abs(c.p - d.p), d.r);
}

int n;
Real x[10], y[10], l[10];

bool ok(Real h)
{
	Circle c[10];
	for (int i = 0; i < n; i++){
		Real r = sqrt(sq(l[i]) - sq(h));
		c[i] = Circle(Point(x[i], y[i]), r);
	}

	for (int i = 0; i < n; i++){
		bool f = true;
		for (int j = 0; j < n; j++){
			if (!intersectCP(c[j], c[i].p)) f = false;
		}
		if (f) return true;
	}

	vector<Point> cps;
	for (int i = 0; i < n; i++){
		for (int j = 0; j < n; j++){
			if (!intersectCC(c[i], c[j])) return false;
			if (contains(c[i], c[j])) continue;
			if (contains(c[j], c[i])) continue;
			auto cp = crossPointsCC(c[i], c[j]);
			cps.push_back(cp.first);
			cps.push_back(cp.second);
		}
	}
	
	for (auto cp : cps){
		bool f = true;
		for (int i = 0; i < n; i++){
			if (!intersectCP(c[i], cp)) f = false;
		}
		if (f) return true;
	}

	return false;
}

int main()
{
	while (cin >> n, n){
		for (int i = 0; i < n; i++){
			cin >> x[i] >> y[i] >> l[i];
		}
		Real lb = 0.0, ub = *min_element(l, l + n);
		for (int j = 0; j < 100; j++){
			Real md = (lb + ub) / 2;
			(ok(md) ? lb : ub) = md;
		}
		cout << fixed << setprecision(20) << lb << endl;
	}
}

Measured memory_bytes: 1344