Problem: cf1392_e
Difficulty: medium
Categories: bit, math
Time limit: 2000 ms, memory limit: 256 MB

This is an interactive problem.

Omkar has just come across a duck! The duck is walking on a grid with $n$ rows and $n$ columns ($2 \leq n \leq 25$) so that the grid contains a total of $n^2$ cells. Let's denote by $(x, y)$ the cell in the $x$-th row from the top and the $y$-th column from the left. Right now, the duck is at the cell $(1, 1)$ (the cell in the top left corner) and would like to reach the cell $(n, n)$ (the cell in the bottom right corner) by moving either down $1$ cell or to the right $1$ cell each second.

Since Omkar thinks ducks are fun, he wants to play a game with you based on the movement of the duck. First, for each cell $(x, y)$ in the grid, you will tell Omkar a nonnegative integer $a_{x,y}$ not exceeding $10^{16}$, and Omkar will then put $a_{x,y}$ uninteresting problems in the cell $(x, y)$. After that, the duck will start their journey from $(1, 1)$ to $(n, n)$. For each cell $(x, y)$ that the duck crosses during their journey (including the cells $(1, 1)$ and $(n, n)$), the duck will eat the $a_{x,y}$ uninteresting problems in that cell. Once the duck has completed their journey, Omkar will measure their mass to determine the total number $k$ of uninteresting problems that the duck ate on their journey, and then tell you $k$.

Your challenge, given $k$, is to exactly reproduce the duck's path, i. e. to tell Omkar precisely which cells the duck crossed on their journey. To be sure of your mastery of this game, Omkar will have the duck complete $q$ different journeys ($1 \leq q \leq 10^3$). Note that all journeys are independent: at the beginning of each journey, the cell $(x, y)$ will still contain $a_{x,y}$ uninteresting tasks.

Interaction

The interaction will begin with a line containing a single integer $n$ ($2 \leq n \leq 25$), the amount of rows and columns in the grid. Read it.

Your program should then print $n$ lines. The $x$-th line should contain $n$ integers $a_{x,1}, a_{x,2}, \dotsc, a_{x,n}$ satisfying $0 \leq a_{x,y} \leq 10^{16}$, where $a_{x,y}$ is the amount of uninteresting problems Omkar should place in the cell $(x, y)$.

After that, you will first receive a single integer $q$, the amount of journeys that the duck will take. $q$ queries will follow; each query will consist of a single line containing an integer $k$, the amount of uninteresting problems that the duck ate on that journey. After each query, given that you have determined that the duck visited the cells $(x_1, y_1), (x_2, y_2), \dotsc, (x_{2n - 1}, y_{2n - 1})$ in that order (it should always be true that $(x_1, y_1) = (1, 1)$ and $(x_{2n - 1}, y_{2n - 1}) = (n, n)$), you should output $2n - 1$ lines so that the $j$-th line contains the two integers $x_j, y_j$.

Bear in mind that if the sum on your path is $k$, but your path is different from the actual hidden path, then your solution is still wrong!

After printing each line 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 documentation for other languages.

Example

Input

```
4

3
23

26

27
```

Output

```
1 2 3 6
4 6 2 10
9 0 7 3
2 8 8 2

1 1
1 2
1 3
2 3
2 4
3 4
4 4

1 1
2 1
3 1
3 2
3 3
3 4
4 4

1 1
1 2
1 3
1 4
2 4
3 4
4 4
```

Note

The duck's three journeys are illustrated below.

$1 + 2 + 3 + 2 + 10 + 3 + 2 = 23$

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

