Problem: Problem

KND is a student programmer at the University of Aizu. He is known to be a sweet tooth. He will be staying in a city for a year and wants to visit all N sweets shops in the city during that time. So I think the best place to live for the past year is the best place to go around the sweets shop. As his neighbor, you have to find a place that minimizes the worst travel time to each sweets shop. The city where this sweets shop is located is represented by a two-dimensional plane for the sake of simplicity. He travels a different distance per unit time depending on his motivation for the desired sweets shop. He also intends to live anywhere (even in the same place as the sweets shop). KND is uncompromising when it comes to sweetness.

Constraints

The input satisfies the following conditions.

* All inputs are integers.
* 2 ≤ N ≤ 100
* 0 ≤ xi, yi ≤ 100
* 1 ≤ vi ≤ 100 (1 ≤ i ≤ N)
* xi ≠ xj or yi ≠ yj (where 1 ≤ i <j ≤ N)

Input

The input consists of multiple test cases. One test case is given in the following format. Indicates the end of input when N = 0.


N
x1 y1 v1
x2 y2 v2
...
xN yN vN


here,

* N: Number of sweets shops
* xi: x-coordinate of the i-th sweetener
* yi: y coordinate of the i-th sweets shop
* vi: Distance traveled per unit time when moving to the i-th sweets shop



Is.

Output

Output the minimum travel time for each test case on one line. This value should not differ more than 10-5 from the value of the judge output.

Example

Input

2
1 1 1
2 2 1
4
1 1 3
3 1 3
4 2 1
1 5 3
0


Output

0.70710678
1.06066017

Solution (in CPP):

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

/*                         */
/*                         */
/* @@ Geometory Library @@ */
/*               by ei1333 */
/*                         */
const double EPS = 1e-8, PI = acos(-1);
 
inline bool eq(double a,double b){ return abs(b - a) < EPS; }
#define curr(P,i) P[i]
#define next(P,i) P[(i+1)%P.size()]
#define prev(P,i) P[(i+P.size()-1) % P.size()]
enum { OUT, ON, IN };
struct Geometory { // Geometory Library
  struct Point {
    double x, y;
    Point(){};
    Point(double x,double y):x(x),y(y){};
    Point operator+(const Point& b) const { return Point(x + b.x,y + b.y); }
    Point operator-(const Point& b) const { return Point(x - b.x,y - b.y); }
    Point operator*(const double b) const { return Point(x * b,y * b); }
    Point operator*(const Point& b) const { return Point(x * b.x - y * b.y,x * b.y + y * b.x); }
    Point operator/(const double b) const { return Point(x / b,y / b); }
    bool operator< (const Point& b) const { return x != b.x ? x < b.x : y < b.y;}
    bool operator==(const Point& b) const { return eq(x,b.x) && eq(y,b.y); }
    double norm(){ return x * x + y * y; }
    double arg(){ return atan2(x,y); }
    double abs(){ return sqrt(norm()); }
    Point rotate(double theta){ return Point(cos(theta) * x - sin(theta) * y,sin(theta) * x + cos(theta) * y); }
    Point rotate90(){ return Point(-y,x); }
    friend ostream& operator<<(ostream& os, Point& p){ return os<<"("<<p.x<<","<<p.y<<")"; }
    friend istream& operator>>(istream& is, Point& a){ return is>>a.x>>a.y; }
  };
    
  struct Line {
    Point a, b;
    Line(){};
    Line(Point a,Point b):a(a),b(b){};
    friend ostream& operator<<(ostream& os, Line& p){ return os<<"("<<p.a.x<<","<<p.a.y<<") to ("<<p.b.x<<","<<p.b.y<<")"; }
    friend istream& operator>>(istream& is, Line& a){ return is>>a.a.x>>a.a.y>>a.b.x>>a.b.y; }
  };
  struct Segment {
    Point a, b;
    Segment(){};
    Segment(Point a,Point b):a(a),b(b){};
    friend ostream& operator<<(ostream& os, Segment& p){ return os<<"("<<p.a.x<<","<<p.a.y<<") to ("<<p.b.x<<","<<p.b.y<<")"; }
    friend istream& operator>>(istream& is, Segment& a){ return is>>a.a.x>>a.a.y>>a.b.x>>a.b.y; }
  };
  struct Circle {
    Point p; double r;
    Circle(){};
    Circle(Point p, double r) : p(p),r(r){};
  };
  typedef vector< Point > Polygon;
  typedef vector< Segment > Segments;
  typedef vector< Line > Lines;
  typedef vector< Circle > Circles;
  typedef pair< Point, Point > PointPoint;
    
  double cross(const Point& a,const Point& b){
    return a.x * b.y - a.y * b.x;
  }
  double dot(const Point& a,const Point& b){
    return a.x * b.x + a.y * b.y;
  }
    
