#include <bits/stdc++.h>
using namespace std;
const int MAX = 2e5 + 5;
int n, ok, c[MAX], mk[MAX];
vector<int> g1[MAX], g2[MAX];
map<pair<int, int>, int> mp;
vector<pair<int, int> > e;
void dfs(int u, int col, vector<int> *g) {
  mk[u] = 1;
  c[u] = col;
  for (int v : g[u]) {
    if (mk[v]) {
      if (c[u] == c[v]) ok = 0;
      continue;
    }
    dfs(v, col ^ 1, g);
  }
}
bool bipartite(vector<int> *g) {
  for (int i = 1; i <= 2 * n; i++) c[i] = mk[i] = 0;
  ok = 1;
  for (int i = 1; i <= 2 * n; i++) {
    if (!mk[i]) dfs(i, 0, g);
  }
  return ok;
}
int main() {
  scanf("%d", &n);
  for (int i = 1; i <= n; i++) {
    int a, b;
    scanf("%d%d", &a, &b);
    g1[a].push_back(b);
    g1[b].push_back(a);
    g2[a].push_back(b);
    g2[b].push_back(a);
    mp[{a, b}] = mp[{b, a}] = 1;
    e.push_back({a, b});
  }
  for (int i = 1; i <= 2 * n; i += 2) {
    if (!mp.count({i, i + 1})) {
      g1[i].push_back(i + 1);
      g1[i + 1].push_back(i);
    }
  }
  if (!mp.count({1, 2 * n})) {
    g2[1].push_back(2 * n);
    g2[2 * n].push_back(1);
  }
  for (int i = 2; i < 2 * n; i += 2) {
    if (!mp.count({i, i + 1})) {
      g2[i].push_back(i + 1);
      g2[i + 1].push_back(i);
    }
  }
  if (bipartite(g1) || bipartite(g2)) {
    for (auto o : e) printf("%d %d\n", c[o.first] + 1, c[o.second] + 1);
  } else
    printf("-1\n");
  return 0;
}
