#include using namespace std; typedef long long ll; template void check_min(T &a, const T &b){ a = (a < b) ? a : b; } template void check_max(T &a, const T &b){ a = (a > b) ? a : b; } #define all(x) (x).begin(), (x).end() const ll INF = 1e18 + 3; void dijkstra(int start, int c_idx, int n, int m, vector>> &adj, vector &d){ priority_queue, vector>, greater>> pq; fill(d.begin(), d.end(), INF); d[start] = 0; pq.push({0, start}); while(!pq.empty()){ auto [du, u] = pq.top(); pq.pop(); if(du > d[u]) continue; for(auto edge: adj[u]){ int to = edge[0]; ll cost = edge[c_idx]; ll cand = du + cost; if(cand < d[to]){ d[to] = cand; pq.push({d[to], to}); } } } } int main(){ ios::sync_with_stdio(false); cin.tie(NULL); freopen("hurry.in", "r", stdin); freopen("hurry.out", "w", stdout); int t; cin >> t; while(t--){ int n, m; cin >> n >> m; vector>> adj(n + 1); for(int i = 0; i < m; ++i){ int u, v, a, b; cin >> u >> v >> a >> b; adj[u].push_back({v, a, b}); adj[v].push_back({u, a, b}); } vector d[2]; for(int i = 0; i < 2; ++i) d[i].resize(n + 1); dijkstra(1, 1, n, m, adj, d[0]); dijkstra(n, 2, n, m, adj, d[1]); ll ans = INF; for(int i = 1; i <= n; ++i) check_min(ans, d[0][i] + d[1][i]); cout << ans << "\n"; } }