#include using namespace std; struct io_setup { io_setup() { ios_base::sync_with_stdio(false); cin.tie(NULL); cout << fixed << setprecision(15); } } io_setup; struct Random_Number_Generator { mt19937_64 mt; Random_Number_Generator() : mt(chrono::steady_clock::now().time_since_epoch().count()) {} // [l,r) での一様乱数 int64_t operator()(int64_t l, int64_t r) { uniform_int_distribution dist(l, r - 1); return dist(mt); } // [0,r) での一様乱数 int64_t operator()(int64_t r) { return (*this)(0, r); } } rng; long long modpow(long long x, long long n, const int &m) { x %= m; long long ret = 1; for (; n > 0; n >>= 1, x *= x, x %= m) { if (n & 1) ret *= x, ret %= m; } return ret; } template T modinv(T a, const T &m) { T b = m, u = 1, v = 0; while (b > 0) { T t = a / b; swap(a -= t * b, b); swap(u -= t * v, v); } return u >= 0 ? u % m : (m - (-u) % m) % m; } // オイラーの φ 関数 (x と m が互いに素ならば、x^φ(m) ≡ 1 (mod m)) template T Euler_totient(T m) { T ret = m; for (T i = 2; i * i <= m; i++) { if (m % i == 0) ret /= i, ret *= i - 1; while (m % i == 0) m /= i; } if (m > 1) ret /= m, ret *= m - 1; return ret; } // x^k ≡ y (mod m) となる最小の非負整数 k (存在しなければ -1) int modlog(int x, int y, int m, int max_ans = -1) { if (max_ans == -1) max_ans = m; long long g = 1; for (int i = m; i > 0; i >>= 1) g *= x, g %= m; g = gcd(g, m); int c = 0; long long t = 1; for (; t % g != 0; c++) { if (t == y) return c; t *= x, t %= m; } if (y % g != 0) return -1; t /= g, y /= g, m /= g; int n = 0; long long gs = 1; for (; n * n < max_ans; n++) gs *= x, gs %= m; unordered_map mp; long long e = y; for (int i = 0; i < n; mp[e] = ++i) e *= x, e %= m; e = t; for (int i = 0; i < n; i++) { e *= gs, e %= m; if (mp.count(e)) return c + n * (i + 1) - mp[e]; } return -1; } // x^k ≡ 1 (mod m) となる最小の正整数 k (x と m は互いに素) template T order(T x, const T &m) { T n = Euler_totient(m); vector ds; for (T i = 1; i * i <= n; i++) { if (n % i == 0) ds.push_back(i), ds.push_back(n / i); } sort(begin(ds), end(ds)); for (auto &e : ds) { if (modpow(x, e, m) == 1) return e; } return -1; } // 素数 p の原始根 template T primitive_root(const T &p) { vector ds; for (T i = 1; i * i <= p - 1; i++) { if ((p - 1) % i == 0) ds.push_back(i), ds.push_back((p - 1) / i); } sort(begin(ds), end(ds)); while (true) { T r = rng(1, p); for (auto &e : ds) { if (e == p - 1) return r; if (modpow(r, e, p) == 1) break; } } } struct Montgomery_Mod_Int_64 { using u64 = uint64_t; using u128 = __uint128_t; static u64 mod; static u64 r; // m*r ≡ 1 (mod 2^64) static u64 n2; // 2^128 (mod mod) u64 x; Montgomery_Mod_Int_64() : x(0) {} Montgomery_Mod_Int_64(long long b) : x(reduce((u128(b) + mod) * n2)) {} static u64 get_r() { // mod 2^64 での逆元 u64 ret = mod; for (int i = 0; i < 5; i++) ret *= 2 - mod * ret; return ret; } static u64 get_mod() { return mod; } static void set_mod(u64 m) { assert(m < (1LL << 62)); assert((m & 1) == 1); mod = m; n2 = -u128(m) % m; r = get_r(); assert(r * mod == 1); } static u64 reduce(const u128 &b) { return (b + u128(u64(b) * u64(-r)) * mod) >> 64; } Montgomery_Mod_Int_64 &operator+=(const Montgomery_Mod_Int_64 &p) { if ((x += p.x) >= 2 * mod) x -= 2 * mod; return *this; } Montgomery_Mod_Int_64 &operator-=(const Montgomery_Mod_Int_64 &p) { if ((x += 2 * mod - p.x) >= 2 * mod) x -= 2 * mod; return *this; } Montgomery_Mod_Int_64 &operator*=(const Montgomery_Mod_Int_64 &p) { x = reduce(u128(x) * p.x); return *this; } Montgomery_Mod_Int_64 &operator/=(const Montgomery_Mod_Int_64 &p) { *this *= p.inverse(); return *this; } Montgomery_Mod_Int_64 &operator++() { return *this += Montgomery_Mod_Int_64(1); } Montgomery_Mod_Int_64 operator++(int) { Montgomery_Mod_Int_64 tmp = *this; ++*this; return tmp; } Montgomery_Mod_Int_64 &operator--() { return *this -= Montgomery_Mod_Int_64(1); } Montgomery_Mod_Int_64 operator--(int) { Montgomery_Mod_Int_64 tmp = *this; --*this; return tmp; } Montgomery_Mod_Int_64 operator+(const Montgomery_Mod_Int_64 &p) const { return Montgomery_Mod_Int_64(*this) += p; }; Montgomery_Mod_Int_64 operator-(const Montgomery_Mod_Int_64 &p) const { return Montgomery_Mod_Int_64(*this) -= p; }; Montgomery_Mod_Int_64 operator*(const Montgomery_Mod_Int_64 &p) const { return Montgomery_Mod_Int_64(*this) *= p; }; Montgomery_Mod_Int_64 operator/(const Montgomery_Mod_Int_64 &p) const { return Montgomery_Mod_Int_64(*this) /= p; }; bool operator==(const Montgomery_Mod_Int_64 &p) const { return (x >= mod ? x - mod : x) == (p.x >= mod ? p.x - mod : p.x); }; bool operator!=(const Montgomery_Mod_Int_64 &p) const { return (x >= mod ? x - mod : x) != (p.x >= mod ? p.x - mod : p.x); }; Montgomery_Mod_Int_64 inverse() const { assert(*this != Montgomery_Mod_Int_64(0)); return pow(mod - 2); } Montgomery_Mod_Int_64 pow(long long k) const { Montgomery_Mod_Int_64 now = *this, ret = 1; for (; k > 0; k >>= 1, now *= now) { if (k & 1) ret *= now; } return ret; } u64 get() const { u64 ret = reduce(x); return ret >= mod ? ret - mod : ret; } friend ostream &operator<<(ostream &os, const Montgomery_Mod_Int_64 &p) { return os << p.get(); } friend istream &operator>>(istream &is, Montgomery_Mod_Int_64 &p) { long long a; is >> a; p = Montgomery_Mod_Int_64(a); return is; } }; typename Montgomery_Mod_Int_64::u64 Montgomery_Mod_Int_64::mod, Montgomery_Mod_Int_64::r, Montgomery_Mod_Int_64::n2; bool Miller_Rabin(unsigned long long n, vector as) { using Mint = Montgomery_Mod_Int_64; if (Mint::get_mod() != n) Mint::set_mod(n); unsigned long long d = n - 1; while (!(d & 1)) d >>= 1; Mint e = 1, rev = n - 1; for (unsigned long long a : as) { if (n <= a) break; unsigned long long t = d; Mint y = Mint(a).pow(t); while (t != n - 1 && y != e && y != rev) { y *= y; t <<= 1; } if (y != rev && (!(t & 1))) return false; } return true; } bool is_prime(unsigned long long n) { if (!(n & 1)) return n == 2; if (n <= 1) return false; if (n < (1LL << 30)) return Miller_Rabin(n, {2, 7, 61}); return Miller_Rabin(n, {2, 325, 9375, 28178, 450775, 9780504, 1795265022}); } unsigned long long Pollard_rho(unsigned long long n) { using Mint = Montgomery_Mod_Int_64; if (!(n & 1)) return 2; if (is_prime(n)) return n; if (Mint::get_mod() != n) Mint::set_mod(n); Mint R, one = 1; auto f = [&](Mint x) { return x * x + R; }; auto rnd = [&]() { return rng(n - 2) + 2; }; while (true) { Mint x, y, ys, q = one; R = rnd(), y = rnd(); unsigned long long g = 1; int m = 128; for (int r = 1; g == 1; r <<= 1) { x = y; for (int i = 0; i < r; i++) y = f(y); for (int k = 0; g == 1 && k < r; k += m) { ys = y; for (int i = 0; i < m && i < r - k; i++) q *= x - (y = f(y)); g = gcd(q.get(), n); } } if (g == n) { do { g = gcd((x - (ys = f(ys))).get(), n); } while (g == 1); } if (g != n) return g; } return 0; } vector factorize(unsigned long long n) { if (n <= 1) return {}; unsigned long long p = Pollard_rho(n); if (p == n) return {n}; auto l = factorize(p); auto r = factorize(n / p); copy(begin(r), end(r), back_inserter(l)); return l; } vector> prime_factor(unsigned long long n) { auto ps = factorize(n); sort(begin(ps), end(ps)); vector> ret; for (auto &e : ps) { if (!ret.empty() && ret.back().first == e) { ret.back().second++; } else { ret.emplace_back(e, 1); } } return ret; } // 素数 p について、x^2 ≡ a (mod p) となる x を 1 つ求める (存在しなければ -1) int sqrt_mod(int a, const int &p) { if (a == 0) return 0; if (p == 2) return a; if (modpow(a, (p - 1) / 2, p) != 1) return -1; int s = p - 1, t = 0; while (s % 2 == 0) s /= 2, t++; long long x = modpow(a, (s + 1) / 2, p); long long u = 1; while (modpow(u, (p - 1) / 2, p) == 1) u = rng(1, p); u = modpow(u, s, p); long long y = (1LL * x * x % p) * modinv(a, p) % p; while (y != 1) { int k = 0; long long z = y; while (z != 1) k++, z *= z, z %= p; for (int i = 0; i < t - k - 1; i++) u *= u, u %= p; x *= u, x %= p; u *= u, u %= p; y *= u, y %= p; t = k; } return x; } // x^(m^e) ≡ a (mod p) (m が p-1 の素因数であり、解が存在する場合) int prime_power_root_mod(int m, int e, int a, const int &p) { int s = p - 1, t = 0; while (s % m == 0) s /= m, t++; vector pw(t + 1, 1); for (int i = 0; i < t; i++) pw[i + 1] = pw[i] * m; int q = pw[e]; long long x = modpow(a, (1 + 1LL * s * (q - modinv(s, q))) / q, p); long long u = 1; while (modpow(u, (p - 1) / m, p) == 1) u = rng(1, p); u = modpow(u, s, p); long long y = modpow(x, q, p) * modinv(a, p) % p; while (y != 1) { int k = 0; long long z = y; while (z != 1) k++, z = modpow(z, m, p); long long w = modpow(u, pw[t - k - e], p); long long v = modpow(w, pw[e + k - 1], p); long long inv = modinv((int)modpow(y, pw[k - 1], p), p); // v^n ≡ inv (mod p) となる最小の n (m 未満であることに注意) を BSGS で求める int n = modlog(v, inv, p, m); w = modpow(w, n, p); x *= w, x %= p; y *= modpow(w, q, p), y %= p; } return x; } // 素数 p について、x^k ≡ a (mod p) となる x を 1 つ求める (存在しなければ -1) int kth_root_mod(int k, int a, const int &p) { if (a == 0) return k == 0 ? -1 : 0; if (p == 2) return a; int g = gcd(k, p - 1); if (modpow(a, (p - 1) / g, p) != 1) return -1; auto ps = prime_factor(g); int x = modpow(a, modinv(k / g, (p - 1) / g), p); for (auto [m, e] : ps) x = prime_power_root_mod(m, e, x, p); return x; } int main() { int T; cin >> T; while (T--) { int K, A, P; cin >> P >> K >> A; cout << kth_root_mod(K, A, P) << '\n'; } }