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

using VI = vector<int>;
using VVI = vector<VI>;
using PII = pair<int, int>;
using LL = long long;
using VL = vector<LL>;
using VVL = vector<VL>;
using PLL = pair<LL, LL>;
using VS = vector<string>;

#define ALL(a)  begin((a)),end((a))
#define RALL(a) (a).rbegin(), (a).rend()
#define PB push_back
#define EB emplace_back
#define MP make_pair
#define SZ(a) int((a).size())
#define SORT(c) sort(ALL((c)))
#define RSORT(c) sort(RALL((c)))

#define FOR(i,a,b) for(int i=(a);i<(b);++i)
#define REP(i,n)  FOR(i,0,n)

#define FF first
#define SS second
template<class S, class T>
istream& operator>>(istream& is, pair<S,T>& p){
  return is >> p.FF >> p.SS;
}
template<class S, class T>
ostream& operator<<(ostream& os, pair<S,T>& p){
  return os << p.FF << " " << p.SS;
}
template<class T>
void maxi(T& x, T y){
  if(x < y) x = y;
}
template<class T>
void mini(T& x, T y){
  if(x > y) x = y;
}

const double EPS = 1e-10;
const double PI  = acos(-1.0);
const LL MOD = 1e9+7;

class Point{
public:
  double x, y;

  Point(double x = 0.0, double y = 0.0) : x(x), y(y){}

