#include <cstdio>
#include <cstdlib>
#include <vector>
#include <algorithm>
#include <cmath>
#include <cstring>
#include <iostream>
#include <iomanip>
#include <limits.h>
#include <set>
#include <string>
#include <queue>
#include <stack>
#include <unordered_map>
#include <unordered_set>
#include <deque>
#include <map>
#include <chrono>
#include <random>
#include <bitset>
#include <tuple>
#include <cassert>
#include "library.h"
#define SZ(x) (LL)(x.size())
#define FR(i,a,b) for(LL i=(a);i<(b);++i)
#define FOR(i,n) FR(i,0,n)
#define FAST ios::sync_with_stdio(0); cin.tie(0); cout.tie(0)
#define A first
#define B second
#define mp(a,b) make_pair(a,b)
typedef long long LL;
typedef long double LD;
typedef unsigned long long ULL;
typedef unsigned __int128 U128;
typedef __int128 I128;
typedef std::pair<int,int> PII;
typedef std::pair<LL,LL> PLL;
typedef std::pair<LD,LD> PLD;
using namespace std;
const int MAXN=1003;
int p[MAXN], e[MAXN][2];
vector<int> adj[MAXN], c[MAXN];
vector<int> res;
set<int> roots;
int n;
bool nxt(int a, int b){
vector<int> m(n,0);
m[a-1]=1;
m[b-1]=1;
if (Query(m)==1) return true;
else return false;
}
int f(int x){
if (p[x]==x) return x;
return (p[x]=f(p[x]));
}
void merge(int r, int i){
p[i]=r;
roots.erase(i);
c[r].push_back(i);
int e1=e[r][0], e2=e[r][1];
if (nxt(e1,i)){
adj[i].push_back(e1);
adj[e1].push_back(i);
e[r][0]=i;
}
else{
adj[i].push_back(e2);
adj[e2].push_back(i);
e[r][1]=i;
}
}
void merge2(int r1, int r2, int i){
if (r1>r2) swap(r1,r2);
int e1=e[r1][0], e2=e[r1][1], e3=e[r2][0], e4=e[r2][1];
bool b1=nxt(e1,i), b3=nxt(e3,i);
if (b1){
adj[i].push_back(e1);
adj[e1].push_back(i);
}
else{
adj[i].push_back(e2);
adj[e2].push_back(i);
}
if (b3){
adj[i].push_back(e3);
adj[e3].push_back(i);
}
else{
adj[i].push_back(e4);
adj[e4].push_back(i);
}
if (b1 && b3) e[r1][0]=e4;
else if (b1 && !b3) e[r1][0]=e3;
else if (!b1 && b3) e[r1][1]=e4;
else e[r1][1]=e3;
p[r2]=p[i]=r1;
for (int x:c[r2]){
p[x]=r1;
c[r1].push_back(x);
}
c[r1].push_back(i);
roots.erase(r2);
}
int query(int i, set<int> v){
vector<int> m(n,0);
m[i-1]=1;
for (int x:v) for (int j:c[x]) m[j-1]=1;
return Query(m);
}
//connected to one component
int bs1(int i, set<int> v){
if (SZ(v)==1) return *v.begin();
vector<int> vec(v.begin(), v.end());
int mid=SZ(vec)/2;
set<int> l;
FOR(j,mid) l.insert(vec[j]);
int a=query(i,l);
if (a==SZ(l)) return bs1(i,l);
set<int> r;
FR(j,mid,SZ(vec)) r.insert(vec[j]);
return bs1(i,r);
}
//connected to 2 components
PII bs2(int i, set<int> v){
vector<int> vec(v.begin(), v.end());
if (SZ(vec)==2) return mp(vec[0],vec[1]);
int mid=SZ(vec)/2;
set<int> l, r;
FOR(j,mid) l.insert(vec[j]);
FR(j,mid,SZ(vec)) r.insert(vec[j]);
int a=query(i,l);
if (a==SZ(l)-1) return bs2(i,l);
else if (a==SZ(l)+1) return bs2(i,r);
else return mp(bs1(i,l), bs1(i,r));
}
void add(int i){
p[i]=i;
e[i][0]=e[i][1]=i;
c[i].push_back(i);
roots.insert(i);
}
void dfs(int u, int par){
res.push_back(u);
for (int v:adj[u]){
if (v==par) continue;
dfs(v,u);
}
}
void Solve(int N){
n=N;
add(1);
FR(i,2,n+1){
int num=SZ(roots);
int a=query(i,roots);
if (a==num+1){
add(i);
//cout<<i<<": "<<1<<"\n";
}
else if (a==num){
int r=bs1(i,roots);
merge(r,i);
//cout<<i<<": "<<2<<"\n";
}
else{
PII pp=bs2(i,roots);
int r1=pp.A, r2=pp.B;
merge2(r1,r2,i);
//cout<<i<<": "<<3<<"\n";
}
}
/*FR(i,1,n+1){
cout<<i<<": ";
for (LL x:adj[i]) cout<<x<<" ";
cout<<"\n";
}*/
int r=0;
FR(i,1,n+1){
if (SZ(adj[i])==1){
r=i;
break;
}
}
dfs(r,-1);
//for (LL x:res) cout<<x<<" ";
//cout<<"\n";
Answer(res);
}