#include <bits/stdc++.h>
#define rep(i,n) for(int i=0;i<(int)(n);i++)
#define INF 1000000007
#define fi first
#define se second
#define show(x) cout << #x << " = " << x << "\n"

using namespace std;

typedef pair<int,int> P;
typedef pair<P,P> PP;
typedef pair<PP,int> PPI;

struct edge
{
    int to,cost,id;
};

template<typename T> class LIS2D
{
private:
    using ptt = pair<T,T>;
    set<ptt> st;
public:
    bool insert(pair<T,T> val){
        bool in = false;
        auto it = st.lower_bound(val);
        if(it != st.end()){
            if(*it == val) return in;
            in = (it->second >= val.second);
        }
        if(in){
            while(it != st.end() && it->second >= val.second){
                it = st.erase(it);
            }
        }else{
            if(it != st.begin()){
                it--;
                in = (it->second > val.second);
            }else{
                in = true;
            }
        }
        if(in) st.insert(val);
        return in;
    }
    void print(){
        for(auto& val : st){
            cout << "{" << val.first << "," << val.second << "}" << " ";
        }
        cout << "\n";
    }
};

int dd[21][20001];
vector<edge> G[101];

int n,m,s,c,g;

int Dijkstra()
{
    LIS2D<int> dp[101][21];
    priority_queue<PPI,vector<PPI>,greater<PPI> > que;
    que.push(PPI(PP(P(0,s),P(0,0)),0));
    rep(i,c){
        dp[s][i].insert(P(-INF,0));
    }
    while(!que.empty()){
        auto pp = que.top();
        auto p = pp.first;
        que.pop();
        int cost = (p.fi).fi, st = (p.fi).se, com = (p.se).fi, dist = (p.se).se, cnt = pp.second;
        if(cnt >= n) continue;
        if(st == g) return cost;
        for(auto& e : G[st]){
            if(e.id == com){
                int new_cost = cost-dd[com][dist]+dd[com][dist+e.cost];
                if(dp[e.to][com].insert(P(-dist-e.cost,new_cost))){
                    que.push(PPI(PP(P(new_cost,e.to),P(com,dist+e.cost)),cnt+1));
                }
            }else{
                if(dp[e.to][e.id].insert(P(-e.cost,cost+dd[e.id][e.cost]))){
                    que.push(PPI(PP(P(cost+dd[e.id][e.cost],e.to),P(e.id,e.cost)),1));
                }
            }
        }
    }
}

class UF {
private:
    int sz; vector<int> par,nrank;
public:
    UF(){}
    UF(int node_size){ sz = node_size; par.resize(sz),nrank.resize(sz,0); rep(i,sz) par[i] = i; }
    int find(int x){ if(par[x] == x){ return x; }else{ return par[x] = find(par[x]); } }
    void unite(int x,int y)
    { x = find(x),y = find(y); if(x == y) return;
    	if(nrank[x] < nrank[y]){ par[x] = y; }else{ par[y] = x; if(nrank[x] == nrank[y]) nrank[x]++; } }
    bool same(int x,int y){ return find(x) == find(y); }
};

int main()
{
    while(1){
        cin >> n >> m >> c >> s >> g;
        if(n == 0){
            break;
        }
        s--,g--;
        rep(i,n){
            G[i].clear();
        }
        UF uf(n);
        rep(i,m){
            int x,y,d,cs;
            cin >> x >> y >> d >> cs;
            G[x-1].push_back((edge){y-1,d,cs-1});
            G[y-1].push_back((edge){x-1,d,cs-1});
            uf.unite(x-1,y-1);
        }
        vector<int> p(c);
        rep(i,c){
            cin >> p[i];
        }
        rep(i,c){
            vector<int> q(p[i]),r(p[i]);
            q[0] = 0;
            rep(j,p[i]-1){
                cin >> q[j+1];
            }
            rep(j,p[i]){
                cin >> r[j];
            }
            rep(j,p[i]-1){
                rep(k,q[j+1]-q[j]){
                    dd[i][q[j]+k+1] = dd[i][q[j]+k]+r[j];
                }
            }
            for(int j=q[p[i]-1]+1;j<=20000;j++){
                dd[i][j] = dd[i][j-1]+r[p[i]-1];
            }
        }
        if(uf.same(s,g)){
            cout << Dijkstra() << "\n";
        }else{
            cout << "-1\n";
        }
    }
}



Measured memory_bytes: 7208