Problem: cf1406_e
Difficulty: medium
Categories: search, math
Time limit: 1000 ms, memory limit: 512 MB

This is an interactive problem.

There is an unknown integer $x$ ($1\le x\le n$). You want to find $x$.

At first, you have a set of integers $\{1, 2, \ldots, n\}$. You can perform the following operations no more than $10000$ times:

* A $a$: find how many numbers are multiples of $a$ in the current set.
* B $a$: find how many numbers are multiples of $a$ in this set, and then delete all multiples of $a$, but $x$ will never be deleted (even if it is a multiple of $a$). In this operation, $a$ must be greater than $1$.
* C $a$: it means that you know that $x=a$. This operation can be only performed once.

Remember that in the operation of type B $a>1$ must hold.

Write a program, that will find the value of $x$.

Input

The first line contains one integer $n$ ($1\le n\le 10^5$). The remaining parts of the input will be given throughout the interaction process.

Interaction

In each round, your program needs to print a line containing one uppercase letter A, B or C and an integer $a$ ($1\le a\le n$ for operations A and C, $2\le a\le n$ for operation B). This line desribes operation you make.

If your operation has type C your program should terminate immediately.

Else your program should read one line containing a single integer, which is the answer to your operation.

After outputting each line, don't forget to flush the output. To do it use:

* fflush(stdout) in C/C++;
* System.out.flush() in Java;
* sys.stdout.flush() in Python;
* flush(output) in Pascal;
* See the documentation for other languages.

It is guaranteed, that the number $x$ is fixed and won't change during the interaction process.

Example

Input

```
10

2

4

0
```

Output

```
B 4

A 2

A 8

C 4
```

Note

Note that to make the sample more clear, we added extra empty lines. You shouldn't print any extra empty lines during the interaction process.

In the first test $n=10$ and $x=4$.

Initially the set is: $\{1,2,3,4,5,6,7,8,9,10\}$.

In the first operation, you ask how many numbers are multiples of $4$ and delete them. The answer is $2$ because there are two numbers divisible by $4$: $\{4,8\}$. $8$ will be deleted but $4$ won't, because the number $x$ will never be deleted. Now the set is $\{1,2,3,4,5,6,7,9,10\}$.

In the second operation, you ask how many numbers are multiples of $2$. The answer is $4$ because there are four numbers divisible by $2$: $\{2,4,6,10\}$.

In the third operation, you ask how many numbers are multiples of $8$. The answer is $0$ because there isn't any number divisible by $8$ in the current set.

