Problem: cf2109_c3
Difficulty: easy
Categories: math
Time limit: 2000 ms, memory limit: 256 MB

This is the hard version of the problem. In this version, the limit of commands you can send is described in the statement.

This is an interactive problem.

Welcome, Duelists! In this interactive challenge, there is an unknown integer $x$ ($1 \le x \le 10^9$). You must make it equal to a given integer in the input $n$. By harnessing the power of "Mathmech" monsters, you can send a command to do one of the following:

|  |  |  |  |  |  |
| --- | --- | --- | --- | --- | --- |
| Command | Constraint | Result | Case | Update | Jury's response |
| "add $y$" | $-10^{18} \le y \le 10^{18}$ | $\mathrm{res} = x + y$ | $\text{if } 1 \le \mathrm{res} \le 10^{18}$ | $x \leftarrow \mathrm{res}$ | "1" |
| $\mathrm{else}$ | $x \leftarrow x$ | "0" |
| "mul $y$" | $1 \le y \le 10^{18}$ | $\mathrm{res} = x \cdot y$ | $\text{if } 1 \le \mathrm{res} \le 10^{18}$ | $x \leftarrow \mathrm{res}$ | "1" |
| $\mathrm{else}$ | $x \leftarrow x$ | "0" |
| "div $y$" | $1 \le y \le 10^{18}$ | $\mathrm{res} = x/y$ | $\text{if } y$ divides $x$ | $x \leftarrow \mathrm{res}$ | "1" |
| $\mathrm{else}$ | $x \leftarrow x$ | "0" |
| "digit" | — | $\mathrm{res} = S(x)$$^{\text{∗}}$ | — | $x \leftarrow \mathrm{res}$ | "1" |

Let $f(n)$ be the minimum integer such that there is a sequence of $f(n)$ commands that transforms $x$ into $n$ for all $x(1 \le x \le 10^9)$. You do not know the value of $x$ in advance. Find $f(n)$ such that, no matter what $x$ is, you can always transform it into $n$ using at most $f(n)$ commands.

Your task is to change $x$ into $n$ using at most $f(n)$ commands.

$^{\text{∗}}$$S(n)$ is a function that returns the sum of all the individual digits of a non-negative integer $n$. For example, $S(123) = 1 + 2 + 3 = 6$

Input

Each test contains multiple test cases. The first line contains the number of test cases $t$ ($1 \le t \le 5000$). The description of the test cases follows.

The first and only line of each test case contains one integer $n$ ($1 \le n \le 10^9$).

Interaction

The interaction for each test case begins by reading the integer $n$.

To send a command, output a line in the following format:

* "add $y$" Add some integer $y$ ($-10^{18} \le y \le 10^{18}$) to $x$.

  The jury will output "1" if $x + y$ is within $[1, 10^{18}]$ (successful), and "0" otherwise. If successful, update $x \leftarrow x + y$.
* "mul $y$" Multiply $x$ by a positive integer $y$ ($1 \le y \le 10^{18}$).

  The jury will output "1" if $x \cdot y$ is within $[1, 10^{18}]$ (successful), and "0" otherwise. If successful, update $x \leftarrow x \cdot y$.
* "div $y$" Divide $x$ by a positive integer $y$ ($1 \le y \le 10^{18}$).

  The jury will output "1" if $y$ is a divisor of $x$ (successful), and "0" otherwise. If successful, update $x \leftarrow \frac{x}{y}$.
* "digit" Make $x$ equal to the sum of its digits.

  The jury will always output "1" and update $x \leftarrow S(x)$.

Note that commands are case sensitive.

When you have determined that $x$ is equal to $n$, output a line in the following format:

* "!" — where the jury will output a "1" if $n$ is equal to $x$, and "-1" otherwise.

Note that answering does not count toward your limit of commands.

If your program makes more than $f(n)$ commands ($f(n)$ is described above) for one test case, or makes an invalid command, then the response to the command will be "-1". After receiving such a response, your program should immediately terminate to receive the verdict Wrong Answer. Otherwise, it may receive any other verdict.

