#include <bits/stdc++.h>
using namespace std;
class Node {
 public:
  char letter;
  Node *parent;
  Node *children[27];
  int left, right;
  Node() {
    for (int i = 0; i < 27; i++) {
      children[i] = NULL;
    }
    left = 0;
    right = 0;
    letter = '*';
  }
};
class Answer {
 public:
  int sum;
  string word1, word2;
};
Node *match(Node *n) {
  bool cont = false;
  for (int i = 0; i < 26; i++) {
    if (n->children[i] != NULL) {
      if ((n->children[i])->right and (n->children[i])->left) {
        return match((n->children[i]));
        cont = true;
      }
    }
  }
  if (!cont) {
    return n;
  }
}
Answer getLength(Node *n) {
  string a, b;
  string prefix;
  Node *cur = n;
  while (cur->letter != '*') {
    prefix.push_back(cur->letter);
    cur = cur->parent;
    cur->left--;
    cur->right--;
  }
  reverse(prefix.begin(), prefix.end());
  n->left--;
  cur = n;
  bool cont;
  do {
    cont = false;
    for (int i = 0; i < 26 and !cont; i++) {
      if (cur->children[i] != NULL and (cur->children[i])->left) {
        cur = cur->children[i];
        cur->left--;
        a.push_back(cur->letter);
        cont = true;
      }
    }
  } while (cont);
  n->right--;
  cur = n;
  do {
    cont = false;
    for (int i = 0; i < 26 and !cont; i++) {
      if (cur->children[i] != NULL and (cur->children[i])->right) {
        cur = cur->children[i];
        cur->right--;
        b.push_back(cur->letter);
        cont = true;
      }
    }
  } while (cont);
  a = prefix + a;
  b = prefix + b;
  Answer ans;
  ans.sum = prefix.size();
  ans.word1 = a;
  ans.word2 = b;
  return ans;
}
int main() {
  int n;
  Node root;
  cin >> n;
  unordered_multimap<string, int> names1;
  for (int q = 0; q < n; q++) {
    string str;
    cin >> str;
    names1.insert({{str, q + 1}});
    Node *cur = &root;
    root.left++;
    for (string::iterator it = str.begin(); it != str.end(); ++it) {
      if (cur->children[char(*it) - 'a'] != NULL) {
        cur->children[char(*it) - 'a']->left++;
      } else {
        Node *node = new Node;
        ;
        node->parent = cur;
        cur->children[char(*it) - 'a'] = node;
        node->left++;
        node->letter = char(*it);
      }
      cur = cur->children[char(*it) - 'a'];
    }
  }
  unordered_multimap<string, int> names2;
  for (int q = 0; q < n; q++) {
    string str;
    cin >> str;
    names2.insert({{str, q + 1}});
    Node *cur = &root;
    root.right++;
    for (string::iterator it = str.begin(); it != str.end(); ++it) {
      if (cur->children[char(*it) - 'a'] != NULL) {
        cur->children[char(*it) - 'a']->right++;
      } else {
        Node *node = new Node;
        ;
        node->parent = cur;
        cur->children[char(*it) - 'a'] = node;
        node->right++;
        node->letter = char(*it);
      }
      cur = cur->children[char(*it) - 'a'];
    }
  }
  Node *cur;
  int sum = 0;
  vector<int> output(n * 2);
  for (int q = 0; q < n; q++) {
    cur = match(&root);
    Answer ans = getLength(cur);
    sum += ans.sum;
    output[q * 2] = (*(names1.find(ans.word1))).second;
    names1.erase(names1.find(ans.word1));
    output[q * 2 + 1] = (*(names2.find(ans.word2))).second;
    names2.erase(names2.find(ans.word2));
  }
  cout << sum << "\n";
  for (int q = 0; q < n; q++) {
    cout << output[q * 2] << " " << output[q * 2 + 1] << "\n";
  }
  return 0;
}
