#include <bits/stdc++.h>
using namespace std;
const int MAXN = 1e5 + 10;
const int maxnode = 800005;
const int sigma_size = 26;
vector<pair<int, int> > ans;
struct Trie {
  int ch[maxnode][sigma_size];
  vector<int> val[maxnode][2];
  int sz;
  void clear() {
    sz = 1;
    memset(ch[0], 0, sizeof(ch[0]));
  }
  Trie() { clear(); }
  int idx(int c) { return c - 'a'; }
  void insert(char* s, int id, int v) {
    int u = 0, n = strlen(s);
    val[u][id].push_back(v);
    for (int i = 0; i < n; i++) {
      int c = idx(s[i]);
      if (!ch[u][c]) {
        memset(ch[sz], 0, sizeof(ch[sz]));
        val[sz][id].clear();
        ch[u][c] = sz++;
      }
      u = ch[u][c];
      val[u][id].push_back(v);
    }
  }
} trie;
bool vis[2][MAXN];
int n, total;
void init() {
  trie.clear();
  ans.clear();
  memset(vis, false, sizeof(vis));
}
void dfs(int u, int dep) {
  for (int i = 0; i < sigma_size; i++) {
    if (trie.ch[u][i]) {
      dfs(trie.ch[u][i], dep + 1);
    }
  }
  vector<int>& name = trie.val[u][0];
  vector<int>& pse = trie.val[u][1];
  int a, b;
  for (int i = 0; i < name.size(); i++) {
    a = name[i];
    if (vis[0][a]) continue;
    for (int j = 0; j < pse.size(); j++) {
      b = pse[j];
      if (vis[1][b]) continue;
      vis[0][a] = vis[1][b] = true;
      ans.push_back(make_pair(a, b));
      total += dep;
      break;
    }
  }
}
char str[maxnode];
int main() {
  while (scanf("%d", &n) != EOF) {
    init();
    for (int i = 1; i <= n; i++) {
      scanf("%s", str);
      trie.insert(str, 0, i);
    }
    for (int i = 1; i <= n; i++) {
      scanf("%s", str);
      trie.insert(str, 1, i);
    }
    total = 0;
    dfs(0, 0);
    printf("%d\n", total);
    for (int i = 0; i < ans.size(); i++) {
      printf("%d %d\n", ans[i].first, ans[i].second);
    }
  }
  return 0;
}
