#include <bits/stdc++.h>
using namespace std;
const int maxn = 2048;
int n, ans[maxn];
struct triple {
  int tr[3];
  triple(int a, int b, int c) {
    tr[0] = a;
    tr[1] = b;
    tr[2] = c;
  }
  bool operator<(const triple& T) const {
    for (int i = 0; i < 3; ++i)
      if (tr[i] != T.tr[i]) return tr[i] < T.tr[i];
    return false;
  }
};
map<triple, char> request;
int tree_size;
struct Tree {
  int t;
  Tree* l;
  Tree* r;
  Tree* ll;
  Tree* rr;
  int subtree_size;
  Tree(int t = 1, Tree* l = NULL, Tree* r = NULL)
      : t(t), l(l), r(r), ll(NULL), rr(NULL) {}
  ~Tree() {
    delete l;
    delete r;
    l = r = NULL;
  }
  void init() {
    l = new Tree(1);
    r = new Tree(2);
  }
  void insert_triples(int a, int b, int c) {
    request[triple(a, b, c)] = 'X';
    request[triple(b, a, c)] = 'X';
    request[triple(c, a, b)] = 'Y';
    request[triple(c, b, a)] = 'Y';
    request[triple(a, c, b)] = 'Z';
    request[triple(b, c, a)] = 'Z';
  }
  char query(int a, int b, int c) {
    triple tri(a, b, c);
    if (request.find(tri) != request.end()) {
      return request[tri];
    }
    printf("%d %d %d\n", a, b, c);
    fflush(stdout);
    char q;
    scanf(" %c", &q);
    if (q == '-') exit(0);
    switch (q) {
      case 'X':
        insert_triples(a, b, c);
        break;
      case 'Y':
        insert_triples(b, c, a);
        break;
      case 'Z':
        insert_triples(a, c, b);
        break;
    };
    return q;
  }
  void hide_children() {
    ll = l;
    rr = r;
    l = r = NULL;
  }
  void show_childrens() {
    if (ll != NULL && rr != NULL) {
      l = ll;
      r = rr;
      ll = NULL;
      rr = NULL;
    }
    if (l) l->show_childrens();
    if (r) r->show_childrens();
  }
  void add_children(int w) {
    if (ll == NULL && rr == NULL) {
      l = new Tree(*this);
      r = new Tree(w);
    } else {
      l = new Tree(ll->t, ll, rr);
      r = new Tree(w);
      ll = rr = NULL;
    }
  }
  char compare(int w) { return query(l->t, r->t, w); }
  int get_size() {
    int size = 1;
    if (l) size += l->get_size();
    if (r) size += r->get_size();
    subtree_size = size;
    return size;
  }
  Tree& find_centroid() {
    if (2 * l->subtree_size > tree_size) return l->find_centroid();
    if (2 * r->subtree_size > tree_size) return r->find_centroid();
    return *this;
  }
  Tree& find_centroid_as_root() {
    tree_size = get_size();
    return find_centroid();
  }
  void find_then_insert(int w) {
    if (l == NULL || r == NULL) {
      add_children(w);
      return;
    }
    Tree& c = find_centroid_as_root();
    char q = c.compare(w);
    if (q == 'X') {
      c.hide_children();
      find_then_insert(w);
    } else if (q == 'Y') {
      (c.r)->find_then_insert(w);
    } else {
      (c.l)->find_then_insert(w);
    }
  }
  void out(int p) {
    if (l == NULL || r == NULL) {
      ans[t] = p;
    } else {
      int new_label = ++n;
      ans[new_label] = p;
      if (l) l->out(new_label);
      if (r) r->out(new_label);
    }
  }
};
int main() {
  scanf("%d", &n);
  Tree T;
  T.init();
  for (int i = 3; i <= n; ++i) {
    T.find_then_insert(i);
    T.show_childrens();
  }
  T.out(-1);
  printf("-1\n");
  for (int i = 1; i <= n; ++i) printf("%d ", ans[i]);
  fflush(stdout);
  return 0;
}
