#include <bits/stdc++.h>
 
#define FOR(i,k,n) for (int (i)=(k); (i)<(n); ++(i))
#define rep(i,n) FOR(i,0,n)
#define all(v) begin(v), end(v)
#define debug(x) cerr<< #x <<": "<<x<<endl
#define debug2(x,y) cerr<< #x <<": "<< x <<", "<< #y <<": "<< y <<endl

using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
typedef vector<int> vi;
typedef vector<vector<int> > vvi;
typedef vector<ll> vll;
typedef vector<vector<ll> > vvll;
template<class T> using vv=vector<vector< T > >;

#define EPS (1e-10)

struct Vector2 {
  //using T = double;
  double x, y;

  Vector2() : x(double(0)), y(double(0)) {}
  Vector2(double x_, double y_) : x(x_), y(y_) {}

  Vector2 operator + (const Vector2& v) const { return Vector2(x + v.x, y + v.y); }
  Vector2 operator - (const Vector2& v) const { return Vector2(x - v.x, y - v.y); }
  Vector2 operator * (const double& k) const { return Vector2(x * k, y * k); }
  Vector2 operator / (const double& k) const { return Vector2(x / k, y / k); }

  Vector2 operator *= (const double& k) { return Vector2(x * k, y * k); }

  double norm2() { return x * x + y * y; }
  double norm() { return sqrt(norm2()); }

  bool operator < (const Vector2& v) const {
    return x != v.x ? x < v.x : y < v.y;
  }
  bool operator == (const Vector2& v) const {
    return fabs(x - v.x) < EPS && fabs(y - v.y) < EPS;
  }

  double dot(const Vector2& v) { return x * v.x + y * v.y; }
  double cross(const Vector2& v) { return x * v.y - y * v.x; }
};

typedef Vector2 Point2;

struct Vector3 {
  //using T = double;
  double x, y, z;

  Vector3() : x(double(0)), y(double(0)), z(double(0)) {}
  Vector3(double x_, double y_, double z_) : x(x_), y(y_), z(z_) {}
  Vector3(Vector2 v, double z_) : x(v.x), y(v.y), z(z_) {}

  Vector3 operator + (const Vector3& v) const { return Vector3(x + v.x, y + v.y, z + v.z); }
  Vector3 operator - (const Vector3& v) const { return Vector3(x - v.x, y - v.y, z - v.z); }
  Vector3 operator * (const double& k) const { return Vector3(x * k, y * k, z * k); }
  Vector3 operator / (const double& k) const { return Vector3(x / k, y / k, z / k); }

  double norm2() { return x * x + y * y + z * z; }
  double norm() { return sqrt(norm2()); }

  bool operator < (const Vector3& v) const {
    if (x == v.x) {
      if (y == v.y) {
        return z <= v.z;
      }
      return y <= v.y;
    }
    return x <= v.x;
  }
  bool operator == (const Vector3& v) const {
    return fabs(x - v.x) < EPS && fabs(y - v.y) < EPS;
  }

  double dot(const Vector3& v) { return x * v.x + y * v.y + z * v.z; }
  Vector3 cross(const Vector3& v) {
    return Vector3(y * v.z - v.y * z,
                   z * v.x - v.z * x,
                   x * v.y - v.x * y);
  }

};

typedef Vector3 Point3;

struct Rope {
  double x, y, l;
  Rope() {}
  Rope(double x_, double y_, double l_) : x(x_), y(y_), l(l_) {}

  bool can_place(Rope rope) {
    auto dist = (Vector3(rope.x, rope.y, rope.l) - Vector3(x, y, 0)).norm();
    return (dist < l);
  }

  bool can_place(Vector3 p) {
    auto dist = (p - Vector3(x, y, 0)).norm();
    return (dist - EPS <= l);
  }
};

Vector3 highest_point(Rope A, Rope B) {
  auto AB = Vector3(B.x - A.x, B.y - A.y, 0);
  double a = B.l;
  double b = A.l;
  double c = AB.norm();
  double cosA = (b*b + c*c - a*a) / (2*b*c);
  double sinA = sqrt(1 - cosA*cosA);
  auto AC = Vector3(AB.x * cosA * b / c, AB.y * cosA * b / c, b * sinA);
  return Vector3(A.x, A.y, 0) + AC;
}

