#include <queue>
#include <cstdio>
#include <vector>
using namespace std;
struct edge { int to, cost; };
bool operator<(const edge& e1, const edge& e2) { return e1.cost < e2.cost; }
int N, M, C, b1, b2, e1, e2, e3, e4;
int main() {
	while (scanf("%d%d%d%d%d", &N, &M, &C, &b1, &b2), b1--, b2--, N) {
		vector<vector<vector<edge> > > G1(C, vector<vector<edge> >(N));
		for (int i = 0; i < M; i++) {
			scanf("%d%d%d%d", &e1, &e2, &e3, &e4); e1--, e2--, e4--;
			G1[e4][e1].push_back(edge{ e2, e3 });
			G1[e4][e2].push_back(edge{ e1, e3 });
		}
		vector<vector<vector<int> > > dist(C, vector<vector<int> >(N, vector<int>(N, 999999999)));
		for (int i = 0; i < C; i++) {
			for (int j = 0; j < N; j++) {
				dist[i][j][j] = 0;
				priority_queue<edge> que1; que1.push(edge{ j, 0 });
				while (!que1.empty()) {
					edge u = que1.top(); que1.pop();
					for (edge e : G1[i][u.to]) {
						if (dist[i][j][e.to] > -u.cost + e.cost) {
							dist[i][j][e.to] = -u.cost + e.cost;
							que1.push(edge{ e.to, -dist[i][j][e.to] });
						}
					}
				}
			}
		}
		vector<int> P(C);
		for (int i = 0; i < C; i++) scanf("%d", &P[i]);
		vector<vector<int> > costs(C, vector<int>(20000));
		for (int i = 0; i < C; i++) {
			vector<int> Q(P[i] + 1), R(P[i]); Q[0] = 0, Q[P[i]] = 19999;
			for (int j = 1; j < P[i]; j++) scanf("%d", &Q[j]);
			for (int j = 0; j < P[i]; j++) scanf("%d", &R[j]);
			for (int j = 0; j < P[i]; j++) {
				for (int k = Q[j] + 1; k <= Q[j + 1]; k++) {
					costs[i][k] = costs[i][k - 1] + R[j];
				}
			}
		}
		vector<vector<int> > G2(N, vector<int>(N, 999999999));
		for (int i = 0; i < C; i++) {
			for (int j = 0; j < N; j++) {
				for (int k = 0; k < N; k++) {
					if (j == k) continue;
					if (dist[i][j][k] == 999999999) continue;
					G2[j][k] = min(G2[j][k], costs[i][dist[i][j][k]]);
				}
			}
		}
		vector<vector<edge> > G3(N);
		for (int i = 0; i < N; i++) {
			for (int j = 0; j < N; j++) {
				if (G2[i][j] != 999999999) G3[i].push_back(edge{ j, G2[i][j] });
			}
		}
		vector<int> dist2(N, 999999999); dist2[b1] = 0;
		priority_queue<edge> que2; que2.push(edge{ b1, 0 });
		while (!que2.empty()) {
			edge u = que2.top(); que2.pop();
			for (edge e : G3[u.to]) {
				if (dist2[e.to] > -u.cost + e.cost) {
					dist2[e.to] = -u.cost + e.cost;
					que2.push(edge{ e.to, -dist2[e.to] });
				}
			}
		}
		printf("%d\n", dist2[b2] != 999999999 ? dist2[b2] : -1);
	}
	return 0;
}