Problem: cf1826_f
Difficulty: medium
Categories: math
Time limit: 4000 ms, memory limit: 256 MB

This is an interactive problem.

There are $n$ distinct hidden points with real coordinates on a two-dimensional Euclidean plane. In one query, you can ask some line $ax + by + c = 0$ and get the projections of all $n$ points to this line in some order. The given projections are not exact, please read the interaction section for more clarity.

Using the minimum number of queries, guess all $n$ points and output them in some order. Here minimality means the minimum number of queries required to solve any possible test case with $n$ points.

The hidden points are fixed in advance and do not change throughout the interaction. In other words, the interactor is not adaptive.

A projection of point $A$ to line $ax + by + c = 0$ is the point on the line closest to $A$.

Input

The first line contains a single integer $t$ ($1 \leq t \leq 50$) — the number of test cases.

The description of the test cases follows.

The first line of each test case contains a single integer $n$ ($2 \leq n \leq 25$) — the number of hidden points.

For each test case, it is guaranteed that for any pair of hidden points, their $x$ coordinates differ by at least $1$. Analogously, $y$ coordinates of any pair also differ by at least $1$.

Coordinates $x$ and $y$ of all hidden points do not exceed $100$ by absolute value.

Interaction

To query a line $ax + by + c = 0$ you should print "? a b c" where all a, b and c are real numbers up to $100$ by absolute value. For less precision issues numbers $a$ and $b$ must satisfy the condition $|a| + |b| \geq 0.1$, where $|a|$ is the absolute value of $a$.

As an answer to the query you will get $n$ points in the form "x\_1 y\_1 ... x\_n y\_n", where points $(x_i, y_i)$ are projections to the line $ax + by + c = 0$. It is guaranteed that each printed point is no more than $10^{-4}$ away from the real projection point. Every coordinate is printed with at most 9 decimal places.

See the interaction example for more clarity.

If you ask too many queries, you will get Wrong answer.

To output an answer you should print "! x\_1 y\_1 ... x\_n y\_n", where $(x_i, y_i)$ are coordinates of the hidden points. You could output the hidden points in any order. The answer would be considered correct if each of the printed points is no more than $10^{-3}$ away from the corresponding hidden point. Printing the answer doesn't count as a query.

After printing a query or the answer, do not forget to output end of 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;
* flush(output) in Pascal;
* stdout.flush() in Python;
* see the documentation for other languages

Example

Input

```
1
2

1 1 2.5 1

1.500000001 1.500000000 2 2
```

Output

```
? 0 1 -1

? 0.2 -0.2 0

! 1 3 2.5 0.500000001
```

Note

In the sample the hidden points are $(1, 3)$ and $(2.5, 0.5)$

A picture, which describes the first query:

