#include <bits/stdc++.h>
using namespace std;
class Node {
 public:
  int l;
  int r;
  int list;
  int number;
  Node(int l, int r, int number) {
    this->l = l;
    this->r = r;
    this->number = number;
    this->list = -1;
  }
};
int main() {
  int Nn;
  scanf("%d", &Nn);
  vector<Node*> v;
  v.push_back((new Node(-1, -1, 0)));
  vector<Node*> noRight;
  vector<Node*> noLeft;
  for (int i = 1; i <= Nn; i++) {
    int r, l;
    scanf("%d %d", &l, &r);
    Node* node = new Node(l, r, i);
    v.push_back(node);
  }
  int last_list = -1;
  for (Node* N : v) {
    if (N->r == -1)
      continue;
    else {
      if (N->list == -1) {
        last_list++;
        N->list = last_list;
        Node* flow = N;
        if (flow->r == 0) noRight.push_back(flow);
        if (flow->l == 0) {
          noLeft.insert(noLeft.begin(), flow);
        }
        while (flow->r != 0 && v[flow->r]->list == -1) {
          flow = v[flow->r];
          flow->list = last_list;
          if (flow->r == 0) noRight.push_back(flow);
        }
        flow = N;
        while (flow->l != 0 && v[flow->l]->list == -1) {
          flow = v[flow->l];
          flow->list = last_list;
          if (flow->l == 0) noLeft.push_back(flow);
        }
      }
    }
  }
  while (noRight.size() > 1 || noLeft.size() > 1) {
    int right = 0, left = 0;
    while (noRight[right]->list == noLeft[left]->list) {
      right++;
    }
    if (right >= noRight.size()) right = noRight.size() - 1;
    while (noRight[right]->list == noLeft[left]->list) {
      left++;
    }
    if (left >= noLeft.size()) left = noLeft.size() - 1;
    noRight[right]->r = noLeft[left]->number;
    noLeft[left]->l = noRight[right]->number;
    int corrlist = noRight[right]->list;
    for (auto tyty : v) {
      if (tyty->list == corrlist) tyty->list = noLeft[left]->list;
    }
    noRight.erase(noRight.begin() + right);
    noLeft.erase(noLeft.begin() + left);
  }
  v.erase(v.begin());
  for (auto nodes : v) {
    printf("%d %d\n", nodes->l, nodes->r);
  }
  return 0;
}
