#include <bits/stdc++.h>
using namespace std;
struct Trie {
  struct Node {
    char c;
    vector<pair<int, int> > n;
    Node* ch[26];
    Node(char ch) {
      this->c = ch;
      for (int i = 0; i < 26; i++) this->ch[i] = NULL;
    }
  };
  Node* root;
  vector<pair<int, int> > res;
  int sum;
  Trie() {
    root = new Node(' ');
    sum = 0;
  }
  void create(string s, int t, int ind) {
    Node* now = root;
    for (int i = 0; i < s.size(); i++) {
      if (now->ch[s[i] - 'a'] == NULL)
        now = now->ch[s[i] - 'a'] = new Node(s[i]);
      else
        now = now->ch[s[i] - 'a'];
    }
    (now->n).push_back(make_pair(ind, t));
  }
  pair<vector<int>, vector<int> > dfs(Node* now, int depth) {
    vector<int> O, P;
    for (int i = 0; i < 26; i++)
      if (now->ch[i] != NULL) {
        pair<vector<int>, vector<int> > t = dfs(now->ch[i], depth + 1);
        O.insert(O.end(), t.first.begin(), t.first.end());
        P.insert(P.end(), t.second.begin(), t.second.end());
      }
    vector<pair<int, int> > t = now->n;
    for (int i = 0; i < t.size(); i++)
      if (t[i].second == 1)
        O.push_back(t[i].first);
      else if (t[i].second == 2)
        P.push_back(t[i].first);
    while (O.size() && P.size()) {
      sum += depth;
      res.push_back(make_pair(O[0], P[0]));
      O.erase(O.begin());
      P.erase(P.begin());
    }
    return make_pair(O, P);
  }
  void doit() {
    dfs(root, 0);
    printf("%d\n", sum);
    for (int i = 0; i < res.size(); i++)
      printf("%d %d\n", res[i].first, res[i].second);
  }
};
int main() {
  Trie trie;
  string s;
  int n;
  scanf("%d\n", &n);
  for (int i = 1; i <= 2; i++)
    for (int j = 1; j <= n; j++) {
      cin >> s;
      trie.create(s, i, j);
    }
  trie.doit();
}