![](https://espresso.codeforces.com/86aa468eed88633fca95efaeae1feba89103565d.png)

A picture, which describes the second query:

![](https://espresso.codeforces.com/810b3a8ee0cdbceb2e328abedc03c48ad4284593.png)

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 long long HARD_CAP = 2000; 

struct Point {
    double x, y;
};


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


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


Point project(Point p, double a, double b, double c) {
    double val = a * p.x + b * p.y + c;
    double len_sq = a * a + b * b;
    
    
    if (len_sq < 1e-18) return {0.0, 0.0}; 
    return {p.x - a * val / len_sq, p.y - b * val / len_sq};
}

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

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

    
    const long long QUERY_LIMIT_PER_CASE = 3;
    query_limit = 1LL * t * QUERY_LIMIT_PER_CASE;
    log_metrics(); 

    
    signal(SIGPIPE, SIG_IGN);

    for (int cas = 0; cas < t; cas++) {
        int n = inf.readInt(2, 25, "n");
        vector<Point> hidden(n);
        for (int i = 0; i < n; i++) {
            hidden[i].x = inf.readDouble();
            hidden[i].y = inf.readDouble();
        }

        cout << n << endl;
        cout.flush();

        int used_this_case = 0;
        while (true) {
            if (queries > HARD_CAP) {
                finish(_pe, "Hard cap exceeded");
            }

            string token;
            if (!(cin >> token)) {
                cout << -1 << endl;
                cout.flush();
                finish(_wa, "Unexpected EOF (expected query or answer)");
            }

            if (token == "!") {
                vector<Point> ans(n);
                for (int i = 0; i < n; i++) {
                    if (!(cin >> ans[i].x >> ans[i].y)) {
                        cout << -1 << endl;
                        cout.flush();
                        finish(_wa, "Malformed answer coordinates");
                    }
                }

                
                const double tol_sq = 1.05e-6; 
                vector<char> used(n, 0);
                for (const auto& h : hidden) {
                    bool found = false;
                    for (int i = 0; i < n; i++) {
                        if (used[i]) continue;
                        double dx = h.x - ans[i].x;
                        double dy = h.y - ans[i].y;
                        if (dx * dx + dy * dy <= tol_sq) {
                            used[i] = 1;
                            found = true;
                            break;
                        }
                    }
                    if (!found) {
                        cout << -1 << endl;
                        cout.flush();
                        finish(_wa, "Guessed points do not match hidden points within tolerance");
                    }
                }

                break; 
            }

            if (token != "?") {
                cout << -1 << endl;
                cout.flush();
                finish(_wa, "Invalid token (expected '?' or '!')");
            }

            if (used_this_case >= (int)QUERY_LIMIT_PER_CASE) {
                cout << -1 << endl;
                cout.flush();
                finish(_wa, "Query limit exceeded");
            }

            double a, b, c;
            if (!(cin >> a >> b >> c)) {
                cout << -1 << endl;
                cout.flush();
                finish(_wa, "Malformed query parameters");
            }

            
            if (fabs(a) > 100.0 + 1e-12 || fabs(b) > 100.0 + 1e-12 || fabs(c) > 100.0 + 1e-12) {
                cout << -1 << endl;
                cout.flush();
                finish(_wa, "Line parameters out of bounds (abs must be <= 100)");
            }
            if (fabs(a) + fabs(b) < 0.1 - 1e-12) {
                cout << -1 << endl;
                cout.flush();
                finish(_wa, "Invalid line parameters: |a| + |b| must be >= 0.1");
            }

            used_this_case++;
            queries++;
            if (queries % 10 == 0) log_metrics();

            vector<pair<double, double>> projs;
            projs.reserve(n);
            for (const auto& h : hidden) {
                Point p = project(h, a, b, c);
                
                
                p.x += rnd.next(-1e-4, 1e-4);
                p.y += rnd.next(-1e-4, 1e-4);
                projs.push_back({p.x, p.y});
            }

            
            shuffle(projs.begin(), projs.end());

            cout << fixed << setprecision(9);
            for (int i = 0; i < n; i++) {
                cout << projs[i].first << " " << projs[i].second << (i + 1 == n ? "" : " ");
            }
            cout << endl;
            cout.flush();
        }
    }

    finish(_ok, "Correct");
}


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");
    
    int n_arg = opt<int>("n", -1);

    
    long long seed_val = 0;
    if (argc > 1) {
        try {
            seed_val = stoll(argv[1]);
        } catch (...) {
            seed_val = 0;
        }
    }

    
    int n;
    if (n_arg != -1) {
        n = n_arg;
    } else {
        
        if (seed_val == 1) n = 2;        
        else if (seed_val == 2) n = 25;  
        else n = rnd.next(2, 25);        
    }

    
    cout << 1 << endl;
    cout << n << endl;

    
    
    
    
    
    
    auto generate_axis = [&](bool tight_packing) {
        vector<double> coords(n);
        double range_width = 200.0; 
        double required_space = (n - 1) * 1.0;
        double slack = range_width - required_space;

        
        vector<double> gaps;
        double sum_gaps = 0;
        for (int i = 0; i <= n; i++) {
            double g;
            if (tight_packing) {
                
                if (rnd.next(5) == 0) g = rnd.next(1.0); 
                else g = 0.0;
            } else {
                
                g = rnd.next(1.0);
            }
            gaps.push_back(g);
            sum_gaps += g;
        }

        if (sum_gaps < 1e-9) sum_gaps = 1.0; 

        
        double current = -100.0 + gaps[0] * (slack / sum_gaps);
        for (int i = 0; i < n; i++) {
            coords[i] = current;
            if (i < n - 1) {
                
                current += 1.0 + gaps[i+1] * (slack / sum_gaps);
            }
        }
        return coords;
    };

    
    bool stress = (seed_val == 2);
    
    
    vector<double> x_coords = generate_axis(stress);
    vector<double> y_coords = generate_axis(stress);

    
    shuffle(y_coords.begin(), y_coords.end());

    
    
    
    
    if (mode == "adp") {
        
        
    }

    
    vector<pair<double, double>> points(n);
    for (int i = 0; i < n; i++) {
        points[i] = {x_coords[i], y_coords[i]};
    }

    
    shuffle(points.begin(), points.end());

    
    cout << fixed << setprecision(20);
    for (const auto& p : points) {
        cout << p.first << " " << p.second << endl;
    }

    return 0;
}