This documentation is automatically generated by online-judge-tools/verification-helper
template< class T>
T pow_ (T x, uint64_t n, uint64_t M){
T u = 1;
if(n > 0){
u = pow_(x, n/2, M);
if (n % 2 == 0) u = (u*u) % M;
else u = (((u * u)% M) * x) % M;
}
return u;
};
bool suspect(__uint128_t a, uint64_t s, uint64_t d, uint64_t n){
__uint128_t x = pow_(a, d, n);
if (x == 1) return true;
for (int r = 0; r < s; ++r) {
if(x == n-1) return true;
x = x * x % n;
}
return false;
}
template<class T>
bool miller_rabin(T m){
uint64_t n = m;
if (n <= 1 || (n > 2 && n % 2 == 0)) return false;
uint64_t d = n - 1, s = 0;
while (!(d&1)) {++s; d >>= 1;}
vector<uint64_t> v = {2, 325, 9375, 28178, 450775, 9780504, 1795265022};
if(n < 4759123141LL) v = {2, 7, 61};
for (auto &&p : v) {
if(p >= n) break;
if(!suspect(p, s, d, n)) return false;
}
return true;
}
#line 1 "math/miller_rabin.cpp"
template< class T>
T pow_ (T x, uint64_t n, uint64_t M){
T u = 1;
if(n > 0){
u = pow_(x, n/2, M);
if (n % 2 == 0) u = (u*u) % M;
else u = (((u * u)% M) * x) % M;
}
return u;
};
bool suspect(__uint128_t a, uint64_t s, uint64_t d, uint64_t n){
__uint128_t x = pow_(a, d, n);
if (x == 1) return true;
for (int r = 0; r < s; ++r) {
if(x == n-1) return true;
x = x * x % n;
}
return false;
}
template<class T>
bool miller_rabin(T m){
uint64_t n = m;
if (n <= 1 || (n > 2 && n % 2 == 0)) return false;
uint64_t d = n - 1, s = 0;
while (!(d&1)) {++s; d >>= 1;}
vector<uint64_t> v = {2, 325, 9375, 28178, 450775, 9780504, 1795265022};
if(n < 4759123141LL) v = {2, 7, 61};
for (auto &&p : v) {
if(p >= n) break;
if(!suspect(p, s, d, n)) return false;
}
return true;
}