#include <bits/stdc++.h>
using namespace std;
template <class T>
using v2d = vector<vector<T> >;
template <class T>
bool uin(T &a, T b) {
  return a > b ? (a = b, true) : false;
}
template <class T>
bool uax(T &a, T b) {
  return a < b ? (a = b, true) : false;
}
mt19937 rng(chrono::system_clock::now().time_since_epoch().count());
const int maxN = 5e4 + 1;
int n;
struct point {
  long long x, y, z;
} a[maxN];
int main() {
  ios_base::sync_with_stdio(false);
  cin.tie(nullptr);
  cin >> n;
  for (int i = 1; i <= (int)(n); ++i) {
    cin >> a[i].x >> a[i].y >> a[i].z;
  }
  map<long long, vector<int> > mpz;
  for (int i = 1; i <= (int)(n); ++i) {
    mpz[a[i].z].emplace_back(i);
  }
  vector<int> rt;
  for (auto &pz : mpz) {
    map<long long, vector<int> > mpy;
    for (auto &fz : pz.second) {
      mpy[a[fz].y].emplace_back(fz);
    }
    vector<int> rs;
    for (auto &py : mpy) {
      sort((py.second).begin(), (py.second).end(),
           [](int x, int y) { return a[x].x < a[y].x; });
      for (int i = 0; i < (int)py.second.size() - 1; i += 2) {
        cout << py.second[i] << ' ' << py.second[i + 1] << '\n';
      }
      if (py.second.size() % 2) {
        rs.emplace_back(py.second.back());
      }
    }
    for (int i = 0; i < (int)rs.size() - 1; i += 2) {
      cout << rs[i] << ' ' << rs[i + 1] << '\n';
    }
    if (rs.size() % 2) {
      rt.emplace_back(rs.back());
    }
  }
  for (int i = 0; i < (int)rt.size() - 1; i += 2) {
    cout << rt[i] << ' ' << rt[i + 1] << '\n';
  }
  return 0;
}
