#include <bits/stdc++.h>
using namespace std;
const int MAXN = 800010;
const int MAXL = 800010;
struct node {
  list<int> student_names;
  list<int> pseudo_names;
  int next[26];
  int how_many = 0;
} nodes[MAXN];
int total = 0;
int root = 1, total_nodes = 1;
void insert(char word[], int name_id, bool type) {
  int n = strlen(word);
  total -= n;
  int current_id = root;
  for (int i = 0; i < n; ++i) {
    int next_index = word[i] - 'a';
    if (nodes[current_id].next[next_index] == 0) {
      nodes[current_id].next[next_index] = ++total_nodes;
    }
    current_id = nodes[current_id].next[next_index];
  }
  if (type) {
    nodes[current_id].student_names.push_back(name_id);
  } else {
    nodes[current_id].pseudo_names.push_back(name_id);
  }
  nodes[current_id].how_many++;
}
list<pair<int, int> > name_pseudo_pairs;
void print_trie(int node_id, char character) {
  printf("Node(%c)[%d] : ", character + 'a', node_id);
  for (int i = 0; i < 26; i++)
    if (nodes[node_id].next[i] != 0) printf("%d ", nodes[node_id].next[i]);
  printf("\n");
  for (int i = 0; i < 26; i++)
    if (nodes[node_id].next[i] != 0) print_trie(nodes[node_id].next[i], i);
}
void print_list(list<int>& mlist) {
  for (list<int>::iterator it = mlist.begin(); it != mlist.end(); ++it) {
    printf("%d ", *it);
  }
  printf("\n");
}
int dfs(int node_id) {
  list<int> tmp_names;
  list<int> tmp_pseudo;
  int sum = nodes[node_id].how_many;
  for (int i = 0; i < 26; ++i) {
    int current_id = nodes[node_id].next[i];
    if (current_id != 0) {
      sum += dfs(current_id);
      nodes[node_id].student_names.splice(nodes[node_id].student_names.end(),
                                          nodes[current_id].student_names);
      nodes[node_id].pseudo_names.splice(nodes[node_id].pseudo_names.end(),
                                         nodes[current_id].pseudo_names);
    }
  }
  while (!nodes[node_id].student_names.empty() &&
         !nodes[node_id].pseudo_names.empty()) {
    name_pseudo_pairs.push_back(make_pair(nodes[node_id].student_names.back(),
                                          nodes[node_id].pseudo_names.back()));
    nodes[node_id].pseudo_names.pop_back();
    nodes[node_id].student_names.pop_back();
    sum -= 2;
  }
  total += sum;
  return sum;
}
int main() {
  int N;
  scanf("%d\n", &N);
  char tmp_word[MAXL];
  for (int i = 0; i < N; i++) {
    gets(tmp_word);
    insert(tmp_word, i + 1, true);
  }
  for (int i = 0; i < N; i++) {
    gets(tmp_word);
    insert(tmp_word, i + 1, false);
  }
  dfs(1);
  printf("%d\n", -total / 2);
  for (list<pair<int, int> >::iterator it = name_pseudo_pairs.begin();
       it != name_pseudo_pairs.end(); ++it) {
    int name = (*it).first;
    int pseudo = (*it).second;
    printf("%d %d\n", name, pseudo);
  }
  return 0;
}
