#include <bits/stdc++.h>
using namespace std;
const int maxn = 5e4 + 10;
struct vert {
  int x, y, z, ind;
  vert() {
    x = -1;
    y = -1;
    z = -1;
    ind = -1;
  }
};
vector<vert> a;
vector<int> wait;
int used[maxn];
bool cmp(const vert& fi, const vert& se) {
  if (fi.x != se.x) return fi.x < se.x;
  if (fi.y != se.y) return fi.y < se.y;
  if (fi.z != se.z) return fi.z < se.z;
  return fi.ind < se.ind;
}
int solve2(int y, int i) {
  int j = i + 1;
  while (j < wait.size() && a[wait[j]].y == y) {
    j++;
  }
  for (int k = i + 1; k < j; k += 2) {
    used[a[wait[k]].ind] = 1;
    used[a[wait[k - 1]].ind] = 1;
    cout << a[wait[k]].ind << " " << a[wait[k - 1]].ind << "\n";
  }
  return j;
}
void solve() {
  int i = 0;
  for (; i < wait.size();) {
    int search_for = a[wait[i]].y;
    i = solve2(search_for, i);
  }
}
void solve3() {
  int i = 1;
  for (; i < wait.size(); i += 2) {
    used[a[wait[i]].ind] = 1;
    used[a[wait[i - 1]].ind] = 1;
    cout << a[wait[i]].ind << " " << a[wait[i - 1]].ind << "\n";
  }
}
int main() {
  ios::sync_with_stdio(false);
  cin.tie(0), cout.tie(0);
  int n;
  cin >> n;
  a.resize(n);
  for (int i = 0; i < n; i++) {
    cin >> a[i].x >> a[i].y >> a[i].z;
    a[i].ind = i + 1;
  }
  sort(a.begin(), a.end(), cmp);
  int i = 0;
  for (; i < n;) {
    vector<int> tmp;
    swap(wait, tmp);
    int pos = 1;
    wait.push_back(i);
    i++;
    while (pos && i < n) {
      if (a[wait.back()].x == a[i].x) {
        wait.push_back(i);
        i++;
      } else {
        pos = 0;
      }
    }
    solve();
  }
  vector<vert> b;
  for (int i = 0; i < n; i++) {
    if (!used[a[i].ind]) {
      b.push_back(a[i]);
    }
  }
  n = b.size();
  swap(a, b);
  i = 0;
  for (; i < n;) {
    vector<int> tmp;
    swap(wait, tmp);
    int pos = 1;
    wait.push_back(i);
    i++;
    while (pos && i < n) {
      if (a[wait.back()].x == a[i].x) {
        wait.push_back(i);
        i++;
      } else {
        pos = 0;
      }
    }
    solve3();
  }
  b.clear();
  for (int i = 0; i < n; i++) {
    if (!used[a[i].ind]) {
      b.push_back(a[i]);
    }
  }
  n = b.size();
  swap(a, b);
  i = 1;
  for (; i < n; i += 2) {
    cout << a[i].ind << " " << a[i - 1].ind << "\n";
  }
  return 0;
}
