#include <bits/stdc++.h>
#pragma comment(linker, "/STACK:1024000000,1024000000")
using namespace std;
template <class T>
inline bool rd(T &ret) {
  char c;
  int sgn;
  if (c = getchar(), c == EOF) return 0;
  while (c != '-' && (c < '0' || c > '9')) c = getchar();
  sgn = (c == '-') ? -1 : 1;
  ret = (c == '-') ? 0 : (c - '0');
  while (c = getchar(), c >= '0' && c <= '9') ret = ret * 10 + (c - '0');
  ret *= sgn;
  return 1;
}
template <class T>
inline void pt(T x) {
  if (x < 0) {
    putchar('-');
    x = -x;
  }
  if (x > 9) pt(x / 10);
  putchar(x % 10 + '0');
}
const int N = 1e6 + 10;
vector<pair<int, int> > ANS;
struct Trie {
  int ch[800000][26], sz;
  int h[800000][2];
  vector<int> end[800000][2];
  int val[800000];
  int pre[800000];
  char he[800000];
  int Newnode() {
    memset(ch[sz], 0, sizeof(ch[sz]));
    val[sz] = h[sz][0] = h[sz][1] = 0;
    end[sz][0].clear();
    end[sz][1].clear();
    return sz++;
  }
  void init() {
    sz = 0;
    Newnode();
  }
  int idx(char c) { return c - 'a'; }
  int insert(char *s, int now, int index) {
    int u = 0;
    for (int i = 0; s[i]; i++) {
      int c = idx(s[i]);
      if (!ch[u][c]) {
        ch[u][c] = Newnode();
        he[sz - 1] = s[i];
        val[sz - 1] = val[u] + 1;
        pre[sz - 1] = u;
      }
      u = ch[u][c];
      h[u][now]++;
    }
    end[u][now].push_back(index);
    return u;
  }
  int dfs(int u) {
    int ans = min(h[u][0], h[u][1]);
    int tmp = 0, tmp2 = 0;
    for (int i = 0; i < 26; i++) {
      int v = ch[u][i];
      if (!v) continue;
      tmp2 += dfs(v);
      tmp += min(h[v][0], h[v][1]);
    }
    for (int i = 0; i < ans - tmp; i++)
      ANS.push_back(pair<int, int>(end[u][0][i], end[u][1][i]));
    int fa = pre[u];
    if (fa) {
      for (int i = ans - tmp; i < end[u][0].size(); i++)
        end[fa][0].push_back(end[u][0][i]);
      for (int i = ans - tmp; i < end[u][1].size(); i++)
        end[fa][1].push_back(end[u][1][i]);
    }
    end[u][0].clear();
    end[u][1].clear();
    return ans + tmp2;
  }
} ac;
int n;
char s[800000];
set<int> myset[2];
int main() {
  ac.init();
  rd(n);
  for (int i = 1; i <= n; i++) {
    scanf("%s", s);
    ac.insert(s, 0, i);
  }
  for (int i = 1; i <= n; i++) {
    scanf("%s", s);
    ac.insert(s, 1, i);
    myset[0].insert(i);
    myset[1].insert(i);
  }
  pt(ac.dfs(0));
  puts("");
  for (auto i : ANS) {
    myset[0].erase(i.first);
    myset[1].erase(i.second);
    pt(i.first);
    putchar(' ');
    pt(i.second);
    putchar('\n');
  }
  for (int i = myset[0].size(); i >= 1; i--) {
    pt(*myset[0].begin());
    putchar(' ');
    pt(*myset[1].begin());
    putchar('\n');
    myset[0].erase(myset[0].begin());
    myset[1].erase(myset[1].begin());
  }
  return 0;
}