$1 + 4 + 9 + 0 + 7 + 3 + 2 = 26$

 ![](https://espresso.codeforces.com/51a62c32428b2281b9792c5262ea1a32cf485943.png) 

$1 + 2 + 3 + 6 + 10 + 3 + 2 = 27$

 ![](https://espresso.codeforces.com/886765d811ec84faf5ba21a905186a032de79b63.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 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 readToken(string& s) {
    s.clear();
    if (!(cin >> s)) return false;
    return true;
}

static bool parseInt128Bounded(const string& s, __int128& val) {
    if (s.empty()) return false;
    int i = 0;
    bool neg = false;
    if (s[i] == '+' || s[i] == '-') {
        neg = (s[i] == '-');
        i++;
        if (i >= (int)s.size()) return false;
    }
    __int128 x = 0;
    for (; i < (int)s.size(); i++) {
        char c = s[i];
        if (c < '0' || c > '9') return false;
        x = x * 10 + (c - '0');
        
    }
    val = neg ? -x : x;
    return true;
}

static bool parseLongLongInRange(const string& s, long long& out, long long lo, long long hi) {
    __int128 v;
    if (!parseInt128Bounded(s, v)) return false;
    if (v < (__int128)lo || v > (__int128)hi) return false;
    out = (long long)v;
    return true;
}

static bool parseULLInRange(const string& s, unsigned long long& out, unsigned long long lo, unsigned long long hi) {
    __int128 v;
    if (!parseInt128Bounded(s, v)) return false;
    if (v < 0) return false;
    if (v < (__int128)lo || v > (__int128)hi) return false;
    out = (unsigned long long)v;
    return true;
}

static bool validatePath(const vector<pair<int,int>>& p, int n) {
    if ((int)p.size() != 2 * n - 1) return false;
    if (p.front() != make_pair(1, 1)) return false;
    if (p.back() != make_pair(n, n)) return false;
    for (auto [x, y] : p) {
        if (x < 1 || x > n || y < 1 || y > n) return false;
    }
    for (int i = 1; i < (int)p.size(); i++) {
        int dx = p[i].first - p[i - 1].first;
        int dy = p[i].second - p[i - 1].second;
        if (!((dx == 1 && dy == 0) || (dx == 0 && dy == 1))) return false;
    }
    return true;
}

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

    int n = inf.readInt(2, 25, "n");
    int q = inf.readInt(1, 1000, "q");

    vector<vector<pair<int,int>>> hiddenPaths;
    hiddenPaths.reserve(q);

    for (int i = 0; i < q; i++) {
        int L = inf.readInt(1, 1000000, "L");
        vector<pair<int,int>> p;
        p.reserve(L);
        for (int j = 0; j < L; j++) {
            int x = inf.readInt(1, n, "x");
            int y = inf.readInt(1, n, "y");
            p.push_back({x, y});
        }
        if (L != 2 * n - 1 || !validatePath(p, n)) {
            
            query_limit = q;
            log_metrics();
            quitf(_fail, "Invalid hidden path in input (case corrupted)");
        }
        hiddenPaths.push_back(std::move(p));
    }

    query_limit = q;
    log_metrics(); 

    
    cout << n << endl;

    
    const unsigned long long A_MAX = 10000000000000000ULL; 
    vector<vector<unsigned long long>> a(n + 1, vector<unsigned long long>(n + 1, 0));

    for (int i = 1; i <= n; i++) {
        for (int j = 1; j <= n; j++) {
            string tok;
            if (!readToken(tok)) finish(_pe, "Unexpected EOF while reading grid values");
            unsigned long long v;
            if (!parseULLInRange(tok, v, 0ULL, A_MAX)) finish(_pe, "Invalid grid value (not in [0,1e16])");
            a[i][j] = v;
        }
    }

    
    cout << q << endl;

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

    for (int qi = 0; qi < q; qi++) {
        __int128 sum = 0;
        for (auto [x, y] : hiddenPaths[qi]) sum += (__int128)a[x][y];

        long long k = (long long)sum; 
        cout << k << endl;

        queries++;
        if (queries > hard_cap) finish(_pe, "Hard cap exceeded");

        vector<pair<int,int>> ans;
        ans.reserve(2 * n - 1);
        for (int t = 0; t < 2 * n - 1; t++) {
            string sx, sy;
            if (!readToken(sx)) finish(_pe, "Unexpected EOF while reading answer path");
            if (!readToken(sy)) finish(_pe, "Unexpected EOF while reading answer path");
            long long x, y;
            if (!parseLongLongInRange(sx, x, 1, n) || !parseLongLongInRange(sy, y, 1, n))
                finish(_pe, "Invalid coordinates in answer path");
            ans.push_back({(int)x, (int)y});
        }

        if (!validatePath(ans, n)) finish(_pe, "Answer path is not a valid monotone path");

        if (ans != hiddenPaths[qi]) {
            finish(_wa, "Wrong path");
        }
    }

    finish(_ok, "OK");
}


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 readTokenSafe(string &s) {
    s.clear();
    if (!(cin >> s)) return false;
    return true;
}

