#include <vector>
#include <iostream>
#include <utility>
#include <algorithm>
#include <string>
#include <deque>
#include <tuple>
#include <queue>
#include <functional>
#include <cmath>
#include <iomanip>
#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 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)>>;
template <class T>
inline void hash_combine(size_t & seed, const T & v) {
    hash<T> hasher;
    seed ^= hasher(v) + 0x9e3779b9 + (seed << 6) + (seed >> 2);
}
 
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) > 0) return 1;   // counter clockwise
else return -1;
    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<int, 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((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) / 2;
                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;
                rep(k, j) {
                    double x[2][3] = { {double(bl[i][0] - bl[j][0]),double(bl[i][1] - bl[j][1]),double(-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])},{ double(bl[i][0] - bl[k][0]),double(bl[i][1] - bl[k][1]),double(-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 (x[1][1] == 0) {
                        if (x[0][1] == 0)continue;
                        if (x[1][0]*x[0][1] - (x[1][1] )*x[0][0] == 0)continue;
                        a = 1/ (2*(x[1][0]*x[0][1] - (x[1][1])*x[0][0]))*(x[1][2]*x[0][1] - x[1][1]  * x[0][2]);
                        b = (x[0][2]*0.5 - a*x[0][0])*(1/ x[0][1]);
                    }
                    else {
                        if (x[0][0]*x[1][1] - (x[0][1])*x[1][0] == 0)continue;
                        a = 1/ (2*(x[0][0]*x[1][1] - (x[0][1] )*x[1][0]))*(x[0][2]*x[1][1] - x[0][1]* x[1][2]);
                        b = (x[1][2] *0.5 - a*x[1][0]) *(1 / x[1][1]);
                    }
                    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;
                }
            }
        }
        cout << fixed << setprecision(7) << sqrt(ans) << endl;
    }
}

Measured memory_bytes: 3216