#include <bits/stdc++.h>
#pragma GCC target("avx2")
#pragma GCC optimization("O3")
#pragma GCC optimization("unroll-loops")
const long long INF = 0x3f3f3f3f3f3f3f3f;
const long long llinf = (1LL << 62);
const int inf = (1 << 30);
const int nmax = 1e5 + 50;
const int mod = 1e9 + 7;
using namespace std;
int n, i, x, y, z, viz[nmax], ex[nmax], ey[nmax], ez[nmax], t, j;
vector<pair<pair<int, int>, pair<int, int> > > vc;
vector<pair<int, int> > rs;
vector<int> v;
int main() {
  ios_base::sync_with_stdio(false);
  cin.tie(0);
  cerr.tie(0);
  cout.tie(0);
  cin >> n;
  for (i = 1; i <= n; i++) {
    cin >> x >> y >> z;
    vc.push_back(make_pair(make_pair(x, y), make_pair(z, i)));
    ex[i] = x, ey[i] = y, ez[i] = z;
  }
  sort(vc.begin(), vc.end());
  for (i = 0; i < (int)vc.size(); i++) {
    v.clear();
    for (j = i; j < (int)vc.size(); j++) {
      if (vc[i].first.first != vc[j].first.first ||
          vc[i].first.second != vc[j].first.second)
        break;
      v.push_back(vc[j].second.second);
    }
    for (t = 0; t < (int)v.size() - 1; t += 2) {
      rs.push_back(make_pair(v[t], v[t + 1]));
      viz[v[t]] = 1;
      viz[v[t + 1]] = 1;
    }
    i = j - 1;
  }
  vc.clear();
  for (i = 1; i <= n; i++) {
    if (viz[i]) continue;
    x = ex[i], y = ey[i], z = ez[i];
    vc.push_back(make_pair(make_pair(x, y), make_pair(z, i)));
  }
  sort(vc.begin(), vc.end());
  for (i = 0; i < (int)vc.size(); i++) {
    v.clear();
    for (j = i; j < (int)vc.size(); j++) {
      if (vc[i].first.first != vc[j].first.first) break;
      v.push_back(vc[j].second.second);
    }
    for (t = 0; t < (int)v.size() - 1; t += 2) {
      rs.push_back(make_pair(v[t], v[t + 1]));
      viz[v[t]] = 1;
      viz[v[t + 1]] = 1;
    }
    i = j - 1;
  }
  vc.clear();
  for (i = 1; i <= n; i++) {
    if (viz[i]) continue;
    x = ex[i], y = ey[i], z = ez[i];
    vc.push_back(make_pair(make_pair(x, y), make_pair(z, i)));
  }
  sort(vc.begin(), vc.end());
  for (i = 0; i < (int)vc.size() - 1; i += 2) {
    rs.push_back(make_pair(vc[i].second.second, vc[i + 1].second.second));
  }
  for (i = 0; i < n / 2; i++)
    cout << rs[i].first << " " << rs[i].second << '\n';
  return 0;
}
