#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <cstring>

#include <iostream>
#include <string>
#include <algorithm>
#include <vector>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <unordered_map>
#include <unordered_set>

#include <complex>

#include <functional>
#include <cassert>

typedef long long ll;
using namespace std;

#define debug(x) cerr << #x << " = " << (x) << endl;


#define mod 1000000007 //1e9+7(prime number)
#define INF 1000000000 //1e9
#define LLINF 2000000000000000000LL //2e18
#define SIZE 100010

typedef double double2;

typedef double P_type;
typedef complex<P_type> P;
const P_type P_eps = 1e-10; //??´??°???????????????

namespace std{
  template<class T> bool operator<(const complex<T> &a, const complex<T> &b){
    return a.real() == b.real() ? a.imag() < b.imag() : a.real() < b.real();
  }
};

P rotate(P p, double theta){
  return p * P(cos(theta), sin(theta));
}

//??????
double dot(P a, P b) {
  return (a * conj(b)).real();
}

//??????
double cross(P a, P b) {
  return (a * conj(b)).imag();
}

//???????¨???????
int ccw(P a, P b, P c){
  if(cross(b-a,c-a) > P_eps) return 1; //COUNTER_CLOCKWISE
  if(cross(b-a,c-a) < -P_eps) return -1; //CLOCKWISE
  if(dot(b-a,c-a) < P_eps) return -2; //c -> a -> b
  if(dot(a-b,c-b) < P_eps) return 2; //a -> b -> c
  return 0; //a -> c -> b
}

/* ??????????????? */
bool isIntersectedCC(P c1, double r1, P c2, double r2){
  double dist = abs(c1 - c2);
  
  return abs(r1 - r2) < dist + P_eps && dist - P_eps < r1 + r2; //?????\?????\?????????
  //return abs(r1 - r2) < dist - P_eps && dist + P_eps < r1 + r2; //?????\?????\?????????
}

/* ????????? */
pair<P,P> getCrosspointCC(P c1, double r1, P c2, double r2){
  //assert(isIntersectedCC(c1, r1, c2, r2));
  
  double dist = abs(c1 - c2);
  double a = acos((r1*r1 + dist * dist - r2 * r2) / (2 * r1 * dist));
  return {c1 + polar(r1, arg(c2 - c1) + a), c1 + polar(r1, arg(c2 - c1) - a)};
}


int n;
P c[10];
int r[10];

bool check(double h){
  vector<P> cross_points;

  double R[10];

  for(int i=0;i<n;i++){
    R[i] = sqrt(r[i]*r[i] - h*h);
  }
  
  for(int i=0;i<n;i++){
    for(int j=i+1;j<n;j++){
      if(!isIntersectedCC(c[i],r[i],c[j],r[j])) continue;
      
      auto res = getCrosspointCC(c[i],R[i],c[j],R[j]);

      cross_points.push_back(res.first);
      cross_points.push_back(res.second);
    }
  }

  bool ok[10] = {};
  int ok_count = 0;
  
  for(int i=0;i<n;i++){
    for(int j=0;j<n;j++){
      if(i == j) continue;

      if(abs(c[i] - c[j]) + R[j] <= R[i]){
        ok_count += !ok[i];
        ok[i] = true;
      }
    }
  }

  if(ok_count == n-1){
    for(int i=0;i<n;i++){
      if(!ok[i]){
        return h <= r[i];
      }
    }
  }
  
  for(int i=0;i<cross_points.size();i++){
    bool flag = true;

    for(int j=0;j<n;j++){
      
      flag &= ok[j] || norm(cross_points[i]-c[j]) <= r[j]*r[j] - h*h + P_eps;
    }

    if(flag) return true;
  }

  return false;
}

bool solve(){
  
  scanf("%d",&n);

  if(n == 0) return false;
  
  for(int i=0;i<n;i++){
    int x,y;

    scanf("%d%d%d",&x,&y,r+i);

    c[i] = P(x,y);
  }

  if(n == 1){
    printf("%.10lf\n",(double2)r[0]);
    return true;
  }
  
  double l = 0, r = 500;

  while(r - l > 1e-10){
    double mid = (l + r)/2;
    
    if(check(mid)){
      l = mid;
    }else{
      r = mid;
    }
  }

  printf("%.10lf\n",(double2)r);
  
  return true;
}

int main(){
  
  while(solve());
  
  return 0;
}

Measured memory_bytes: 3540