#include #include #include using namespace std; using u64 = unsigned long long; u64 mod_mul(u64 a, u64 b, u64 m) { return __uint128_t(a) * b % m; // https://github.com/wizykowski/miller-rabin/blob/master/mulmod64.h //u64 res; //__asm__("mulq %2;" // "divq %3;" // : "=&d"(res), "+%a"(a) // : "rm"(b), "rm"(m) // : "cc"); //return res; } u64 mod_pow(u64 x, u64 k, u64 m) { if(k == 0) { return 1; } if(k & 1) { return mod_mul(x, mod_pow(x, k-1, m), m); } return mod_pow(mod_mul(x, x, m), k>>1, m); } bool is_prime(u64 n) { if(n < 2) { return false; } for(u64&& p : {2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31}) { if(n < p * p) { return true; } if(n % p == 0) { return false; } } u64 s = 0, d = n-1; while(!(d & 1)) { ++s, d>>=1; } for(u64&& a : {2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37}) { u64 x = mod_pow(a, d, n); if(x == 1 || x == n-1) { continue; } bool flag = false; for(u64 loop=1; loop