Problem: cf1355_f
Difficulty: hard
Categories: greedy, math
Time limit: 2000 ms, memory limit: 256 MB

This is an interactive problem.

We have hidden an integer $1 \le X \le 10^{9}$. You don't have to guess this number. You have to find the number of divisors of this number, and you don't even have to find the exact number: your answer will be considered correct if its absolute error is not greater than 7 or its relative error is not greater than $0.5$. More formally, let your answer be $ans$ and the number of divisors of $X$ be $d$, then your answer will be considered correct if at least one of the two following conditions is true:

* $| ans - d | \le 7$;
* $\frac{1}{2} \le \frac{ans}{d} \le 2$.

You can make at most $22$ queries. One query consists of one integer $1 \le Q \le 10^{18}$. In response, you will get $gcd(X, Q)$ — the greatest common divisor of $X$ and $Q$.

The number $X$ is fixed before all queries. In other words, interactor is not adaptive.

Let's call the process of guessing the number of divisors of number $X$ a game. In one test you will have to play $T$ independent games, that is, guess the number of divisors $T$ times for $T$ independent values of $X$.

Input

The first line of input contains one integer $T$ ($1 \le T \le 100$) — the number of games.

Interaction

To make a query print a line "? Q" ($1 \le Q \le 10^{18}$). After that read one integer $gcd(X, Q)$. You can make no more than $22$ such queries during one game.

If you are confident that you have figured out the number of divisors of $X$ with enough precision, you can print your answer in "! ans" format. $ans$ have to be an integer. If this was the last game, you have to terminate the program, otherwise you have to start the next game immediately. Note that the interactor doesn't print anything in response to you printing answer.

After printing a query do not forget to output end of line and flush the output. To do this, use:

* fflush(stdout) or cout.flush() in C++;
* System.out.flush() in Java;
* flush(output) in Pascal;
* stdout.flush() in Python;
* see documentation for other languages.

Example

Input

```
2

1

1

1

1024

1048576

4194304
```

Output

```
? 982306799268821872

? 230856864650023977

? 134690134760714371

! 5
? 1024

? 1048576

? 1073741824

! 42
```

Note

Why the limitation for number of queries is 22 exactly? Maybe the problem author is a Taylor Swift fan.

Let's look at the example.

In the first game $X = 998\,244\,353$ is hidden. Would be hard to guess this, right? This number is prime, so the number of its divisors is 2. The solution has made several random queries, and all the responses turned out to be 1 (strange things, not even one of three random numbers is divisible by $998\,244\,353$). It's fare to assume that the hidden number doesn't have many divisors, so the solution has answered 5. Why not. This answer will be considered correct since $| 5 - 2 | = 3 \le 7$.

In the second game $X = 4\,194\,304 = 2^{22}$ is hidden, it has 23 divisors. The solution has made queries $1024 = 2^{10}$, $1\,048\,576 =2^{20}$, $1\,073\,741\,824 = 2^{30}$ and got responses $1024 = 2^{10}$, $1\,048\,576 =2^{20}$, $4\,194\,304 = 2^{22}$, respectively. Then the solution got completely confused and answered the answer to The Ultimate Question of Life, the Universe, and Everything. This answer will be considered correct since $\frac{1}{2} \le \frac{42}{23} \le 2$.

Non-adaptive interactor (C++):
#include "testlib.h"
#include <bits/stdc++.h>
using namespace std;

static long long queries = 0;
static long long query_limit = 0;

static void log_metrics() {
    try {
        tout << "queries=" << queries << "\n";
        tout << "query_limit=" << query_limit << "\n";
        tout.flush();
    } catch (...) {
        
    }
}

static void finish(TResult verdict, const string& msg) {
    log_metrics();
    quitf(verdict, "%s", msg.c_str());
}

static bool parse_ll_strict(const string& s, long long& out) {
    if (s.empty()) return false;
    size_t pos = 0;
    try {
        long long v = stoll(s, &pos, 10);
        if (pos != s.size()) return false;
        out = v;
        return true;
    } catch (...) {
        return false;
    }
}

static long long count_divisors_1e9(long long x) {
    if (x <= 0) return 0;
    long long n = x;
    long long res = 1;
    for (long long p = 2; p * p <= n; p += (p == 2 ? 1 : 2)) {
        if (n % p == 0) {
            int e = 0;
            while (n % p == 0) {
                n /= p;
                ++e;
            }
            res *= (e + 1LL);
        }
    }
    if (n > 1) res *= 2LL;
    return res;
}

