#include <bits/stdc++.h>
using namespace std;
#define SZ(x) (int)(x.size())
#define REP(i, n) for(int i=0;i<(n);++i)
#define FOR(i, a, b) for(int i=(a);i<(b);++i)
#define RREP(i, n) for(int i=(int)(n)-1;i>=0;--i)
#define RFOR(i, a, b) for(int i=(int)(b)-1;i>=(a);--i)
#define ALL(a) a.begin(),a.end()
#define DUMP(x) cerr<<#x<<" = "<<(x)<<endl
#define DEBUG(x) cerr<<#x<<" = "<<(x)<<" (L"<<__LINE__<<")"<< endl;
using ll = long long;
using vi = vector<int>;
using vvi = vector<vi>;
using vll = vector<ll>;
using vvll = vector<vll>;
using P = pair<int, int>;
const double eps = 1e-8;
const ll MOD = 1000000007;
const int INF = INT_MAX / 2;
const ll LINF = LLONG_MAX / 2;
template <typename T1, typename T2>
bool chmax(T1 &a, const T2 &b) {
    if (a < b) { a = b; return true; }
    return false;
}
template <typename T1, typename T2>
bool chmin(T1 &a, const T2 &b) {
    if (a > b) { a = b; return true; }
    return false;
}
template<typename T>
ostream &operator<<(ostream &os, const vector<T> &v) {
    os << "[";
    REP(i, SZ(v)) {
        if (i) os << ", ";
        os << v[i];
    }
    return os << "]";
}
template<typename T1, typename T2>
ostream &operator<<(ostream &os, const map<T1, T2> &mp) {
    os << "{";
    int a = 0;
    for (auto &tp : mp) {
        if (a) os << ", ";
        a = 1;
        os << tp;
    }
    return os << "}";
}
template<typename T1, typename T2>
ostream &operator<<(ostream &os, const pair<T1, T2> &p) {
    os << p.first << ":" << p.second;
    return os;
}


template<typename T>
struct edge {
    int src, to;
    T cost;

    edge() {}
    edge(int to, T cost) : src(-1), to(to), cost(cost) {}
    edge(int src, int to, T cost) : src(src), to(to), cost(cost) {}

    friend ostream& operator<<(ostream& os, const edge& e) {
        return os << "(" << e.src << "->" << e.to << ":" << e.cost << ")";
    }
};

template<typename T>
vector<T> dijkstra(const vector<vector<edge<T>>> &g, int s, T INF) {
    vector<T> d(g.size(), INF);
    using Pi = pair<T, int>;
    priority_queue<Pi, vector<Pi>, greater<Pi>> que;
    d[s] = 0;
    que.emplace(d[s], s);
    while (!que.empty()) {
        T cost;
        int v;
        tie(cost, v) = que.top();
        que.pop();
        if (d[v] < cost) continue;
        for (auto &e : g[v]) {
            T nxt = cost + e.cost;
            if (d[e.to] > nxt) {
                d[e.to] = nxt;
                que.emplace(nxt, e.to);
            }
        }
    }
    return d;
}

int main() {
    cin.tie(0);
    ios::sync_with_stdio(false);
    cout << fixed << setprecision(10);

    for (;;) {
        int n, m, C, s, g;
        cin >> n >> m >> C >> s >> g;
        --s, --g;
        if (n == 0) break;

        vector<vvi> G(C, vvi(n, vi(n, INF)));
        REP(c, C) REP(i, n) G[c][i][i] = 0;
        REP(i, m) {
            int x, y, d, c;
            cin >> x >> y >> d >> c;
            --x, --y, --c;
            chmin(G[c][x][y], d);
            chmin(G[c][y][x], d);
        }
        REP(c, C) {
            REP(k, n) {
                REP(i, n) {
                    REP(j, n) {
                        if (G[c][i][k] == INF or G[c][k][j] == INF) continue;
                        chmin(G[c][i][j], G[c][i][k] + G[c][k][j]);
                    }
                }
            }
        }

        vi p(C);
        REP(i, C) cin >> p[i];

        const int MAX_L = 200 * 100 + 1;
        vvi cost(C, vi(MAX_L));
        REP(i, C) {
            int k = 0;
            vi q(p[i]-1), r(p[i]);
            REP(j, p[i]-1) cin >> q[j];
            REP(j, p[i]) cin >> r[j];
            REP(j, p[i]-1) {
                for (; k < q[j]; ++k) {
                    cost[i][k+1] = cost[i][k] + r[j];
                }
            }
            for (; k+1 < MAX_L; ++k) {
                cost[i][k+1] = cost[i][k] + r[p[i]-1];
            }
        }

        vector<vector<edge<int>>> graph(n);
        REP(c, C) {
            REP(i, n) {
                REP(j, n) {
                    if (G[c][i][j] == INF) continue;
                    graph[i].emplace_back(j, cost[c][G[c][i][j]]);
                }
            }
        }

        auto dist = dijkstra(graph, s, INF);

        int ans = dist[g];

        if (ans == INF) ans = -1;
        cout << ans << endl;

    }

    return 0;
}



Measured memory_bytes: 7920