/*
 * c.cc: 
 */

#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<iostream>
#include<string>
#include<vector>
#include<map>
#include<set>
#include<stack>
#include<list>
#include<queue>
#include<deque>
#include<algorithm>
#include<numeric>
#include<utility>
#include<complex>
#include<functional>

using namespace std;

/* constant */

const int MAX_N = 200;
const int MAX_M = 200;
const int MAX_K = 20;

/* typedef */

/* global variables */

int ks[MAX_N], sis[MAX_N][MAX_K], his[MAX_N][MAX_K];
int maxms[MAX_N];
double hs[MAX_N][MAX_M + 1], dp[MAX_N + 1][MAX_M + 1];

/* subroutines */

/* main */

int main() {
  int n, m;
  cin >> n >> m;

  for (int i = 0; i < n; i++) {
    cin >> ks[i];
    for (int j = 0; j < ks[i]; j++) cin >> sis[i][j] >> his[i][j];
  }
  
  for (int i = 0; i < n; i++) {
    hs[i][0] = 0.0;
    int m0 = 0;
    for (int j = 0; j < ks[i]; j++) {
      int m1 = m0 + sis[i][j] * his[i][j];
      int maxl = min(m1 - 1, m);
      for (int l = m0 + 1; l <= maxl; l++)
	hs[i][l] = hs[i][m0] + (double)(l - m0) / sis[i][j];
      if (m1 <= m) hs[i][m1] = hs[i][m0] + his[i][j];
      m0 = m1;
      if (m0 >= m) break;
    }
    maxms[i] = min(m0, m);
    continue;
    printf("maxms[%d]=%d:", i, maxms[i]);
    for (int j = 0; j <= maxms[i]; j++) printf(" %lf", hs[i][j]); putchar('\n');
  }

  for (int i = 0; i <= n; i++)
    for (int j = 0; j <= m; j++) dp[i][j] = -1.0;
  dp[0][0] = 0.0;

  for (int i = 0; i < n; i++) {
    memcpy(dp[i + 1], dp[i], sizeof(dp[i]));
    for (int j = 0; j <= m; j++)
      if (dp[i][j] >= 0.0) {
	for (int k = 1; k <= maxms[i] && j + k <= m; k++) {
	  double ndp = dp[i][j] + hs[i][k];
	  if (dp[i + 1][j + k] < ndp) dp[i + 1][j + k] = ndp;
	}
      }
    continue;
    printf("%d:", i + 1);
    for (int j = 0; j <= m; j++) printf(" %lf", dp[i + 1][j]); putchar('\n');
  }

  printf("%.8lf\n", dp[n][m]);
  return 0;
}