  Point operator + (const Point& p) const{ return Point(x + p.x, y + p.y); }
  Point& operator += (const Point& p){ x += p.x; y += p.y; return *this;}
  Point operator - (const Point& p) const{ return Point(x - p.x, y - p.y); }
  Point& operator -= (const Point& p){ x -= p.x; y -= p.y; return *this;}
  Point operator * (double a) const{ return Point(a*x, a*y); }
  Point& operator *= (double a){ x *= a; y *= a; return *this;}
  Point operator / (double a) const{ return Point(x / a, y / a); }
  Point& operator /= (double a){ x /= a; y /= a; return *this;}

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

class Circle{
public:
	Point c;
	double r;
};
typedef Point Vector;

double dot(Vector a, Vector b){
	return a.x*b.x + a.y*b.y;
}
double cross(Vector a, Vector b){
	return a.x*b.y - a.y*b.x;
}
Point rotate(Point p,double angle){
  return Point(p.x*cos(angle) - p.y*sin(angle),
			   p.x*sin(angle) + p.y*cos(angle));
}

pair<Point, Point> getCrossPoints(const Circle& c1, const Circle& c2){
  double d = (c2.c - c1.c).abs();
  double a = (c1.r*c1.r + d*d - c2.r*c2.r) / (2*d);
  Vector e = (c2.c - c1.c) / d;
  Vector h = rotate(e, PI/2) * sqrt(max(c1.r*c1.r - a*a, 0.));
  if(d + min(c1.r, c2.r) <= max(c1.r, c2.r))
	return MP(c1.c + e*c1.r, c1.c + e*c1.r);

  return MP(c1.c + e*a + h, c1.c + e*a - h);
}

// ??????????????§?????¢???????????????
// ?????????????????°???O(N^2)
void partCircles(const vector<Circle>& cs, set<LL>& res){
  int N = SZ(cs);
  vector<Point> ps;
  REP(i,N) REP(j,N){
	if(i == j) continue;
	auto cc = getCrossPoints(cs[i], cs[j]);
	Point crossPoints[2] = {cc.FF, cc.SS};
	REP(k,2){
	  Vector delta = crossPoints[1-k] - crossPoints[k];
	  if(delta.abs() == 0)
		delta = crossPoints[k] - cs[i].c;
	  delta /= delta.abs();
	  REP(d,4){
		ps.PB(crossPoints[k] + delta*EPS);
		delta = rotate(delta, PI/2);
	  }
	}
  }

  for(auto&& p: ps){
	LL bit = 0;
	REP(i,N)
	  if((cs[i].c - p).abs() < cs[i].r)
		bit |= 1LL<<i;
	res.insert(bit);
  }
}

// ?????¢?????´?????§??????????????¨????????????????????????????????????
// ????????????O(N^2)
void partPoints(vector<Point> ps, set<PLL>& res){
  int N = SZ(ps);
  REP(i,N){
	Vector e(0,1);
	REP(d,4){
	  ps.PB(ps[i]+e*EPS);
	  e = rotate(e, PI/2);
	}
  }
  
  REP(i,SZ(ps)) REP(j,SZ(ps)){
	if(i == j) continue;
	Point p1 = ps[i];
	Point p2 = ps[j];
	Vector e = p2 - p1;
	e /= e.abs();
	e = rotate(e, PI/2);
	LL b1 = 0, b2 = 0;
	REP(k,N)
	  if(dot(e, ps[k]-p1) >= 0)
		b1 |= 1LL<<k;
	  else
		b2 |= 1LL<<k;
	if(b1 > b2) swap(b1, b2);
	res.insert(MP(b1,b2));
  }
}

int N, M;
double calcBest(LL bps, LL bcs, VI& as, vector<double>& vs, vector<Circle>& cs){
  Point q(0, 0);
  double inv = 0.;
  REP(i,M){
	if((bcs>>i&1) == 0 || (bps>>as[i]&1) == 0) continue;
	double tmp = 1. / (vs[i] * vs[i]);
	q.x += cs[i].c.x * tmp;
	q.y += cs[i].c.y * tmp;
	inv += tmp;
  }
  if(inv <= 0) return 0;
  q.x /= inv;
  q.y /= inv;

  double res = 0.;
  REP(i,M){
	if((bcs>>i&1) == 0 || (bps>>as[i]&1) == 0) continue;
	res += ((cs[i].c - q).norm() - (cs[i].r * cs[i].r)) / (vs[i] * vs[i]);
  }
  return res;
}

int main(){
  cin.tie(0);
  ios_base::sync_with_stdio(false);

  while(cin>>N>>M,N){
	vector<Point> ps(N);
	REP(i,N) cin >> ps[i].x >> ps[i].y;
	VI as(M), bs(M);
	vector<double> vs(M);
	vector<Circle> cs(M);
	REP(i,M){
	  cin >> as[i] >> bs[i] >> vs[i];
	  --as[i];
	  --bs[i];
	  cs[i].c = ps[as[i]];
	  cs[i].r = (ps[bs[i]] - ps[as[i]]).abs();
	}
	if(M <= 2){
	  cout << fixed << setprecision(9) << 0. << endl;
	  continue;
	}

	set<LL> planes;
	set<PLL> points;
	partCircles(cs, planes);
	partPoints(ps, points);

	double best = 0.;
	for(auto&& bpos: points){
	  double d1 = 0, d2 = 0;
	  for(auto&& bpls: planes){
		mini(d1, calcBest(bpos.FF, bpls, as, vs, cs));
		mini(d2, calcBest(bpos.SS, bpls, as, vs, cs));
	  }
	  mini(best, d1+d2);
	}

	double ans = 0;
	REP(i,M) ans += pow(cs[i].r / vs[i], 2);
	cout << fixed << setprecision(9) << sqrt((ans+best)/M) << endl;
  }

  return 0;
}
### Prompt

In CPP, your task is to solve the following problem:

Warp Drive

<image>

The warp drive technology is reforming air travel, making the travel times drastically shorter. Aircraft reaching above the warp fields built on the ground surface can be transferred to any desired destination in a twinkling.

With the current immature technology, however, building warp fields is quite expensive. Our budget allows building only two of them. Fortunately, the cost does not depend on the locations of the warp fields, and we can build them anywhere on the ground surface, even at an airport.

Your task is, given locations of airports and a list of one way flights among them, find the best locations to build the two warp fields that give the minimal average cost. The average cost is the root mean square of travel times of all the flights, defined as follows.

<image>

Here, m is the number of flights and tj is the shortest possible travel time of the j-th flight. Note that the value of tj depends on the locations of the warp fields.

For simplicity, we approximate the surface of the ground by a flat two dimensional plane, and approximate airports, aircraft, and warp fields by points on the plane. Different flights use different aircraft with possibly different cruising speeds. Times required for climb, acceleration, deceleration and descent are negligible. Further, when an aircraft reaches above a warp field, time required after that to its destination is zero. As is explained below, the airports have integral coordinates. Note, however, that the warp fields can have non-integer coordinates.

Input

The input consists of at most 35 datasets, each in the following format.

n m
x1 y1
...
xn yn
a1 b1 v1
...
am bm vm


n is the number of airports, and m is the number of flights (2 ≤ n ≤ 20, 2 ≤ m ≤ 40). For each i, xi and yi are the coordinates of the i-th airport. xi and yi are integers with absolute values at most 1000. For each j, aj and bj are integers between 1 and n inclusive, and are the indices of the departure and arrival airports for the j-th flight, respectively. vj is the cruising speed for the j-th flight, that is, the distance that the aircraft of the flight moves in one time unit. vj is a decimal fraction with two digits after the decimal point (1 ≤ vj ≤ 10).

The following are guaranteed.

* Two different airports have different coordinates.
* The departure and arrival airports of any of the flights are different.
* Two different flights have different departure airport and/or arrival airport.



The end of the input is indicated by a line containing two zeros.

Output

For each dataset, output the average cost when you place the two warp fields optimally. The output should not contain an absolute error greater than 10-6.

Sample Input


3 4
100 4
100 0
0 0
1 2 1.00
2 1 1.00
3 1 9.99
3 2 9.99
7 6
0 0
1 0
2 0
0 10
1 10
2 10
20 5
1 7 1.00
2 7 1.00
3 7 1.00
4 7 1.00
5 7 1.00
6 7 1.00
4 4
-1 -1
1 -1
-1 1
1 1
1 4 1.10
4 2 2.10
2 3 3.10
3 1 4.10
8 12
-91 0
-62 0
-18 0
2 0
23 0
55 0
63 0
80 0
2 7 3.96
3 2 2.25
2 4 5.48
8 7 9.74
5 6 6.70
7 6 1.51
4 1 7.41
5 8 1.11
6 3 2.98
3 4 2.75
1 8 5.89
4 5 5.37
0 0


Output for the Sample Input


1.414214
0.816497
0.356001
5.854704






Example

Input

3 4
100 4
100 0
0 0
1 2 1.00
2 1 1.00
3 1 9.99
3 2 9.99
7 6
0 0
1 0
2 0
0 10
1 10
2 10
20 5
1 7 1.00
2 7 1.00
3 7 1.00
4 7 1.00
5 7 1.00
6 7 1.00
4 4
-1 -1
1 -1
-1 1
1 1
1 4 1.10
4 2 2.10
2 3 3.10
3 1 4.10
8 12
-91 0
-62 0
-18 0
2 0
23 0
55 0
63 0
80 0
2 7 3.96
3 2 2.25
2 4 5.48
8 7 9.74
5 6 6.70
7 6 1.51
4 1 7.41
5 8 1.11
6 3 2.98
3 4 2.75
1 8 5.89
4 5 5.37
0 0


Output

1.414214
0.816497
0.356001
5.854704

### Response

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

using VI = vector<int>;
using VVI = vector<VI>;
using PII = pair<int, int>;
using LL = long long;
using VL = vector<LL>;
using VVL = vector<VL>;
using PLL = pair<LL, LL>;
using VS = vector<string>;

#define ALL(a)  begin((a)),end((a))
#define RALL(a) (a).rbegin(), (a).rend()
#define PB push_back
#define EB emplace_back
#define MP make_pair
#define SZ(a) int((a).size())
#define SORT(c) sort(ALL((c)))
#define RSORT(c) sort(RALL((c)))

#define FOR(i,a,b) for(int i=(a);i<(b);++i)
#define REP(i,n)  FOR(i,0,n)

#define FF first
#define SS second
template<class S, class T>
istream& operator>>(istream& is, pair<S,T>& p){
  return is >> p.FF >> p.SS;
}
template<class S, class T>
ostream& operator<<(ostream& os, pair<S,T>& p){
  return os << p.FF << " " << p.SS;
}
template<class T>
void maxi(T& x, T y){
  if(x < y) x = y;
}
template<class T>
void mini(T& x, T y){
  if(x > y) x = y;
}

const double EPS = 1e-10;
const double PI  = acos(-1.0);
const LL MOD = 1e9+7;

class Point{
public:
  double x, y;

