#include <bits/stdc++.h>
using namespace std;
inline long long read() {
  long long x = 0;
  char ch = getchar();
  bool f = 0;
  for (; !isdigit(ch); ch = getchar())
    if (ch == '-') f = 1;
  for (; isdigit(ch); ch = getchar()) x = x * 10 + ch - '0';
  return f ? -x : x;
}
void write(long long x) {
  if (x < 0) putchar('-'), x = -x;
  if (x >= 10) write(x / 10);
  putchar(x % 10 + '0');
}
void writeln(long long x) {
  write(x);
  puts("");
}
void writep(long long x) {
  write(x);
  putchar(' ');
}
const int N = 1000005;
int n, cnt;
struct info {
  long long x, y, z;
  int id;
} a[N], b[N];
bool cmp(info a, info b) {
  if (a.x != b.x) return a.x < b.x;
  if (a.y != b.y) return a.y < b.y;
  return a.z < b.z;
}
void solve(bool d) {
  cnt = 0;
  sort(a + 1, a + n + 1, cmp);
  for (int i = 1, j = 1; i <= n; i = j + 1) {
    j = i;
    if (d) {
      while (j + 1 <= n && a[j + 1].x == a[j].x && a[j + 1].y == a[j].y) j++;
    } else
      while (j + 1 <= n && a[j + 1].x == a[j].x) j++;
    for (int k = i; k <= j; k += 2) {
      if (k + 1 > j) break;
      writep(a[k].id);
      writeln(a[k + 1].id);
    }
    if ((j - i + 1) % 2) b[++cnt] = a[j];
  }
  if (cnt == 0) exit(0);
  n = cnt;
  for (int i = (int)(1); i <= (int)(n); i++) a[i] = b[i];
}
int main() {
  n = read();
  for (int i = (int)(1); i <= (int)(n); i++)
    a[i].x = read(), a[i].y = read(), a[i].z = read(), a[i].id = i;
  solve(1);
  solve(0);
  for (int i = 1; i <= n; i += 2) writep(a[i].id), writeln(a[i + 1].id);
}
