#include <bits/stdc++.h>
using namespace std;
struct node {
  node() {
    for (int i = 0; i < 26; i++) l[i] = 0;
  }
  node* l[26];
  vector<int> ad;
};
struct tri {
  int N;
  node* root;
  tri() { root = new node(); }
  void insert(node* n, char* s, int ad) {
    if (*s == 0) {
      n->ad.push_back(ad);
    } else {
      int c = *s - 'a';
      if (!n->l[c]) n->l[c] = new node();
      insert(n->l[c], s + 1, ad);
    }
  }
  void solve(node* n, vector<int>& l, vector<int>& r,
             vector<pair<int, int> >& ans) {
    if (!n) return;
    for (int i = 0; i < 26; i++) {
      vector<int> L, R;
      solve(n->l[i], L, R, ans);
      for (int c : L) l.push_back(c);
      for (int c : R) r.push_back(c);
    }
    for (int c : n->ad) {
      if (c <= N)
        l.push_back(c);
      else
        r.push_back(c);
    }
    while (!l.empty() && !r.empty()) {
      ans.push_back(pair<int, int>(l.back(), r.back()));
      l.pop_back(), r.pop_back();
    }
  }
  void insert(char* s, int ad) { return insert(root, s, ad); }
  void solve(vector<pair<int, int> >& ans) {
    vector<int> l, r;
    return solve(root, l, r, ans);
  }
} T;
char buf[800005] = "";
string D[200005];
int main() {
  int N;
  scanf("%d", &N);
  T.N = N;
  for (int i = 1; i <= 2 * N; i++) {
    scanf("%s", buf);
    T.insert(buf, i);
    D[i] = buf;
  }
  vector<pair<int, int> > ans;
  T.solve(ans);
  int tot = 0;
  for (int i = 0; i < N; i++) {
    int x = ans[i].first, y = ans[i].second;
    for (int j = 0; j < D[x].size() && j < D[y].size(); j++, tot++) {
      if (D[x][j] != D[y][j]) break;
    }
  }
  printf("%d\n", tot);
  for (pair<int, int> c : ans) printf("%d %d\n", c.first, c.second - N);
  return 0;
}
