#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<vector>
using namespace std;
const int maxn = 1010;
int n;
struct Point
{
int x,y;
int p;
Point(const int& x = 0,const int& y = 0,const int& p =0 ):x(x),y(y),p(p){}
Point(const Point& rsh)
{
this->x = rsh.x;
this->y = rsh.y;
this->p = rsh.p;
}
};
vector<Point>points;
struct Edge
{
int from,to;
double w;
Edge(const int& from = 0,const int& to = 0,const double& w = 0.0):from(from),to(to),w(w){}
Edge(const Edge& rsh)
{
this->from = rsh.from;
this->to = rsh.to;
this->w = rsh.w;
}
bool operator < (const Edge& rsh) const
{
return this->w < rsh.w;
}
};
vector<Edge>edges;
double dis(Point& A,Point& B)
{
return sqrt((double)(A.x - B.x)*(A.x - B.x) + (A.y - B.y)*(A.y - B.y));
}
int root[maxn];
void init_set(int n)
{
for(int i = 0 ; i < n ; i++)
{
root[i] = i;
}
}
int find_set(int x)
{
if(x != root[x])
{
root[x] = find_set(root[x]);
}
return root[x];
}
void union_set(int a,int b)
{
int x = find_set(a);
int y = find_set(b);
if(x != y)
{
root[x] = y;
}
}
double Tree[maxn][maxn];
double maxcost[maxn][maxn];
vector<int>nodes;
void init()
{
init_set(n);
points.clear();
edges.clear();
nodes.clear();
memset(maxcost,0,sizeof(maxcost));
memset(Tree,0,sizeof(Tree));
}
void dfs(int u,int fa,double facost)
{
for(int i = 0 ; i < nodes.size() ; i++)
{
int x = nodes[i];
maxcost[u][x] = maxcost[x][u] = max(maxcost[x][fa],facost);
}
nodes.push_back(u);
for(int i = 0 ; i < n ; i++)
{
if(i != fa && Tree[u][i] != 0)
{
dfs(i,u,Tree[i][u]);
}
}
}
int main()
{
#ifdef LOCAL
freopen("in.txt","r",stdin);
#endif
int ncase;
scanf("%d",&ncase);
while(ncase--)
{
scanf("%d",&n);
int x,y,p;
int from,to;
double w;
init();
for(int i = 0 ; i < n ; i++)
{
scanf("%d %d %d",&x,&y,&p);
points.push_back(Point(x,y,p));
}
for(int i = 0 ; i < n ; i++)
{
for(int j = i + 1 ; j < n ; j++)
{
from = i;
to = j;
w = dis(points[i],points[j]);
edges.push_back(Edge(from,to,w));
}
}
sort(edges.begin(),edges.end());
double mst =0;
for(int i = 0 ; i < edges.size() ; i++)
{
from = edges[i].from;
to = edges[i].to;
w = edges[i].w;
if(find_set(from) != find_set(to))
{
union_set(from,to);
mst += w;
Tree[from][to] = Tree[to][from] = w;
}
}
dfs(0,-1,0);
double ans = -1;
for(int i = 0 ; i < n ; i++)
{
for(int j = i + 1 ; j < n ; j++)
{
ans = max(ans,((double)(points[i].p + points[j].p))/ (mst - maxcost[i][j]));
}
}
printf("%.2lf\n",ans);
}
return 0;
}