static bool read_token(string& tok) {
    return (cin >> tok) ? true : false;
}

int main(int argc, char** argv) {
    registerInteraction(argc, argv);
    atexit(log_metrics);

    int T = 0;
    try {
        T = inf.readInt(1, 100, "T");
    } catch (...) {
        query_limit = 0;
        log_metrics();
        quitf(_fail, "Invalid hidden input (failed to read T)");
    }

    vector<long long> xs;
    xs.reserve(T);
    for (int i = 0; i < T; i++) {
        long long x = 0;
        try {
            x = inf.readLong(1LL, 1000000000LL, ("X[" + to_string(i) + "]").c_str());
        } catch (...) {
            query_limit = 0;
            log_metrics();
            quitf(_fail, "Invalid hidden input (failed to read X)");
        }
        xs.push_back(x);
    }

    query_limit = 22LL * (long long)T;
    const long long hard_cap = max(200000LL, 10LL * query_limit);

    
    log_metrics();

    cout << T << "\n";
    cout.flush();

    for (int game = 0; game < T; game++) {
        const long long X = xs[game];
        const long long d = count_divisors_1e9(X);

        bool answered = false;
        while (!answered) {
            if (queries > hard_cap) finish(_pe, "Hard cap exceeded (too many queries)");

            string cmd;
            if (!read_token(cmd)) finish(_pe, "Unexpected EOF from contestant");

            if (cmd == "?") {
                string qtok;
                if (!read_token(qtok)) finish(_pe, "Query missing Q");
                long long q = 0;
                if (!parse_ll_strict(qtok, q)) finish(_pe, "Invalid Q token");
                if (q < 1LL || q > 1000000000000000000LL) finish(_pe, "Q out of range");

                long long g = std::gcd(X, q);
                ++queries;
                cout << g << "\n";
                cout.flush();
            } else if (cmd == "!") {
                string atok;
                if (!read_token(atok)) finish(_pe, "Answer missing ans");
                long long ans = 0;
                if (!parse_ll_strict(atok, ans)) finish(_pe, "Invalid ans token");
                if (ans < 0) finish(_pe, "Negative ans");

                bool ok_abs = llabs(ans - d) <= 7LL;
                bool ok_rel = false;
                if (d > 0) {
                    long double ratio = (long double)ans / (long double)d;
                    ok_rel = (ratio >= 0.5L - 1e-18L && ratio <= 2.0L + 1e-18L);
                }

                if (!(ok_abs || ok_rel)) {
                    finish(_wa, "Wrong answer");
                }

                answered = true;
                
            } else {
                finish(_pe, "Unknown command (expected '?' or '!')");
            }
        }
    }

    
    string extra;
    if (cin >> extra) finish(_pe, "Extra output after finishing all games");

    finish(_ok, "OK");
}


Adaptive interactor (C++):

Test generator (C++):
#include "testlib.h"
#include <bits/stdc++.h>
using namespace std;

static long long mul_mod(long long a, long long b, long long mod) {
    return (long long)((__int128)a * (__int128)b % mod);
}

static long long pow_mod(long long a, long long d, long long mod) {
    long long r = 1 % mod;
    long long x = a % mod;
    while (d > 0) {
        if (d & 1) r = mul_mod(r, x, mod);
        x = mul_mod(x, x, mod);
        d >>= 1;
    }
    return r;
}

static bool isPrime64(long long n) {
    if (n < 2) return false;
    for (long long p : {2LL, 3LL, 5LL, 7LL, 11LL, 13LL, 17LL, 19LL, 23LL, 29LL, 31LL, 37LL}) {
        if (n == p) return true;
        if (n % p == 0) return n == p;
    }
    long long d = n - 1, s = 0;
    while ((d & 1) == 0) d >>= 1, ++s;

    auto witness = [&](long long a) -> bool {
        if (a % n == 0) return false;
        long long x = pow_mod(a, d, n);
        if (x == 1 || x == n - 1) return false;
        for (long long i = 1; i < s; i++) {
            x = mul_mod(x, x, n);
            if (x == n - 1) return false;
        }
        return true;
    };

    
    for (long long a : {2LL, 325LL, 9375LL, 28178LL, 450775LL, 9780504LL, 1795265022LL}) {
        if (witness(a)) return false;
    }
    return true;
}

