#include <bits/stdc++.h>
using namespace std;
inline void fastio() {
  ios_base::sync_with_stdio(false), cin.tie(NULL), cout.tie(NULL);
}
int dx[] = {-1, 0, 1, 0, -1, -1, 1, 1};
int dy[] = {0, 1, 0, -1, -1, 1, 1, -1};
class point {
 public:
  int x;
  int y;
  int z;
  int ind;
  point(int xc, int yc, int zc, int i) {
    x = xc;
    y = yc;
    z = zc;
    ind = i;
  }
};
bool myComp(point p1, point p2) {
  if (p1.x != p2.x)
    return p1.x < p2.x;
  else {
    if (p1.y != p2.y)
      return p1.y < p2.y;
    else
      return p1.z < p2.z;
  }
}
int main() {
  fastio();
  int n;
  cin >> n;
  vector<point> v;
  for (int i = 1; i <= n; i++) {
    int xi, yi, zi;
    cin >> xi >> yi >> zi;
    point p(xi, yi, zi, i);
    v.push_back(p);
  }
  sort(v.begin(), v.end(), myComp);
  deque<point> q;
  for (auto p : v) q.push_back(p);
  point endp(1000000000, 0, 0, -1);
  q.push_back(endp);
  while (q.front().x != 1000000000) {
    point p1 = q.front();
    q.pop_front();
    point p2 = q.front();
    q.pop_front();
    if (p1.x == p2.x and p1.y == p2.y)
      cout << p1.ind << " " << p2.ind << endl;
    else {
      q.push_back(p1);
      q.push_front(p2);
    }
  }
  q.push_back(q.front());
  q.pop_front();
  while (q.front().x != 1000000000) {
    point p1 = q.front();
    q.pop_front();
    point p2 = q.front();
    q.pop_front();
    if (p1.x == p2.x and p1.z == p2.z)
      cout << p1.ind << " " << p2.ind << endl;
    else {
      q.push_back(p1);
      q.push_front(p2);
    }
  }
  q.push_back(q.front());
  q.pop_front();
  while (q.front().x != 1000000000) {
    point p1 = q.front();
    q.pop_front();
    point p2 = q.front();
    q.pop_front();
    if (p1.x == p2.x)
      cout << p1.ind << " " << p2.ind << endl;
    else {
      q.push_back(p1);
      q.push_front(p2);
    }
  }
  q.push_back(q.front());
  q.pop_front();
  while (q.front().x != 1000000000) {
    point p1 = q.front();
    q.pop_front();
    point p2 = q.front();
    q.pop_front();
    cout << p1.ind << " " << p2.ind << endl;
  }
  return 0;
}
