#include <bits/stdc++.h>
#pragma GCC optimize("O3")
using namespace std;
const int maxN = 1005;
long long x[maxN], y[maxN];
long long det(int i, int j, int k) {
  return (x[j] - x[i]) * (y[k] - y[i]) - (x[k] - x[i]) * (y[j] - y[i]);
}
long long askArea(int i, int j, int k) {
  cout << 1 << " " << i << " " << j << " " << k << endl;
  long long resp;
  cin >> resp;
  return resp;
}
int askVec(int i, int j, int k) {
  cout << 2 << " " << i << " " << j << " " << k << endl;
  int res;
  cin >> res;
  return res;
}
int n;
int main() {
  cin >> n;
  int who = n;
  vector<int> up, down;
  for (int i = 2; i < n; i++) {
    if (askVec(1, i, who) < 0) {
      up.emplace_back(i);
    } else {
      down.emplace_back(i);
    }
  }
  vector<pair<long long, int> > get_vals;
  for (int v : up) {
    get_vals.emplace_back(askArea(1, v, who), v);
  }
  sort(get_vals.begin(), get_vals.end());
  reverse(get_vals.begin(), get_vals.end());
  deque<int> ans_up;
  if (!get_vals.empty()) ans_up.push_back(get_vals[0].second);
  for (int i = 1; i < get_vals.size(); i++) {
    int p = get_vals[i].second;
    if (askVec(1, p, ans_up.front()) < 0)
      ans_up.push_front(p);
    else
      ans_up.push_back(p);
  }
  vector<int> perm;
  for (int v : ans_up) perm.push_back(v);
  perm.push_back(who);
  get_vals.clear();
  deque<int> ans_down;
  for (int v : down) {
    get_vals.emplace_back(askArea(1, v, who), v);
  }
  sort(get_vals.begin(), get_vals.end());
  reverse(get_vals.begin(), get_vals.end());
  if (!get_vals.empty()) ans_down.push_back(get_vals[0].second);
  for (int i = 1; i < get_vals.size(); i++) {
    int p = get_vals[i].second;
    if (askVec(1, p, ans_down.front()) < 0)
      ans_down.push_front(p);
    else
      ans_down.push_back(p);
  }
  for (int v : ans_down) perm.push_back(v);
  reverse(perm.begin(), perm.end());
  cout << 0 << " ";
  cout << 1 << " ";
  for (int v : perm) cout << v << " ";
  cout << endl;
  return 0;
}
