#include #include #include #include #include #include #include #include #include #include using namespace boost::multiprecision; using i64 = int64_t; using u64 = uint64_t; using i32 = int32_t; using u32 = uint32_t; template std::vector vec(T elem, int len) { return std::vector(len, elem); } void run(void) { i32 n, m; std::cin >> n >> m; std::vector> edge; std::vector> g(n); for (int i = 0; i < m; ++i) { i32 u, v, a, b; std::cin >> u >> v >> a >> b; u--; v--; edge.emplace_back(u, v, a, b); if (u != v) { g[u].push_back(i); g[v].push_back(i); //std::cout << i << ":" << u << " " << v << " " << a << " " << b << std::endl; } } std::vector nu(n, 1); std::vector de(n, 0); nu[0] = 0; de[0] = 1; using F = std::pair, int>; auto cmp = [&](F x, F y) { const auto a = x.first; const auto b = y.first; return a.first * b.second > a.second * b.first; }; std::priority_queue, decltype(cmp)> pq(cmp); pq.emplace(std::make_pair(nu[0], de[0]), 0); while (pq.size()) { auto [p, v] = pq.top(); auto [a, b] = p; pq.pop(); if (nu[v] != a || de[v] != b) continue; for (const int j : g[v]) { const auto [p, q, x, y] = edge[j]; const int u = p ^ q ^ v; cpp_int next_nu = y * a + x * b; cpp_int next_de = y * b; cpp_int g = gcd(next_nu, next_de); if (g != 1) { next_nu = next_nu / g; next_de = next_de / g; } if (next_nu * de[u] < next_de * nu[u]) { nu[u] = next_nu; de[u] = next_de; pq.emplace(std::make_pair(nu[u], de[u]), u); } } } for (int i = 1; i < n; ++i) { std::cout << nu[i] << " " << de[i] << "\n"; } } int main(void) { std::cin.tie(nullptr); std::ios::sync_with_stdio(false); run(); return 0; }