static bool parseLongLong(const string& s, long long &v) {
    
    if (s.empty()) return false;
    int i = 0;
    bool neg = false;
    if (s[i] == '+' || s[i] == '-') {
        neg = (s[i] == '-');
        i++;
    }
    if (i >= (int)s.size()) return false;
    long long x = 0;
    for (; i < (int)s.size(); i++) {
        char c = s[i];
        if (c < '0' || c > '9') return false;
        int d = c - '0';
        
        if (x > (LLONG_MAX - d) / 10) return false;
        x = x * 10 + d;
    }
    v = neg ? -x : x;
    return true;
}

static bool parseUnsignedLongLong(const string& s, unsigned long long &v) {
    if (s.empty()) return false;
    int i = 0;
    if (s[i] == '+') i++;
    if (i >= (int)s.size()) return false;
    unsigned long long x = 0;
    for (; i < (int)s.size(); i++) {
        char c = s[i];
        if (c < '0' || c > '9') return false;
        int d = c - '0';
        if (x > (ULLONG_MAX - (unsigned long long)d) / 10ULL) return false;
        x = x * 10ULL + (unsigned long long)d;
    }
    v = x;
    return true;
}

static bool validatePath(const vector<pair<int,int>>& p, int n) {
    if ((int)p.size() != 2 * n - 1) return false;
    if (p.front() != make_pair(1, 1)) return false;
    if (p.back() != make_pair(n, n)) return false;
    for (auto [x, y] : p) {
        if (x < 1 || x > n || y < 1 || y > n) return false;
    }
    for (int i = 1; i < (int)p.size(); i++) {
        int dx = p[i].first - p[i - 1].first;
        int dy = p[i].second - p[i - 1].second;
        if (!((dx == 1 && dy == 0) || (dx == 0 && dy == 1))) return false;
    }
    return true;
}

static vector<pair<int,int>> makePathFromPattern(int n, unsigned long long pattern) {
    int x = 1, y = 1;
    vector<pair<int,int>> p;
    p.reserve(2 * n - 1);
    p.push_back({x, y});
    const int moves = 2 * n - 2;
    for (int step = 0; step < moves; step++) {
        if (x == n) {
            y++;
        } else if (y == n) {
            x++;
        } else {
            bool goDown = ((pattern >> step) & 1ULL) != 0ULL;
            if (goDown) x++;
            else y++;
        }
        p.push_back({x, y});
    }
    return p;
}

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

    
    
    
    
    
    int n = inf.readInt(2, 25, "n");
    int q = inf.readInt(1, 1000, "q");
    vector<unsigned long long> patterns;
    patterns.reserve(q);
    for (int i = 0; i < q; i++) {
        long long v = inf.readLong(0LL, (long long)((1ULL<<62)-1), "pattern");
        patterns.push_back((unsigned long long)v);
    }

    
    query_limit = q;
    log_metrics(); 

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

    
    vector<vector<unsigned long long>> a(n, vector<unsigned long long>(n, 0));
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < n; j++) {
            string tok;
            if (!readTokenSafe(tok)) finish(_pe, "Contestant didn't output full grid");
            unsigned long long val;
            if (!parseUnsignedLongLong(tok, val)) finish(_pe, "Grid value not an unsigned integer");
            if (val > 10000000000000000ULL) finish(_pe, "Grid value exceeds 1e16");
            a[i][j] = val;
        }
    }

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

    auto expectPathFromContestant = [&](const vector<pair<int,int>>& realPath) {
        
        vector<pair<int,int>> out;
        out.reserve(2*n-1);
        for (int i = 0; i < 2*n-1; i++) {
            string sx, sy;
            if (!readTokenSafe(sx)) finish(_pe, "Contestant ended early while outputting path");
            if (!readTokenSafe(sy)) finish(_pe, "Contestant ended early while outputting path");
            long long x, y;
            if (!parseLongLong(sx, x) || !parseLongLong(sy, y)) finish(_pe, "Path coordinates not integers");
            if (x < 1 || x > n || y < 1 || y > n) finish(_pe, "Path coordinates out of range");
            out.push_back({(int)x,(int)y});
        }
        if (!validatePath(out, n)) finish(_wa, "Answer path is not a valid monotone path");
        if (out != realPath) finish(_wa, "Path does not match");
    };

    auto computeSumOnPath = [&](const vector<pair<int,int>>& p) -> long long {
        __int128 s = 0;
        for (auto [x, y] : p) s += (__int128)a[x - 1][y - 1];
        if (s < 0 || s > (__int128)LLONG_MAX) finish(_fail, "sum overflow (interactor bug)");
        return (long long)s;
    };

    const long long hard_cap = max(200000LL, 10LL * query_limit);
    for (int qi = 0; qi < q; qi++) {
        vector<pair<int,int>> hiddenPath = makePathFromPattern(n, patterns[qi]);
        if (!validatePath(hiddenPath, n)) finish(_fail, "generated hidden path invalid (interactor bug)");

        long long k = computeSumOnPath(hiddenPath);
        cout << k << "\n";
        cout.flush();

        queries++;
        if (queries > hard_cap) finish(_pe, "too many interactions");

        expectPathFromContestant(hiddenPath);
    }
    finish(_ok, "OK");
}


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

