#include <iostream>
#include <algorithm>
#include <queue>
#include <vector>
#include <cstdio>
#include <climits>
using namespace std;

const int inf = INT_MAX / 2;

struct Edge{
    int to, cost, com;
    Edge(int to, int cost, int com)
        : to(to), cost(cost), com(com) {}
};

struct State{
    int v, cost, com;
    State(int v, int cost, int com)
        : v(v), cost(cost), com(com) {}
    bool operator<(const State a)const{
        return cost > a.cost;
    }
};

int n,m,c,s,g,p[22],q[22][55],r[22][55];
int dp[22][110];
int dist[22][110][110]; // = 距離
vector<Edge> edge[110];


int calc[22][200100]; // 値合ってるかな…
int getCost(int kind, int kyori){
    int i;
    if( kyori == 0 ) return 0;
    if( calc[kind][kyori] != inf ) return calc[kind][kyori];

    for(i=1; i<=p[kind]; i++){
        if( q[kind][i-1] + 1 <= kyori && kyori <= q[kind][i] ){
            return calc[kind][kyori] = getCost(kind, kyori - 1) + r[kind][i];
        }
    }
    puts("aaa");
    exit(-1);
}


int main(){
    int i,j,k;

    while( cin >> n >> m >> c >> s >> g ){
        if( !(n || m || c || s || g) ) break;

        // init
        for(i=0; i<22; i++)
            for(j=0; j<110; j++)
                for(k=0; k<110; k++)
                    dist[i][j][k] = inf;

        for(i=0; i<22; i++)
            for(j=0; j<200100; j++)
                calc[i][j] = inf;

        for(i=0; i<110; i++) edge[i].clear();

        for(i=0; i<22; i++)
            for(j=0; j<110; j++)
                dp[i][j] = inf;

        s--, g--;
        for(i=0; i<m; i++){
            int x, y, d, cc;
            cin >> x >> y >> d >> cc;
            x--, y--, cc--;
            dist[cc][y][x] = min(dist[cc][y][x], d);
            dist[cc][x][y] = min(dist[cc][x][y], d);
        }

        // p
        for(i=0; i<c; i++) cin >> p[i];

        for(i=0; i<c; i++){
            // q
            q[i][0] = 0;
            q[i][p[i]] = inf;
            for(j=1; j<=p[i]-1; j++) cin >> q[i][j];

            // r
            for(j=1; j<=p[i]; j++) cin >> r[i][j];
        }
        

        // 一つの鉄道会社で移動できる全対間の最短経路を求める
        for(int t=0; t<c; t++)
            for(i=0; i<n; i++)
                dist[t][i][i] = 0;
        for(int t=0; t<c; t++){
            for(k=0; k<n; k++){
                for(i=0; i<n; i++){
                    for(j=0; j<n; j++){
                        dist[t][i][j] = min(dist[t][i][j],
                                            dist[t][i][k] + dist[t][k][j]);
                    }
                }
            }
        }

        
        // グラフを再構築
        for(int t=0; t<c; t++){
            for(i=0; i<n; i++){
                for(j=0; j<n; j++){
                    if( dist[t][i][j] != inf ){
                        edge[i].push_back(Edge(j, getCost(t, dist[t][i][j]), t));
                    }
                }
            }
        }

        priority_queue<State> q;
        q.push(State(s, 0, -1));

        int res = -1;
        while( !q.empty() ){
            State st = q.top();
            q.pop();

            if( st.v == g ){
                res = st.cost;
                break;
            }

            for(i=0; i<edge[st.v].size(); i++){
                if( st.com == edge[st.v][i].com ) continue;

                int nextV = edge[st.v][i].to;
                int nextCost = st.cost + edge[st.v][i].cost;
                int nextCom = edge[st.v][i].com;
                
                if( dp[nextCom][nextV] > nextCost ){
                    dp[nextCom][nextV] = nextCost;
                    q.push(State(nextV, nextCost, nextCom));
                }
            }
        }

        cout << res << endl;
    }
    return 0;
}

Measured memory_bytes: 22000