#include <bits/stdc++.h>
using namespace std;
template <class T>
inline void read(T &x) {
  int f = 0;
  x = 0;
  char ch = getchar();
  for (; !isdigit(ch); ch = getchar()) f |= (ch == '-');
  for (; isdigit(ch); ch = getchar()) x = x * 10 + ch - '0';
  if (f) x = -x;
}
int prufer[7], c[7], e[7][7], cc[7];
int tmp[7][7], cur[7], owo[7];
int n, m, a, b, cnt;
char s[7], t[7];
const int N = 105, M = 405, inf = 1e9;
struct Edge {
  int u, v, f, c;
};
struct ISAP {
  int n, m, s, t, res;
  int num[N], cur[N], d[N];
  int link[M], h[N], p[N];
  Edge e[M];
  inline void init(int _n) {
    n = _n, m = 0, res = 0;
    memset(h, -1, sizeof h);
    memset(cur, -1, sizeof cur);
  }
  inline void add(int u, int v, int w) {
    e[m] = (Edge){u, v, 0, w};
    link[m] = h[u], cur[u] = h[u] = m++;
    e[m] = (Edge){v, u, 0, 0};
    link[m] = h[v], cur[v] = h[v] = m++;
  }
  inline int aug() {
    int mn = inf;
    for (int x = t; x != s; x = e[p[x]].u) mn = min(mn, e[p[x]].c - e[p[x]].f);
    for (int x = t; x != s; x = e[p[x]].u) e[p[x]].f += mn, e[p[x] ^ 1].f -= mn;
    return mn;
  }
  int Maxflow(int _s, int _t) {
    int u = _s;
    s = _s, t = _t;
    memset(num, 0, sizeof num);
    memset(d, 0, sizeof d), num[0] = n;
    while (d[s] < n) {
      if (u == t) res += aug(), u = s;
      int flag = 0;
      for (int k = cur[u]; ~k; k = link[k])
        if (e[k].f < e[k].c && d[u] == d[e[k].v] + 1) {
          cur[u] = k, p[u = e[k].v] = k;
          flag = 1;
          break;
        }
      if (flag) continue;
      int mn = n;
      for (int k = cur[u] = h[u]; ~k; k = link[k])
        if (e[k].f < e[k].c) mn = min(mn, d[e[k].v] + 1);
      if (!(--num[d[u]])) return res;
      num[d[u] = mn]++, u = (u == s ? s : e[p[u]].u);
    }
    return res;
  }
} G;
int id[7][7], tot;
void doit() {
  vector<pair<int, int> > E;
  memcpy(tmp, e, sizeof e);
  memcpy(cc, c, sizeof c);
  vector<int> vec;
  for (int i = (1); i <= (m); i++) vec.push_back(i);
  for (int i = (1); i <= (m - 2); i++) {
    int u = prufer[i], t = -1;
    for (int j = 0; j < (vec.size()); j++) {
      int appear = 0;
      for (int k = (i); k <= (m - 2); k++)
        if (prufer[k] == vec[j]) {
          appear = 1;
          break;
        }
      if (!appear) {
        t = j;
        break;
      }
    }
    E.push_back(make_pair(u, vec[t]));
    vec.erase(vec.begin() + t);
  }
  E.push_back(make_pair(vec[0], vec[1]));
  for (int i = 0; i < (E.size()); i++) {
    if (E[i].first > E[i].second) swap(E[i].first, E[i].second);
    tmp[E[i].first][E[i].second]--;
    if (tmp[E[i].first][E[i].second] < 0) return;
  }
  int aim = 0;
  for (int i = (1); i <= (m); i++) cc[i]--, aim += cc[i];
  int S, T;
  tot = m;
  for (int i = (1); i <= (m); i++)
    for (int j = (i); j <= (m); j++) id[i][j] = ++tot;
  S = ++tot, T = ++tot;
  G.init(T);
  for (int i = (1); i <= (m); i++)
    for (int j = (i); j <= (m); j++) {
      G.add(S, id[i][j], tmp[i][j]);
      G.add(id[i][j], i, inf);
      G.add(id[i][j], j, inf);
    }
  for (int i = (1); i <= (m); i++) G.add(i, T, cc[i]);
  if (G.Maxflow(S, T) != aim) return;
  owo[1] = cur[1] = 1;
  for (int i = (2); i <= (m + 1); i++) owo[i] = cur[i] = cur[i - 1] * 10;
  for (auto x : E) printf("%d %d\n", owo[x.first], owo[x.second]);
  for (int i = (1); i <= (m); i++)
    for (int j = (i); j <= (m); j++) {
      int A = 0, B = 0;
      for (int k = G.h[id[i][j]]; ~k; k = G.link[k]) {
        if (G.e[k].v == i)
          B += G.e[k].f;
        else if (G.e[k].v == j)
          A += G.e[k].f;
      }
      for (int k = (1); k <= (A); k++) {
        printf("%d %d\n", owo[i], ++cur[j]);
        cc[j]--, tmp[i][j]--;
      }
      for (int k = (1); k <= (B); k++) {
        printf("%d %d\n", owo[j], ++cur[i]);
        cc[i]--, tmp[i][j]--;
      }
    }
  exit(0);
}
void dfs(int k) {
  if (k == m - 1) {
    doit();
    return;
  }
  for (int i = (1); i <= (m); i++) {
    prufer[k] = i;
    dfs(k + 1);
  }
}
int main() {
  read(n);
  if (n <= 9) {
    for (int i = (1); i <= (n - 1); i++) printf("%d %d\n", i, i + 1);
    return 0;
  }
  for (int t = 1; t <= n; t *= 10, m++)
    ;
  c[m] = n - 9, c[1] = 9;
  for (int i = (2); i <= (m - 1); i++) {
    c[i] = c[i - 1] * 10;
    c[m] -= c[i];
  }
  for (int i = (1); i <= (n - 1); i++) {
    scanf("%s%s", s, t);
    a = strlen(s), b = strlen(t);
    if (a > b) swap(a, b);
    e[a][b]++;
  }
  dfs(1), puts("-1");
  return 0;
}
