#include <bits/stdc++.h>
using namespace std;
int N;
struct node {
  int parent;
  int edge[26];
};
int S;
node trie[900000];
vector<int> ids[900000];
bool used[900000];
int SUM;
vector<pair<int, int> > ans;
void dfs(int x, int depth = 0) {
  int i;
  for ((i) = 0; (i) < (int)(26); (i)++)
    if (trie[x].edge[i] != -1) dfs(trie[x].edge[i], depth + 1);
  vector<int> v0, v1;
  for ((i) = 0; (i) < (int)(ids[x].size()); (i)++) {
    int id = ids[x][i];
    if (used[id]) continue;
    if (id < N)
      v0.push_back(id);
    else
      v1.push_back(id);
  }
  int tmp = min((int)(v0.size()), (int)(v1.size()));
  for ((i) = 0; (i) < (int)(tmp); (i)++) {
    SUM += depth;
    int p = v0[i], q = v1[i];
    ans.push_back(make_pair(p, q));
    used[p] = used[q] = true;
  }
}
int new_node(int p) {
  trie[S].parent = p;
  int i;
  for ((i) = 0; (i) < (int)(26); (i)++) trie[S].edge[i] = -1;
  S++;
  return S - 1;
}
int trans(int x, char c) {
  int y = trie[x].edge[c - 'a'];
  if (y == -1) {
    y = new_node(x);
    trie[x].edge[c - 'a'] = y;
  }
  return y;
}
void update(string s, int id) {
  int cur = 0;
  ids[cur].push_back(id);
  int i;
  for ((i) = 0; (i) < (int)(s.length()); (i)++) {
    cur = trans(cur, s[i]);
    ids[cur].push_back(id);
  }
}
char buf[900000];
int main(void) {
  int i;
  S = 1;
  trie[0].parent = -1;
  for ((i) = 0; (i) < (int)(26); (i)++) trie[0].edge[i] = -1;
  cin >> N;
  for ((i) = 0; (i) < (int)(2 * N); (i)++) {
    scanf("%s", buf);
    string s = buf;
    update(s, i);
  }
  dfs(0);
  cout << SUM << endl;
  for ((i) = 0; (i) < (int)(N); (i)++)
    printf("%d %d\n", ans[i].first + 1, ans[i].second - N + 1);
  return 0;
}
