#include<bits/stdc++.h> using namespace std; struct node{ int u, v, w, nex; bool gone; node(){} node(int a,int b,int c){ u = a;v = b;w = c;gone = false; } bool operator <(const node&a)const{ return w < a.w; } }; const int maxE = 1000100; const int maxP = 100010; node Gra[maxE]; int dp[maxP], F[maxP]; int T,n,m; long long ans; double edgeSum; vector<pair<int, int> >mp[maxP]; int Find(int x){ if(F[x] == x) return x; return F[x] = Find(F[x]); } void init(int nn){ for(int i = 0; i <= nn; i ++){ F[i] = i; mp[i].clear(); } edgeSum = 0; ans = 0; } int dfs(int rt, int no){ int point = 1; for(int i = mp[rt].size() - 1; i >=0; i --){ int to = mp[rt][i].first; int w = mp[rt][i].second; if(to == no) continue; point += dfs(to, rt); double temp = ((double)dp[to] * (double)(n - dp[to]) * w); edgeSum += temp; } dp[rt] = point; return point; } int main(){ int w,v,u;scanf("%d",&T); while(T --){ scanf("%d%d",&n,&m); init(n); for(int i = 0; i < m; i ++){ scanf("%d%d%d",&Gra[i].u,&Gra[i].v,&Gra[i].w); } sort(Gra, Gra + m); for(int i = 0; i < m; i ++){ u = Gra[i].u;v = Gra[i].v;w = Gra[i].w; int fina = Find(u), finb = Find(v); if(fina != finb){ F[fina] = finb; ans = ans + w; mp[u].push_back(make_pair(v,w)); mp[v].push_back(make_pair(u,w)); } } dfs(1, 1); printf("%lld %.2lf ",ans,edgeSum*2.0/n/(n - 1)); } return 0; }