#include #include #define rep(i,n) for(int i=0;i vi; typedef vector vl; typedef vector> vvi; typedef vector> vvl; typedef long double ld; typedef pair P; template ostream& operator<<(ostream& os, const static_modint& a) {os << a.val(); return os;} template ostream& operator<<(ostream& os, const dynamic_modint& a) {os << a.val(); return os;} template istream& operator>>(istream& is, static_modint& a) {long long x; is >> x; a = x; return is;} template istream& operator>>(istream& is, dynamic_modint& a) {long long x; is >> x; a = x; return is;} template istream& operator>>(istream& is, vector& v){int n = v.size(); assert(n > 0); rep(i, n) is >> v[i]; return is;} template ostream& operator<<(ostream& os, const pair& p){os << p.first << ' ' << p.second; return os;} template ostream& operator<<(ostream& os, const vector& v){int n = v.size(); rep(i, n) os << v[i] << (i == n - 1 ? "\n" : " "); return os;} template ostream& operator<<(ostream& os, const vector>& v){int n = v.size(); rep(i, n) os << v[i] << (i == n - 1 ? "\n" : ""); return os;} template ostream& operator<<(ostream& os, const set& se){for(T x : se) os << x << " "; os << "\n"; return os;} template ostream& operator<<(ostream& os, const unordered_set& se){for(T x : se) os << x << " "; os << "\n"; return os;} template ostream& operator<<(ostream& os, const atcoder::segtree& seg){int n = seg.max_right(0, [](S){return true;}); rep(i, n) os << seg.get(i) << (i == n - 1 ? "\n" : " "); return os;} template ostream& operator<<(ostream& os, const atcoder::lazy_segtree& seg){int n = seg.max_right(0, [](S){return true;}); rep(i, n) os << seg.get(i) << (i == n - 1 ? "\n" : " "); return os;} template void chmin(T& a, T b){a = min(a, b);} template void chmax(T& a, T b){a = max(a, b);} template T pow_mod(T A, T N, T MOD){ T res = 1 % MOD; A %= MOD; while(N){ if(N & 1) res = (res * A) % MOD; A = (A * A) % MOD; N >>= 1; } return res; } template T pow_real(T A, T N, T INF){ T res = 1; while(N){ if(N & 1){ res = (res * A); if(res > INF) res = INF; } A = (A * A); if(A > INF) A = INF; N >>= 1; } return res; } // phib -> b - 1 int main(){ int n, m, l; cin >> n >> m >> l; int b = -1; { // ok >= b, ng < b int ok = 1000000001, ng = 0; while(ok - ng > 1){ int mid = (ok + ng) / 2; cout << "? " << mid << ' ' << 1 << "\n"; flush(cout); int res; cin >> res; if(res < mid) ok = mid; else ng = mid; } b = ok; } if(b == 1){ cout << "! 0\n"; return 0; } n %= b; if(n == 0){ if(m == 0 and l > 0) cout << "! 1\n"; else cout << "! 0\n"; return 0; } int e_real = pow_real(m, l, 1001001001); int e = pow_mod(m, l, b - 1); int ans; if(e_real >= (b - 1)) ans = pow_mod(n, e + (b - 1), b); else ans = pow_mod(n, e, b); cout << "! " << ans << "\n"; return 0; }