#include <bits/stdc++.h>
using namespace std;
template <class T, class U>
void ckmin(T &a, U b) {
  if (a > b) a = b;
}
template <class T, class U>
void ckmax(T &a, U b) {
  if (a < b) a = b;
}
const int MAXN = 52;
const int MAXM = 113;
const int MAXT = 20013;
const int INF = 1000000007;
const long double EPS = 1e-9;
const long double PI = 3.141592653589793;
vector<complex<long double> > roots;
void gen(int deg) {
  roots.resize(deg);
  roots[0] = complex<long double>(1, 0);
  roots[1] = complex<long double>(cos(2.0 * PI / deg), sin(2.0 * PI / deg));
  for (auto i = (2); i < (deg); i++) {
    roots[i] = roots[i - 1] * roots[1];
  }
  return;
}
void fft(vector<complex<long double> > &f) {
  int n = ((int)(f).size());
  vector<complex<long double> > g(n);
  for (int i = n >> 1; i; i >>= 1) {
    for (int j = 0; j < n; j += i) {
      int t = (j << 1) - (((j << 1) >= n) ? n : 0);
      for (auto k = (0); k < (i); k++) {
        g[j + k] = f[t + k] + roots[j] * f[t + k + i];
      }
    }
    swap(f, g);
  }
}
vector<long double> conv(vector<long double> p, vector<long double> q) {
  int siz = ((int)(p).size()) + ((int)(q).size()) - 1,
      siz1 = (1 << (32 - __builtin_clz(siz)));
  vector<long double> res(siz);
  if (((int)(p).size()) <= 100 || ((int)(q).size()) <= 100) {
    for (auto i = (0); i < (((int)(p).size())); i++) {
      for (auto j = (0); j < (((int)(q).size())); j++) {
        res[i + j] += p[i] * q[j];
      }
    }
    return res;
  }
  vector<complex<long double> > p1(((int)(p).size())), q1(((int)(q).size()));
  for (auto i = (0); i < (((int)(p).size())); i++)
    p1[i] = complex<long double>(p[i], 0);
  for (auto i = (0); i < (((int)(q).size())); i++)
    q1[i] = complex<long double>(q[i], 0);
  gen(siz1);
  p1.resize(siz1);
  q1.resize(siz1);
  fft(p1);
  fft(q1);
  for (auto i = (0); i < (siz1); i++) p1[i] *= q1[i];
  fft(p1);
  for (auto i = (0); i < (siz1); i++) p1[i] /= siz1;
  reverse(p1.begin() + 1, p1.end());
  for (auto i = (0); i < (siz); i++) {
    res[i] = real(p1[i]);
  }
  return res;
}
int N, M, T, X;
vector<int> edge[MAXN];
int to[MAXM], cost[MAXM];
vector<long double> prob[MAXM], dp[MAXN];
int path[MAXN];
priority_queue<pair<int, int>, vector<pair<int, int> >,
               greater<pair<int, int> > >
    pq1;
queue<int> q;
bitset<MAXN> active;
vector<long double> comb(vector<long double> a, vector<long double> b) {
  for (auto i = (0); i < (T - 1); i++) b.push_back(b[T]);
  reverse((a).begin(), (a).end());
  vector<long double> c = conv(a, b);
  vector<long double> res(T);
  for (auto i = (0); i < (T); i++) {
    res[i] = c[T - 1 + i];
  }
  return res;
}
int32_t main() {
  cout << fixed << setprecision(12);
  cerr << fixed << setprecision(4);
  ios_base::sync_with_stdio(false);
  cin.tie(0);
  cin >> N >> M >> T >> X;
  T++;
  for (auto i = (0); i < (M); i++) {
    int u, v, c;
    cin >> u >> v >> c;
    u--;
    v--;
    edge[v].push_back(i);
    to[i] = u;
    cost[i] = c;
    prob[i].resize(T);
    for (auto j = (1); j < (T); j++) {
      int x;
      cin >> x;
      prob[i][j] = 0.00001 * x;
    }
  }
  fill(path, path + N, INF);
  path[N - 1] = 0;
  pq1.push({0, N - 1});
  while (!pq1.empty()) {
    int d = pq1.top().first, u = pq1.top().second;
    pq1.pop();
    if (d != path[u]) {
      continue;
    }
    for (int e : edge[u]) {
      int v = to[e];
      if (path[v] > d + cost[e]) {
        path[v] = d + cost[e];
        pq1.push({path[v], v});
      }
    }
  }
  for (auto i = (0); i < (N - 1); i++) {
    dp[i].resize(T + 1);
    fill((dp[i]).begin(), (dp[i]).end(), INF);
    dp[i][T] = path[i] + X;
  }
  dp[N - 1].resize(T + 1);
  fill((dp[N - 1]).begin(), (dp[N - 1]).end(), 0);
  dp[N - 1][T] = X;
  q.push(N - 1);
  active[N - 1] = true;
  while (!q.empty()) {
    int u = q.front();
    q.pop();
    if (!active[u]) continue;
    active[u] = false;
    for (int e : edge[u]) {
      int v = to[e];
      vector<long double> res = comb(prob[e], dp[u]);
      bool ins = false;
      for (auto j = (0); j < (T); j++) {
        res[j] += cost[e];
        if (dp[v][j] > res[j] + EPS) {
          dp[v][j] = res[j];
          ins = true;
        }
      }
      if (ins && !active[v]) {
        active[v] = true;
        q.push(v);
      }
    }
  }
  cout << dp[0][0] << '\n';
  return 0;
}
