#include using namespace std; using point = pair; using edge = int; using graph = vector>; int main() { constexpr int64_t inf = 1e18; int n, m; cin >> n >> m; vector u(m), v(m), c(m), d(m), distance(n, inf); graph to(n); for (int i = 0; i < m; i++) { cin >> u.at(i) >> v.at(i) >> c.at(i) >> d.at(i); u.at(i)--; v.at(i)--; to.at(u.at(i)).push_back(i); to.at(v.at(i)).push_back(i); } priority_queue, greater> q; q.emplace(0, 0); while (not q.empty()) { auto [cost, vertex] = q.top(); q.pop(); if (cost >= distance.at(vertex)) continue; distance.at(vertex) = cost; for (auto next : to.at(vertex)) { int v_next = u.at(next) + v.at(next) - vertex; int64_t cost_next = cost + c.at(next); if (cost_next >= distance.at(v_next)) continue; q.emplace(cost_next, v_next); } } vector passed(m); int current = n - 1; while (current) { for (auto prev : to.at(current)) { int v_prev = u.at(prev) + v.at(prev) - current; if (distance.at(current) == distance.at(v_prev) + c.at(prev)) { current = v_prev; passed.at(prev) = true; break; } } } q.emplace(distance.at(n - 1), n - 1); for (int i = 0; i < n; i++) { distance.at(i) = inf; } while (not q.empty()) { auto [cost, vertex] = q.top(); q.pop(); if (cost >= distance.at(vertex)) continue; distance.at(vertex) = cost; for (auto next : to.at(vertex)) { int v_next = u.at(next) + v.at(next) - vertex; int64_t cost_next = cost + c.at(next); if (passed.at(next)) { cost_next = cost + d.at(next); } if (cost_next >= distance.at(v_next)) continue; q.emplace(cost_next, v_next); } } cout << distance.at(0) << endl; }