#include <bits/stdc++.h>
using namespace std;
const int inf = 0x7fffffff;
int n, m, k, w;
char arr[1005][15][15];
int diff(int a, int b) {
  int ret = 0;
  for (int i = 0, _n = (n); i < _n; ++i)
    for (int j = 0, _n = (m); j < _n; ++j)
      if (arr[a][i][j] != arr[b][i][j]) ret++;
  return ret;
}
int p[1005], r[1005];
void link(int x, int y) {
  if (r[x] == r[y]) r[x]++;
  if (r[x] < r[y])
    p[x] = y;
  else
    p[y] = x;
}
int find(int x) {
  if (p[x] != x) p[x] = find(p[x]);
  return p[x];
}
struct tdata {
  int x, y, c;
};
bool operator<(const tdata &a, const tdata &b) { return a.c > b.c; }
int dist[1005][1005];
int main() {
  scanf("%d %d %d %d\n", &n, &m, &k, &w);
  for (int i = (1), _b = (k); i <= _b; ++i)
    for (int j = 0, _n = (n); j < _n; ++j) scanf("%s", arr[i][j]);
  for (int i = (1), _b = (k); i <= _b; ++i)
    for (int j = (1), _b = (k); j <= _b; ++j) dist[i][j] = diff(i, j);
  int cost[1005];
  for (int i = (1), _b = (k); i <= _b; ++i) cost[i] = inf;
  priority_queue<tdata> pq;
  for (int i = (1), _b = (k); i <= _b; ++i) pq.push((tdata){i, 0, n * m});
  bool done[1005] = {false};
  int ans = 0;
  vector<pair<int, int> > out;
  while (!pq.empty()) {
    tdata p = pq.top();
    pq.pop();
    if (done[p.x]) continue;
    out.push_back(make_pair(p.x, p.y));
    ans += p.c;
    done[p.x] = true;
    for (int i = (1), _b = (k); i <= _b; ++i)
      if (!done[i] && dist[p.x][i] * w < cost[i]) {
        cost[i] = dist[p.x][i] * w;
        pq.push((tdata){i, p.x, cost[i]});
      }
  }
  printf("%d\n", ans);
  for (int i = 0, _n = (out.size()); i < _n; ++i)
    printf("%d %d\n", out[i].first, out[i].second);
  return 0;
}