static long long getSeedFromArgs(int argc, char** argv) {
    
    
    if (argc >= 2) {
        try {
            return stoll(string(argv[1]));
        } catch (...) {
            return 0;
        }
    }
    return 0;
}

static vector<pair<int,int>> randomPath(int n) {
    
    vector<int> moves;
    moves.reserve(2*n-2);
    for (int i = 0; i < n-1; i++) moves.push_back(0); 
    for (int i = 0; i < n-1; i++) moves.push_back(1); 
    
    for (int i = (int)moves.size()-1; i > 0; --i) {
        int j = rnd.next(0, i);
        swap(moves[i], moves[j]);
    }
    int x = 1, y = 1;
    vector<pair<int,int>> cells;
    cells.reserve(2*n-1);
    cells.push_back({x,y});
    for (int mv : moves) {
        if (mv == 0) y++;
        else x++;
        cells.push_back({x,y});
    }
    return cells;
}

static vector<pair<int,int>> adversarialZigzag(int n) {
    
    int x=1,y=1;
    vector<pair<int,int>> cells;
    cells.reserve(2*n-1);
    cells.push_back({x,y});
    
    int r = n-1, d = n-1;
    while (r > 0 || d > 0) {
        if (r > 0) { y++; r--; cells.push_back({x,y}); }
        if (d > 0) { x++; d--; cells.push_back({x,y}); }
    }
    return cells;
}

