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

#define rep(i,a,b) for(int i=(a);i<(b);i++)

template<class F>
double binarySearch(double l, double r, F f) {
	if (f(l))return l;
	for (int i = 0; i < 200; i++) {
		double m = (l + r) / 2;
		if (f(m))
			r = m;
		else
			l = m;
	}
	return r;
}

const double EPS = 1e-8;

struct Point {
	double x, y;
	Point() :x(0.0), y(0.0) {}
	Point(double x, double y) :x(x), y(y) {}

	Point& operator+=(const Point& p) { x += p.x; y += p.y; return *this; }
	Point& operator-=(const Point& p) { x -= p.x; y -= p.y; return *this; }
	Point& operator*=(double a) { x *= a; y *= a; return *this; }
	Point& operator/=(double a) { x /= a; y /= a; return *this; }

	double abs() { return sqrt(norm()); }
	double norm() { return x * x + y * y; }

};
Point operator+(const Point& p1, const Point& p2) { return Point(p1) += p2; }
Point operator-(const Point& p1, const Point& p2) { return Point(p1) -= p2; }
Point operator*(const Point& p, double a) { return Point(p) *= a; }
Point operator/(const Point& p, double a) { return Point(p) /= a; }

struct Vector :public Point {
	using Point::Point;
	Vector() {}
	Vector(const Point& P) { x = P.x; y = P.y; }
	Vector rotate(double rad) { return Vector(x * cos(rad) - y * sin(rad), x * sin(rad) + y * cos(rad)); }
	Vector unit() { return *this / abs(); }
};

struct Circle {
	Point c;
	double r;
	Circle() {}
	Circle(Point c, double r) :c(c), r(r) {}
};

double arg(Vector p) { return atan2(p.y, p.x); }

Vector polar(double r, double a) { return Point(cos(a) * r, sin(a) * r); }

double get_distance(Point a, Point b) {
	return (a - b).abs();
}

int intersect(Circle c1, Circle c2) {
	double d = get_distance(c1.c, c2.c);
	if (d > c1.r + c2.r)return 4;
	if (d == c1.r + c2.r)return 3;
	if (d + c1.r == c2.r || d + c2.r == c1.r)return 1;
	if (d + c1.r < c2.r || d + c2.r < c1.r)return 0;
	return 2;
}

pair<Point, Point> get_cross_points(Circle c1, Circle c2) {
	int m = intersect(c1, c2);
	assert(m != 4 && m != 0);
	double d = (c1.c - c2.c).abs();
	double a = acos((c1.r * c1.r - c2.r * c2.r + d * d) / (2 * c1.r * d));
	double t = arg(c2.c - c1.c);
	return make_pair(c1.c + polar(c1.r, t + a), c1.c + polar(c1.r, t - a));
}


signed main() {
	cout << fixed << setprecision(10);
	for (int n; cin >> n && n;) {
		vector<double> x(n), y(n), l(n);
		rep(i, 0, n)cin >> x[i] >> y[i] >> l[i];

		auto f = [&](double h) {
			//cerr << "h " << h << endl;
			vector<Circle> c(n);
			vector<Point> P;
			rep(i, 0, n) {
				if (l[i] < h)return true;
				double theta = asin(h / l[i]);
				c[i].r = l[i] * cos(theta);
				c[i].c = Point(x[i], y[i]);
				//cerr << i << " " << c[i].r << endl;
				P.push_back(c[i].c);
			}

			rep(i, 0, n)rep(j, i + 1, n) {
				int m = intersect(c[i], c[j]);
				if (m == 4)return true;
				if (m != 0) {
					auto cp = get_cross_points(c[i], c[j]);
					P.push_back(cp.first);
					P.push_back(cp.second);
				}
			}

			// ok = true なら ゆるんでて大丈夫
			bool ok = false;
			// 全部に含まれている点が存在したら ok = true にする
			for (auto p : P) {
				// 含まれているなら true
				//cerr << p.x << " " << p.y << endl;
				bool ok2 = true;
				rep(i, 0, n) {
					double d = get_distance(c[i].c, p);
					//cerr << "d " << d - EPS << " c[i].r " << c[i].r << endl;
					// 含まれていない
					if (d - EPS > c[i].r)
						ok2 = false;
				}
				if (ok2)
					ok = true;
				//cerr << ok2 << endl;
			}

			return !ok;

		};

		double h = binarySearch(0, 300, f);

		cout << h << endl;
	}
	return 0;
}


Measured memory_bytes: 3652