#include <bits/stdc++.h>
using namespace std;
int dx4[] = {0, 0, 1, -1};
int dy4[] = {1, -1, 0, 0};
int dx8[] = {0, 0, 1, -1, 1, 1, -1, -1};
int dy8[] = {1, -1, 0, 0, 1, -1, 1, -1};
int dxH[] = {2, 2, -2, -2, 1, 1, -1, -1};
int dyH[] = {1, -1, 1, -1, 2, -2, 2, -2};
int nlmon[] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
int lmon[] = {0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
const double GRS = (1 + sqrt(5)) / 2;
template <typename T>
T in() {
  char ch;
  T n = 0;
  bool ng = false;
  while (1) {
    ch = getchar();
    if (ch == '-') {
      ng = true;
      ch = getchar();
      break;
    }
    if (ch >= '0' && ch <= '9') break;
  }
  while (1) {
    n = n * 10 + (ch - '0');
    ch = getchar();
    if (ch<'0' | ch> '9') break;
  }
  return (ng ? -n : n);
}
template <typename T>
T power(T X, T P) {
  T ans = (T)1;
  for (T i = 1; i <= P; i++) {
    ans = ans * X;
  }
  return ans;
}
template <typename T>
T ABS(T A, T B) {
  T ret = A - B;
  if (ret < 0) return -ret;
  return ret;
}
const long long MOD = 1000000007;
const long long BIGMAX = power(2, 63) - 1;
template <typename T>
T ADD(T X, T Y, T M) {
  if (X + Y < 0)
    return (X - M) + Y;
  else if (X + Y >= M)
    return X + Y - M;
  else
    return X + Y;
}
template <typename T>
T prod(T a, T b, T c) {
  T x = 0, y = a % c;
  while (b > 0) {
    if (b % 2 == 1) {
      x = ADD(x, y, c);
    }
    y = (y * 2) % c;
    b /= 2;
  }
  return x % c;
}
template <typename T>
T bigmod(T a, T b, T c) {
  T x = (T)1, y = a % c;
  while (b > 0) {
    if (b % (T)2 == (T)1) {
      x = (x * y) % c;
    }
    y = (y * y) % c;
    b /= (T)2;
  }
  return x;
}
template <typename T>
T MODINVERSE(T a) {
  return bigmod(a, (T)(MOD - 2), (T)MOD);
}
template <typename T>
T GCD(T x, T y) {
  while (y != 0) {
    T z = x % y;
    x = y;
    y = z;
  }
  return x;
}
bool isvowel(char ch) {
  ch = toupper(ch);
  if (ch == 'A' || ch == 'E' || ch == 'I' || ch == 'O' || ch == 'U')
    return true;
  return false;
}
template <typename T>
T isleap(T year) {
  if (year % (T)400 == (T)0 || (year % (T)100 != (T)0 && year % (T)4 == (T)0))
    return true;
  return false;
}
vector<int> graph[10005];
int L[1005], R[1005];
bool visited[10005];
int pre;
void DFS(int u) {
  pre = u;
  visited[u] = true;
  for (int i = 0; i < graph[u].size(); i++) {
    int v = graph[u][i];
    if (!visited[v]) {
      DFS(v);
    }
  }
}
int main() {
  int n;
  scanf("%d", &n);
  for (int i = 1; i <= n; i++) {
    int l, r;
    scanf("%d %d", &l, &r);
    L[i] = l, R[i] = r;
    if (l) graph[l].push_back(i), graph[i].push_back(l);
    if (r) graph[i].push_back(r), graph[r].push_back(i);
  }
  bool flag = false;
  int cnt = 0;
  int nod;
  for (int i = 1; i <= n; i++) {
    if (!L[i]) {
      if (cnt) {
        R[pre] = i, L[i] = pre;
      }
      DFS(i);
      cnt++;
    }
  }
  for (int i = 1; i <= n; i++) {
    printf("%d %d\n", L[i], R[i]);
  }
}
