#include using namespace std; using ull = unsigned long long; template istream& operator >> (istream& is, vector& vec) { for(T& x : vec) is >> x; return is; } template struct csr { struct Node { csr* g; int u; template void emplace_back(Args&&... args){ g->add_edge(u, T(std::forward(args)...)); } auto begin(){ return g->E.begin() + g->start[u]; } auto end(){ return g->E.begin() + g->start[u + 1]; } int size(){ return g->start[u + 1] - g->start[u]; } T& operator[](int p){ return *(begin() + p); } }; int N; std::vector start; std::vector E; std::vector> edge; csr(int n) : N(n), start(n + 1) {edge.reserve(n);} void add_edge(int u, T v){ assert(0 <= u && u < N); start[u + 1]++; edge.emplace_back(u, v); } void build(){ E.resize(edge.size()); for(int i = 0; i < N; i++) start[i + 1] += start[i]; auto cnt = start; for(auto [u, v] : edge) E[cnt[u]++] = v; } const int size() {return N;} Node operator[](int u) {return Node{this, u};} }; int main(){ ios::sync_with_stdio(false); cin.tie(0); int n, m; cin >> n >> m; csr> g(n); for(int i = 0; i < m; i++){ int u, v, w; cin >> u >> v >> w; u--, v--; g[u].emplace_back(v, w); g[v].emplace_back(u, w); } g.build(); vector a(n), b(n), c(n); cin >> a >> b >> c; priority_queue, vector>, greater>> pq; vector dp(n, 0xFFFF'FFFF'FFFF'FFFFULL); dp[0] = 1; pq.emplace(1, 0); while(!pq.empty()){ auto [d, v] = pq.top(); pq.pop(); if(d > dp[v]) continue; ull Ad = (dp[v] + a[v] - 1) / a[v]; ull Lu = Ad * a[v] + (Ad % b[v] == 0 ? c[v] : 0); for(auto [u, w] : g[v]){ if(Lu + w >= dp[u]) continue; dp[u] = Lu + w; pq.emplace(dp[u], u); } if(Ad % b[v] != 0) continue; Ad++; Lu = Ad * a[v] + (Ad % b[v] == 0 ? c[v] : 0); for(auto [u, w] : g[v]){ if(Lu + w >= dp[u]) continue; dp[u] = Lu + w; pq.emplace(dp[u], u); } } cout << dp[n - 1] << '\n'; }