#include <bits/stdc++.h>
using namespace std;
struct TitikT {
  long long value;
  long long area;
};
long long N, areaT, ccwP, arr[200010], uppersize, lowersize;
vector<TitikT> upper, lower;
bool cmp(TitikT &a, TitikT &b) { return a.area < b.area; }
void Solve() {
  cin >> N;
  for (long long i = 3; i <= N; i++) {
    cout << 2 << " " << 1 << " " << 2 << " " << i << endl;
    cin >> ccwP;
    if (ccwP == 1)
      upper.push_back({i, 0});
    else
      lower.push_back({i, 0});
  }
  uppersize = upper.size();
  lowersize = lower.size();
  for (long long i = 0; i < uppersize; i++) {
    cout << 1 << " " << 1 << " " << 2 << " " << upper[i].value << endl;
    cin >> areaT;
    upper[i].area = areaT;
  }
  for (long long i = 0; i < lowersize; i++) {
    cout << 1 << " " << 1 << " " << 2 << " " << lower[i].value << endl;
    cin >> areaT;
    lower[i].area = areaT;
  }
  sort(upper.begin(), upper.end(), cmp);
  sort(lower.begin(), lower.end(), cmp);
  long long kiri = 1, kanan = 1;
  for (long long i = 1; i < uppersize; i++) {
    cout << 2 << " " << 1 << " " << upper[i - 1].value << " " << upper[i].value
         << endl;
    cin >> ccwP;
    if (ccwP == 1) {
      arr[2 + lowersize + kanan] = upper[i - 1].value;
      kanan++;
    } else {
      arr[1 + N - kiri] = upper[i - 1].value;
      kiri++;
    }
  }
  if (uppersize > 0) arr[1 + N - kiri] = upper[uppersize - 1].value;
  kiri = 1, kanan = 1;
  for (long long i = 1; i < lowersize; i++) {
    cout << 2 << " " << 1 << " " << lower[i - 1].value << " " << lower[i].value
         << endl;
    cin >> ccwP;
    if (ccwP == 1) {
      arr[1 + kiri] = lower[i - 1].value;
      kiri++;
    } else {
      arr[2 + lowersize - kanan] = lower[i - 1].value;
      kanan++;
    }
  }
  if (lowersize > 0) arr[2 + lowersize - kanan] = lower[lowersize - 1].value;
  arr[1] = 1;
  arr[2 + lowersize] = 2;
}
int main() {
  Solve();
  cout << 0;
  for (long long i = 1; i <= N; i++) {
    cout << " " << arr[i];
  }
  cout << endl;
}