In the fourth operation, you know that $x=4$, which is the right answer.

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 vector<int> build_spf(int n) {
    vector<int> spf(n + 1, 0), primes;
    if (n >= 1) spf[1] = 1;
    for (int i = 2; i <= n; i++) {
        if (spf[i] == 0) {
            spf[i] = i;
            primes.push_back(i);
        }
        for (int p : primes) {
            long long v = 1LL * i * p;
            if (v > n) break;
            spf[(int)v] = p;
            if (p == spf[i]) break;
        }
    }
    return spf;
}

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

    ios::sync_with_stdio(false);
    cin.tie(nullptr);

    int n = inf.readInt(1, 100000, "n");

    query_limit = 10000;
    log_metrics(); 

    if (inf.seekEof()) {
        finish(_pe, "Hidden input schema mismatch: expected 'n x' for non-adaptive interactor.");
    }
    int x = inf.readInt(1, n, "x");

    
    cout << n << endl; 

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

    int S = min(450, n);
    vector<long long> smallCount(S + 1, 0);
    for (int d = 1; d <= S; d++) smallCount[d] = n / d;

    vector<char> alive(n + 1, 1);
    alive[0] = 0;

    vector<char> cleaned(n + 1, 0); 

    vector<int> spf = build_spf(n);

    static vector<int> divs, tmp;
    auto decSmallCountsForDeleted = [&](int y) {
        
        
        int t = y;
        vector<pair<int,int>> fac;
        while (t > 1) {
            int p = spf[t];
            int c = 0;
            while (t % p == 0) {
                t /= p;
                c++;
            }
            fac.push_back({p, c});
        }
        divs.clear();
        divs.push_back(1);
        for (auto [p, c] : fac) {
            tmp.clear();
            size_t need = divs.size() * (size_t)(c + 1);
            if (tmp.capacity() < need) tmp.reserve(need);
            for (int d : divs) {
                long long mul = 1;
                for (int k = 0; k <= c; k++) {
                    tmp.push_back((int)(d * mul));
                    mul *= p;
                }
            }
            divs.swap(tmp);
        }
        for (int d : divs) {
            if (d <= S) smallCount[d]--;
        }
    };

    auto getCount = [&](int a) -> long long {
        if (a <= S) return smallCount[a];
        long long ans = 0;
        for (int m = a; m <= n; m += a) ans += (alive[m] != 0);
        return ans;
    };

    while (true) {
        string cmd;
        long long a_ll;

        if (!(cin >> cmd)) {
            finish(_pe, "Unexpected EOF: contestant terminated without 'C a'.");
        }
        if (!(cin >> a_ll)) {
            finish(_pe, "Protocol error: expected integer after command.");
        }

        if (cmd != "A" && cmd != "B" && cmd != "C") {
            finish(_pe, "Protocol error: command must be one of A, B, C.");
        }

        if (a_ll < LLONG_MIN / 2 || a_ll > LLONG_MAX / 2) {
            finish(_pe, "Protocol error: integer out of range.");
        }
        if (a_ll < 1 || a_ll > n) {
            finish(_pe, "Protocol error: parameter a out of allowed range.");
        }
        int a = (int)a_ll;

        queries++;
        if (queries > hard_cap) {
            finish(_pe, "Hard cap exceeded (too many operations).");
        }

        if (cmd == "C") {
            if (a == x) finish(_ok, "Correct.");
            finish(_wa, "Incorrect guess.");
        } else if (cmd == "A") {
            long long ans = getCount(a);
            cout << ans << endl;
        } else { 
            if (a <= 1) {
                finish(_pe, "Protocol error: operation B requires a > 1.");
            }
            long long ans = getCount(a);
            cout << ans << endl;

            if (!cleaned[a]) {
                cleaned[a] = 1;
                for (int m = a; m <= n; m += a) {
                    if (m == x) continue; 
                    if (!alive[m]) continue;
                    alive[m] = 0;
                    decSmallCountsForDeleted(m);
                }
            }
        }
    }
}


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

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

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 vector<int> build_spf(int n) {
    vector<int> spf(n + 1, 0), primes;
    if (n >= 1) spf[1] = 1;
    for (int i = 2; i <= n; i++) {
        if (spf[i] == 0) {
            spf[i] = i;
            primes.push_back(i);
        }
        for (int p : primes) {
            long long v = 1LL * i * p;
            if (v > n) break;
            spf[(int)v] = p;
            if (p == spf[i]) break;
        }
    }
    return spf;
}

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

    ios::sync_with_stdio(false);
    cin.tie(nullptr);

    
    
    
    
    int n = inf.readInt(1, 100000, "n");
    int x = 0;
    if (!inf.seekEof()) {
        x = inf.readInt(1, n, "x");
    } else {
        x = n; 
    }

    log_metrics(); 

    cout << n << endl;

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

    int S = min(450, n);
    vector<long long> smallCount(S + 1, 0);
    for (int d = 1; d <= S; d++) smallCount[d] = n / d;

    vector<char> alive(n + 1, 1);
    alive[0] = 0;

    vector<char> cleaned(n + 1, 0); 

    vector<int> spf = build_spf(n);

    static vector<int> divs, tmp;
    auto decSmallCountsForDeleted = [&](int y) {
        
        
        int t = y;
        vector<pair<int, int>> fac;
        while (t > 1) {
            int p = spf[t];
            int c = 0;
            while (t % p == 0) {
                t /= p;
                c++;
            }
            fac.push_back({p, c});
        }
        divs.clear();
        divs.push_back(1);
        for (auto [p, c] : fac) {
            tmp.clear();
            tmp.reserve(divs.size() * (size_t)(c + 1));
            for (int d : divs) {
                long long mul = 1;
                for (int k = 0; k <= c; k++) {
                    tmp.push_back((int)(d * mul));
                    mul *= p;
                }
            }
            divs.swap(tmp);
        }
        for (int d : divs) {
            if (d <= S) smallCount[d]--;
        }
    };

    auto getCount = [&](int a) -> long long {
        if (a <= S) return smallCount[a];
        long long ans = 0;
        for (int m = a; m <= n; m += a) ans += (alive[m] != 0);
        return ans;
    };

    while (true) {
        string cmd;
        long long a_ll;

        if (!(cin >> cmd)) {
            finish(_pe, "Unexpected EOF: contestant terminated without 'C a'.");
        }
        if (!(cin >> a_ll)) {
            finish(_pe, "Protocol error: expected integer after command.");
        }

        if (cmd != "A" && cmd != "B" && cmd != "C") {
            finish(_pe, "Protocol error: command must be one of A, B, C.");
        }
        if (a_ll < 1 || a_ll > n) {
            finish(_pe, "Protocol error: parameter a out of allowed range.");
        }
        int a = (int)a_ll;

        queries++;
        if (queries > hard_cap) {
            finish(_pe, "Hard cap exceeded (too many operations).");
        }

        if (cmd == "C") {
            if (a == x) finish(_ok, "Correct.");
            finish(_wa, "Incorrect guess.");
        } else if (cmd == "A") {
            long long ans = getCount(a);
            cout << ans << endl;
        } else { 
            if (a <= 1) {
                finish(_pe, "Protocol error: operation B requires a > 1.");
            }
            long long ans = getCount(a);
            cout << ans << endl;

            if (!cleaned[a]) {
                cleaned[a] = 1;
                for (int m = a; m <= n; m += a) {
                    if (m == x) continue; 
                    if (!alive[m]) continue;
                    alive[m] = 0;
                    decSmallCountsForDeleted(m);
                }
            }
        }
    }
}



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

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

    string mode = opt<string>("mode", "non");
    int n = opt<int>("n", 100000);

    
    
    
    

    
    int seed = 1;
    if (argc >= 2) {
        
        
        try { seed = stoi(argv[1]); } catch (...) { seed = 1; }
    }

    
    n = max(1, min(n, 100000));

    auto isPrime = [&](int x)->bool{
        if (x < 2) return false;
        for (int i = 2; 1LL*i*i <= x; i++) if (x % i == 0) return false;
        return true;
    };

    auto prevPrimeLE = [&](int x)->int{
        for (int v = x; v >= 2; --v) if (isPrime(v)) return v;
        return 2;
    };

    auto nextPrimeGE = [&](int x)->int{
        for (int v = x; v <= n; ++v) if (isPrime(v)) return v;
        return prevPrimeLE(n);
    };

    
    int x = 1;

    if (seed == 1) {
        
        x = 1;
    } else if (seed == 2) {
        
        x = n;
    } else if (seed == 3) {
        
        x = prevPrimeLE(n);
    } else {
        
        
        
        
        
        
        
        int pick = rnd.next(1, 100);

        if (pick <= 45) {
            
            vector<int> primes = {2,3,5,7,11,13,17,19,23,29,31};
            long long val = 1;
            for (int p : primes) {
                int emax = 0;
                long long t = val;
                while (t * p <= n) { t *= p; emax++; }
                if (emax == 0) continue;
                
                int e = rnd.next(0, emax);
                for (int i = 0; i < e; i++) {
                    if (val * p > n) break;
                    val *= p;
                }
                if (val == n) break;
            }
            if (val < 2) val = 2;
            x = (int)val;
            
            if (x <= 3 || isPrime(x)) {
                int p = 2;
                while (1LL*x*p <= n) x *= p;
                if (x < 2) x = 4;
            }
        } else if (pick <= 75) {
            
            int p;
            if (rnd.next(0, 1) == 0) p = 2;
            else if (rnd.next(0, 1) == 0) p = 3;
            else p = nextPrimeGE(max(2, n/1000));
            long long val = p;
            while (val * p <= n) val *= p;
            x = (int)val;
            if (x < 2) x = min(n, 4);
        } else {
            
            int s = (int)sqrt((double)n);
            int p = prevPrimeLE(max(2, s + rnd.next(-2000, 2000)));
            int q = prevPrimeLE(max(2, (n / p)));
            
            if (p < 2) p = 2;
            if (q < 2) q = 2;
            long long val = 1LL*p*q;
            if (val > n) {
                q = prevPrimeLE(max(2, (int)(n / p)));
                val = 1LL*p*q;
            }
            if (val < 2) val = 2;
            x = (int)val;
            
            if (isPrime(x) && x >= 4) x = (x/2)*2;
            if (x < 2) x = 2;
            if (x > n) x = n;
        }

        
        if (x < 1) x = 1;
        if (x > n) x = n;
    }

    if (mode == "adp") {
        
        cout << n << "\n";
    } else if (mode == "non") {
        
        cout << n << " " << x << "\n";
    } else {
        
        cout << n << " " << x << "\n";
    }

    return 0;
}