static long long nextPrimeAtLeast(long long x, long long hi) {
    if (x <= 2) return 2;
    if ((x & 1) == 0) x++;
    for (long long v = x; v <= hi; v += 2) {
        if (isPrime64(v)) return v;
    }
    return -1;
}

static long long prevPrimeAtMost(long long x, long long lo) {
    if (x < 2) return -1;
    if (x == 2) return 2;
    if ((x & 1) == 0) x--;
    for (long long v = x; v >= lo; v -= 2) {
        if (isPrime64(v)) return v;
    }
    return -1;
}

static long long primeNear(long long lo, long long hi) {
    lo = max(lo, 2LL);
    hi = max(hi, 2LL);
    if (lo > hi) swap(lo, hi);
    long long start = rnd.next(lo, hi);
    long long up = nextPrimeAtLeast(start, hi);
    if (up != -1) return up;
    long long down = prevPrimeAtMost(start, lo);
    if (down != -1) return down;
    
    for (long long v = lo; v <= hi; v++) if (isPrime64(v)) return v;
    return 2;
}

static long long pow_limit(long long base, int exp, long long lim) {
    __int128 v = 1;
    for (int i = 0; i < exp; i++) {
        v *= base;
        if (v > lim) return lim + 1;
    }
    return (long long)v;
}

struct Cand {
    long long val;
    long long divs;
};

static void shrinkTop(vector<Cand>& v, int keep) {
    sort(v.begin(), v.end(), [](const Cand& a, const Cand& b) {
        if (a.divs != b.divs) return a.divs > b.divs;
        return a.val > b.val;
    });
    if ((int)v.size() > keep) v.resize(keep);
}

static vector<long long> highlyCompositeList(long long maxX, int keep) {
    vector<int> primes = {2, 3, 5, 7, 11, 13, 17, 19, 23, 29};
    vector<Cand> best;
    best.reserve(keep * 4);

    function<void(int,int,long long,long long)> dfs = [&](int idx, int lastExp, long long curVal, long long curDivs) {
        best.push_back({curVal, curDivs});
        if ((int)best.size() > keep * 20) shrinkTop(best, keep * 10);

        if (idx >= (int)primes.size()) return;
        int p = primes[idx];
        __int128 v = curVal;
        for (int e = 1; e <= lastExp; e++) {
            v *= p;
            if (v > maxX) break;
            long long nv = (long long)v;
            long long nd = curDivs * (e + 1LL);
            dfs(idx + 1, e, nv, nd);
        }
    };

    dfs(0, 60, 1LL, 1LL);
    shrinkTop(best, keep);

    vector<long long> vals;
    vals.reserve(best.size());
    for (auto &c : best) vals.push_back(c.val);

    
    sort(vals.begin(), vals.end());
    vals.erase(unique(vals.begin(), vals.end()), vals.end());
    return vals;
}

static long long makePrimePower(long long maxX) {
    static vector<int> smallPr = {2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31};
    int p = smallPr[rnd.next(0, (int)smallPr.size() - 1)];
    int maxExp = 1;
    while (pow_limit(p, maxExp + 1, maxX) <= maxX) maxExp++;
    int e = rnd.next(1, maxExp);
    long long v = pow_limit(p, e, maxX);
    if (v < 1 || v > maxX) v = p;
    return v;
}

static long long makeSemiprime(long long maxX) {
    long long s = (long long)sqrt((long double)maxX);
    long long off1 = rnd.next(0LL, 4000LL);
    long long off2 = rnd.next(0LL, 4000LL);
    long long p = prevPrimeAtMost(s - off1, 2);
    long long q = nextPrimeAtLeast(s + off2, 2LL * s + 100000);
    if (p == -1) p = 2;
    if (q == -1) q = 2;
    __int128 prod = (__int128)p * (__int128)q;
    if (prod <= maxX) return (long long)prod;

    
    long long q2 = prevPrimeAtMost((long long)(maxX / p), 2);
    if (q2 != -1) return p * q2;

    
    long long sp = 2;
    long long lp = prevPrimeAtMost(maxX / sp, 2);
    if (lp == -1) lp = 2;
    return sp * lp;
}

static long long makeSmooth(long long maxX) {
    vector<int> primes = {2, 3, 5, 7, 11, 13, 17, 19};
    long long x = 1;
    int maxUsed = rnd.next(3, 7);
    int lastExp = 60;
    for (int i = 0; i < maxUsed; i++) {
        int p = primes[i];
        int expLimit = 0;
        while (expLimit + 1 <= lastExp && pow_limit(p, expLimit + 1, maxX / x) <= maxX / x) expLimit++;
        expLimit = min(expLimit, lastExp);
        int e = rnd.next(0, expLimit);
        if (e == 0) continue;
        long long pe = pow_limit(p, e, maxX);
        if (pe > maxX / x) break;
        x *= pe;
        lastExp = e;
    }
    if (x < 1) x = 1;
    if (x > maxX) x = maxX;
    return x;
}

