#include <bits/stdc++.h>
using namespace std;
using point = complex<double>;
const int T = 1 << 16;
point root[T];
void fft(vector<point>& a) {
  int n = a.size();
  vector<int> reverse(n);
  for (int i = 0; i < n; ++i) {
    reverse[i] = (reverse[i / 2] + (i % 2) * n) / 2;
    if (i < reverse[i]) {
      swap(a[i], a[reverse[i]]);
    }
  }
  for (int i = 1; i < n; i *= 2) {
    for (int j = 0; j < n; j += 2 * i) {
      for (int k = 0; k < i; ++k) {
        point l = a[j + k];
        point r = a[i + j + k] * root[i + k];
        a[j + k] = l + r;
        a[i + j + k] = l - r;
      }
    }
  }
}
vector<point> mul(vector<point> a, vector<point> b) {
  int n = 1, m = a.size() + b.size();
  while (n < m) {
    n *= 2;
  }
  a.resize(n), b.resize(n);
  fft(a), fft(b);
  for (int i = 0; i < n; ++i) {
    a[i] *= b[i];
  }
  fft(a);
  for (auto& i : a) {
    i /= n;
  }
  reverse(a.begin() + 1, a.end());
  a.resize(m - 1);
  return a;
}
const int M = 100;
const int N = 50;
double prob[M][T], expect[M][T], ans[N][T];
array<int, 3> edges[M];
long long dist[N];
int main() {
  ios_base::sync_with_stdio(false);
  cin.tie(nullptr);
  cout << fixed << setprecision(6);
  for (int i = 1; i < T; i *= 2) {
    for (int j = 0; j < i; ++j) {
      root[i + j] = polar(1.0, j * M_PI / i);
    }
  }
  int n, m, t, x;
  cin >> n >> m >> t >> x;
  for (int i = 0; i < m; ++i) {
    int u, v, w;
    cin >> u >> v >> w;
    edges[i] = {u - 1, v - 1, w};
    for (int j = 1; j <= t; ++j) {
      int p;
      cin >> p;
      prob[i][j] = p / 100000.0;
    }
  }
  fill(dist, dist + n - 1, LLONG_MAX);
  for (int i = 0; i < n; ++i) {
    for (int j = 0; j < m; ++j) {
      auto [u, v, w] = edges[j];
      if (dist[v] < LLONG_MAX) {
        dist[u] = min(dist[u], dist[v] + w);
      }
    }
  }
  for (int i = 0; i < n - 1; ++i) {
    fill(ans[i], ans[i] + t + 1, HUGE_VAL);
  }
  for (int i = 0; i < m; ++i) {
    auto [u, v, w] = edges[i];
    double sum = 0.0;
    for (int j = t; j >= 0; --j) {
      expect[i][j] = w + sum * (dist[v] + x);
      sum += prob[i][j];
    }
    ans[u][0] = min(ans[u][0], expect[i][0]);
  }
  for (int i = 1; i <= t; ++i) {
    for (int j = 0; j < m; ++j) {
      auto [u, v, w] = edges[j];
      for (int k = 1; i % k == 0; k *= 2) {
        vector<point> poly =
            mul(vector<point>(ans[v] + i - k, ans[v] + i),
                vector<point>(prob[j] + k, prob[j] + min(2 * k, t + 1)));
        for (int l = 0; l <= t - i && l <= (int)poly.size(); ++l) {
          expect[j][l + i] += poly[l].real();
        }
      }
      ans[u][i] = min(ans[u][i], expect[j][i]);
    }
  }
  cout << ans[0][t] << "\n";
}
