#include using namespace std; #include #define rep(i, l, r) for (int i = (int)(l); i<(int)(r); i++) #define ll long long int main() { int N, M; cin >> N >> M; vector> Edges(M); rep(i, 0, M) { int u, v, c; cin >> u >> v >> c; u--; v--; c--; Edges[i] = {c, u, v}; } array cnt = {0, 0, 0, 0, 0, 0}; atcoder::dsu d(N); sort(Edges.begin(), Edges.end()); for (int i = 0; i < M; i++) { auto[c, u, v] = Edges[i]; if (!d.same(u, v)) { d.merge(u, v); cnt[c]++; } } //累積 for (int i = 4; i >= 0; i--) cnt[i] += cnt[i+1]; //dp[t] : 今まででたのがtとなるようにするまでにかかるコストの期待値 //6, 5, 4, 4, 3, 2 -> 7, 6, 4, 4, 3, 2 : 辞書順で後にいく int power[6]; power[0] = 1; for (int i = 1; i < 6; i++) power[i] = power[i-1] * 11; double dp[10'000'000]; array A; for (A[0] = cnt[0]; A[0] >= 0; A[0]--) for (A[1] = min(A[0], cnt[1]); A[1] >= 0; A[1]--) for (A[2] = min(A[1], cnt[2]); A[2] >= 0; A[2]--) { for (A[3] = min(A[2], cnt[3]); A[3] >= 0; A[3]--) for (A[4] = min(A[3], cnt[4]); A[4] >= 0; A[4]--) for (A[5] = min(A[4], cnt[5]); A[5] >= 0; A[5]--) { int hash = 0; rep(i, 0, 6) hash += A[i]*power[i]; int Ahash = hash; double t = 0; int loop = 0; array B = A; bool f = false; rep(i, 0, 6) { if (B[i] != cnt[i]) { f = true; B[i]++; hash += power[i]; } if (f) t += dp[hash]; else loop++; } if (loop == 6) { dp[Ahash] = 0; continue; } t += 6; t /= (6 - loop); dp[Ahash] = t; } } cout << fixed << setprecision(15) << dp[0] << endl; }