static long long makeNearMax(long long maxX) {
    long long delta = rnd.next(0LL, 100000LL);
    long long x = maxX - delta;
    if (x < 1) x = 1;
    return x;
}

int main(int argc, char* argv[]) {
    registerGen(argc, argv, 1);

    string mode = opt<string>("mode", "non");
    long long maxX = opt<long long>("maxx", 1000000000LL);

    int seed = 1;
    if (argc >= 2) {
        seed = atoi(argv[1]);
        if (seed <= 0) seed = 1;
    }

    if (mode == "adp") {
        int T = opt<int>("t", 100);
        long long L = opt<long long>("l", 1LL);
        long long R = opt<long long>("r", maxX);
        if (L < 1) L = 1;
        if (R > maxX) R = maxX;
        if (L > R) swap(L, R);
        cout << T << "\n" << L << " " << R << "\n";
        return 0;
    }

    
    vector<long long> xs;

    auto pushX = [&](long long x) {
        if (x < 1) x = 1;
        if (x > maxX) x = maxX;
        xs.push_back(x);
    };

    if (seed == 1) {
        
        pushX(1);
        pushX(2);
        pushX(4);
        pushX(536870912LL);     
        pushX(1000000000LL);    
        pushX(999999937LL);     
        pushX(73513440LL);      
        
        long long s = (long long)sqrt((long double)maxX);
        long long p = prevPrimeAtMost(s, 2);
        long long q = nextPrimeAtLeast(s + 1, 2LL * s + 100000);
        __int128 prod = (__int128)p * (__int128)q;
        if (p != -1 && q != -1 && prod <= maxX) pushX((long long)prod);
        else pushX(makeSemiprime(maxX));
    } else if (seed == 2) {
        
        pushX(1);
        pushX(999999937LL);
        pushX(536870912LL);      
        pushX(387420489LL);      
        pushX(282475249LL);      
        pushX(73513440LL);
        pushX(999999996LL);
        pushX(999999000LL);
        pushX(makeSemiprime(maxX));
        pushX(makePrimePower(maxX));
    } else if (seed == 3) {
        
        auto hc = highlyCompositeList(maxX, 60);
        pushX(1);
        pushX(maxX);
        pushX(999999937LL);
        pushX(536870912LL);
        pushX(387420489LL);
        for (int i = (int)hc.size() - 1; i >= 0 && (int)xs.size() < 20; i--) {
            pushX(hc[i]);
        }
        while ((int)xs.size() < 25) {
            pushX(makeSemiprime(maxX));
        }
    } else {
        int T = opt<int>("t", 100);
        auto hc = highlyCompositeList(maxX, 120);

        
        pushX(1);
        pushX(maxX);
        pushX(536870912LL);
        pushX(387420489LL);
        pushX(999999937LL);
        if (!hc.empty()) pushX(hc.back());

        while ((int)xs.size() < T) {
            int typ = rnd.next(0, 99);
            long long x = 1;

            if (typ < 25 && !hc.empty()) {
                int idx = rnd.next(0, (int)hc.size() - 1);
                x = hc[idx];
            } else if (typ < 40) {
                long long lo = max(2LL, maxX - 2000000LL);
                long long hi = maxX;
                x = primeNear(lo, hi);
            } else if (typ < 58) {
                x = makeSemiprime(maxX);
            } else if (typ < 72) {
                x = makePrimePower(maxX);
            } else if (typ < 88) {
                x = makeSmooth(maxX);
            } else {
                x = makeNearMax(maxX);
            }

            
            if (rnd.next(0, 9) == 0) {
                long long p = primeNear(max(2LL, maxX / 100000LL), maxX);
                long long m = makeSmooth(min(maxX, 100000LL));
                if (m < 1) m = 1;
                if ((__int128)p * m <= maxX) x = p * m;
            }

            pushX(x);
        }
    }

    int T = (int)xs.size();
    T = max(1, min(100, T));
    cout << T << "\n";
    for (int i = 0; i < T; i++) {
        cout << xs[i] << "\n";
    }
    return 0;
}