#include <bits/stdc++.h>
using namespace std;
long long query(int t, int a, int b, int c) {
  cout << t << ' ' << a << ' ' << b << ' ' << c << '\n';
  long long ret;
  cin >> ret;
  fflush(stdout);
  return ret;
}
int main() {
  int N;
  cin >> N;
  vector<int> L, R;
  for (int i = 3; i <= N; i++) {
    long long t = query(2, i, 1, 2);
    if (t == 1)
      L.push_back(i);
    else
      R.push_back(i);
  }
  vector<pair<long long, long long> > La, Ra;
  for (int x : L) La.emplace_back(query(1, x, 1, 2), x);
  for (int x : R) Ra.emplace_back(query(1, x, 1, 2), x);
  pair<long long, long long> Lmx = {0, 0}, Rmx = {0, 0};
  if (!La.empty()) Lmx = *max_element(La.begin(), La.end());
  if (!Ra.empty()) Rmx = *max_element(Ra.begin(), Ra.end());
  vector<pair<long long, long long> > LL, LR, RL, RR;
  for (pair<long long, long long> x : La) {
    if (x == Lmx) continue;
    long long t = query(2, x.second, 1, Lmx.second);
    if (t == 1)
      LL.push_back(x);
    else
      LR.push_back(x);
  }
  for (pair<long long, long long> x : Ra) {
    if (x == Rmx) continue;
    long long t = query(2, x.second, 2, Rmx.second);
    if (t == 1)
      RL.push_back(x);
    else
      RR.push_back(x);
  }
  sort(RR.begin(), RR.end());
  sort(RL.rbegin(), RL.rend());
  sort(LR.begin(), LR.end());
  sort(LL.rbegin(), LL.rend());
  vector<int> ans;
  ans.push_back(1);
  for (pair<long long, long long> x : RR) ans.push_back(x.second);
  if (Rmx.second) ans.push_back(Rmx.second);
  if (ans.size() >= 2 && ans[ans.size() - 2] != 1 && ans.back() != 1 &&
      query(2, 1, ans[ans.size() - 2], ans.back()) == -1)
    swap(ans[ans.size() - 2], ans.back());
  if (!RL.empty()) ans.push_back(RL[0].second);
  if (ans.size() >= 2 && ans[ans.size() - 2] != 1 && ans.back() != 1 &&
      query(2, 1, ans[ans.size() - 2], ans.back()) == -1)
    swap(ans[ans.size() - 2], ans.back());
  for (int i = 1; i < RL.size(); i++) ans.push_back(RL[i].second);
  ans.push_back(2);
  for (pair<long long, long long> x : LR) ans.push_back(x.second);
  if (Lmx.second) ans.push_back(Lmx.second);
  if (ans.size() >= 2 && ans[ans.size() - 2] != 1 && ans.back() != 1 &&
      query(2, 1, ans[ans.size() - 2], ans.back()) == -1)
    swap(ans[ans.size() - 2], ans.back());
  if (!LL.empty()) ans.push_back(LL[0].second);
  if (ans.size() >= 2 && ans[ans.size() - 2] != 1 && ans.back() != 1 &&
      query(2, 1, ans[ans.size() - 2], ans.back()) == -1)
    swap(ans[ans.size() - 2], ans.back());
  for (int i = 1; i < LL.size(); i++) ans.push_back(LL[i].second);
  cout << 0 << ' ';
  for (long long x : ans) cout << x << ' ';
}
