#include<bits/stdc++.h>
using namespace std;
typedef double db;
const db eps=1e-6;
const db pi=acos(-1);
int n;
struct Node{
int id;db h;
Node(){}
Node(int id,db h):id(id),h(h){}
};
int cmp1(Node a,Node b){return a.h<b.h;}
int cmp2(Node a,Node b){return a.h>b.h;}
vector<Node>v1,v2,v3,v4,v5;
db ask2(int i,int j,int k){//aiaj 和 aiak的叉积
cout<<2<<" "<<i<<" "<<j<<" "<<k<<endl;
db res;
cin>>res;
return res;
}
db ask1(int i,int j,int k){//aiaj 和 aiak的叉积
cout<<1<<" "<<i<<" "<<j<<" "<<k<<endl;
db res;
cin>>res;
return res;
}
vector<int>ans;
int main(){
cin>>n;
for(int i=3;i<=n;i++){
db res=ask2(1,2,i);db ress=ask1(1,2,i);
if(res>0)v1.push_back(Node(i,ress));//在a1a2左侧
else v2.push_back(Node(i,ress));//在a1a2右侧
if(fabs(ress)-fabs(res)>eps)return 0;
}
ans.push_back(1);
int mid=0;
double Max=-1e16;
for(auto x:v2){if(x.h>Max)mid=x.id,Max=x.h;}
for(auto x:v2){
if(x.id==mid)continue;
db res=ask2(1,mid,x.id);
if(res>0)v4.push_back(x);//在1-mid段
else v3.push_back(x);//在mid-2段
}
sort(v3.begin(),v3.end(),cmp1);//按h升序
sort(v4.begin(),v4.end(),cmp2);//按h降序
for(auto x:v3)ans.push_back(x.id);
if(mid)ans.push_back(mid);
for(auto x:v4)ans.push_back(x.id);
v5=v4;
ans.push_back(2);
v3.clear();v4.clear();
Max=-1e16;
mid=0;
for(auto x:v1){if(x.h>Max)mid=x.id,Max=x.h;}
for(auto x:v1){
if(x.id==mid)continue;
db res=ask2(1,mid,x.id);
if(res>0)v4.push_back(x);//在mid-1段
else v3.push_back(x); //在2-mid段
}
sort(v3.begin(),v3.end(),cmp1);//按h升序
sort(v4.begin(),v4.end(),cmp2);//按h降序
for(auto x:v3)ans.push_back(x.id);
if(mid)ans.push_back(mid);
for(auto x:v4)ans.push_back(x.id);
cout<<0<<" ";
for(auto x:ans)cout<<x<<" ";
}