#include <bits/stdc++.h>
using namespace std;
const int N = 2e5 + 5, inf = 0x3f3f3f3f;
int n, m, v[7], e[7][7], _e[7][7], used[7][7];
int de;
pair<int, int> a[7];
int tot, head[N], nxt[N], to[N], w[N], id[7][7], idx, s, t, d[N], vis[7];
void add(int x, int y, int z) {
  to[++tot] = y, w[tot] = z, nxt[tot] = head[x], head[x] = tot;
  to[++tot] = x, w[tot] = 0, nxt[tot] = head[y], head[y] = tot;
}
void init() {
  idx = 0;
  for (int i = 1; i <= m; ++i)
    for (int j = i + 1; j <= m; ++j) id[i][j] = ++idx;
  s = 0;
  t = idx + m + 1;
}
bool bfs() {
  for (int i = s; i <= t; ++i) d[i] = 0;
  queue<int> q;
  q.push(s);
  d[s] = 1;
  while (!q.empty()) {
    int x = q.front();
    q.pop();
    for (int i = head[x]; i; i = nxt[i])
      if (w[i] && !d[to[i]]) {
        q.push(to[i]);
        d[to[i]] = d[x] + 1;
        if (to[i] == t) return true;
      }
  }
  return false;
}
int dinic(int x, int flow) {
  if (x == t) return flow;
  int rest = flow;
  for (int i = head[x]; i; i = nxt[i]) {
    if (d[to[i]] != d[x] + 1 || !w[i]) continue;
    int k = dinic(to[i], min(rest, w[i]));
    if (!k) d[to[i]] = 0;
    w[i] -= k, w[i ^ 1] += k;
    rest -= k;
    if (!rest) break;
  }
  return flow - rest;
}
void dfs2(int x, int &cnt) {
  ++cnt;
  vis[x] = 1;
  for (int i = 1; i <= m - 1; ++i) {
    if (a[i].first == x && !vis[a[i].second]) dfs2(a[i].second, cnt);
    if (a[i].second == x && !vis[a[i].first]) dfs2(a[i].first, cnt);
  }
}
bool check() {
  int cnt = 0;
  memset(vis, 0, sizeof vis);
  dfs2(1, cnt);
  if (cnt != m) return false;
  memcpy(_e, e, sizeof e);
  for (int i = 1; i < m; ++i) --_e[a[i].first][a[i].second];
  tot = 1;
  for (int i = s; i <= t; ++i) head[i] = 0;
  int fs = 0, ft = 0;
  for (int i = 1; i <= m; ++i) {
    add(idx + i, t, v[i] - 1);
    ft += v[i] - 1;
    for (int j = i + 1; j <= m; ++j)
      add(s, id[i][j], _e[i][j]), add(id[i][j], idx + i, inf),
          add(id[i][j], idx + j, inf), fs += _e[i][j];
  }
  if (fs ^ ft) return false;
  int flow = 0, mxflow = 0;
  while (bfs())
    while (flow = dinic(s, inf)) mxflow += flow;
  return mxflow == fs;
}
int key[7], p[7];
void print() {
  key[1] = p[1] = 1;
  for (int i = 2; i <= m; ++i) key[i] = p[i] = p[i - 1] * 10;
  for (int i = 1; i < m; ++i)
    cout << key[a[i].first] << ' ' << key[a[i].second] << endl;
  for (int i = 1; i <= m; ++i)
    for (int j = i + 1; j <= m; ++j) {
      int x = id[i][j];
      for (int k = head[x]; k; k = nxt[k]) {
        int y = to[k];
        if (y == s || w[k] == inf) continue;
        for (int t = 1; t <= inf - w[k]; ++t) {
          if (y == idx + i)
            cout << ++p[i] << ' ' << key[j] << endl;
          else
            cout << ++p[j] << ' ' << key[i] << endl;
        }
      }
    }
  for (int i = 1; i <= m; ++i)
    for (int j = p[i] + 1; j <= key[i] + v[i] + e[i][i] - 1; ++j)
      cout << key[i] << ' ' << j << endl;
}
bool dfs(int x) {
  if (x == m) return check();
  for (int i = 1; i <= m; ++i)
    for (int j = i + 1; j <= m; ++j)
      if (!used[i][j] && e[i][j]) {
        used[i][j] = 1;
        a[x] = make_pair(i, j);
        if (dfs(x + 1)) return true;
        used[i][j] = 0;
      }
  return false;
}
int main() {
  ios::sync_with_stdio(false);
  cin >> n;
  if (n >= 10) {
    v[1] = 9;
    if (n >= 100) {
      v[2] = 90;
      if (n >= 1000) {
        v[3] = 900;
        if (n >= 10000) {
          v[4] = 9000;
          if (n >= 100000) {
            v[5] = 90000;
            v[6] = n - 99999, m = 6;
          } else
            v[5] = n - 9999, m = 5;
        } else
          v[4] = n - 999, m = 4;
      } else
        v[3] = n - 99, m = 3;
    } else
      v[2] = n - 9, m = 2;
  } else
    v[1] = n, m = 1;
  for (int i = 1; i < n; ++i) {
    string u, v;
    cin >> u >> v;
    if (n == 150123 && i == 1 && u.length() == 5) de = 1;
    if (u.length() > m || v.length() > m) cout << -1 << endl, exit(0);
    if (u.length() > v.length()) swap(u, v);
    ++e[u.length()][v.length()];
  }
  for (int i = 1; i <= m; ++i) {
    v[i] -= e[i][i];
    if (v[i] <= 0) cout << -1 << endl, exit(0);
  }
  init();
  if (dfs(1))
    print();
  else
    cout << -1 << endl, exit(0);
  return 0;
}
