#include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #define VV(a, b, c, d) vector>(a, vector(b, c)) #define VVV(a, b, c, d, e) vector>>(a, VV(b, c, d, e)); #define all(obj) (obj).begin(), (obj).end() typedef long long int ll; typedef long double ld; typedef std::vector v1; typedef std::vector v2; typedef std::vector v3; using namespace std; namespace fact{ struct MontgomeryReduction{ __uint128_t MOD, NEG_INV, R2; MontgomeryReduction(uint64_t MOD_): MOD(MOD_){ NEG_INV = 0; __uint128_t s = 1, t = 0; for(int i=0;i<64;i++){ if (~t & 1) { t += MOD; NEG_INV += s; } t >>= 1; s <<= 1; } R2 = ((__uint128_t)1<<64) % MOD; R2 = R2 * R2 % MOD; } // return x * R % MOD; inline uint64_t generate(uint64_t x) const{ return reduce((__uint128_t)x * R2); } // return x / R % MOD; inline uint64_t reduce(__uint128_t x) const{ x = (x + ((uint64_t)x * (uint64_t)NEG_INV) * MOD) >> 64; return x < MOD? x: x-MOD; } }; uint64_t gcd(uint64_t a, uint64_t b){ if(a == 0) return b; if(b == 0) return a; int shift = __builtin_ctzll(a | b); a >>= __builtin_ctzll(a); do { b >>= __builtin_ctzll(b); if(a > b) std::swap(a, b); b -= a; }while(b); return (a << shift); } bool is_prime(uint64_t n, const MontgomeryReduction &mr){ if(n<=1) return false; if(n==2) return true; if(!(n&1)) return false; uint64_t d = n - 1, one = mr.generate(1); while(!(d&1)) d >>= 1; for(uint64_t a : {2, 325, 9375, 28178, 450775, 9780504, 1795265022}){ if(n <= a) break; uint64_t t = d; auto modpow = [&](uint64_t x, uint64_t k){ uint64_t r = one; while(k){ if(k&1) r = mr.reduce((__uint128_t)r * x); x = mr.reduce((__uint128_t)x * x); k >>= 1; } return r; }; uint64_t y = modpow(mr.generate(a), t), n_minus_one = mr.generate(n-1); while(t != n-1 && y != one && y != n_minus_one){ y = mr.reduce((__uint128_t)y * y); t <<= 1; } if(y != n_minus_one && t % 2 == 0) return false; } return true; } uint64_t rho(uint64_t n){ if((n&1)==0) return 2; for(auto p:{3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41}){ if(n%p==0) return p; if(n= n ? tmp - n : tmp;}; while(true){ c = (3 * c + 1)%99; uint64_t y = 2, r = 1, q = 1, g = 1, ys, x; while(g==1){ x = y; for(int i=0;iy?x-y:y-x)); } g = gcd(mr.reduce(q), n); k += m; } r <<= 1; } if(g==n){ while(g==1){ ys = f(ys); g = gcd(n, (x>y?x-y:y-x)); } } if(g factorize(ll n) { if(n == 1) return {}; ll x = rho(n); if(x == n) return {x}; vector le = factorize(x); vector ri = factorize(n / x); le.insert(le.end(), ri.begin(), ri.end()); return le; } vector PrimeFactor(ll N){ vector p = factorize(N); sort(all(p)); decltype(p)::iterator result = std::unique(p.begin(), p.end()); p.erase(result, p.end()); return p; } vector DivisorRestore(ll N){ vector p = factorize(N); sort(all(p)); vector> x(1, {1}); ll num = 1, idx = 0; for(int i=0;i{1}); num = 1; idx++; } } ll l = 0, r = 1; vector ret{1}; for(int i=0;i(ret.begin()+l, ret.end()); } } template T mod_inv(T a, T MOD){ T u[] = {a, 1, 0}, v[] = {MOD, 0, 1}, t; while(*v){ t = *u / *v; swap(u[0] -= t * v[0], v[0]); swap(u[1] -= t * v[1], v[1]); swap(u[2] -= t * v[2], v[2]); } u[1] %= MOD; return (u[1] < 0) ? (u[1] + MOD) : u[1]; } template int mod_inv(int a){ int u[] = {a, 1, 0}, v[] = {MOD, 0, 1}, t; while(*v){ t = *u / *v; swap(u[0] -= t * v[0], v[0]); swap(u[1] -= t * v[1], v[1]); swap(u[2] -= t * v[2], v[2]); } u[1] %= MOD; return (u[1] < 0) ? (u[1] + MOD) : u[1]; } //A_i = x_i mod m_i //-> lcm(m)以下のmodで全ての条件を満たす数を返す //xが全て0の場合は0 //unsafe: 互いに素かつ解が必ず存在する O(N^2) ll garner_unsafe(const vector&x, vector m, ll MOD){ int n = x.size(); assert(n == m.size()); vector kp(n+1, 0), rmult(n+1, 1); m.push_back(MOD); for(int i=0;i(rmult[i], m[i])) % m[i]; if(y < 0) y += m[i]; for(int j=i+1;j<=n;j++){ kp[j] = (kp[j] + rmult[j] * y) % m[j]; rmult[j] = (rmult[j] * m[i]) % m[j]; } } return kp[n]; } //A_i = x_i mod m_i //-> lcm(m)以下のmodで全ての条件を満たす数を返す //xが全て0の場合は0 //互いに素でない場合、 解が存在しない場合も使える O((Nlog(M_MAX))^2 + N * M_MAX^(1/4)) ll garner(const vector x, vector m, ll MOD){ int n = x.size(); assert(n == m.size()); unordered_map>> mp; bool f = false; for(int i=0;i max_p) max_p = pa.second, mo = pa.first; ans = (ans * max_p) % MOD; } return ans; } vector x2, m2; for(auto &k:mp){ ll max_p = -1, mo = -1; for(auto pa:k.second) if(pa.second > max_p) max_p = pa.second, mo = pa.first; for(auto pa:k.second) if(mo % pa.second != pa.first) return -1; x2.push_back(mo); m2.push_back(max_p); } return garner_unsafe(x2, m2, MOD); } int main(){ int n;std::cin >> n; vector x(n), m(n); for(int i=0;i> x[i] >> m[i]; std::cout << garner(x, m, 1000000007) << '\n'; }