#include <bits/stdc++.h>
const int N = 5e4 + 5;
struct Point {
  int x, y, z, id;
  void input() { scanf("%d%d%d", &x, &y, &z); }
} a[N];
int main() {
  std::map<std::pair<int, int>, std::vector<Point> > f;
  std::map<int, std::vector<Point> > g;
  std::vector<Point> h;
  int n;
  scanf("%d", &n);
  for (int i = 1; i <= n; i++) {
    a[i].input();
    a[i].id = i;
    f[std::pair<int, int>(a[i].x, a[i].y)].push_back(a[i]);
  }
  for (auto &p : f) {
    auto &v = p.second;
    std::sort(v.begin(), v.end(),
              [](const Point &a, const Point &b) { return a.z < b.z; });
    if (v.size() & 1) g[v.back().x].push_back(v.back()), v.pop_back();
    for (int i = 0; i < v.size(); i += 2)
      printf("%d %d\n", v[i].id, v[i + 1].id);
  }
  for (auto &p : g) {
    auto &v = p.second;
    std::sort(v.begin(), v.end(),
              [](const Point &a, const Point &b) { return a.y < b.y; });
    if (v.size() & 1) h.push_back(v.back()), v.pop_back();
    for (int i = 0; i < v.size(); i += 2)
      printf("%d %d\n", v[i].id, v[i + 1].id);
  }
  for (int i = 0; i < h.size(); i += 2) printf("%d %d\n", h[i].id, h[i + 1].id);
  return 0;
}
