import std.stdio;
import std.ascii;
import std.range;
import std.array;
import std.functional;
import std.algorithm;
import std.conv;
import std.container;
import std.math;
import std.numeric;
import std.string;
import std.c.string;
import std.random;
import std.regex;
import std.typecons;

const INF = int.max / 8;

struct Edge {
    int from, to, cost, T;
}

void main() {
    int N, M, C, S, G;
    int[] P;
    int[][] Q, R;
    Edge[][] F;

    int calcCost(int T, int d, int ci = 0) {
        if (d < Q[T][ci + 1]) {
            return R[T][ci + 1] * (d - Q[T][ci]);
        } else {
            return R[T][ci + 1] * (Q[T][ci + 1] - Q[T][ci]) + calcCost(T, d, ci + 1);
        }
    }

    bool input() {
        scanf("%d %d %d %d %d\n", &N, &M, &C, &S, &G);
        if (N == 0) return false;
        S--; G--;
        F = new Edge[][N];
        foreach (i; 0 .. M) {
            int x, y, d, c; scanf("%d %d %d %d\n", &x, &y, &d, &c);
            x--; y--; c--;
            F[x] ~= Edge(x, y, d, c);
            F[y] ~= Edge(y, x, d, c);
        }
        P = readln.chomp.split(" ").map!(to!int).array;
        Q = new int[][C];
        R = new int[][C];
        foreach (i; 0 .. C) {
            auto buf = readln.chomp;
            if (!buf.empty) {
                Q[i] = buf.split(" ").map!(to!int).array;
            }
            Q[i] = [0] ~ Q[i] ~ [INF];
            buf = readln.chomp;
            R[i] = [0] ~ buf.split(" ").map!(to!int).array;
        }
        return true;
    }
    void solve() {
        auto X = new int[][](N, N);
        foreach (i; 0 .. N) X[i][] = INF;

        struct P {
            int v, cost;
        }
        foreach (s; 0 .. N) {
            foreach (c; 0 .. C) {
                BinaryHeap!(Array!P, "a.cost > b.cost") PQ;
                PQ.insert(P(s, 0));
                auto dist = new int[N];
                dist[] = INF;
                dist[s] = 0;
                while (!PQ.empty) {
                    auto cur = PQ.front; PQ.removeFront;
                    foreach (e; F[cur.v]) {
                        if (e.T != c) continue;
                        auto next = e.to;
                        auto ncost = cur.cost + e.cost;
                        if (dist[next] > ncost) {
                            dist[next] = ncost;
                            PQ.insert(P(next, ncost));
                        }
                    }
                }
                foreach (v; 0 .. N) {
                    if (dist[v] == INF) continue;
                    X[s][v] = min(X[s][v], calcCost(c, dist[v]));
                }
            }
        }
        //foreach (x; X) writeln(x);
        foreach (k; 0 .. N) foreach (i; 0 .. N) foreach (j; 0 .. N) {
            X[i][j] = min(X[i][j], X[i][k] + X[k][j]);
        }
        auto ans = X[S][G];
        writeln(ans == INF ? -1 : ans);
    }

    while (input) solve;
}