#line 1 "main.cpp" #include #line 1 "/home/anqooqie/.proconlib/tools/mod.hpp" #include #line 1 "/home/anqooqie/.proconlib/tools/quo.hpp" #line 5 "/home/anqooqie/.proconlib/tools/quo.hpp" namespace tools { template constexpr ::std::common_type_t quo(const M lhs, const N rhs) { if (lhs >= 0) { return lhs / rhs; } else { if (rhs >= 0) { return -((-lhs - 1 + rhs) / rhs); } else { return (-lhs - 1 + -rhs) / -rhs; } } } } #line 6 "/home/anqooqie/.proconlib/tools/mod.hpp" namespace tools { template constexpr ::std::common_type_t mod(const M lhs, const N rhs) { if constexpr (::std::is_unsigned_v && ::std::is_unsigned_v) { return lhs % rhs; } else { return lhs - ::tools::quo(lhs, rhs) * rhs; } } } #line 1 "/home/anqooqie/.proconlib/tools/inv_mod.hpp" #line 1 "/home/anqooqie/.proconlib/tools/extgcd.hpp" #line 7 "/home/anqooqie/.proconlib/tools/extgcd.hpp" namespace tools { template ::std::tuple extgcd(T prev_r, T r) { T prev_s(1); T prev_t(0); T s(0); T t(1); while (r != 0) { const T q = ::tools::quo(prev_r, r); ::std::tie(prev_r, r) = ::std::make_pair(r, prev_r - q * r); ::std::tie(prev_s, s) = ::std::make_pair(s, prev_s - q * s); ::std::tie(prev_t, t) = ::std::make_pair(t, prev_t - q * t); } if (prev_r < T(0)) prev_r = -prev_r; return ::std::make_tuple(prev_s, prev_t, prev_r); } } #line 7 "/home/anqooqie/.proconlib/tools/inv_mod.hpp" namespace tools { template constexpr T2 inv_mod(const T1 x, const T2 m) { const auto [x0, y0, gcd] = ::tools::extgcd(x, m); assert(gcd == 1); return ::tools::mod(x0, m); } } #line 4 "main.cpp" // Source: https://qiita.com/drken/items/ae02240cd1f8edfc86fd // License: unknown // Author: drken namespace tools { template ::std::optional garner(const Iterator& begin, const Iterator& end, const long long upper_bound) { ::std::vector b, m; for (auto it = begin; it != end; ++it) { b.push_back(::tools::mod(it->first, it->second)); m.push_back(it->second); } ::std::vector coeffs(m.size() + 1, 1); ::std::vector constants(m.size() + 1, 0); for (::std::size_t k = 0; k < b.size(); ++k) { long long t = ::tools::mod((b[k] - constants[k]) * ::tools::inv_mod(coeffs[k], m[k]), m[k]); for (::std::size_t i = k + 1; i < m.size(); ++i) { (constants[i] += t * coeffs[i]) %= m[i]; (coeffs[i] *= m[k]) %= m[i]; } if ((constants[m.size()] += t * coeffs[m.size()]) > upper_bound) return ::std::nullopt; if ((coeffs[m.size()] *= m[k]) > upper_bound) return ::std::nullopt; } return constants.back(); } } namespace tools { template ::std::optional extended_garner(const Iterator& begin, const Iterator& end, const long long upper_bound) { ::std::vector<::std::pair> v; for (auto it = begin; it != end; ++it) { v.emplace_back(::tools::mod(it->first, it->second), it->second); } for (::std::size_t i = 0; i < v.size(); ++i) { for (::std::size_t j = 0; j < i; ++j) { long long g = ::std::gcd(v[i].second, v[j].second); if ((v[i].first - v[j].first) % g != 0) return ::std::nullopt; v[i].second /= g; v[j].second /= g; long long gi = ::std::gcd(v[i].second, g); long long gj = g / gi; do { g = ::std::gcd(gi, gj); gi *= g; gj /= g; } while (g != 1); v[i].second *= gi; v[j].second *= gj; v[i].first %= v[i].second; v[j].first %= v[j].second; } } return ::tools::garner(v.begin(), v.end(), upper_bound); } } using ll = long long; int main() { std::cin.tie(nullptr); std::ios_base::sync_with_stdio(false); ll N, M; std::cin >> N >> M; std::vector> v(M); for (auto& [C, B] : v) std::cin >> B >> C; if (const auto answer = tools::extended_garner(v.begin(), v.end(), N); answer) { std::cout << *answer << '\n'; } else { std::cout << "NaN" << '\n'; } return 0; }