  Point(double x = 0.0, double y = 0.0) : x(x), y(y){}

  Point operator + (const Point& p) const{ return Point(x + p.x, y + p.y); }
  Point& operator += (const Point& p){ x += p.x; y += p.y; return *this;}
  Point operator - (const Point& p) const{ return Point(x - p.x, y - p.y); }
  Point& operator -= (const Point& p){ x -= p.x; y -= p.y; return *this;}
  Point operator * (double a) const{ return Point(a*x, a*y); }
  Point& operator *= (double a){ x *= a; y *= a; return *this;}
  Point operator / (double a) const{ return Point(x / a, y / a); }
  Point& operator /= (double a){ x /= a; y /= a; return *this;}

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

class Circle{
public:
	Point c;
	double r;
};
typedef Point Vector;

double dot(Vector a, Vector b){
	return a.x*b.x + a.y*b.y;
}
double cross(Vector a, Vector b){
	return a.x*b.y - a.y*b.x;
}
Point rotate(Point p,double angle){
  return Point(p.x*cos(angle) - p.y*sin(angle),
			   p.x*sin(angle) + p.y*cos(angle));
}

pair<Point, Point> getCrossPoints(const Circle& c1, const Circle& c2){
  double d = (c2.c - c1.c).abs();
  double a = (c1.r*c1.r + d*d - c2.r*c2.r) / (2*d);
  Vector e = (c2.c - c1.c) / d;
  Vector h = rotate(e, PI/2) * sqrt(max(c1.r*c1.r - a*a, 0.));
  if(d + min(c1.r, c2.r) <= max(c1.r, c2.r))
	return MP(c1.c + e*c1.r, c1.c + e*c1.r);

  return MP(c1.c + e*a + h, c1.c + e*a - h);
}

// ??????????????§?????¢???????????????
// ?????????????????°???O(N^2)
void partCircles(const vector<Circle>& cs, set<LL>& res){
  int N = SZ(cs);
  vector<Point> ps;
  REP(i,N) REP(j,N){
	if(i == j) continue;
	auto cc = getCrossPoints(cs[i], cs[j]);
	Point crossPoints[2] = {cc.FF, cc.SS};
	REP(k,2){
	  Vector delta = crossPoints[1-k] - crossPoints[k];
	  if(delta.abs() == 0)
		delta = crossPoints[k] - cs[i].c;
	  delta /= delta.abs();
	  REP(d,4){
		ps.PB(crossPoints[k] + delta*EPS);
		delta = rotate(delta, PI/2);
	  }
	}
  }

  for(auto&& p: ps){
	LL bit = 0;
	REP(i,N)
	  if((cs[i].c - p).abs() < cs[i].r)
		bit |= 1LL<<i;
	res.insert(bit);
  }
}

// ?????¢?????´?????§??????????????¨????????????????????????????????????
// ????????????O(N^2)
void partPoints(vector<Point> ps, set<PLL>& res){
  int N = SZ(ps);
  REP(i,N){
	Vector e(0,1);
	REP(d,4){
	  ps.PB(ps[i]+e*EPS);
	  e = rotate(e, PI/2);
	}
  }
  
  REP(i,SZ(ps)) REP(j,SZ(ps)){
	if(i == j) continue;
	Point p1 = ps[i];
	Point p2 = ps[j];
	Vector e = p2 - p1;
	e /= e.abs();
	e = rotate(e, PI/2);
	LL b1 = 0, b2 = 0;
	REP(k,N)
	  if(dot(e, ps[k]-p1) >= 0)
		b1 |= 1LL<<k;
	  else
		b2 |= 1LL<<k;
	if(b1 > b2) swap(b1, b2);
	res.insert(MP(b1,b2));
  }
}

int N, M;
double calcBest(LL bps, LL bcs, VI& as, vector<double>& vs, vector<Circle>& cs){
  Point q(0, 0);
  double inv = 0.;
  REP(i,M){
	if((bcs>>i&1) == 0 || (bps>>as[i]&1) == 0) continue;
	double tmp = 1. / (vs[i] * vs[i]);
	q.x += cs[i].c.x * tmp;
	q.y += cs[i].c.y * tmp;
	inv += tmp;
  }
  if(inv <= 0) return 0;
  q.x /= inv;
  q.y /= inv;

  double res = 0.;
  REP(i,M){
	if((bcs>>i&1) == 0 || (bps>>as[i]&1) == 0) continue;
	res += ((cs[i].c - q).norm() - (cs[i].r * cs[i].r)) / (vs[i] * vs[i]);
  }
  return res;
}

int main(){
  cin.tie(0);
  ios_base::sync_with_stdio(false);

  while(cin>>N>>M,N){
	vector<Point> ps(N);
	REP(i,N) cin >> ps[i].x >> ps[i].y;
	VI as(M), bs(M);
	vector<double> vs(M);
	vector<Circle> cs(M);
	REP(i,M){
	  cin >> as[i] >> bs[i] >> vs[i];
	  --as[i];
	  --bs[i];
	  cs[i].c = ps[as[i]];
	  cs[i].r = (ps[bs[i]] - ps[as[i]]).abs();
	}
	if(M <= 2){
	  cout << fixed << setprecision(9) << 0. << endl;
	  continue;
	}

	set<LL> planes;
	set<PLL> points;
	partCircles(cs, planes);
	partPoints(ps, points);

	double best = 0.;
	for(auto&& bpos: points){
	  double d1 = 0, d2 = 0;
	  for(auto&& bpls: planes){
		mini(d1, calcBest(bpos.FF, bpls, as, vs, cs));
		mini(d2, calcBest(bpos.SS, bpls, as, vs, cs));
	  }
	  mini(best, d1+d2);
	}

	double ans = 0;
	REP(i,M) ans += pow(cs[i].r / vs[i], 2);
	cout << fixed << setprecision(9) << sqrt((ans+best)/M) << endl;
  }

  return 0;
}
```