#include <vector>
#include <iostream>
#include <utility>
#include <algorithm>
#include <string>
#include <deque>
#include <tuple>
#include <queue>
#include <functional>
#include <cmath>
#include <iomanip>
#include <set>
#include <map>
#include <numeric>
#include <unordered_map>
#include <unordered_set>
#include <complex>
#include <iterator>
#include <array>
#include <chrono>
//cin.sync_with_stdio(false);
//streambuf
using namespace std;
typedef long long ll;
typedef long double ld;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
typedef pair<double, double> pdd;
using vi = vector<int>;
using vll = vector<ll>;
using vpii = vector<pii>;
template<class T, int s>using va = vector<array<T, s>>;
template<class T, class T2> using umap = unordered_map<T, T2>;
template<class T> using uset = unordered_set<T>;
template<class T, class S> void cmin(T &a, const S b) { if (a > b)a = b; }
template<class T, class S> void cmax(T &a, const S b) { if (a < b)a = b; }
#define ALL(a) a.begin(),a.end()
#define rep(i,a) for(int i=0;i<a;i++)
#define rep1(i,a) for(int i=1;i<=a;i++)
#define rrep(i,a) for(int i=a-1;i>=0;i--)
#define rrep1(i,a) for(int i=a;i;i--)
const ll mod = 1000000007;
#ifndef INT_MAX
const int INT_MAX = numeric_limits<signed>().max();
#endif
template<class T>using heap = priority_queue<T, vector<T>, greater<T>>;
template<class T>using pque = priority_queue<T, vector<T>, function<T(T, T)>>;
const ld eps = 1e-11, pi = acos(-1.0);
typedef complex<ld> P;
typedef vector<P> VP;
ld dot(P a, P b) { return real(conj(a) * b); }
ld cross(P a, P b) { return imag(conj(a) * b); }
 
namespace std {
    bool operator<(const P &a, const P &b) {
        return abs(a.real() - b.real()) < eps ? a.imag() < b.imag() : a.real() < b.real();
    }
}
 
struct L { P a, b; };//line->l,segment->s
struct C { P p; ld r; };
 
int ccw(P a, P b, P c) {
    b -= a; c -= a;
    if (cross(b, c) > eps) return 1;   // counter clockwise
    if (cross(b, c) < -eps) return -1; // clockwise
    if (dot(b, c) < 0) return 2;       // c--a--b on line
    if (norm(b) < norm(c)) return -2;  // a--b--c on line
    return 0;                          // a--c--b on line
}
int main() {
	int n;
	cin.sync_with_stdio(0);
	while (cin >> n, n) {
		va<float, 3> bl(n);
		rep(i, n)rep(j, 3)cin >> bl[i][j];
		//va<double, 3> h;
		double ans = 1e9;
		int mina = 0;
		rep(i, n)if (ans > bl[i][2])ans = bl[i][2], mina = i;
		ans *= ans;
		rep(i, n) {
			rep(j, i) {
				double l = sqrt(double(bl[i][0] - bl[j][0])*(bl[i][0] - bl[j][0]) + (bl[i][1] - bl[j][1])*(bl[i][1] - bl[j][1]));
				double a = ((bl[j][2] * bl[j][2] - bl[i][2] * bl[i][2]) / l + l)*0.5;
				double x = (bl[i][0] * a + bl[j][0] * (l - a)) / l, y = (bl[i][1] * a + bl[j][1] * (l - a)) / l, z = bl[j][2] * bl[j][2] - a*a;
				if (z < 0)continue;
				if (z<ans&&a > 0 && a < l)ans = z;
				double x00 = bl[i][0] - bl[j][0], x01 = bl[i][1] - bl[j][1], x02 = -bl[i][2] * bl[i][2] + bl[j][2] * bl[j][2] + bl[i][0] * bl[i][0] + bl[i][1] * bl[i][1] - bl[j][0] * bl[j][0] - bl[j][1] * bl[j][1];
				if (x01 != 0) {
					double rv = 1 / x01;
					rep(k, j) {
						double x10 = bl[i][0] - bl[k][0], x11 = bl[i][1] - bl[k][1], x12 = -bl[i][2] * bl[i][2] + bl[k][2] * bl[k][2] + bl[i][0] * bl[i][0] + bl[i][1] * bl[i][1] - bl[k][0] * bl[k][0] - bl[k][1] * bl[k][1];
						double a, b, c;
						if (x11 == 0) {
							a = x12*0.5 / x10;
							b = (x02*0.5 - a*x00)*rv;
						}
						else {
							double rv2 = x10 * x01 - x11*x00;
							if (rv2 == 0)continue;
							rv2 = 1 / rv2;
							a = rv2*(x12 * x01 - x11 * x02)*0.5;
							b = (x02 * 0.5 - a*x00)*rv;
						}
						c = bl[i][2] * bl[i][2] - (a - bl[i][0])*(a - bl[i][0]) - (b - bl[i][1])*(b - bl[i][1]);
						if (c < 0)continue;
						if (c >= ans)continue;
						int cc = ccw(P(a, b), P(bl[i][0], bl[i][1]), P(bl[j][0], bl[j][1]));
						if (cc == ccw(P(a, b), P(bl[j][0], bl[j][1]), P(bl[k][0], bl[k][1])) && cc == ccw(P(a, b), P(bl[k][0], bl[k][1]), P(bl[i][0], bl[i][1])))ans = c;
					}
				}
				else {
					double a = x02*0.5 / x00;
					double c_ = bl[i][2] * bl[i][2] - (a - bl[i][0])*(a - bl[i][0]);
					rep(k, j) {
						double x11 = bl[i][1] - bl[k][1];
						if (x11 == 0)continue;
						double x10 = bl[i][0] - bl[k][0],x12 = -bl[i][2] * bl[i][2] + bl[k][2] * bl[k][2] + bl[i][0] * bl[i][0] + bl[i][1] * bl[i][1] - bl[k][0] * bl[k][0] - bl[k][1] * bl[k][1];
						double b = (x12*0.5 - a*x10) / x11, c;
						c = c_ - (b - bl[i][1])*(b - bl[i][1]);
						if (c < 0)continue;
						if (c >= ans)continue;
						int cc = ccw(P(a, b), P(bl[i][0], bl[i][1]), P(bl[j][0], bl[j][1]));
						if (cc == ccw(P(a, b), P(bl[j][0], bl[j][1]), P(bl[k][0], bl[k][1])) && cc == ccw(P(a, b), P(bl[k][0], bl[k][1]), P(bl[i][0], bl[i][1])))ans = c;
					}
				}
			}
		}
		cout << fixed << setprecision(7) << sqrt(ans) << endl;
	}
}

Measured memory_bytes: 3252