#include <iostream>
#include <algorithm>
#include <limits>
#include <vector>
#include <queue>
//#define _DEBUG
//
//#ifdef _DEBUG
//#endif

using namespace std;

typedef long long LL;
const LL kInf = numeric_limits< LL >::max() / 2;

struct InputEdge {
  int u, v, d, c;

  InputEdge(int _u, int _v, int _d, int _c) {
    u = _u, v = _v, d = _d, c = _c;
  }
};

struct Edge {
  int v, cpn, nxt;
  LL cst;
} edges[401000];

struct PQNode {
  int u, cpn;
  LL cst;

  PQNode(int _u, int _cpn, LL _cst) {
    u = _u, cpn = _cpn, cst = _cst;
  }

  bool operator > (const PQNode &rpq) const {
    return cst > rpq.cst;
  }
};

typedef priority_queue< PQNode, vector< PQNode >, greater< PQNode > > PQue;

int N, M, C, S, G;
vector< InputEdge > ipt_edge;
LL rail_dist[21][101][101];
int gph[101], edge_cnt;
int pi[101];
LL qi[55], ri[55];
LL f[101][22];

void read_edge(void);
void floyd_warshall(void);
void build_graph(void);
LL find_cost(int, LL);
void solve(void);
void add_edge(int, int, int, LL);

inline void rlx(LL &r, LL n) { r = min(r, n); }

int main() {
  while (cin >> N >> M >> C >> S >> G) {
#ifdef _DEBUG
  cout << "N = " << N << ", M = " << M
    << ", C = " << C << ", S = " << S << ", G = " << G << endl;
#endif
    if (N + M + C + S + G == 0) break;
    read_edge();
    floyd_warshall();
    build_graph();
    solve();
  }

  return 0;
}

void read_edge(void) {
  fill(&rail_dist[0][0][0], &rail_dist[21][0][0], kInf);
  ipt_edge.clear();
  for (int i = 0; i < M; ++i) {
    int u, v, d, c;
    cin >> u >> v >> d >> c;
    ipt_edge.push_back(InputEdge(u, v, d, c));
    rail_dist[c][u][v] = min(rail_dist[c][u][v], LL(d));
    rail_dist[c][v][u] = rail_dist[c][u][v];
  }
}

void floyd_warshall(void) {
  for (int ci = 1; ci <= C; ++ci)
    for (int k = 1; k <= N; ++k)
      for (int i = 1; i <= N; ++i)
        for (int j = 1; j <= N; ++j)
          rlx(rail_dist[ci][i][j], rail_dist[ci][i][k] + rail_dist[ci][k][j]);
}

void build_graph(void) {
  for (int ci = 1; ci <= C; ++ci)
    cin >> pi[ci];

  fill(&gph[0], &gph[N + 1], -1), edge_cnt = 0;
  for (int ci = 1; ci <= C; ++ci) {
    for (int i = 0; i < pi[ci] - 1; ++i)
      cin >> qi[i];
    for (int i = 0; i < pi[ci]; ++i)
      cin >> ri[i];

    for (int i = 1; i <= N; ++i)
      for (int j = i + 1; j <= N; ++j)
        if (rail_dist[ci][i][j] < kInf) {
          LL cst = find_cost(ci, rail_dist[ci][i][j]);
          add_edge(i, j, ci, cst);
        }
  }

#ifdef _DEBUG
  for (int u = 1; u <= N; ++u) {
    cout << "u = " << u << endl;
    for (int eid = gph[u]; eid != -1; eid = edges[eid].nxt) {
      Edge &re = edges[eid];
      cout << "  v = " << re.v << ", cpn = " << re.cpn
        << ", re.cst = " << re.cst << endl;
    }
  }
#endif
}

LL find_cost(int ci, LL d) {
  LL ret = 0, cur_d = 0;
  int i;

  i = 0;
  while (i < pi[ci] - 1 && qi[i] < d)
    ret += (qi[i] - cur_d) * ri[i], cur_d = qi[i], ++i;

  if (cur_d < d)
    ret += (d - cur_d) * ri[i];

  return ret;
}

void solve(void) {
  PQue pq;
  LL res = -1;

  fill(&f[0][0], &f[101][0], kInf);
  f[S][21] = 0, pq.push(PQNode(S, 21, 0));
  while (!pq.empty()) {
    PQNode tp(pq.top());  pq.pop();
    int u = tp.u, cpn = tp.cpn;
    LL cst = tp.cst;

    if (cst > f[u][cpn])  continue;
    if (u == G) { res = cst;  break; }

    for (int eid = gph[u]; eid != -1; eid = edges[eid].nxt) {
      Edge &re = edges[eid];
      if (re.cpn != cpn && f[re.v][re.cpn] > f[u][cpn] + re.cst) {
        f[re.v][re.cpn] = f[u][cpn] + re.cst;
        pq.push(PQNode(re.v, re.cpn, f[re.v][re.cpn]));
      }
    }
  }

  cout << res << "\n";
}

void add_edge(int u, int v, int c, LL cst) {
  Edge &r1 = edges[edge_cnt], &r2 = edges[edge_cnt + 1];
  r1.v = v, r1.cpn = c, r1.cst = cst, r1.nxt = gph[u], gph[u] = edge_cnt;
  r2.v = u, r2.cpn = c, r2.cst = cst, r2.nxt = gph[v], gph[v] = edge_cnt + 1;
  edge_cnt += 2;
}

Measured memory_bytes: 11504