#include <iostream>
#include <vector>
#include <iomanip>
#include <tuple>
#include <cmath>

#define ISLOOSE(a,b)	(disdis(a, b) + get<2>(a) * get<2>(a) <= get<2>(b) * get<2>(b))

using namespace std;

double disdis(const tuple<double, double, double>& a, const tuple<double, double, double>& b)
{
	return (get<0>(a) - get<0>(b)) * (get<0>(a) - get<0>(b)) + (get<1>(a) - get<1>(b)) * (get<1>(a) - get<1>(b));
}

double heron(double a, double b, double c)
{
	double s = (a + b + c) / 2;
	return sqrt(s*(s - a)*(s - b)*(s - c));
}

double heron2(double a, double b, double c, double d, double e, double f)
{
	return sqrt((a*d*(b + c + e + f - a - d) + b*e*(c + a + f + d - b - e) + c*f*(a + b + d + e - c - f) - a*b*f - a*e*c - d*b*c - d*e*f) / 144.0);
}

tuple<double, double, double> com(const tuple<double, double, double>& a, const tuple<double, double, double>& b)
{
	if (disdis(a, b) + get<2>(a) * get<2>(a) <= get<2>(b) * get<2>(b)) {
		return a;
	}
	else if (disdis(a, b) + get<2>(b) * get<2>(b) <= get<2>(a) * get<2>(a)) {
		return b;
	}
	else {
		double l = heron(get<2>(a), get<2>(b), sqrt(disdis(a, b))) * 2 / sqrt(disdis(a, b));
		double d1 = sqrt(get<2>(a) * get<2>(a) - l * l);
		double d2 = sqrt(get<2>(b) * get<2>(b) - l * l);
		return tuple<double, double, double>(get<0>(a) + (get<0>(b) - get<0>(a)) * d1 / (d1 + d2), get<1>(a) + (get<1>(b) - get<1>(a)) * d1 / (d1 + d2), l);
	}
}

double two(const tuple<double, double, double>& a, const tuple<double, double, double>& b)
{
	if (disdis(a, b) + get<2>(a) * get<2>(a) <= get<2>(b) * get<2>(b)) {
		return (double)get<2>(a);
	}
	else if (disdis(a, b) + get<2>(b) * get<2>(b) <= get<2>(a) * get<2>(a)) {
		return (double)get<2>(b);
	}
	else {
		double d = sqrt(disdis(a, b));
		return heron(get<2>(a), get<2>(b), d) * 2 / d;
	}
}

double three(const tuple<double, double, double>& a, const tuple<double, double, double>& b, const tuple<double, double, double>& c)
{
	tuple<double, double, double> temp;

	if (ISLOOSE(a, b) && ISLOOSE(a, c))
		return get<2>(a);
	if (ISLOOSE(b, a) && ISLOOSE(b, c))
		return get<2>(b);
	if (ISLOOSE(c, a) && ISLOOSE(c, b))
		return get<2>(c);

	if (ISLOOSE(temp = com(a, b), c))
		return get<2>(temp);
	if (ISLOOSE(temp = com(b, c), a))
		return get<2>(temp);
	if (ISLOOSE(temp = com(c, a), b))
		return get<2>(temp);

	return heron2(get<2>(a) * get<2>(a), get<2>(b) * get<2>(b), get<2>(c) * get<2>(c), disdis(b, c), disdis(c, a), disdis(a, b))
		* 3.0 / heron(sqrt(disdis(a, b)), sqrt(disdis(b, c)), sqrt(disdis(c, a)));
}

int main()
{
	int n;
	double res;
	while (cin >> n, n) {
		vector< tuple<double, double, double> > str(n);
		for (int i = 0; i < n; i++) {
			cin >> get<0>(str[i]) >> get<1>(str[i]) >> get<2>(str[i]);
		}
		if (n == 1) {
			cout << fixed << setprecision(7) << (double)get<2>(str[0]) << endl;
		}
		else if (n == 2) {
			cout << fixed << setprecision(7) << two(str[0], str[1]) << endl;
		}
		else {
			res = 100000000.0;
			for (int i = 0; i < n; i++) {
				for (int j = i + 1; j < n; j++) {
					for (int k = j + 1; k < n; k++) {
						res = min(res, three(str[i], str[j], str[k]));
					}
				}
			}
			cout << fixed << setprecision(7) << res << endl;
		}
	}
	return 0;
}

Measured memory_bytes: 3280