#include "dango3.h"
#include<bits/stdc++.h>
using namespace std;
int n, m;
namespace sub12{
void solve(){
vector<vector<int>>color(n);
vector<int>p(n * m);
iota(p.begin(), p.end(), 1);
for(int i = 0; i + 1 < n; i++){
vector<int>cur(p.begin(), p.begin() + (n - i - 1)), np = cur;
for(int j = 0; j < i; j++){
cur.push_back(color[j][0]);
}
for(int j = n - i - 1; j < p.size(); j++){
cur.push_back(p[j]);
if(Query(cur) > 0){
cur.pop_back();
color[i].push_back(p[j]);
}
else{
np.push_back(p[j]);
}
}
swap(p, np);
}
color[n - 1] = p;
for(int i = 0; i < m; i++){
p.clear();
for(int j = 0; j < n; j++){
p.push_back(color[j].back());
color[j].pop_back();
}
Answer(p);
}
}
}
mt19937 rng(chrono::high_resolution_clock::now().time_since_epoch().count());
namespace sub3{
void solve(){
vector<int>p(n - 1), perm(n * m);
iota(perm.begin(), perm.end(), 1);
shuffle(perm.begin(), perm.end(), rng);
perm.insert(perm.begin(), -1);
for(int i = 0; i + 1 < n; i++){
p[i] = perm[i + 1];
}
int i = n;
for(int cnt = 1; cnt < m; i++){
p.push_back(perm[i]);
if(Query(p) == 1){
vector<int>np;
for(int j = 0; j < p.size(); j++){
np.push_back(p[j]);
swap(p[j], p.back());
p.pop_back();
if(Query(p) == 0){
p.push_back(np.back());
np.pop_back();
swap(p[j], p.back());
}
else{
j--;
}
}
Answer(p);
swap(p, np);
cnt++;
}
}
for(; i <= n * m; i++){
p.push_back(perm[i]);
}
Answer(p);
}
}
namespace sub4{
void solve(){
vector<int>p(n - 1), perm(n * m);
iota(perm.begin(), perm.end(), 1);
shuffle(perm.begin(), perm.end(), rng);
perm.insert(perm.begin(), -1);
for(int i = 0; i + 1 < n; i++){
p[i] = perm[i + 1];
}
int i = n;
for(int cnt = 1; cnt < m; cnt++){
int low = i, high = n * m - 1, next_i;
while(low <= high){
int mid = (low + high) >> 1;
vector<int>cp = p;
cp.insert(cp.end(), perm.begin() + i, perm.begin() + mid + 1);
if(Query(cp) > 0){
high = (next_i = mid) - 1;
}
else{
low = mid + 1;
}
}
p.insert(p.end(), perm.begin() + i, perm.begin() + next_i);
int color = 0;
vector<int>np;
for(; color + 1 < n && ((n - color - 1) << 2) < p.size(); color++){
int low = color, high = int(p.size()) - 1, pos = -1;
while(low <= high){
int mid = (low + high) >> 1;
vector<int>cp(p.begin() + mid, p.end());
cp.push_back(perm[next_i]);
cp.insert(cp.end(), p.begin(), p.begin() + color);
if(Query(cp) == 1){
low = (pos = mid) + 1;
}
else{
high = mid - 1;
}
}
if(pos == -1){
color = n;
break;
}
np.insert(np.end(), p.begin() + color, p.begin() + pos);
p.erase(p.begin() + color, p.begin() + pos);
}
for(int j = color; j < p.size() && color + 1 < n; j++){
np.push_back(p[j]);
swap(p[j], p.back());
p.pop_back();
p.push_back(perm[next_i]);
int x = Query(p);
p.pop_back();
if(x == 0){
p.push_back(np.back());
np.pop_back();
swap(p[j], p.back());
color++;
}
else{
j--;
}
}
p.push_back(perm[next_i]);
Answer(p);
i = next_i + 1;
swap(p, np);
}
for(; i <= n * m; i++){
p.push_back(perm[i]);
}
Answer(p);
}
}
void Solve(int N, int M){
n = N;
m = M;
if(n <= 100 && m <= 10){
sub12::solve();
}
else if(n == 200 && m == 25){
sub3::solve();
}
else{
sub4::solve();
}
}