#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <ctime>
#include <iostream>
#include <algorithm>
#include <sstream>
#include <string>
#include <vector>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <utility>
#include <cctype>
#include <numeric>
using namespace std;

#define rep(i,n) for(int (i)=0; (i)<(int)(n); ++(i))
#define foreach(c,i) for(__typeof((c).begin()) i=(c).begin();i!=(c).end();i++)

const int kInf = 1 << 28;
struct edge {
  int to, cost, camp;
  bool operator<(const edge& other) const {
    return cost > other.cost;
  }
};
int N, M, C, S, G;
int P[22], Q[22][52], R[22][52], cost[22][10004];
int dis[22][102][102], d[102][22];
vector<edge> es[102];

void calc_cost() {
  for (int i = 0; i < C; ++i) {
    int k = 0, r = R[i][0];
    cost[i][0] = 0;
    for (int j = 1; j <= 10002; ++j) {
      cost[i][j] = cost[i][j-1] + r;
      if (Q[i][k] == j) {
        r = R[i][k+1];
        ++k;
      }
    }
  }
}

int get_cost(int camp, int dist) {
  if (dist <= 10002)
    return cost[camp][dist];
  return cost[camp][10002] + (dist - 10002) * R[camp][P[camp]-1];
}

int calcost(int camp, int dist) {
  int t = lower_bound(Q[camp], Q[camp] + P[camp] - 1, dist) - Q[camp];
  if (t == 0) {
    // printf("[%d,%d] t = %d, ret = %d\n", camp, dist, t, dist * R[camp][0]);
    return dist * R[camp][0];
  }
  int ret = R[camp][0] * Q[camp][0];
  for (int i = 1; i < t; ++i) ret += R[camp][i] * (Q[camp][i] - Q[camp][i-1]);
  ret += R[camp][t] * (dist - Q[camp][t-1]);
  // printf("[%d,%d] t = %d , ret = %d\n", camp, dist, t, ret);
  return ret;
}

int solve() {
  // calc_cost();

  rep(c,C) rep(i,N) dis[c][i][i] = 0;
  rep(c,C) rep(k,N) rep(i,N) rep(j,N) {
    dis[c][i][j] = min(dis[c][i][j], dis[c][i][k] + dis[c][k][j]);
  }
  
  rep(i,N) es[i].clear();
  
  for (int c = 0; c < C; ++c) {
    for (int i = 0; i < N; ++i) {
      for (int j = i+1; j < N; ++j) {
        if (dis[c][i][j] < kInf) {
          // int dd = get_cost(c, dis[c][i][j]);
          int dd = calcost(c, dis[c][i][j]);
          // printf("%d %d : %d\n", i, j, dd);
          es[i].push_back((edge){j, dd, c});
          es[j].push_back((edge){i, dd, c});
        }
      }
    }
  }

  rep(i,N) rep(j,C) d[i][j] = kInf;
  priority_queue<edge> pq;
  d[S][20] = 0;
  pq.push((edge){S, 0, 20});
  while (!pq.empty()) {
    edge p = pq.top(); pq.pop();
    int v = p.to;
    if (d[v][p.camp] < p.cost) continue;
    rep(i,es[v].size()) {
      edge e = es[v][i];
      if (p.camp == e.camp) continue;
      if (d[e.to][e.camp] > p.cost + e.cost) {
        d[e.to][e.camp] = p.cost + e.cost;
        pq.push((edge){e.to, d[e.to][e.camp], e.camp});
      }
    }
  }
  int ret = *min_element(d[G], d[G] + C);
  return ret != kInf ? ret : -1 ;
}

int main() {
  while (scanf("%d%d%d%d%d", &N, &M, &C, &S, &G), N | M) {
    --S; --G;

    rep(i,C) rep(j,N) rep(k,N) dis[i][j][k] = kInf;
    int x, y, d, c;
    rep(i,M) {
      scanf("%d%d%d%d", &x, &y, &d, &c);
      --x; --y; --c;
      dis[c][x][y] = min(dis[c][x][y], d);
      dis[c][y][x] = min(dis[c][y][x], d);
    }
    rep(i,C) scanf("%d", P+i);
    rep(i,C) {
      rep(j,P[i]-1) scanf("%d", Q[i] + j);
      rep(j,P[i]) scanf("%d", R[i] + j);
    }
    printf("%d\n", solve());
  }
  return 0;
}

Measured memory_bytes: 5508