Problem: Idol --- It's the eternal longing of girls. However, only a handful stand at the top. You have decided to enter such a survival world as an idol producer. And today, I will take your idol and challenge an important audition.

The three elements that determine the audition are visual, dance, and vocal. There are m appeal times during the audition, and each idol can make a visual appeal, a dance appeal, or a vocal appeal for each appeal time. When you make a visual appeal, the idol's visual points are only her visual value, when you make a dance appeal, the dance points are only her dance value, and when you make a vocal appeal, the vocal points are only her vocal value. Will rise.

After m appeals, 3 of the N idols with the highest visual points have 5 audition points, 3 with the highest dance points have 3 audition points, and 3 with the highest vocal points. 2 Earn audition points. On the other hand, if the visual points are the lowest, the audition points will be deducted by 1 point, if the dance points are the lowest, the audition points will be deducted by 1 point, and if the vocal points are the lowest, the audition points will be deducted by 1 point. (Even if the audition point is 1 or less, 1 point will be deducted from it).

At the beginning of the audition, each idol has 0 visual points, dance points, and vocal points. You are the producer of Idol 1 and you can tell which appeal to make at each appeal time. Idols other than Idol 1 will randomly make one of the appeals at equal probability at each appeal time (that is, each with a one-third chance). If idol 1 has the same visual, dance, and vocal points as other idols, idol 1 is always inferior. Find the expected value when instructed to maximize the expected value of the audition points earned by Idol 1. The fate of an idol depends on your instructions!

By the way, all instructions are given before the audition starts, and the instructions cannot be changed during the audition after that. In other words, it is not possible for other idols to see which appeal they have made since the audition began and then give instructions to maximize the expected value in that case.



Input

The input is given in the form:

> n m
> vi1 da1 vo1
> vi2 da2 vo2
> ...
> vin dan von
>

The first line shows the number of idols participating in the audition n (4 ≤ n ≤ 2000) and the number of appeal times in this audition m (1 ≤ m ≤ 2000). The next n lines contain the visual value vii, dance value dai, and vocal value voi (1 ≤ vii, dai, voi ≤ 10,000) for idle i, respectively.

Output

Output the maximum expected value of audition points earned by idle 1 in one line.

Examples

Input

4 1
1 1 1
1 1 1
1 1 1
1 1 1


Output

2.777777777778


Input

4 10
1 1 1
10 10 10
10 10 10
10 10 10


Output

-2.335340954780


Input

9 9
13 5 19
19 21 37
15 1 7
7 11 15
21 23 25
33 29 19
13 19 11
21 5 15
7 13 1


Output

4.678837855075

Solution (in CPP):

Solution:
#include <bits/stdc++.h>
#define REP(i,n) for(int i=0; i<(int)(n); ++i)

using namespace std;


struct Solver{
    int n, m;
    vector<double> prob_use;
    vector<double> prob_use_sum;
    vector<int> val;

    Solver(int n_, int m_, vector<int> val_) : 
        n(n_), m(m_), prob_use(m + 1, 0.0), prob_use_sum(m + 2, 0.0), val(val_) {
        prob_use[0] = 1.0;
        for(int i = 0; i < m; i++){
            vector<double> next(m + 1, 0.0);
            for(int j = 0; j <= i; j++){
                next[j] += prob_use[j] * 2.0 / 3.0;
                next[j + 1] += prob_use[j] * 1.0 / 3.0;
            }
            prob_use.swap(next);
        }
        for(int i = 0; i <= m; i++){
            prob_use_sum[i + 1] = prob_use_sum[i] + prob_use[i];
        }
    }

    map<int, double> memo;
    double calc(int x, int win_point, int lose_point){
        if(memo.count(x)) return memo[x];
        double& res = memo[x];
        res = 0.0;

        double dp[2][4] = {}; // win, lose
        dp[0][0] = 1.0;
        for(int i = 0; i < n; i++) {
            double next[2][4] = {};
            int e = (x + val[i] - 1) / val[i];
            if(e > m+1) e = m+1;
            // [0, e) -> win
            // [e, inf) -> lose
            double win = prob_use_sum[e];
            double lose = 1.0 - win;

            for(int j = 0; j <= 1; j++) {
                for(int k = 0; k <= 3; k++) {
                    // win
                    int nj = min(1, j + 1);
                    next[nj][k] += win * dp[j][k];

                    // lose
                    int nk = min(3, k + 1);
                    next[j][nk] += lose * dp[j][k];
                }
            }
            memcpy(dp, next, sizeof(dp));
        }
        double get_p = 0.0;
        double lost_p = 0.0;
        for(int i = 0; i <= 1; i++) {
            for(int j = 0; j <= 3; j++) {
                bool get = j <= 2;
                bool lost = i == 0;
                assert(dp[i][j] == 0 || !get || !lost);
                if(get) get_p += dp[i][j];
                if(lost) lost_p += dp[i][j];
            }
        }

        return res = get_p * win_point - lost_p * lose_point;
    }
};

int main(){
    int n, m;
    while(cin >> n >> m){
        n--;
        int vi, da, vo;
        cin >> vi >> da >> vo;

        vector<vector<int>> val(3, vector<int>(n));
        REP(i, n) REP(j, 3) cin >> val[j][i];

        vector<Solver> solvers;
        REP(i, 3){
            solvers.push_back(Solver(n, m, val[i]));
        }

        double ans = -1e16;
        for(int x = 0; x <= m; x++){
            for(int y = 0; x + y <= m; y++){
                int z = m - x - y;
                double pos = 0;
                pos += solvers[0].calc(x * vi, 5, 1);
                pos += solvers[1].calc(y * da, 3, 1);
                pos += solvers[2].calc(z * vo, 2, 1);
                ans = max(ans, pos);
            }
        }
        printf("%.12f\n", ans);
    }
    return 0;
}