After printing a command, do not forget to output the end of the line and flush the output. Otherwise, you will get Idleness limit exceeded. To do this, use:

* fflush(stdout) or cout.flush() in C++;
* System.out.flush() in Java;
* sys.stdout.flush() in Python;
* std::io::stdout().flush() in Rust;
* see the documentation for other languages.

The interactor is non-adaptive. The unknown integer $x$ does not change during the interaction.

Example

Input

```
2
100

0

1

1

1

5

1

1

1
```

Output

```
add -10

add 1

mul 10

!

digit

div 2

!
```

Note

|  |  |  |
| --- | --- | --- |
| Solution | Jury | Explanation |
|  | $\texttt{2}$ | There are 2 test cases. |
|  | $\texttt{100}$ | In the first test case, the unknown integer $x = 9$ and we have to make it equal to $n = 100$. |
| $\texttt{add -10}$ | $\texttt{0}$ | The answer to "add -10" is "0". This means that the addition command was not successful as $x + y = 9 + (-10) \le 0$, and $x$ remains $9$ after the command |
| $\texttt{add 1}$ | $\texttt{1}$ | The answer to "add 1" is "1". This means that the addition command was successful as $x + y = 9 + 1 = 10$, and $x$ changes to $10$ after the command. |
| $\texttt{mul 10}$ | $\texttt{1}$ | The answer to "mul 10" is "1". This means that the multiplication command was successful as $x \cdot y = 10 \cdot 10 = 100$, and $x$ changes to $100$ after the command. |
| $\texttt{!}$ | $\texttt{1}$ | The answer to "!" is "1". This means you have determined that $x$ equals $n$. |
|  | $\texttt{5}$ | In the second test case, the unknown integer $x = 1234$ and we have to make it equal to $n = 5$. |
| $\texttt{digit}$ | $\texttt{1}$ | The answer to "digit" is "1". This means that $x$ turned into the sum of its digits $1 + 2 + 3 + 4 = 10$, and $x$ changes to $10$ after the command. |
| $\texttt{div 2}$ | $\texttt{1}$ | The answer to "div 2" is "1". This means that the division command was successful as $y = 2$ is a divisor of $x = 10$, and $x$ changes to $\frac{x}{y} = \frac{10}{2} = 5$ after the command. |
| $\texttt{!}$ | $\texttt{1}$ | The answer to "!" is "1". This means you have determined that $x$ equals $n$. |

Note that the empty lines in the example input and output are for the sake of clarity, and do not occur in the real interaction.

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 const int LIMIT_PER_CASE = 150; 


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


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


long long digit_sum(long long val) {
    string s = to_string(val);
    long long sum = 0;
    for (char c : s) sum += (c - '0');
    return sum;
}

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

    
    int t = inf.readInt();
    
    
    cout << t << endl;

    
    query_limit = (long long)t * LIMIT_PER_CASE;
    log_metrics(); 

    for (int i = 0; i < t; ++i) {
        
        long long n = inf.readLong();
        long long x = inf.readLong();
        
        
        cout << n << endl;

        int case_queries = 0;
        bool case_active = true;

        while (case_active) {
            string token;
            if (!(cin >> token)) {
                finish(_wa, "Unexpected EOF while reading command (test case " + to_string(i+1) + ")");
            }

            
            if (token == "?") {
                if (!(cin >> token)) {
                    finish(_wa, "Unexpected EOF after '?'");
                }
            }

            
            if (token == "!") {
                if (x == n) {
                    cout << "1" << endl;
                    case_active = false; 
                } else {
                    cout << "-1" << endl;
                    finish(_wa, "Wrong Answer: guessed x=" + to_string(x) + " but expected n=" + to_string(n));
                }
                
                continue;
            }

            
            
            if (case_queries >= LIMIT_PER_CASE) {
                cout << "-1" << endl;
                finish(_wa, "Query limit exceeded for test case " + to_string(i+1));
            }

            
            queries++;
            case_queries++;

            
            string reply = "0";
            bool success = false;
            
            if (token == "add") {
                long long y;
                if (!(cin >> y)) finish(_wa, "Invalid format for add command");
                
                
                if (y < -1000000000000000000LL || y > 1000000000000000000LL) {
                    cout << "-1" << endl;
                    finish(_wa, "Argument y out of range for add command");
                }
                
                
                __int128 res = (__int128)x + y;
                if (res >= 1 && res <= 1000000000000000000LL) {
                    x = (long long)res;
                    success = true;
                }
            }
            else if (token == "mul") {
                long long y;
                if (!(cin >> y)) finish(_wa, "Invalid format for mul command");

                
                if (y < 1 || y > 1000000000000000000LL) {
                    cout << "-1" << endl;
                    finish(_wa, "Argument y out of range for mul command");
                }

                
                __int128 res = (__int128)x * y;
                if (res >= 1 && res <= 1000000000000000000LL) {
                    x = (long long)res;
                    success = true;
                }
            }
            else if (token == "div") {
                long long y;
                if (!(cin >> y)) finish(_wa, "Invalid format for div command");

                
                if (y < 1 || y > 1000000000000000000LL) {
                    cout << "-1" << endl;
                    finish(_wa, "Argument y out of range for div command");
                }

                
                if (x % y == 0) {
                    x = x / y;
                    success = true;
                }
            }
            else if (token == "digit") {
                
                x = digit_sum(x);
                success = true;
            }
            else {
                
                cout << "-1" << endl;
                finish(_wa, "Unknown command: " + token);
            }

            reply = success ? "1" : "0";
            cout << reply << endl;
        }
    }

    finish(_ok, "All cases passed");
    return 0;
}


