#include <bits/stdc++.h>
using namespace std;
const int inf = 1e9 + 9;
const long long int MOD = 1e9 + 696969;
mt19937_64 rng(0);
int random(int l, int r) { return uniform_int_distribution<int>(l, r)(rng); }
const long long INF = 1e18;
const int maxn = 1000100;
bool LOCAL = 0;
long long int X[maxn], Y[maxn];
int n;
inline long long int det(int i, int j) { return X[i] * Y[j] - X[j] * Y[i]; }
inline long long int area(int i, int j, int k) {
  return abs(det(i, j) + det(j, k) + det(k, i));
}
int ask_sign(int i, int j, int k) {
  cout << 2 << ' ' << i << ' ' << j << ' ' << k << endl;
  if (LOCAL) {
    long long int xa = X[j] - X[i];
    long long int xb = X[k] - X[i];
    long long int ya = Y[j] - Y[i];
    long long int yb = Y[k] - Y[i];
    long long int det = xa * yb - xb * ya;
    if (det > 0)
      return 1;
    else
      return -1;
  }
  int odp;
  cin >> odp;
  return odp;
}
long long int ask_area(int i, int j, int k) {
  cout << 1 << ' ' << i << ' ' << j << ' ' << k << endl;
  if (LOCAL) {
    return area(i, j, k);
  }
  long long int odp;
  cin >> odp;
  return odp;
}
vector<int> order;
long long int tab[1010];
long long int znak[1010];
int perm[1010];
int DL;
vector<int> solve(int lewy, int prawy, vector<int> pozycje) {
  0 && cerr;
  if (pozycje.empty()) return {};
  int kt = 0;
  for (int i = 1; i < (int)pozycje.size(); ++i) {
    if (tab[pozycje[i]] > tab[pozycje[kt]]) kt = i;
  }
  vector<pair<long long int, long long int> > lewe, prawe;
  for (int i = 0; i < (int)pozycje.size(); ++i) {
    if (i == kt) continue;
    int node = pozycje[i];
    int sgn = ask_sign(lewy, pozycje[kt], node);
    if (sgn == -1)
      prawe.push_back({tab[node], node});
    else
      lewe.push_back({-tab[node], node});
  }
  sort(begin(lewe), end(lewe));
  sort(begin(prawe), end(prawe));
  vector<int> res = {};
  for (auto &node : prawe) res.push_back(node.second);
  res.push_back(pozycje[kt]);
  for (auto &node : lewe) res.push_back(node.second);
  return res;
}
int main() {
  cin >> n;
  if (LOCAL) {
    for (int i = (1); i <= (n); ++i) cin >> X[i] >> Y[i];
  }
  for (int i = (3); i <= (n); ++i) tab[i] = ask_area(1, 2, i);
  for (int i = (3); i <= (n); ++i) znak[i] = ask_sign(1, 2, i);
  vector<int> minuses = {};
  vector<int> pluses = {};
  for (int i = (3); i <= (n); ++i) {
    if (znak[i] > 0)
      pluses.push_back(i);
    else
      minuses.push_back(i);
  }
  auto ans_first = solve(1, 2, minuses);
  0 && cerr;
  auto ans_second = solve(2, 1, pluses);
  0 && cerr;
  cout << 0 << ' ' << 1 << ' ';
  for (auto &node : ans_first) cout << node << ' ';
  cout << 2 << ' ';
  for (auto &node : ans_second) cout << node << ' ';
  cout << endl;
}
