#include <bits/stdc++.h>
using namespace std;
const int N = 1010;
int n, m, k, wt;
int ufs[N];
struct flat {
  char s[110];
  void init() {
    int q = 1;
    for (int i = 1; i <= n; ++i) {
      scanf("%s", s + q);
      q += m;
    }
  }
} ft[N];
struct eset {
  int u, v, w;
} es[N * N];
int esp;
struct edge {
  int to, nx;
} ee[N * 2];
int eq[N], en = 1, vis[N];
bool cmp_es(const eset& a, const eset& b) { return a.w < b.w; }
int gef(int u) { return (ufs[u] == u) ? u : (ufs[u] = gef(ufs[u])); }
int dist(const flat& a, const flat& b) {
  int res = 0;
  for (int i = 1; i <= n * m; ++i) res += (a.s[i] != b.s[i]);
  return res;
}
void link(int u, int v) { ee[++en] = (edge){v, eq[u]}, eq[u] = en; }
void dfs(int u, int p) {
  vis[u] = 1;
  printf("%d %d\n", u, p);
  for (int j = eq[u], v; v = ee[j].to, j; j = ee[j].nx)
    if (!vis[v] && v != p) {
      dfs(v, u);
    }
}
void workans(int ntot) {
  for (int i = 1; i <= k; ++i) ufs[i] = i;
  int tot = k;
  for (int i = 1; i <= esp && tot != ntot; ++i) {
    int u = es[i].u;
    int v = es[i].v;
    if (gef(u) != gef(v)) {
      ufs[ufs[u]] = ufs[v];
      link(u, v);
      link(v, u);
      --tot;
    }
  }
  for (int i = 1; i <= k; ++i)
    if (!vis[i]) {
      dfs(i, 0);
    }
}
int main() {
  scanf("%d %d %d %d", &n, &m, &k, &wt);
  for (int i = 1; i <= k; ++i) ft[i].init();
  for (int i = 1; i <= k; ++i)
    for (int j = i + 1; j <= k; ++j) {
      es[++esp] = (eset){i, j, dist(ft[i], ft[j])};
    }
  sort(es + 1, es + esp + 1, cmp_es);
  for (int i = 1; i <= k; ++i) ufs[i] = i;
  int tot = k, pay = 0;
  int ans = n * m * k, bst = k;
  for (int i = 1; i <= esp; ++i) {
    int u = es[i].u;
    int v = es[i].v;
    if (gef(u) != gef(v)) {
      ufs[ufs[u]] = ufs[v];
      --tot;
      pay += es[i].w * wt;
    }
    int cur = n * m * tot + pay;
    if (cur < ans) {
      ans = cur;
      bst = tot;
    }
  }
  printf("%d\n", ans);
  workans(bst);
}
