#include <iostream>
#include <vector>
#include <queue>

using namespace std;

class range {
private:
  struct Iterator {
    int val;
    int operator*() {return val;}
    bool operator!=(Iterator& itr) {return val < itr.val;}
    void operator++() {++val;}
  };
  Iterator i, n;
public:
  range(int n) : i({0}), n({n}) {}
  range(int i, int n) : i({i}), n({n}) {}
  Iterator& begin() {return i;}
  Iterator& end() {return n;}
};

template<class T> inline T at(const vector<T> &v, int i) {return v[(i % (int)v.size() + v.size()) % v.size()];}

template<class T> inline bool is_max(T &a, const T &b) {return a < b ? a = b, true : false;}
template<class T> inline bool is_min(T &a, const T &b) {return a > b ? a = b, true : false;}

struct Edge {
  int to, dis, com;
};

int main() {
  while (true) {
    int n, m, c, s, g;
    cin >> n >> m >> c >> s >> g;
    if (n == 0 && m == 0 && c == 0 && s == 0 && g == 0) break;
    --s, --g;
    vector<Edge> edge[n];
    for (int i : range(m)) {
      int x, y, d, c;
      cin >> x >> y >> d >> c;
      --x, --y, --c;
      edge[x].emplace_back((Edge){y, d, c});
      edge[y].emplace_back((Edge){x, d, c});
    }
    int p[c];
    for (int i : range(c)) cin >> p[i];
    vector<int> q[c], r[c];
    for (int i : range(c)) {
      q[i].emplace_back(0);
      for (int j : range(p[i] - 1)) {
        int qq;
        cin >> qq;
        q[i].emplace_back(qq);
      }
      q[i].emplace_back(100000);
      for (int j : range(p[i])) {
        int rr;
        cin >> rr;
        r[i].emplace_back(rr);
      }
    }
    int dis[n][n];
    const int INF = 1e9;
    for (int i : range(n)) for (int j : range(n)) dis[i][j] = INF;
    for (int i : range(c)) for (int j : range(n)) {
      priority_queue<pair<int, int>, vector<pair<int, int>>, greater<pair<int, int>>> que;
      que.push(make_pair(0, j));
      int dd[n];
      for (int k : range(n)) dd[k] = 1e9;
      while (!que.empty()) {
        auto now = que.top(); que.pop();
        int cost = now.first;
        int pos = now.second;
        if (dd[pos] <= cost) continue;
        dd[pos] = cost;
        for (const auto& e : edge[pos]) if (e.com == i) que.push(make_pair(cost + e.dis, e.to));
      }
      for (int k : range(n)) if (dd[k] != INF) {
        int c = 0;
        for (int l : range(p[i])) {
          if (dd[k] < q[i][l + 1]) {
            is_min(dis[j][k], c + (dd[k] - q[i][l]) * r[i][l]);
            break;
          }
          c += (q[i][l + 1] - q[i][l]) * r[i][l];
        }
      }
    }
    for (int k : range(n)) for (int i : range(n)) for (int j : range(n)) is_min(dis[i][j], dis[i][k] + dis[k][j]);
    if (dis[s][g] == INF) cout << -1 << endl;
    else cout << dis[s][g] << endl;
  }
}