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

#define rep(i,x,y) for(int i=(x);i<(y);++i)
#define debug(x) #x << "=" << (x)

#ifdef DEBUG
#define _GLIBCXX_DEBUG
#define show(x) std::cerr << debug(x) << " (L:" << __LINE__ << ")" << std::endl
#else
#define show(x)
#endif

typedef long long int ll;
typedef pair<int,int> pii;
template<typename T> using vec=std::vector<T>;

const int inf=1<<30;
const long long int infll=1LL<<62;
const double eps=1e-7;
const int dx[]={1,0,-1,0},dy[]={0,1,0,-1};

template <typename T> ostream &operator<<(ostream &os, const vector<T> &vec){
    os << "[";
    for (const auto &v : vec) {
    	os << v << ",";
    }
    os << "]";
    return os;
}

typedef complex<long double> point;
typedef pair<point,point> line;
struct circle{
    point o;
    long double r;
    circle(){}
    circle(const point o,const long double r):o(o),r(r){}
};
bool equal(const long double x1,const long double x2){ return abs(x1-x2)<eps; }
bool equal(const point& a,const point& b){ return equal(a.real(),b.real()) and equal(a.imag(),b.imag()); }
long double length(const point& a){ return abs(a); }
long double distance(const point& a,const point& b){ return abs(a-b); }
long double dot(const point& a,const point& b){ return a.real()*b.real()+a.imag()*b.imag(); }
long double cross(const point& a,const point& b){ return a.real()*b.imag()-a.imag()*b.real(); }

point polar(const long double &r, const long double &th) { return point(r*cosl(th),r*sinl(th)); }
int icc(const circle &c, const circle &d) {
    /*
      1 : intersect
      0 : distinct
      -1: c < d
      -2: c > d

      intersect or contain : true
      distinct             : false
    */
    long double od = abs((c.o-d.o));
    return c.r+d.r<od+eps ? 0 : od+c.r<d.r+eps ? -1 : od+d.r<c.r+eps ? -2 : 1;
}

pair<point,point> ccc(const circle &c1, const circle &c2) {
    if(!icc(c1,c2)) return pair<point,point>(c1.o,c2.o);
    long double w = abs(c2.o-c1.o), th = arg(c2.o-c1.o);
    long double dth = acosl((c1.r*c1.r+w*w-c2.r*c2.r)/(2.*c1.r*w));
    return std::pair<point,point>(c1.o+polar(c1.r,th-dth),c1.o+polar(c1.r,th+dth));
}


void solve(int n){
    vector<long double> x(n),y(n),l(n);
    rep(i,0,n) cin >> x[i] >> y[i] >> l[i];

    auto ok=[&](long double h){
        vector<circle> cs;
        rep(i,0,n) cs.push_back(circle(point(x[i],y[i]),sqrtl(l[i]*l[i]-h*h)));

        vector<bool> del(n);
        rep(i,0,n) rep(j,i+1,n){
            auto &c1=cs[i],&c2=cs[j];
            int k=icc(c1,c2);
            if(!k) return false;
            if(k==-1) del[j]=true;
            if(k==-2) del[i]=true;
        }
        vector<point> ps;
        int cnt=0;
        rep(i,0,n){
            if(del[i]) continue;
            ++cnt;
            rep(j,i+1,n){
                if(del[j]) continue;
                auto &c1=cs[i],&c2=cs[j];
                auto ppp=ccc(c1,c2);
                ps.push_back(ppp.first);
                ps.push_back(ppp.second);
            }
        }
        if(cnt==1) return true;
        for(auto &p:ps){
            bool f=true;
            for(auto &c:cs){
                if(abs(p-c.o)<=c.r+eps) continue;
                f=false;
            }
            if(f) return true;
        }
        return false;
    };

    long double lb=1,ub=inf;
    rep(i,0,n) ub=min(ub,l[i]);
    rep(i,0,128){
        long double m=(lb+ub)/2;
        if(ok(m)) lb=m;
        else ub=m;
    }
    cout << lb << endl;
}

int main(){
    std::cin.tie(0);
    std::ios::sync_with_stdio(false);
    cout.setf(ios::fixed);
    cout.precision(10);
    while(true){
        int n;
        cin >> n;
        if(!n) break;
        solve(n);
    }
    return 0;
}

Measured memory_bytes: 3564