#include <bits/stdc++.h>
using namespace std;
const int MAXN = 50500;
struct point {
  int x, y, z, idx;
} arr[MAXN];
bool cmpx(point a, point b) {
  if (a.x != b.x)
    return a.x < b.x;
  else if (a.y != b.y)
    return a.y < b.y;
  return a.z < b.z;
}
queue<int> Q;
int main() {
  ios_base::sync_with_stdio(0);
  cin.tie(0);
  int n;
  cin >> n;
  for (int i = 0; i < n; i++) {
    cin >> arr[i].x >> arr[i].y >> arr[i].z;
    arr[i].idx = i + 1;
  }
  sort(arr, arr + n, cmpx);
  queue<int> PQ[MAXN];
  int t = arr[0].x;
  int s = arr[0].y;
  bool flag = false;
  int num = 0;
  for (int i = 0; i < n; i++) {
    if (arr[i].x == t) {
      if (arr[i].y == s) {
        if (flag) {
          cout << arr[i - 1].idx << " " << arr[i].idx << "\n";
          flag = false;
        } else {
          flag = true;
          if (i == n - 1) PQ[num].push(i);
        }
      } else {
        s = arr[i].y;
        if (flag) {
          PQ[num].push(i - 1);
          if (i == n - 1) PQ[num].push(i);
        } else {
          flag = true;
          if (i == n - 1) PQ[num].push(i);
        }
      }
    } else {
      t = arr[i].x;
      s = arr[i].y;
      if (flag) {
        PQ[num++].push(i - 1);
        if (i == n - 1) PQ[num].push(i);
      } else {
        flag = true;
        num++;
        if (i == n - 1) PQ[num].push(i);
      }
    }
  }
  num++;
  queue<int> tot;
  for (int i = 0; i < num; i++) {
    while (PQ[i].size() >= 2) {
      int a = PQ[i].front();
      PQ[i].pop();
      int b = PQ[i].front();
      PQ[i].pop();
      cout << arr[a].idx << " " << arr[b].idx << "\n";
    }
    if (PQ[i].size()) tot.push(PQ[i].front());
  }
  while (tot.size()) {
    int a = tot.front();
    tot.pop();
    int b = tot.front();
    tot.pop();
    cout << arr[a].idx << " " << arr[b].idx << "\n";
  }
}