  int ccw(const Point& a,Point b,Point c){
    b = b - a, c = c - a;
    if(cross(b,c) > EPS)    return +1;  // a → b で 反時計方向におれて c
    if(cross(b,c) < -EPS)    return -1; // a → b で 時計方向におれて c
    if(dot(b,c) < 0)      return +2;  // c -- a -- bで一直線上
    if(b.norm() < c.norm()) return -2; // a -- b -- cで一直線上
    return 0;  // a -- c -- bで一直線上
  }
  Point Projection(const Line& l, const Point& p){
    double t = dot( p - l.a, l.a - l.b) / (l.a - l.b).norm();
    return l.a + (l.a - l.b) * t;
  }
  Point Projection(const Segment& l, const Point& p){
    double t = dot( p - l.a, l.a - l.b) / (l.a - l.b).norm();
    return l.a + (l.a - l.b) * t;
  }
  Point Reflection(const Line& l, const Point& p){
    return p + (Projection( l, p) - p) * 2.0;
  }
    
  double Distance( const Line& l,const Point& p) { //OK
    return (p - Projection( l, p)).abs();
  }
    
  bool Intersect(const Line& l, const Line& m){
    return abs(cross(l.b - l.a, m.b - m.a)) > EPS || abs(cross(l.b-l.a, m.b-l.a)) < EPS;
  }
  bool Intersect(const Line& l, const Segment& s){
    return cross( l.b - l.a, s.a - l.a) * cross( l.b - l.a, s.b - l.a) < EPS;
  }
  bool Intersect(const Line& l, const Point& p){
    return abs(ccw(l.a, l.b, p)) != -1;
  }
  bool Intersect(const Segment& s, const Segment& t){
    return ccw(s.a, s.b, t.a) * ccw(s.a, s.b, t.b) <= 0 && ccw(t.a, t.b, s.a) * ccw(t.a, t.b, s.b) <= 0;
  }
  bool Intersect(const Segment& s, const Point& p){
    return ccw(s.a, s.b, p) == 0;
  }
  bool Intersect(const Circle& c,const Line& l){
    return Distance( l, c.p) <= c.r + EPS;
  }
  bool Intersect(const Circle& c,const Point& p){
    return abs( ( p - c.p).abs() - c.r ) < EPS;
  }
  int Intersect(const Circle& c, const Segment& l){
    if( (Projection( l, c.p) - c.p).norm() - c.r * c.r > EPS) return 0;
    const double d1 = ( c.p - l.a).abs(), d2 = ( c.p - l.b).abs();
    if( d1 < c.r + EPS && d2 < c.r + EPS) return 0;
    if( d1 < c.r - EPS && d2 > c.r + EPS || d1 > c.r + EPS && d2 < c.r - EPS ) return 1;
    const Point h = Projection( l, c.p);
    if( dot( l.a - h, l.b - h) < 0) return 2;
    return 0;
  }
  bool Intersect(const Circle& a,const Circle& b){
    return ( ( a.p - b.p).norm() - ( a.r + b.r) * ( a.r + b.r) < EPS) &&
      ( ( a.p - b.p).norm() - ( a.r - b.r) * ( a.r - b.r) > -EPS);
  }
  double Distance(const Segment& s,const Point& p){
    Point r = Projection(s, p);
    if ( Intersect( s, r)) return ( r - p).abs();
    return min( ( s.a - p).abs(), ( s.b - p).abs());
  }
  double Distance(const Segment& a,const Segment& b){
    if(Intersect( a, b)) return 0;
    return min( min( Distance( a, b.a), Distance( a, b.b)), min( Distance( b, a.a), Distance( b, a.b)));
  }
  double Distance(const Line& l,const Line& m) {
    return Intersect( l, m) ? 0 : Distance( l, m.a);
  }
  double Distance(const Line& l,const Segment& s) { //OK
    if (Intersect(l, s)) return 0;
    return min(Distance(l, s.a), Distance(l, s.b));
  }
  double Distance(const Point& a,const Point& b){ //OK
    return ( a - b).abs();
  }
  Point Crosspoint(const Segment& l,const Segment& m) { //OK
    double A = cross(l.b - l.a, m.b - m.a);
    double B = cross(l.b - l.a, l.b - m.a);
    if (abs(A) < EPS && abs(B) < EPS) return m.a; // same line
    return m.a + (m.b - m.a) * B / A;
  }
  PointPoint Crosspoint(const Circle& c,const Line l){
    Point hp = Projection( l, c.p), h =  hp - c.p;
    const double d2 = h.norm();
    Point v = ( l.b - l.a) * sqrt( c.r * c.r - d2) / ( l.b - l.a).abs();
    return PointPoint(hp - v, hp + v);
  }
  PointPoint Crosspoint(const Circle& c,const Segment& l) {
    Line aa = Line( l.a, l.b);
    if(Intersect(c, l) == 2) return Crosspoint(c, aa);
    PointPoint ret = Crosspoint(c, aa);
    if(dot(l.a - ret.first, l.b - ret.first) < 0) ret.second = ret.first;
    else ret.first = ret.second;
    return ret;
  }
  PointPoint Crosspoint(const Circle& c1,const Circle& c2){ //OK
    double d = (c1.p - c2.p).abs();
    double s = (c1.r + c2.r + d) / 2;
    double S = sqrt( s * ( s - c1.r) * ( s - c2.r) * ( s - d));
    double h = 2 * S / d;
    Point v = ( c2.p - c1.p) / ( c2.p - c1.p).abs();
    double m = sqrt( c1.r * c1.r - h * h);
    return PointPoint( c1.p + v * m + Point(0,1) * h * v, c1.p + v * m - Point(0,1) * h * v);
  }
  bool parallel(const Line& a,const Line& b){
    return abs(cross( a.b - a.a, b.b - b.a)) < EPS;
  }
  bool orthogonal(const Line& a,const Line& b){
    return abs(dot( a.a - a.b, b.a - b.b)) < EPS;
  }
  int Contains(const Polygon& Q,const Point& p){
    bool in = false;
    for(int i = 0 ; i < Q.size() ; i++ ){
      Point a = curr(Q,i) - p, b = next(Q,i) - p;
      if(a.y > b.y) swap(a,b);
      if(a.y <= 0 && 0 < b.y && cross(a,b) < 0) in = !in;
      if(cross(a,b) == 0 && dot(a,b) <= 0) return ON;
    }
    return in ? IN : OUT;
  }
  bool Contains(const Circle& c,const Point& p){
    return ( c.p - p).abs() < c.r + EPS;
  }
  double Area2(const Polygon& p){ //OK
    double A = 0;
    for (int i = 0; i < p.size(); ++i){
      A += cross(curr(p, i), next(p, i));
    }
    return A;
  }
  bool IsConvex(const Polygon& p){
    for(int i = 0; i < p.size(); i++){
      if(ccw(prev(p,i),curr(p,i),next(p,i)) == -1) return false;
    }
    return true;
  }
  Polygon Convex_Hull(Polygon& p){
    int n = p.size(), k = 0;
    if(n >= 3){
      sort( p.begin(), p.end());
      vector< Point > ch(2 * n);
      for(int i = 0; i < n; ch[k++] = p[i++]){
        while(k >= 2 && cross( ch[k - 1] - ch[k - 2], p[i] - ch[k - 1]) < 0) --k;
      }
      for(int i = n - 2, t = k + 1; i >= 0; ch[k++] = p[i--]){
        while(k >= t && cross( ch[k - 1] - ch[k - 2], p[i] - ch[k - 1]) < 0) --k;
      }
      ch.resize( k - 1);
      return ch;
    } else {
      return p;
    }
  }
  double Convex_Diameter(Polygon& p){
    int n = p.size();
    int is = 0, js = 0;
    for(int i = 1; i < n; i++){
      if(p[i].y > p[is].y) is = i;
      if(p[i].y < p[js].y) js = i;
    }
    double maxdis = ( p[is] - p[js]).norm();
  
    int maxi, maxj, i, j;
    i = maxi = is;
    j = maxj = js;
    do {
      if(cross( next( p, i) - curr( p, i), next( p, j) - curr( p, j)) >= 0){
        j = (j + 1) % n;
      } else {
        i = (i + 1) % n;
      }
      if(( p[i] - p[j]).norm() > maxdis){
        maxdis = ( p[i] - p[j]).norm();
        maxi = i; maxj = j;
      }
    }  while (i != is || j != js);
    return maxdis;
  }
};
  
