#include <bits/stdc++.h>
using namespace std;
int n;
vector<pair<pair<int, int>, int>> pts;
bool vis[50002];
int main() {
  cin >> n;
  pts.clear();
  for (int i = 1; i <= n; ++i) {
    int x, y, z;
    cin >> x >> y >> z;
    pts.push_back(make_pair(make_pair(x, y), z));
  }
  memset(vis, false, sizeof(vis));
  vector<pair<int, int>> ans;
  ans.clear();
  map<pair<int, int>, vector<pair<int, int>>> mp;
  for (int i = 1; i <= n; ++i) {
    mp[pts[i - 1].first].push_back(make_pair(pts[i - 1].second, i));
  }
  for (auto vs : mp) {
    auto v = vs.second;
    sort(v.begin(), v.end());
    for (int i = 0; i + 1 < v.size(); i += 2) {
      ans.push_back(make_pair(v[i].second, v[i + 1].second));
      vis[v[i].second] = true;
      vis[v[i + 1].second] = true;
    }
  }
  map<int, vector<pair<int, int>>> mp2;
  for (int i = 1; i <= n; ++i) {
    if (!vis[i]) {
      mp2[pts[i - 1].first.first].push_back(
          make_pair(pts[i - 1].first.second, i));
    }
  }
  for (auto vs : mp2) {
    auto v = vs.second;
    sort(v.begin(), v.end());
    for (int i = 0; i + 1 < v.size(); i += 2) {
      vis[v[i].second] = true;
      vis[v[i + 1].second] = true;
      ans.push_back(make_pair(v[i].second, v[i + 1].second));
    }
  }
  vector<pair<int, int>> mp3;
  for (int i = 1; i <= n; ++i) {
    if (!vis[i]) {
      mp3.push_back(make_pair(pts[i - 1].first.first, i));
    }
  }
  sort(mp3.begin(), mp3.end());
  for (int i = 0; i + 1 < mp3.size(); i += 2) {
    ans.push_back(make_pair(mp3[i].second, mp3[i + 1].second));
  }
  for (int i = 0; i < ans.size(); ++i) {
    cout << ans[i].first << " " << ans[i].second << endl;
  }
  return 0;
}
