#include <bits/stdc++.h>
using namespace std;
vector<pair<int, pair<int, int> > > v;
char s[1003][10][10];
int n, m;
int diff(int x, int y) {
  int i, j;
  int ret = 0;
  for (i = 0; i < n; i++) {
    for (j = 0; j < m; j++) {
      ret += (s[x][i][j] != s[y][i][j]);
    }
  }
  return ret;
}
int par[2000];
int findpar(int x) {
  if (par[x] == x) return x;
  return par[x] = findpar(par[x]);
}
int merge(int x, int y) {
  x = findpar(x);
  y = findpar(y);
  if (x == y) return 0;
  if (rand() % 2)
    par[x] = y;
  else
    par[y] = x;
  return 1;
}
vector<int> g[2005];
void dfs(int cnode, int par) {
  if (cnode != 0) {
    printf("%d %d\n", cnode, par);
  }
  for (int i = 0; i < (int)g[cnode].size(); i++) {
    if (g[cnode][i] == par) continue;
    dfs(g[cnode][i], cnode);
  }
}
int main() {
  int i, k, w;
  cin >> n >> m >> k >> w;
  for (i = 0; i < 2000; i++) par[i] = i;
  for (i = 1; i <= k; i++) {
    v.push_back(make_pair(n * m, make_pair(0, i)));
    for (int j = 0; j < n; j++) {
      scanf(" %s", s[i][j]);
    }
    for (int j = 1; j < i; j++) {
      int cdiff = diff(i, j) * w;
      if (cdiff <= n * m) {
        v.push_back(make_pair(cdiff, make_pair(i, j)));
      }
    }
  }
  sort(v.begin(), v.end());
  int cost = 0;
  for (i = 0; i < (int)v.size(); i++) {
    if (merge(v[i].second.first, v[i].second.second)) {
      cost += v[i].first;
      g[v[i].second.first].push_back(v[i].second.second);
      g[v[i].second.second].push_back(v[i].second.first);
    }
  }
  cout << cost << endl;
  dfs(0, 0);
  return 0;
}
