#include <bits/stdc++.h>
using namespace std;
const int N = 2323;
const long long MOD = 998244353LL;
long long ask(int i, int j, int k, int l) {
  printf("%d %d %d %d\n", i, j, k, l);
  fflush(stdout);
  long long ret;
  scanf("%lld", &ret);
  return ret;
}
long long area[N], side[N];
int n, m, k;
vector<int> vec[4];
inline bool cmp1(int x, int y) { return area[x] < area[y]; }
inline bool cmp2(int x, int y) { return area[x] > area[y]; }
int main() {
  int cases = 1;
  for (int iii = 1; iii <= cases; ++iii) {
    scanf("%d", &n);
    int pos1 = 0, pos2 = 0;
    for (int i = 3; i <= n; ++i) {
      area[i] = ask(1, 1, 2, i);
      side[i] = ask(2, 1, 2, i);
      if (side[i] < 0) {
        if (area[i] > area[pos1]) pos1 = i;
      }
      if (side[i] > 0) {
        if (area[i] > area[pos2]) pos2 = i;
      }
    }
    for (int i = 3; i <= n; ++i) {
      int temp;
      if (side[i] < 0) {
        if (i == pos1)
          temp = 1;
        else
          temp = ask(2, 1, pos1, i);
      }
      if (side[i] > 0) {
        if (i == pos2)
          temp = 1;
        else
          temp = ask(2, 1, pos2, i);
      }
      if (temp == -1) temp = 0;
      if (side[i] == -1) side[i] = 0;
      vec[side[i] * 2 + temp].push_back(i);
    }
    sort(vec[0].begin(), vec[0].end(), cmp1);
    sort(vec[1].begin(), vec[1].end(), cmp2);
    sort(vec[2].begin(), vec[2].end(), cmp1);
    sort(vec[3].begin(), vec[3].end(), cmp2);
    printf("0 1");
    for (auto it : vec[0]) printf(" %d", it);
    for (auto it : vec[1]) printf(" %d", it);
    printf(" 2");
    for (auto it : vec[2]) printf(" %d", it);
    for (auto it : vec[3]) printf(" %d", it);
  }
}
