#include <bits/stdc++.h>
#pragma GCC target("avx2")
#pragma GCC optimize("O3")
#pragma GCC optimize("unroll-loops")
using namespace std;
long long int query(long long int t, long long int i, long long int j,
                    long long int k) {
  cout << t << " " << i << " " << j << " " << k << '\n' << flush;
  long long int ans;
  cin >> ans;
  return ans;
}
int main() {
  ios_base::sync_with_stdio(false);
  cin.tie(NULL);
  long long int n;
  cin >> n;
  long long int start = 1;
  long long int nay = 2;
  vector<long long int> avail;
  for (long long int i = 3; i <= n; ++i) {
    if (query(2, start, i, nay) > 0) nay = i;
  }
  pair<long long int, long long int> bga = {-1, -1};
  vector<pair<long long int, long long int>> pos, neg;
  map<long long int, long long int> sins;
  for (long long int i = 2; i <= n; ++i) {
    if (i == nay) continue;
    sins[i] = query(1, start, nay, i);
    bga = max(bga, {sins[i], i});
  }
  long long int big = bga.second;
  for (long long int i = 2; i <= n; ++i) {
    if (i == big || i == nay) continue;
    if (query(2, start, big, i) > 0)
      pos.push_back({sins[i], i});
    else
      neg.push_back({sins[i], i});
  }
  sort(pos.begin(), pos.end());
  reverse(pos.begin(), pos.end());
  sort(neg.begin(), neg.end());
  cout << 0 << " " << start << " " << nay;
  for (auto o : neg) cout << " " << o.second;
  cout << " " << big;
  for (auto o : pos) cout << " " << o.second;
  cout << endl << flush;
}
