#include <bits/stdc++.h>
template<typename T>
struct Edge {
    int from, to;
    T cost;
    Edge(int from, int to, T cost) {
        this->from = from;
        this->to = to;
        this->cost = cost;
    }
};
bool operator == (Edge<int> e1, Edge<int> e2) {
    return e1.from == e2.from &&
            e1.to == e2.to &&
            e1.cost == e2.cost;
}
bool operator > (Edge<int> e1, Edge<int> e2) {
    return e1.cost < e2.cost;
}
template<typename T>
using Edges = std::vector<Edge<T>>;
template<typename T>
using Graph = std::vector<Edges<T>>;
template <typename T>
std::vector<T> dijkstra(const Graph<T> &g, int s) {
    int sz = (int)(g.size());
    std::vector<T> dist(sz, std::numeric_limits<T>::max());
    std::priority_queue<std::pair<T, int>, std::vector<std::pair<T, int>>, std::greater<std::pair<T, int>>> pq;
    dist[s] = 0;
    pq.push({0, s});
    while(!pq.empty()) {
        T d = pq.top().first;
        int now = pq.top().second;
        pq.pop();
        if(d > dist[now]) continue;
        for(int i=0;i<(int)(g[now].size());++i) {
            int next = g[now][i].to;
            T cost = g[now][i].cost;
            if(dist[next] > dist[now] + cost) {
                dist[next] = dist[now] + cost;
                pq.push({cost, next});
            }
        }
    }
    return dist;
}
using namespace std;
using ll = long long;
using ld = long double;
using P = pair<int, int>;
using vi = vector<int>;
using vvi = vector<vector<int>>;
using vll = vector<ll>;
using vvll = vector<vector<ll>>;
const double eps = 1e-10;
const int MOD = 1000000007;
const int INF = 1000000000;
const ll LINF = 1ll<<50;
template<typename T>
void printv(const vector<T>& s) {
  for(int i=0;i<(int)(s.size());++i) {
    cout << s[i];
    if(i == (int)(s.size())-1) cout << endl;
    else cout << " ";
  }
}
int main() {
  cin.tie(0);
  ios::sync_with_stdio(false);
  cout << fixed << setprecision(10);
  while(1) {
    int n, m, c, s, g; cin >> n >> m >> c >> s >> g;
    if(n == 0) break;
    s--; g--;
    vector<vvi> dist(c, vvi(n, vi(n, INF)));
    for(int i=0;i<c;++i) {
      for(int j=0;j<n;++j) {
        dist[i][j][j] = 0;
      }
    }
    for(int i=0;i<m;++i) {
      int x, y, d, col; cin >> x >> y >> d >> col;
      x--; y--; col--;
      dist[col][x][y] = min(dist[col][x][y], d);
      dist[col][y][x] = min(dist[col][y][x], d);
    }
    vector<int> p(c);
    for(int i=0;i<c;++i) {
      cin >> p[i];
    }
    vector<vector<int>> q(c), r(c);
    for(int i=0;i<c;++i) {
      for(int j=0;j<p[i]-1;++j) {
        int tmp; cin >> tmp;
        q[i].push_back(tmp);
      }
      q[i].push_back(INF);
      for(int j=0;j<p[i];++j) {
        int tmp; cin >> tmp;
        r[i].push_back(tmp);
      }
    }
    vector<vector<int>> diff(c, vector<int>(100100, 0));
    for(int i=0;i<c;++i) {
      diff[i][0] = 0;
      int pos = 0;
      for(int j=1;j<=100100;++j) {
        if(q[i][pos] < j) pos++;
        diff[i][j] = diff[i][j-1] + r[i][pos];
      }
    }
    for(int col=0;col<c;++col) {
      for(int k=0;k<n;++k) {
        for(int i=0;i<n;++i) {
          for(int j=0;j<n;++j) {
            if(dist[col][i][k] == INF || dist[col][k][j] == INF) continue;
            dist[col][i][j] = min(dist[col][i][j], dist[col][i][k] + dist[col][k][j]);
          }
        }
      }
    }
    Graph<int> gr(n);
    for(int i=0;i<n;++i) {
      for(int j=0;j<n;++j) {
        if(i == j) continue;
        int mi = INF;
        for(int k=0;k<c;++k) {
          if(dist[k][i][j] == INF) continue;
          mi = min(mi, diff[k][dist[k][i][j]]);
        }
        if(mi != INF) {
          gr[i].push_back(Edge<int>(i, j, mi));
          gr[j].push_back(Edge<int>(j, i, mi));
        }
      }
    }
    vector<int> ans = dijkstra(gr, s);
    cout << (ans[g] == INT_MAX ? -1 : ans[g]) << endl;
  }
}



Measured memory_bytes: 12140