#include <bits/stdc++.h>
using namespace std;
const int mod = 1000000007;
struct edge {
  int u, v, val;
  bool operator<(const edge &x) const { return val < x.val; }
} e[1005 * 1005];
char mp[1005][11][11];
vector<int> g[1005];
vector<int> cost[1005];
int rt[1005];
int find(int x) {
  if (rt[x] == x) return x;
  return rt[x] = find(rt[x]);
}
int w, foo, ans;
int buf[1005][2], sz;
void dfs(int u, int fa, int c) {
  if (fa != -1 && c * w < foo)
    buf[sz][1] = fa + 1, buf[sz++][0] = u + 1, ans += c * w;
  else
    buf[sz][1] = 0, buf[sz++][0] = u + 1, ans += foo;
  int len = g[u].size();
  for (int i = 0; i < len; ++i)
    if (g[u][i] != fa) dfs(g[u][i], u, cost[u][i]);
}
int main() {
  int r, c, N;
  cin >> r >> c >> N >> w;
  int M = 0;
  foo = r * c;
  for (int i = 0; i < N; ++i) {
    for (int j = 0; j < r; ++j) scanf("%s", mp[i][j]);
    for (int j = 0; j < i; ++j) {
      int cnt = 0;
      for (int k = 0; k < r; ++k)
        for (int l = 0; l < c; ++l) cnt += mp[i][k][l] != mp[j][k][l];
      e[M].u = i, e[M].v = j, e[M].val = cnt;
      ++M;
    }
  }
  sort(e, e + M);
  for (int i = 0; i < N; ++i) rt[i] = i;
  for (int i = 0; i < M; ++i) {
    int u = e[i].u, v = e[i].v;
    int fu = find(u), fv = find(v);
    if (fu != fv) {
      rt[fu] = fv;
      g[u].push_back(v);
      g[v].push_back(u);
      cost[u].push_back(e[i].val);
      cost[v].push_back(e[i].val);
    }
  }
  dfs(0, -1, 0);
  printf("%d\n", ans);
  for (int i = 0; i < N; ++i) printf("%d %d\n", buf[i][0], buf[i][1]);
  return 0;
}
