#include <bits/stdc++.h>
using namespace std;
const int mn = 2e5 + 5;
int n;
long long query(int type, int i, int j, int k) {
  printf("%d %d %d %d\n", type, i, j, k);
  fflush(stdout);
  long long ans;
  scanf("%lld", &ans);
  return ans;
}
pair<long long, long long> find1() {
  int i = 1, j = 2, k = 3;
  for (int k = 3; k <= n; k++) {
    if (query(2, i, j, k) > 0) j = k;
  }
  return {i, j};
}
long long area[mn];
pair<long long, long long> getArea(pair<long long, long long> u) {
  int i = u.first, j = u.second;
  long long maxarea = 0;
  int who;
  for (int k = 1; k <= n; k++) {
    if (k == i || k == j) continue;
    area[k] = query(1, i, j, k);
    if (maxarea < area[k]) {
      maxarea = area[k];
      who = k;
    }
  }
  return {i, who};
}
int main() {
  scanf("%d", &n);
  auto u = find1();
  auto v = getArea(u);
  vector<pair<long long, long long> > l, r;
  for (int i = 1; i <= n; i++) {
    if (i != v.first && i != v.second) {
      auto c = query(2, v.first, v.second, i);
      if (c > 0) {
        l.push_back({area[i], i});
      } else
        r.push_back({area[i], i});
    }
  }
  sort(l.begin(), l.end());
  reverse(l.begin(), l.end());
  sort(r.begin(), r.end());
  printf("0");
  printf(" %d", v.first);
  for (auto &i : r) printf(" %d", i.second);
  printf(" %d", v.second);
  for (auto &i : l) printf(" %d", i.second);
  puts("");
  return 0;
}
