#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;
}