Adaptive interactor (C++):

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");
    long long seed_val = atoll(argv[1]); 

    vector<long long> ns;
    vector<long long> xs;

    
    
    auto add = [&](long long n, long long x) {
        ns.push_back(n);
        if (mode == "non") {
            xs.push_back(x);
        }
    };

    
    auto rndC = [&]() { return rnd.next(1LL, 1000000000LL); };

    if (seed_val == 1) {
        
        add(1, 1);
        add(1000000000, 1000000000);
        add(1, 1000000000);
        add(1000000000, 1);
        add(100, 9);
    } else if (seed_val == 2) {
        
        add(2, 3);
        add(3, 2);
        add(5, 1234);
        add(10, 100); 
        add(12345, 67890); 
    } else if (seed_val == 3) {
        
        add(10, 1000);
        add(1000, 10);
        add(999, 1000);
        add(1000, 999);
        add(123, 6); 
    } else {
        
        int t = 100; 
        for (int i = 0; i < t; ++i) {
            long long n, x;
            int type = rnd.next(1, 6);
            
            if (type == 1) { 
                n = rnd.next(1, 100);
                x = rnd.next(1, 100);
            } else if (type == 2) { 
                n = rnd.next(900000000LL, 1000000000LL);
                x = rnd.next(900000000LL, 1000000000LL);
            } else if (type == 3) { 
                n = rndC();
                long long delta = rnd.next(-2000, 2000);
                x = n + delta;
                if (x < 1) x = 1;
                if (x > 1000000000) x = 1000000000;
            } else if (type == 4) { 
                n = rndC();
                x = rndC();
            } else if (type == 5) { 
                long long base = rnd.next(1, 10000);
                long long mult = rnd.next(1, 10000);
                long long val1 = base;
                long long val2 = base * mult;
                
                if (val2 > 1000000000) {
                     val2 = base * (1000000000 / base);
                     if (val2 == 0) val2 = 1000000000; 
                }
                if (rnd.next(2)) {
                    n = val1; x = val2;
                } else {
                    n = val2; x = val1;
                }
            } else { 
                 x = rndC();
                 long long temp = x;
                 long long sum = 0;
                 while(temp > 0) { sum += temp % 10; temp /= 10; }
                 n = sum; 
                 
                 if (rnd.next(2)) swap(n, x);
            }
            add(n, x);
        }
    }

    
    
    cout << ns.size() << "\n";
    for (size_t i = 0; i < ns.size(); ++i) {
        cout << ns[i];
        if (mode == "non") {
            
            cout << " " << xs[i];
        }
        cout << "\n";
    }

    return 0;
}