#include <bits/stdc++.h>
using namespace std;
const int N = 1005;
long long query(int t, int i, int j, int k) {
  long long ret = 0;
  printf("%d %d %d %d\n", t, i, j, k);
  fflush(stdout);
  scanf("%lld", &ret);
  return ret;
}
long long Sign[N], Sqr[N], Sign2[N], Pri[N];
long long Pos[N], Neg[N];
int tmpp[N];
int n, ptot = 1, ntot = 1;
bool cmp(const int AA, const int BB) {
  if (Pri[AA] != Pri[BB]) return Pri[AA] < Pri[BB];
  if (Pri[AA] & 1) return Sqr[AA] < Sqr[BB];
  return Sqr[AA] > Sqr[BB];
}
int main() {
  scanf("%d", &n);
  for (int i = 3; i <= n; i++) Sign[i] = query(2, 1, 2, i);
  for (int i = 3; i <= n; i++) Sqr[i] = query(1, 1, 2, i);
  long long PosMax = 0ll, NegMax = 0ll, pmax = 0, nmax = 0;
  for (int i = 3; i <= n; i++) {
    if (Sign[i] == 1 && Sqr[i] > PosMax) pmax = i, PosMax = Sqr[i];
    if (Sign[i] == -1 && Sqr[i] > NegMax) nmax = i, NegMax = Sqr[i];
  }
  if (PosMax) {
    for (int i = 3; i <= n; i++) {
      if (Sign[i] == 1 && i != pmax) {
        int tmp = (int)query(2, pmax, 1, i);
        if (tmp == -1)
          Pri[i] = 4;
        else
          Pri[i] = 3;
      }
    }
    Pri[pmax] = 4;
  }
  if (NegMax) {
    for (int i = 3; i <= n; i++) {
      if (Sign[i] == -1 && i != nmax) {
        int tmp = (int)query(2, nmax, 1, i);
        if (tmp == -1)
          Pri[i] = 2;
        else
          Pri[i] = 1;
      }
    }
    Pri[nmax] = 1;
  }
  Pri[1] = 1, Pri[2] = 3;
  for (int i = 1; i <= n; i++) tmpp[i] = i;
  sort(tmpp + 1, tmpp + n + 1, cmp);
  printf("0");
  for (int i = 1; i <= n; i++) printf(" %d", tmpp[i]);
  puts("");
  return 0;
}
