#include <iostream>
#include <vector>
#include <array>
#include <list>
#include <string>
#include <stack>
#include <queue>
#include <deque>
#include <unordered_map>
#include <unordered_set>
#include <tuple>
#include <memory>
#include <cmath>
#include <algorithm>
#include <functional>
#include <iomanip>
#include <numeric>
#include <climits>
#include <cfloat>
#include <cassert>
#include <random>
#include <set>

class FeeGraph {
	std::vector<int> _distance, _price_diff, min_price;
public:
	FeeGraph(std::vector<int> distance, std::vector<int> price) : _distance{ 0 }, _price_diff{ std::move(price) }, min_price{ 0 } {
		_distance.reserve(distance.size() + 1); std::copy(distance.begin(), distance.end(), std::back_inserter(_distance));
		for (auto i = 0; i < _price_diff.size() - 1; ++i) {
			min_price.push_back(min_price.back() + _price_diff[i] * (_distance[i + 1] - _distance[i]));
		}
	};
	int price_of(int distance) const {
		const auto pos = std::distance(_distance.begin(), std::upper_bound(_distance.begin(), _distance.end(), distance)) - 1;
		return min_price[pos] + (distance - _distance[pos]) * _price_diff[pos];
	}

};
struct Rail {
	int x, y, length, company;
};
int main() {
	const auto comparator = [](const std::pair<int, int> a, const std::pair<int, int> b) {return a.second > b.second; };
	while (true) {
		int n, m, company, start, goal; std::cin >> n >> m >> company >> start >> goal; --start; --goal; if (n == 0 && m == 0) break;
		std::vector<Rail> rails(m); for (auto& r : rails) {
			std::cin >> r.x >> r.y >> r.length >> r.company; --r.x; --r.y; --r.company;
		}
		std::vector<std::vector<std::vector<int>>> cost(company, std::vector<std::vector<int>>(n, std::vector<int>(n, INT_MAX)));
		for (auto c = 0; c < company; ++c) {
			for (const auto r : rails) if (r.company == c) {
				cost[c][r.x][r.y] = cost[c][r.y][r.x] = std::min(cost[c][r.x][r.y], r.length);
			}
			for (auto k = 0; k < n; ++k) {
				for (auto i = 0; i < n; ++i) if (cost[c][i][k] != INT_MAX) {
					for (auto j = 0; j < i; ++j) if (cost[c][k][j] != INT_MAX) {
						cost[c][i][j] = cost[c][j][i] = std::min(cost[c][i][j], cost[c][i][k] + cost[c][k][j]);
					}
				}
			}
		}
		std::vector<int> part_count(company); for (auto& p : part_count) std::cin >> p;
		std::vector<FeeGraph> fees; fees.reserve(company);
		for (const auto p : part_count) {
			std::vector<int> distance(p - 1), price(p);
			for (auto& q : distance) std::cin >> q;
			for (auto& r : price) std::cin >> r;
			fees.emplace_back(std::move(distance), std::move(price));
		}
		for (auto c = 0; c < company; ++c) {
			for (auto i = 0; i < n; ++i) {
				for (auto j = 0; j < n; ++j) if (cost[c][i][j] != INT_MAX) {
					cost[c][i][j] = fees[c].price_of(cost[c][i][j]);
				}
			}
		}
		auto merged = cost.front();
		for (auto c = 1; c < company; ++c) {
			for (auto i = 0; i < n; ++i) {
				for (auto j = 0; j < n; ++j) {
					merged[i][j] = std::min(merged[i][j], cost[c][i][j]);
				}
			}
		}
	 	std::priority_queue<std::pair<int, int>, std::vector<std::pair<int, int>>, decltype(comparator)> queue(comparator);
		std::vector<int> min_cost(n, INT_MAX);
		queue.emplace(start, 0); min_cost[start] = 0;
		while (!queue.empty()) {
			const auto top = queue.top(); queue.pop();
			if (top.first == goal) break;
			if (min_cost[top.first] == top.second) {
				for (auto i = 0; i < n; ++i) if (merged[top.first][i] != INT_MAX) {
					if (min_cost[i] > top.second + merged[top.first][i]) {
						min_cost[i] = top.second + merged[top.first][i];
						queue.emplace(i, min_cost[i]);
					}
				}
			}
		}
		std::cout << (min_cost[goal] == INT_MAX ? -1 : min_cost[goal]) << std::endl;
	}
}


Measured memory_bytes: 3996