struct Circle2 {
  double x, y, r;
  Circle2() {}
  Circle2(double x_, double y_, double r_) : x(x_), y(y_), r(r_) {}
  Circle2(Rope rope) : x(rope.x), y(rope.y), r(rope.l) {}
};

struct Line2 {
  double a, b, c;
  Line2() {}
  Line2(double a_, double b_, double c_) : a(a_), b(b_), c(c_) {}
};

Vector3 rotate(Vector2 middle, Vector2 v, double alpha) {
  v *= cos(alpha);
  return Vector3(middle.x + v.x, middle.y + v.y, sin(alpha));
}

Vector3 highest_point(Rope A, Rope B, Rope C) {
  auto c1 = Circle2(A);
  auto c2 = Circle2(B);
  auto line = Line2(-2*c1.x + 2*c2.x, -2*c1.y + 2*c2.y, c1.x*c1.x + c1.y*c1.y - c1.r*c1.r - c2.x*c2.x - c2.y*c2.y + c2.r*c2.r);
  double d = line.a * c1.x + line.b * c1.y + line.c;
  double a2b2 = line.a*line.a + line.b*line.b;
  Vector2 middle;
  middle.x = (-line.a * d) / a2b2 + c1.x;
  middle.y = (-line.b * d) / a2b2 + c1.y;
  double root = sqrt(a2b2 * c1.r*c1.r - d*d);
  Vector2 v;
  v.x = line.b * root / a2b2;
  v.y = -line.a * root / a2b2;

  double a1 = 2 * (- (C.x - middle.x) * v.x - (C.y - middle.y) * v.y);
  double a0 = (C.x - middle.x) * (C.x - middle.x) + (C.y - middle.y) * (C.y - middle.y) + v.norm2() - C.l * C.l;
  double cosA = -a0 / a1;
  double sinA = sqrt(1 - cosA*cosA);
  return Vector3(middle.x + v.x * cosA, middle.y + v.y * cosA, v.norm() * sinA);
}

int main() {
  int n;
  while (true) {
    cin >> n;
    if (n == 0) {
      break;
    }
    vector<Rope> ropes(n);
    rep (i, n) {
      int x, y, l;
      scanf("%d %d %d", &x, &y, &l);
      ropes[i] = Rope(x, y, l);
    }
    if (n == 1) {
      printf("%.9f\n", ropes[0].l);
      continue;
    }
    if (n == 2) {
      double ans = 0;
      if (ropes[1].can_place(ropes[0])) {
        ans = max(ans, ropes[0].l);
      }
      if (ropes[0].can_place(ropes[1])) {
        ans = max(ans, ropes[1].l);
      }
      if (ans == 0) {
        ans = highest_point(ropes[0], ropes[1]).z;
      }
      printf("%.9f\n", ans);
      continue;
    }

    vector<Rope> theropes(3);
    double ans = DBL_MAX;
    rep (i, n) {
      theropes[0] = ropes[i];
      FOR (j, i+1, n) {
        theropes[1] = ropes[j];
        FOR (k, j+1, n) {
          double theans = 0;
          theropes[2] = ropes[k];
          //
          rep (ii, 3) {
            auto target = theropes[ii];
            auto checkA = theropes[(ii+1)%3];
            auto checkB = theropes[(ii+2)%3];
            if (checkA.can_place(target) && checkB.can_place(target)) {
              theans = max(theans, target.l);
            }
          }
          //debug(theans);
          if (theans == 0) {
            rep (ii, 3) {
              auto targetA = theropes[ii];
              auto targetB = theropes[(ii+1)%3];
              auto check = theropes[(ii+2)%3];
              auto target_point = highest_point(targetA, targetB);
              if (check.can_place(target_point)) {
                theans = max(theans, target_point.z);
              }
            }
          }
          //debug(theans);
          if (theans == 0) {
            theans = max(theans, highest_point(theropes[0], theropes[1], theropes[2]).z);
          }
          assert(theans > 0);
          ans = min(ans, theans);
        }
      }
    }
    printf("%.9f\n", ans);
  }
  return 0;
}

Measured memory_bytes: 3316