#include <bits/stdc++.h>
using namespace std;
const int N = 1e6;
const long long INF = 1e18;
const long double EPS = 10e-9;
mt19937_64 rng(chrono::steady_clock::now().time_since_epoch().count());
long long random(long long a, long long b) {
  return uniform_int_distribution<long long>(a, b)(rng);
}
long long query(int type, int i, int j, int k) {
  cout << type << " " << i << " " << j << " " << k << endl;
  long long input;
  cin >> input;
  return input;
}
bool menor_a_mayor_area(pair<int, pair<long long, int>> &a,
                        pair<int, pair<long long, int>> &b) {
  return a.second.first <= b.second.first;
}
bool antihorario(pair<int, pair<long long, int>> a,
                 pair<int, pair<long long, int>> b) {
  if (a.second.second != b.second.second)
    return a.second.second < b.second.second;
  if (a.second.second == -1) return a.second.first <= b.second.first;
  return a.second.first >= b.second.first;
}
vector<long long> Sort(int ini, int fin, vector<long long> puntos) {
  vector<long long> ret;
  int sz = puntos.size();
  if (sz == 0) return ret;
  vector<pair<int, pair<long long, int>>> punto_area_signo;
  for (int i = 0; i < sz; i++) {
    long long doble_area = query(1, ini, fin, puntos[i]);
    punto_area_signo.push_back(make_pair(puntos[i], make_pair(doble_area, 0)));
  }
  sort((punto_area_signo).begin(), (punto_area_signo).end(),
       menor_a_mayor_area);
  int pivote = punto_area_signo[sz - 1].first;
  for (int i = 0; i < sz - 1; i++)
    punto_area_signo[i].second.second =
        query(2, ini, pivote, punto_area_signo[i].first);
  sort((punto_area_signo).begin(), (punto_area_signo).end(), antihorario);
  for (int i = 0; i < sz; i++) ret.push_back(punto_area_signo[i].first);
  return ret;
}
int main() {
  ios::sync_with_stdio(0);
  cin.tie(0);
  int n;
  cin >> n;
  vector<long long> left, right;
  for (int i = 3; i < n + 1; i++) {
    if (query(2, 1, i, 2) == 1)
      right.push_back(i);
    else
      left.push_back(i);
  }
  vector<long long> sorted_right = Sort(1, 2, right);
  vector<long long> sorted_left = Sort(2, 1, left);
  vector<long long> ans;
  ans.push_back(1);
  int sz = sorted_right.size();
  for (int i = 0; i < sz; i++) ans.push_back(sorted_right[i]);
  ans.push_back(2);
  sz = sorted_left.size();
  for (int i = 0; i < sz; i++) ans.push_back(sorted_left[i]);
  if (query(2, ans[0], ans[1], ans[2]) == -1)
    for (int i = 0; i < n / 2; i++) swap(ans[i], ans[n - 1 - i]);
  cout << "0";
  for (int i = 0; i < n; i++) cout << " " << ans[i];
  cout << endl;
  return 0;
}
