#include <bits/stdc++.h>
using namespace std;
const double pi = acos(-1);
struct Complex {
  double x, y;
  Complex() { x = y = 0; };
  Complex(double a, double b) { x = a, y = b; }
} A[20010 << 3], B[20010 << 3], C[20010 << 3];
Complex operator+(Complex a, Complex b) {
  return Complex(a.x + b.x, a.y + b.y);
}
Complex operator-(Complex a, Complex b) {
  return Complex(a.x - b.x, a.y - b.y);
}
Complex operator*(Complex a, Complex b) {
  return Complex(a.x * b.x - a.y * b.y, a.x * b.y + a.y * b.x);
}
struct data {
  int u, s;
  data(){};
  data(int a, int b) { u = a, s = b; }
  bool operator<(const data &a) const { return s > a.s; }
};
int n, m, t, x;
int cnt, head[55], nxt[110], to[110], w[110];
int dis[55];
bool vis[55], inq[55];
double p[110][20010 << 3], f[55][20010 << 3], now[20010 << 3];
int bit = 0, limit = 1;
int rev[20010 << 3];
void FFT(Complex *a, int opt) {
  for (int i = 0; i < limit; i++)
    if (i < rev[i]) swap(a[i], a[rev[i]]);
  for (int mid = 1; mid < limit; mid <<= 1) {
    int len = mid << 1;
    Complex wn = Complex(cos(pi / mid), opt * sin(pi / mid));
    for (int i = 0; i < limit; i += len) {
      Complex omega = Complex(1, 0);
      for (int j = 0; j < mid; j++, omega = omega * wn) {
        Complex x = a[i + j], y = omega * a[i + mid + j];
        a[i + j] = x + y, a[i + mid + j] = x - y;
      }
    }
  }
  if (opt == -1)
    for (int i = 0; i < limit; i++) a[i].x /= limit;
}
void mul(double *a, double *b, double *c) {
  for (int i = 0; i <= t * 2; i++) A[i] = Complex(a[i], 0);
  for (int i = 0; i <= t * 2; i++) B[i] = Complex(b[i], 0);
  for (int i = t * 2 + 1; i < limit; i++) A[i] = B[i] = Complex(0, 0);
  FFT(A, 1), FFT(B, 1);
  for (int i = 0; i < limit; i++) C[i] = A[i] * B[i];
  FFT(C, -1);
  for (int i = 0; i < limit; i++) c[i] = C[i].x;
}
void adde(int u, int v, int wi) {
  to[++cnt] = v;
  w[cnt] = wi;
  nxt[cnt] = head[u];
  head[u] = cnt;
}
void dijkstra() {
  priority_queue<data> q;
  memset(dis, 127, sizeof(dis));
  dis[n] = 0;
  q.push(data(n, dis[n]));
  while (!q.empty()) {
    data now = q.top();
    q.pop();
    if (vis[now.u]) continue;
    vis[now.u] = 1;
    for (int i = head[now.u]; i; i = nxt[i]) {
      int v = to[i];
      if (dis[now.u] + w[i] < dis[v]) {
        dis[v] = dis[now.u] + w[i];
        q.push(data(v, dis[v]));
      }
    }
  }
}
void SPFA() {
  queue<int> q;
  for (int i = 1; i <= n; i++) {
    for (int j = 0; j <= t; j++) f[i][j] = 0x7fffffff;
    for (int j = t + 1; j <= 2 * t; j++) f[i][j] = dis[i] + x;
  }
  for (int j = 0; j <= t; j++) f[n][j] = 0;
  q.push(n);
  inq[n] = 1;
  while (!q.empty()) {
    int u = q.front();
    q.pop();
    inq[u] = 0;
    for (int i = head[u]; i; i = nxt[i]) {
      int v = to[i];
      mul(f[u], p[i], now);
      bool flag = false;
      for (int j = 0; j <= t; j++) {
        if (now[t + j + 1] + w[i] < f[v][j]) {
          f[v][j] = now[t + j + 1] + w[i];
          flag = 1;
        }
      }
      if (flag) {
        if (!inq[v]) {
          inq[v] = 1;
          q.push(v);
        }
      }
    }
  }
}
int main() {
  scanf("%d%d%d%d", &n, &m, &t, &x);
  for (int i = 1; i <= m; i++) {
    int u, v, w;
    scanf("%d%d%d", &u, &v, &w);
    adde(v, u, w);
    for (int j = t; j >= 1; j--) {
      scanf("%lf", &p[i][j]);
      p[i][j] /= 1e5;
    }
  }
  while (limit <= (t << 2)) limit <<= 1, bit++;
  for (int i = 0; i < limit; i++)
    rev[i] = (rev[i >> 1] >> 1) | ((i & 1) << (bit - 1));
  dijkstra();
  SPFA();
  printf("%.10lf\n", f[1][0]);
  return 0;
}