Geometory geo;
typedef Geometory::Point P;
typedef Geometory::Line L;
typedef Geometory::Segment S;
typedef Geometory::Circle C;

int N, x[100], y[100], v[100];

bool calc(double value) /* value の円で全部の円がくっつくかどうか */
{
  vector< P > pts;
  for(int i = 0; i < N; i++) {
    pts.push_back(P(x[i], y[i]));
  }
  for(int i = 0; i < N; i++) {
    for(int j = N - 1; j > i; j--) {
      if(!geo.Intersect(C(P(x[i], y[i]), value * v[i]), C(P(x[j], y[j]), value * v[j]))) continue;

      Geometory::PointPoint pi = geo.Crosspoint(C(P(x[i], y[i]), value * v[i]), C(P(x[j], y[j]), value * v[j]));
      pts.push_back(pi.first);
      pts.push_back(pi.second);
    }
  }
  for(int j = 0; j < pts.size(); j++) {
    int i;
    for(i = 0; i < N; i++) {
      double dist = sqrt((x[i] - pts[j].x) * (x[i] - pts[j].x) + (y[i] - pts[j].y) * (y[i] - pts[j].y));
      if(dist > value * v[i] + EPS) break; 
    }
    if(i == N) return(true);
  }
  return(false);
}

int main()
{  
  while(cin >> N, N) {
    for(int i = 0; i < N; i++) {
      cin >> x[i] >> y[i] >> v[i];
    }
    double low = 0, high = 1e5;
    for(int i = 0; i < 100; i++) {
      double mid = (low + high) / 2;
      if(calc(mid)) high = mid;
      else low = mid;
    }
    cout << fixed << setprecision(10) << (low + high) / 2 << endl;
  }
}