#include <bits/stdc++.h>
using namespace std;
const int N = 8e5 + 10;
int n, match[100000], ans;
string s;
struct node {
  int child[30], dep;
  vector<int> nameID;
  node() {
    memset(child, -1, sizeof child);
    dep = 0;
  }
};
vector<node> trie;
bool matchit(int v, int ind) {
  if (trie[v].nameID.size() == 0) return 0;
  int tmp = trie[v].nameID.back();
  return (min(tmp, ind) < n && max(tmp, ind) >= n);
}
void add(string name, int ind) {
  int v = 0;
  for (int i = 0; i < name.size(); i++) {
    int c = (int)(name[i] - 'a');
    if (trie[v].child[c] == -1) {
      trie[v].child[c] = trie.size();
      trie.push_back(node());
      trie[trie.size() - 1].dep = trie[v].dep + 1;
    }
    v = trie[v].child[c];
  }
  if (matchit(v, ind)) {
    int tmp = trie[v].nameID.back();
    trie[v].nameID.pop_back();
    match[min(tmp, ind)] = max(tmp, ind);
    ans += trie[v].dep;
  } else
    trie[v].nameID.push_back(ind);
}
void DFS(int v) {
  for (int i = 0; i < 26; i++) {
    if (trie[v].child[i] == -1) continue;
    DFS(trie[v].child[i]);
    vector<int> &ch = trie[trie[v].child[i]].nameID;
    vector<int> &p = trie[v].nameID;
    if (ch.size() == 0) continue;
    if (!matchit(v, ch[0])) {
      for (int i = 0; i < ch.size(); i++) p.push_back(ch[i]);
      ch.clear();
      continue;
    }
    while (ch.size() && p.size()) {
      int x = ch.back(), y = p.back();
      ch.pop_back();
      p.pop_back();
      match[min(x, y)] = max(x, y);
      ans += trie[v].dep;
    }
    if (ch.size()) {
      for (int i = 0; i < ch.size(); i++) p.push_back(ch[i]);
      ch.clear();
    }
  }
}
int main() {
  ios_base::sync_with_stdio(0);
  cin.tie(0);
  cout.tie(0);
  trie.push_back(node());
  cin >> n;
  for (int i = 0; i < 2 * n; i++) {
    cin >> s;
    add(s, i);
  }
  DFS(0);
  cout << ans << endl;
  for (int i = 0; i < n; i++) cout << i + 1 << " " << match[i] + 1 - n << endl;
  return 0;
}
