#include <bits/stdc++.h>
using namespace std;
template <class T>
inline void init(T &x) {
  x = 0;
  char ch = getchar();
  bool t = 0;
  for (; ch > '9' || ch < '0'; ch = getchar())
    if (ch == '-') t = 1;
  for (; ch >= '0' && ch <= '9'; ch = getchar())
    x = (x << 1) + (x << 3) + (ch - 48);
  if (t) x = -x;
  return;
}
const double PI = acos(-1);
const int N = 1e5 + 10;
const int T = 2e4 + 10;
const int MAXN = 2e5 + 10;
const double INF = 1e18;
struct Complex {
  double x, y;
  Complex(double _x = 0.0, double _y = 0.0) { x = _x, y = _y; }
  inline Complex operator+(const Complex B) {
    return Complex(x + B.x, y + B.y);
  }
  inline Complex operator-(const Complex B) {
    return Complex(x - B.x, y - B.y);
  }
  inline Complex operator*(const Complex B) {
    return Complex(x * B.x - y * B.y, x * B.y + y * B.x);
  }
} w[MAXN], A[MAXN], B[MAXN];
const int M = 220;
int n, m, rader[MAXN];
struct edge {
  int to, next;
} a[M];
int head[M], cnt = 0;
double t[110][T << 1], cost[110];
inline void add(int x, int y) {
  a[++cnt] = (edge){y, head[x]};
  head[x] = cnt;
}
priority_queue<pair<int, int> > Q;
bool vis[M];
int dis[M];
double ans = 0;
int tim, x, R;
double f[51][T << 1], g[M][T << 1];
inline void Dij() {
  Q.push(pair<int, int>(0, n));
  for (int i = 1; i < n; ++i) dis[i] = 1e9;
  dis[n] = 0;
  while (!Q.empty()) {
    pair<int, int> S = Q.top();
    Q.pop();
    int u = S.second, len = -S.first;
    if (vis[u] || dis[u] != len) continue;
    vis[u] = 1;
    for (int v, i = head[u]; i; i = a[i].next) {
      v = a[i].to;
      if (dis[v] > dis[u] + cost[i])
        dis[v] = dis[u] + cost[i], Q.push(pair<int, int>(-dis[v], v));
    }
  }
  return;
}
inline void FFT(Complex *A, int n, int f) {
  for (int i = 0; i < n; ++i)
    if (rader[i] > i) swap(A[i], A[rader[i]]);
  for (int i = 1; i < n; i <<= 1) {
    for (int p = i << 1, j = 0; j < n; j += p) {
      for (int k = 0; k < i; ++k) {
        Complex W = w[n / i * k];
        if (f == -1) W.y = -W.y;
        Complex X = A[j | k], Y = W * A[j | k | i];
        A[j | k] = X + Y, A[j | k | i] = X - Y;
      }
    }
  }
  if (f == -1)
    for (int i = 0; i < n; ++i) A[i].x /= (double)n;
  return;
}
inline int prework(int m) {
  int len = 1, up = -1;
  for (; len <= m; ++up, len <<= 1)
    ;
  for (int i = 0; i < len; ++i) {
    rader[i] = (rader[i >> 1] >> 1) | ((i & 1) << up);
    w[i] = Complex(cos(PI / len * i), sin(PI / len * i));
  }
  return len;
}
inline void Solve(int l, int r) {
  if (l > tim) return;
  if (l == r) {
    for (int u = 1; u <= n; ++u) {
      for (int v, i = head[u]; i; i = a[i].next) {
        v = a[i].to;
        f[v][l] = min(f[v][l], g[i][l] + cost[i]);
      }
    }
    return;
  }
  int mid = l + r >> 1;
  Solve(mid + 1, r);
  int len = prework((r - l) << 1);
  for (int u = 1; u <= n; ++u) {
    for (int v, i = head[u]; i; i = a[i].next) {
      v = a[i].to;
      for (int j = 0; j < len; ++j) A[j] = Complex(), B[j] = Complex();
      int a0 = 0, b0 = 0;
      for (int j = mid + 1; j <= r; ++j) A[a0++] = Complex(f[u][j], 0);
      for (int j = l; j < r; ++j) B[b0++] = Complex(t[i][r - j], 0);
      FFT(A, len, 1), FFT(B, len, 1);
      for (int j = 0; j < len; ++j) A[j] = A[j] * B[j];
      FFT(A, len, -1);
      for (int j = l; j <= mid; ++j) g[i][j] += A[j - mid + r - l - 1].x;
    }
  }
  Solve(l, mid);
}
int main() {
  init(n), init(m), init(tim), init(x);
  int u, v, c;
  for (int i = 1; i <= m; ++i) {
    init(u), init(v), init(c);
    add(v, u);
    for (int j = 1; j <= tim; ++j) {
      int x;
      init(x);
      t[cnt][j] = (double)(x) / 1e5;
    }
    cost[cnt] = c;
  }
  Dij();
  R = tim << 1;
  for (int i = 1; i < n; ++i) {
    for (int j = 0; j <= tim; ++j) f[i][j] = INF;
    for (int j = tim + 1; j <= R; ++j) f[i][j] = dis[i] + x;
  }
  for (int j = tim + 1; j <= R; ++j) f[n][j] = x;
  Solve(0, R);
  printf("%.10lf\n", f[1][0]);
}
