#include <stdio.h>
#include <memory.h>
#include <vector>
#include <queue>
#include <functional>

using namespace std;

struct edge { int x, y, dist, company; };
typedef pair<int, int> P;

//FILE *in = freopen("input.txt", "r", stdin);

const int INF = 0x7ffffff;

int n, m, c, s, g;
int e[10000][4];
int costInt[21][101];
int costFair[21][101];
int cost[21][101];
int cn[21];

vector<edge> Map[101];
int data[101][101];
int ddist[101][101];

void input() {
	int x, y, z, w;
	for(int i = 1; i <= n; i++) {
		Map[i].clear();
	}

	for(int i = 0; i < m; i++){
		scanf("%d%d%d%d", &x, &y, &z, &w);
		edge e1 = {x, y, z, w};
		Map[x].push_back(e1);
		edge e2 = {y, x, z, w};
		Map[y].push_back(e2);
	}
	for(int i = 1; i <= c; i++){
		scanf("%d", &cn[i]);
	}
	for(int i = 1; i <= c; i++){
		for(int j = 0; j < cn[i] - 1; j++){
			scanf("%d", &costInt[i][j]);
		}
		costInt[i][cn[i]-1] = INF;
		for(int j = 0; j < cn[i]; j++){
			scanf("%d", &costFair[i][j]);
		}
	}

	for(int i = 1; i <= n; i++) {
		fill(data[i] + 1, data[i] + n + 1, INF);
		fill(ddist[i] + 1, ddist[i] + n + 1, INF);
	}
}

int get_cost(int i, int dist) {
	int k = 0;
	int sum = 0;
	for(int j = 0; j < cn[i]; j++){
		if(k <= costInt[i][j]) {
			if (costInt[i][j] < dist) {
				sum += costFair[i][j] * (costInt[i][j] - k);
				k = costInt[i][j];
			}
			else {
				sum += costFair[i][j] * (dist - costInt[i][j-1]);
				k = costInt[i][j];
				break;
			}
		}
	}
	return sum;
}

void make_graph(int s, int company) {
	int dist[101];
	priority_queue<P, vector<P>, greater<P>> que;
	fill(dist + 1, dist + n + 1, INF);
	dist[s] = 0;
	que.push(P(0,s));

	while(!que.empty()) {
		P p = que.top(); que.pop();
		int v = p.second;
		if (dist[v] < p.first) continue;
		for (int i = 0; i < Map[v].size(); i++) {
			edge e = Map[v][i];
			if (e.company != company) continue;
			if (dist[e.y] > dist[v] + e.dist) {
				dist[e.y] = dist[v] + e.dist;
				que.push(P(dist[e.y], e.y));
			}
		}
	}

	for(int i = 1; i <= n; i++) {
		if (dist[i] != INF) {
			int cd = get_cost(company, dist[i]);
			if (data[s][i] > cd) {
				data[s][i] = cd;
				ddist[s][i] = dist[i];
			}
			else if (data[s][i] == cd) {
				if (ddist[s][i] > dist[i]) {
					ddist[s][i] = dist[i];
				}
			}
		}
	}
}

void dijkstra() {
	int dist[101];
	int dst[101];
	priority_queue<P, vector<P>, greater<P>> que;
	fill(dist + 1, dist + n + 1, INF);
	fill(dst + 1, dst + n + 1, INF);
	dist[s] = 0;
	que.push(P(0, s));

	while (!que.empty()){
		P p = que.top(); que.pop();
		int v = p.second;
		if (dist[v] < p.first) continue;
		for(int i = 1; i <= n; i++) {
			if (data[v][i] == INF)continue;
			if (dist[i] > dist[v] + data[v][i]) {
				dist[i] = dist[v] + data[v][i];
				dst[i] = dst[v] + ddist[v][i];
				que.push(P(dist[i], i));
			}
			else if (dist[i] == dist[v] + data[v][i]) {
				if (dst[i] > dst[v] + ddist[v][i]) {
					dst[i] = dst[v] + ddist[v][i];
					que.push(P(dist[i], i));
				}
			}
		}
	}

	if(dist[g] == INF) {
		printf("-1\n");
	}
	else {
		printf("%d\n", dist[g]);
	}
}

void process() {
	for(int i = 1; i <= n; i++) {
		bool check[21];
		memset(check, 0, sizeof(check));
		for (int j = 0; j < Map[i].size(); j++) {
			if(check[Map[i][j].company])continue;
			check[Map[i][j].company] = true;
			make_graph(i, Map[i][j].company);
		}
	}
	dijkstra();
}

int main() {
	while(true){
		scanf("%d%d%d%d%d", &n, &m, &c, &s, &g);
		if(n == 0 && m == 0 && c == 0 && s == 0 && g == 0) break;
		input();
		process();
	}
	return 0;
}

Measured memory_bytes: 2044