#include <bits/stdc++.h>
using namespace std;
int n;
void check_if_zero(long long x) {
  if (x == 0) exit(0);
}
long long get_area(int a, int b, int c) {
  long long result;
  cout << 1 << ' ' << a << ' ' << b << ' ' << c << endl;
  cin >> result;
  check_if_zero(result);
  assert(result > 0);
  return result;
}
int get_sign(int o, int a, int b) {
  int result;
  cout << 2 << ' ' << o << ' ' << a << ' ' << b << endl;
  cin >> result;
  check_if_zero(result);
  assert(abs(result) == 1);
  return result;
}
vector<int> lef, rig;
void divide() {
  for (int i = 3; i <= n; i++) {
    int sign = get_sign(1, 2, i);
    if (sign == 1)
      lef.push_back(i);
    else
      rig.push_back(i);
  }
}
long long area12[1005];
void _do(vector<int> &lst) {
  if (lst.size() <= 1) return;
  long long best = 0;
  for (auto v : lst) {
    area12[v] = get_area(1, 2, v);
    if (area12[v] > area12[best]) best = v;
  }
  vector<int> l, r;
  for (auto v : lst) {
    if (v == best) continue;
    if (get_sign(1, best, v) == 1)
      l.push_back(v);
    else
      r.push_back(v);
  }
  sort(l.begin(), l.end(), [&](int x, int y) { return area12[x] > area12[y]; });
  sort(r.begin(), r.end(), [&](int x, int y) { return area12[x] < area12[y]; });
  lst.clear();
  for (auto v : r) lst.push_back(v);
  lst.push_back(best);
  for (auto v : l) lst.push_back(v);
}
void answer() {
  cout << 0 << ' ' << 1 << ' ';
  for (auto v : rig) cout << v << ' ';
  cout << 2 << ' ';
  for (auto v : lef) cout << v << ' ';
  cout << endl;
}
int main() {
  cin >> n;
  assert(n >= 3);
  divide();
  _do(lef);
  _do(rig);
  answer();
}
