#include <bits/stdc++.h>
using namespace std;
const int inf = 1e9;
int n, N, M, S, T, sl, fh, sum, pw[10], fa[10], cnt[10], id[10][10], a[10][10],
    num[1 << 20];
int dep[100], gap[100];
char es[10], et[10];
pair<int, int> E[100];
int t, h[100], cur[100];
struct edge {
  int to, val, nxt;
} e[100000];
int rd() {
  sl = 0;
  fh = 1;
  char ch = getchar();
  while (ch < '0' || '9' < ch) {
    if (ch == '-') fh = -1;
    ch = getchar();
  }
  while ('0' <= ch && ch <= '9') sl = sl * 10 + ch - '0', ch = getchar();
  return sl * fh;
}
int getfa(int x) {
  if (fa[x] != x) fa[x] = getfa(fa[x]);
  return fa[x];
}
void add(int u, int v, int w) {
  e[++t] = (edge){v, w, h[u]};
  h[u] = t;
  e[++t] = (edge){u, 0, h[v]};
  h[v] = t;
}
int dfs(int u, int f) {
  if (u == T) return f;
  if (f <= 0) return f;
  int v, q = 0, tmp;
  for (int &i = cur[u]; i; i = e[i].nxt)
    if (e[i].val && dep[u] - 1 == dep[v = e[i].to]) {
      tmp = dfs(v, min(f, e[i].val));
      f -= tmp;
      q += tmp;
      e[i].val -= tmp;
      e[i ^ 1].val += tmp;
      if (!f) return q;
    }
  if (!(--gap[dep[u]])) dep[S] = T + 1;
  ++gap[++dep[u]];
  cur[u] = h[u];
  return q;
}
int Dinic() {
  int res = 0;
  memcpy(cur + 1, h + 1, T << 2);
  memset(dep + 1, 0, T << 2);
  memset(gap + 1, 0, T << 2);
  for (gap[0] = T; dep[S] <= T; res += dfs(S, inf))
    ;
  return res;
}
int main() {
  n = rd();
  int x, y;
  cnt[1] = pw[1] = 1;
  for (int i = 2; i <= 6; ++i) cnt[i] = pw[i] = pw[i - 1] * 10;
  for (M = 6; pw[M] > n; --M)
    ;
  pw[M + 1] = n + 1;
  for (int i = 1; i < n; ++i) {
    scanf("%s%s", es, et);
    x = strlen(es);
    y = strlen(et);
    if (x == y) cnt[x]++;
    a[x][y]++;
    if (x != y) a[y][x]++;
  }
  for (int i = 1; i <= M; ++i)
    if (cnt[i] >= pw[i + 1]) return puts("-1"), 0;
  for (int i = 1; i <= M; ++i)
    for (int j = i + 1; j <= M; ++j) E[id[i][j] = ++N] = make_pair(i, j);
  for (int i = 1; i < 1 << N; ++i) num[i] = num[i ^ (i & -i)] + 1;
  int fx, fy, flg;
  S = M + N + 1;
  T = M + N + 2;
  for (int s = 0; s < 1 << N; ++s)
    if (num[s] == M - 1) {
      flg = 1;
      for (int i = 1; i <= M; ++i) fa[i] = i;
      for (int i = 1; flg && i <= N; ++i)
        if ((s >> (i - 1)) & 1) {
          fx = getfa(E[i].first);
          fy = getfa(E[i].second);
          if (fx == fy)
            flg = 0;
          else
            fa[fy] = fx;
          if (!a[E[i].first][E[i].second]) flg = 0;
        }
      if (flg) {
        for (int i = 1; i <= N; ++i)
          if ((s >> (i - 1)) & 1)
            a[E[i].first][E[i].second]--, a[E[i].second][E[i].first]--;
        t = 1;
        sum = 0;
        memset(h + 1, 0, T << 2);
        for (int i = 1; i <= M; ++i) add(S, i, pw[i + 1] - cnt[i] - 1);
        for (int i = 1; i <= M; ++i)
          for (int j = i + 1; j <= M; ++j)
            add(id[i][j] + M, T, a[i][j]), add(i, id[i][j] + M, inf),
                add(j, id[i][j] + M, inf), sum += a[i][j];
        if (Dinic() == sum) {
          for (int i = 1; i <= M; ++i) cnt[i] = pw[i];
          for (int i = 1; i <= N; ++i)
            if ((s >> (i - 1)) & 1)
              printf("%d %d\n", pw[E[i].first], pw[E[i].second]);
          for (int i = 1; i <= M; ++i)
            for (; a[i][i]; --a[i][i]) printf("%d %d\n", pw[i], ++cnt[i]);
          for (int i = 1; i <= M; ++i)
            for (int j = i + 1; j <= M; ++j)
              for (int x = h[id[i][j] + M]; x; x = e[x].nxt) {
                if (e[x].to == i)
                  for (int k = 1; k <= e[x].val; ++k)
                    printf("%d %d\n", pw[j], ++cnt[i]);
                if (e[x].to == j)
                  for (int k = 1; k <= e[x].val; ++k)
                    printf("%d %d\n", pw[i], ++cnt[j]);
              }
          return 0;
        }
        for (int i = 1; i <= N; ++i)
          if ((s >> (i - 1)) & 1)
            a[E[i].first][E[i].second]++, a[E[i].second][E[i].first]++;
      }
    }
  puts("-1");
  return 0;
}