static vector<pair<int,int>> edgeThenEdge(int n, bool topThenRightCol) {
    int x=1,y=1;
    vector<pair<int,int>> cells;
    cells.reserve(2*n-1);
    cells.push_back({x,y});
    if (topThenRightCol) {
        
        for (int i=0;i<n-1;i++){ y++; cells.push_back({x,y}); }
        for (int i=0;i<n-1;i++){ x++; cells.push_back({x,y}); }
    } else {
        
        for (int i=0;i<n-1;i++){ x++; cells.push_back({x,y}); }
        for (int i=0;i<n-1;i++){ y++; cells.push_back({x,y}); }
    }
    return cells;
}

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

    string mode = opt<string>("mode", "non");
    long long seed = getSeedFromArgs(argc, argv);

    int n;
    int q;

    if (seed == 1) {
        n = 2; q = 3;
    } else if (seed == 2) {
        n = 25; q = 1000;
    } else if (seed == 3) {
        n = 25; q = 1;
    } else {
        n = opt<int>("n", 25);
        n = max(2, min(25, n));
        q = opt<int>("q", 1000);
        q = max(1, min(1000, q));
    }

    
    if (mode == "non") {
        
        
        cout << n << "\n";
        cout << q << "\n";

        vector<vector<pair<int,int>>> paths;
        paths.reserve(q);

        if (seed == 1) {
            
            paths.push_back(edgeThenEdge(n, true));  
            paths.push_back(edgeThenEdge(n, false)); 
            paths.push_back(edgeThenEdge(n, true));
        } else if (seed == 2) {
            
            paths.push_back(edgeThenEdge(n, true));
            paths.push_back(edgeThenEdge(n, false));
            paths.push_back(adversarialZigzag(n));
            
            for (int i = 3; i < q; i++) {
                int t = rnd.next(0, 99);
                if (t < 8) paths.push_back(paths[rnd.next(0, (int)paths.size()-1)]);
                else if (t < 12) paths.push_back(adversarialZigzag(n));
                else paths.push_back(randomPath(n));
            }
        } else if (seed == 3) {
            
            paths.push_back(adversarialZigzag(n));
        } else {
            
            int pref = min(q, 5);
            if (pref >= 1) paths.push_back(edgeThenEdge(n, true));
            if (pref >= 2) paths.push_back(edgeThenEdge(n, false));
            if (pref >= 3) paths.push_back(adversarialZigzag(n));
            if (pref >= 4) paths.push_back(randomPath(n));
            if (pref >= 5) paths.push_back(randomPath(n));
            for (int i = (int)paths.size(); i < q; i++) {
                int t = rnd.next(0, 99);
                if (t < 10 && !paths.empty()) paths.push_back(paths[rnd.next(0, (int)paths.size()-1)]);
                else if (t < 15) paths.push_back(adversarialZigzag(n));
                else paths.push_back(randomPath(n));
            }
        }

        for (int i = 0; i < q; i++) {
            
            
            cout << (2*n - 1) << "\n";
            for (auto [x,y] : paths[i]) {
                cout << x << " " << y << "\n";
            }
        }
        return 0;
    } else if (mode == "adp") {
        
        
        
        
        
        
        cout << n << "\n";
        cout << q << "\n";

        auto emitK = [&](unsigned long long k) {
            
            
            unsigned long long LIM = (1ULL << 62) - 1;
            if (k > LIM) k = LIM;
            cout << (unsigned long long)k << "\n";
        };

        if (seed == 1) {
            
            emitK(0);
            emitK(1);
            emitK((1ULL<<20) + 3);
        } else if (seed == 2) {
            
            
            emitK(0);
            emitK((1ULL<<40) - 1);
            
            unsigned long long alt = 0;
            for (int b = 0; b < 60; b++) if (b % 2 == 1) alt |= (1ULL<<b);
            emitK(alt);
            
            unsigned long long alt2 = 0;
            for (int b = 0; b < 60; b++) if (b % 2 == 0) alt2 |= (1ULL<<b);
            emitK(alt2);
            
            for (int b = 0; b < 10; b++) emitK(1ULL << (b*6));
            int produced = 4 + 10;
            for (int i = produced; i < q; i++) {
                int t = rnd.next(0, 99);
                if (t < 10) {
                    int b = rnd.next(0, 60);
                    emitK(1ULL << b);
                } else if (t < 20) {
                    
                    int b = rnd.next(1, 61);
                    unsigned long long base = 1ULL << (b-1);
                    unsigned long long delta = (unsigned long long)rnd.next(0, 7);
                    emitK(base - 1 + delta);
                } else if (t < 30) {
                    
                    unsigned long long k = 0;
                    int bits = rnd.next(15, 35);
                    for (int j = 0; j < bits; j++) {
                        int b = rnd.next(0, 45);
                        k |= (1ULL<<b);
                    }
                    emitK(k);
                } else {
                    
                    unsigned long long hi = (unsigned long long)rnd.next(0, (int)((1U<<30)-1));
                    unsigned long long lo = (unsigned long long)rnd.next(0, (int)((1U<<30)-1));
                    unsigned long long k = (hi<<30) ^ lo; 
                    k &= ((1ULL<<60)-1);
                    emitK(k);
                }
            }
        } else if (seed == 3) {
            
            unsigned long long k = 0;
            for (int b = 0; b < 60; b += 3) k |= (1ULL<<b);
            emitK(k);
        } else {
            
            emitK(0);
            if (q >= 2) emitK((1ULL<<55) - 1);
            for (int i = 2; i < q; i++) {
                int t = rnd.next(0, 99);
                if (t < 15) {
                    int b = rnd.next(0, 60);
                    emitK(1ULL<<b);
                } else {
                    unsigned long long hi = (unsigned long long)rnd.next(0, (int)((1U<<30)-1));
                    unsigned long long lo = (unsigned long long)rnd.next(0, (int)((1U<<30)-1));
                    unsigned long long k = (hi<<30) + lo;
                    k &= ((1ULL<<60)-1);
                    emitK(k);
                }
            }
        }
        return 0;
    } else {
        
        cout << 2 << "\n";
        cout << 1 << "\n";
        cout << 3 << "\n";
        cout << "1 1\n1 2\n2 2\n";
        return 0;
    }
}