#include <bits/stdc++.h>
using namespace std;
const int UNDEF = -1;
const int INF = 1e18;
template <typename T>
inline bool chkmax(T &aa, T bb) {
  return aa < bb ? aa = bb, true : false;
}
template <typename T>
inline bool chkmin(T &aa, T bb) {
  return aa > bb ? aa = bb, true : false;
}
static char stdinBuffer[1024];
static char *stdinDataEnd = stdinBuffer + sizeof(stdinBuffer);
static const char *stdinPos = stdinDataEnd;
void readAhead(size_t amount) {
  size_t remaining = stdinDataEnd - stdinPos;
  if (remaining < amount) {
    memmove(stdinBuffer, stdinPos, remaining);
    size_t sz = fread(stdinBuffer + remaining, 1,
                      sizeof(stdinBuffer) - remaining, stdin);
    stdinPos = stdinBuffer;
    stdinDataEnd = stdinBuffer + remaining + sz;
    if (stdinDataEnd != stdinBuffer + sizeof(stdinBuffer)) *stdinDataEnd = 0;
  }
}
int readInt() {
  readAhead(16);
  int x = 0;
  bool neg = false;
  while (*stdinPos == ' ' || *stdinPos == '\n') ++stdinPos;
  if (*stdinPos == '-') {
    ++stdinPos;
    neg = true;
  }
  while (*stdinPos >= '0' && *stdinPos <= '9') {
    x *= 10;
    x += *stdinPos - '0';
    ++stdinPos;
  }
  return neg ? -x : x;
}
const int maxn = 30001;
const int maxid = maxn * 4;
bitset<maxid> active;
int id2node[maxid][3];
int _src2id[maxn];
int src2id[maxn][4];
int _dest2id[maxn];
int dest2id[maxn][8];
int node2cnt[maxn];
pair<pair<int, int>, int> id2st[maxid];
set<pair<pair<pair<int, int>, int>, int> > s;
void update_st(int id) {
  int a = id2node[id][0];
  int b = id2node[id][1];
  int c = id2node[id][2];
  int bCnt = node2cnt[b];
  int cCnt = node2cnt[c];
  id2st[id] =
      make_pair(make_pair(max(bCnt, cCnt), min(bCnt, cCnt)), -node2cnt[a]);
}
void update_id(int id) {
  s.erase(make_pair(id2st[id], id));
  update_st(id);
  s.insert(make_pair(id2st[id], id));
}
void update_nodes(int input_id) {
  set<int> ids;
  for (int k = 0; k < 3; k++) {
    int node = id2node[input_id][k];
    for (int i = 0; i < 4; i++) {
      int id = src2id[node][i];
      if (active[id]) ids.insert(id);
    }
    for (int i = 0; i < 8; i++) {
      int id = dest2id[node][i];
      if (active[id]) ids.insert(id);
    }
  }
  for (auto &id : ids) update_id(id);
}
int main() {
  active.set();
  int n = readInt();
  for (int v = 1; v <= n; v++) node2cnt[v] = 4;
  for (int id = 1; id <= 4 * n; id++) {
    int a = readInt(), b = readInt(), c = readInt();
    id2node[id][0] = a;
    id2node[id][1] = b;
    id2node[id][2] = c;
    src2id[a][_src2id[a]++] = id;
    dest2id[b][_dest2id[b]++] = id;
    dest2id[c][_dest2id[c]++] = id;
    id2st[id] = make_pair(make_pair(4, 4), -4);
    s.insert(make_pair(id2st[id], id));
  }
  vector<int> final;
  while (!s.empty()) {
    auto top = *(s.begin());
    s.erase(s.begin());
    int id = top.second;
    final.push_back(id);
    active[id] = false;
    int a = id2node[id][0], b = id2node[id][1], c = id2node[id][2];
    node2cnt[a]--;
    ++node2cnt[b];
    ++node2cnt[c];
    update_nodes(id);
  }
  printf("YES\n");
  for (auto &id : final) printf("%d ", id);
  printf("\n");
}
