#include <bits/stdc++.h>
using namespace std;
const long long INFll = 1ll * 1000 * 1000 * 1000 * 1000 * 1000 * 1000;
const int MOD = 1000 * 1000 * 1000 + 7;
const int DVP = 101010;
const int sdx[8] = {0, 1, 1, 1, 0, -1, -1, -1};
const int sdy[8] = {1, 1, 0, -1, -1, -1, 0, 1};
struct edge {
  int a, b, c;
};
vector<edge> g;
bool used[1500];
vector<pair<int, int> > ng[1500], v_ans;
char a[1500][100][100];
int p[1500];
bool comp(edge a, edge b) { return (a.c < b.c); }
int get(int v) { return (p[v] == v ? v : p[v] = get(p[v])); }
int unite(int a, int b) {
  if (rand() & 1) swap(a, b);
  if (a != b) p[a] = b;
}
void dfs(int v) {
  used[v] = true;
  for (int i = 0; i < ng[v].size(); i++) {
    int to = ng[v][i].first, c = ng[v][i].second;
    if (!used[to]) {
      v_ans.push_back(make_pair(to + 1, v + 1));
      used[to] = true;
      dfs(to);
    }
  }
}
int main() {
  int n, m, k, w;
  scanf("%d%d%d%d\n", &n, &m, &k, &w);
  for (int t = 0; t < k; t++)
    for (int i = 0; i < n; i++) {
      for (int j = 0; j < m; j++) scanf("%c", &a[t][i][j]);
      scanf("\n");
    }
  for (int t = 0; t < k; t++)
    for (int l = t + 1; l < k; l++) {
      int cnt = 0;
      for (int i = 0; i < n; i++)
        for (int j = 0; j < m; j++)
          if (a[t][i][j] != a[l][i][j]) cnt++;
      edge e = {t, l, cnt * w};
      g.push_back(e);
    }
  sort(g.begin(), g.end(), comp);
  for (int i = 0; i < k; i++) p[i] = i;
  int ans = 0;
  for (int i = 0; i < g.size(); i++) {
    int a = g[i].a, b = g[i].b, c = g[i].c;
    if (n * m <= c) break;
    if (get(a) != get(b)) {
      ng[a].push_back(make_pair(b, c));
      ng[b].push_back(make_pair(a, c));
      ans += c;
      unite(get(a), get(b));
    }
  }
  for (int i = 0; i < k; i++)
    if (!used[i]) {
      v_ans.push_back(make_pair(i + 1, 0));
      ans += n * m;
      dfs(i);
    }
  printf("%d\n", ans);
  for (int i = 0; i < v_ans.size(); i++)
    printf("%d %d\n", v_ans[i].first, v_ans[i].second);
  return 0;
}
