#include <vector>
#include <list>
#include <map>
#include <set>
#include <stack>
#include <queue>
#include <deque>
#include <algorithm>
#include <utility>
#include <functional>
#include <sstream>
#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <cctype>
#include <string>
#include <cstring>
#include <ctime>
#include <climits>
#include <cassert>
#include <memory>
#include <time.h>
using namespace std;
inline int toInt(string s) {int v; istringstream sin(s);sin>>v;return v;}
template<class T> inline string toString(T x) {ostringstream sout;sout<<x;return sout.str();}
typedef vector<int> vi;
typedef vector<vi> vvi;
typedef vector<string> vs;
typedef pair<int, int> pii;
typedef long long ll;
#define ALL(a) (a).begin(),(a).end()
#define RALL(a) (a).rbegin(),(a).rend()
#define EXIST(s,e) ((s).find(e)!=(s).end())
#define FOR(i,a,b) for(int i=(a);i<(b);++i)
#define REP(i,n) FOR(i,0,n)
const double EPS = 1e-9;
const double PI  = acos(-1.0);

#include <complex>
typedef complex<double> P;
#define LT(x,y) ((x)-(y)<=-EPS)

vector<P> cross_circles(P c1,double r1,P c2,double r2){
	double d=abs(c2-c1);
	if(LT(r1+r2,d)||LT(d,fabs(r1-r2)))
		return vector<P>();
	double l=0.5*((r1*r1-r2*r2)/d+d);
	double h=sqrt(r1*r1-l*l);
	vector<P> ret(2);
	ret[0]=P(l,+h)*(c2-c1)/d+c1;
	ret[1]=P(l,-h)*(c2-c1)/d+c1;
	return ret;
}

double distance(double y1,double x1,double y2,double x2){
	double dy=y1-y2;
	double dx=x1-x2;
	return sqrt(dy*dy+dx*dx);
}

bool ok(vi &y,vi &x,vi &l, double h){
	int n=y.size();
	vector<P> all_cross;
	REP(i,n){
		FOR(j,i+1,n){
			if(l[i]+EPS<h||l[j]+EPS<h){
				return false;
			}
			double di=sqrt(l[i]*l[i]-h*h);
			double dj=sqrt(l[j]*l[j]-h*h);
			double dist2=distance(y[i],x[i],y[j],x[j]);
			bool intersected=di+dj+EPS>dist2;
			vector<P> cross=cross_circles(P(y[i],x[i]),di,P(y[j],x[j]),dj);
			if(cross.size()==0){
				if(!intersected){
					return false;
				}
			}else{
				all_cross.push_back(cross[0]);
				all_cross.push_back(cross[1]);
			}
		}
		all_cross.push_back(P(y[i],x[i]));
	}

	REP(ci,all_cross.size()){
		bool ok=true;
		REP(k,n){
			double dk=sqrt(l[k]*l[k]-h*h);
			if(distance(y[k],x[k],all_cross[ci].real(),all_cross[ci].imag())>dk+EPS){
				ok=false;
			}
		}
		if(ok){
			return true;
		}
	}
	return false;
}

int main(){
	cout.precision(30);
	int n;
	while(cin>>n,n){
		vi x(n),y(n),l(n);
		int maxl=0;
		REP(i,n){
			cin>>x[i]>>y[i]>>l[i];
			maxl=max(maxl,l[i]);
		}

		double lb=1,ub=maxl;
		REP(time,1000){
			double mid=(lb+ub)/2;
			if(!ok(y,x,l,mid)){
				ub=mid;
			}else{
				lb=mid;
			}
		}
		cout<<ub<<endl;
	}
}