#include <bits/stdc++.h>
using namespace std;
#pragma comment(linker, "/STACK:16777216")
const int inf = 0x3f3f3f3f;
const long long int INF = 100000000000001ll;
const string debug_line = "yolo";
const double PI = 4 * atan(1);
char s[800011];
int trie[800011][26];
int count1[800011];
int count2[800011];
vector<int> ispresent1[800011];
vector<int> ispresent2[800011];
int node_count = 1;
bool visited[800010];
int matched[800010];
vector<int> order1;
vector<int> order2;
void DFS(int u, int p) {
  for (int(i) = (0); (i) < (26); ++(i)) {
    if (trie[u][i] != -1) {
      DFS(trie[u][i], u);
    }
  }
  int index1 = (int)ispresent1[u].size() - 1;
  int index2 = (int)ispresent2[u].size() - 1;
  while (index1 >= 0 && index2 >= 0) {
    matched[ispresent1[u][index1]] = ispresent2[u][index2];
    index1--;
    index2--;
  }
  while (index1 >= 0) {
    ispresent1[p].push_back(ispresent1[u][index1]);
    index1--;
  }
  while (index2 >= 0) {
    ispresent2[p].push_back(ispresent2[u][index2]);
    index2--;
  }
}
void fill_num(int n) {
  for (int(i) = (1); (i) < (n + 1); ++(i)) {
    scanf("%s", s);
    int begin1 = 1;
    int l1 = strlen(s);
    for (int(j) = (0); (j) < (l1); ++(j)) {
      if (trie[begin1][s[j] - 'a'] == -1) {
        trie[begin1][s[j] - 'a'] = ++node_count;
        begin1 = node_count;
        if (j == l1 - 1) {
          ispresent1[begin1].push_back(i);
        }
        count1[begin1]++;
      } else {
        begin1 = trie[begin1][s[j] - 'a'];
        if (j == l1 - 1) {
          ispresent1[begin1].push_back(i);
        }
        count1[begin1]++;
      }
    }
  }
  for (int(i) = (1); (i) < (n + 1); ++(i)) {
    scanf("%s", s);
    int begin1 = 1;
    int l1 = strlen(s);
    for (int(j) = (0); (j) < (l1); ++(j)) {
      if (trie[begin1][s[j] - 'a'] == -1) {
        trie[begin1][s[j] - 'a'] = ++node_count;
        begin1 = node_count;
        if (j == l1 - 1) {
          ispresent2[begin1].push_back(i);
        }
        count2[begin1]++;
      } else {
        begin1 = trie[begin1][s[j] - 'a'];
        if (j == l1 - 1) {
          ispresent2[begin1].push_back(i);
        }
        count2[begin1]++;
      }
    }
  }
  long long answer1 = 0;
  for (int(i) = (0); (i) < (800001); ++(i)) {
    answer1 = answer1 + (long long)(min(count1[i], count2[i]));
  }
  printf("%lld\n", answer1);
  DFS(1, 1);
  for (int(i) = (1); (i) < (n + 1); ++(i)) {
    printf("%d %d\n", i, matched[i]);
  }
}
int main() {
  int n;
  scanf("%d", &n);
  for (int(i) = (0); (i) < (800001); ++(i)) {
    for (int(j) = (0); (j) < (26); ++(j)) {
      trie[i][j] = -1;
    }
  }
  fill_num(n);
  return 0;
}
