#include <bits/stdc++.h>
using namespace std;
const int maxn = 5e4 + 10;
struct Point {
  int id;
  int x, y, z;
  bool operator<(const Point& ref) const {
    if (x < ref.x) {
      return true;
    }
    if (x > ref.x) {
      return false;
    }
    if (y < ref.y) {
      return true;
    }
    if (y > ref.y) {
      return false;
    }
    if (z < ref.z) {
      return true;
    }
    if (z > ref.z) {
      return false;
    }
    return true;
  }
};
Point points[maxn];
Point points2[maxn];
vector<pair<int, int> > ans;
int v[maxn];
inline int nxt(int i, int n) {
  while (i < n && v[i] == 1) {
    i++;
  }
  return i;
}
int process_3d(int n) {
  int i = nxt(0, n);
  int j = nxt(i + 1, n);
  if (i >= n || j >= n) {
    return 0;
  }
  for (;;) {
    Point& a = points[i];
    Point& b = points[j];
    if (a.x == b.x && a.y == b.y) {
      ans.push_back(make_pair(a.id, b.id));
      v[i] = 1;
      v[j] = 1;
      i = nxt(j + 1, n);
      j = nxt(i + 1, n);
    } else {
      i = j;
      j = nxt(i + 1, n);
    }
    if (i >= n || j >= n) {
      break;
    }
  }
  return 0;
}
int process_2d(int n) {
  int i = nxt(0, n);
  int j = nxt(i + 1, n);
  if (i >= n || j >= n) {
    return 0;
  }
  for (;;) {
    Point& a = points[i];
    Point& b = points[j];
    if (a.x == b.x) {
      ans.push_back(make_pair(a.id, b.id));
      v[i] = 1;
      v[j] = 1;
      i = nxt(j + 1, n);
      j = nxt(i + 1, n);
    } else {
      i = j;
      j = nxt(i + 1, n);
    }
    if (i >= n || j >= n) {
      break;
    }
  }
}
int process_1d(int n) {
  int i = nxt(0, n);
  int j = nxt(i + 1, n);
  if (i >= n || j >= n) {
    return 0;
  }
  for (;;) {
    Point& a = points[i];
    Point& b = points[j];
    if (true) {
      ans.push_back(make_pair(a.id, b.id));
      v[i] = 1;
      v[j] = 1;
      i = nxt(j + 1, n);
      j = nxt(i + 1, n);
    } else {
      i = j;
      j = nxt(i + 1, n);
    }
    if (i >= n || j >= n) {
      break;
    }
  }
}
int main() {
  int n;
  scanf("%d", &n);
  for (int i = 0; i < n; i++) {
    scanf("%d%d%d", &points[i].x, &points[i].y, &points[i].z);
    points[i].id = i + 1;
  }
  memset(v, 0, sizeof(v));
  sort(points, points + n);
  process_3d(n);
  process_2d(n);
  process_1d(n);
  for (int i = 0; i < ans.size(); i++) {
    printf("%d %d\n", ans[i].first, ans[i].second);
  }
  return 0;
}
