#include <bits/stdc++.h>
using namespace std;
long long int n, m, k, w, l, parent[10010];
pair<long long int, pair<long long int, long long int> > p[1001000];
vector<long long int> adj[10010];
void make_set() {
  for (long long int i = 0; i <= k; i++) parent[i] = i;
}
long long int find(long long int x) {
  if (parent[x] == x) return x;
  return parent[x] = find(parent[x]);
}
void unioni(long long int x, long long int y) {
  long long int first = find(x);
  long long int second = find(y);
  parent[first] = parent[second];
}
void dfs(long long int u, long long int par = -1) {
  for (auto v : adj[u]) {
    if (v != par) {
      cout << v << " " << u << endl;
      dfs(v, u);
    }
  }
}
void Kruskal() {
  long long int x, y, cost, minicost = 0, i;
  for (i = 0; i < l; i++) {
    x = p[i].second.first;
    y = p[i].second.second;
    cost = p[i].first;
    if (find(x) != find(y)) {
      minicost += cost;
      adj[x].push_back(y);
      adj[y].push_back(x);
      unioni(x, y);
    }
  }
  cout << minicost << endl;
  dfs(0);
}
int main() {
  ios_base::sync_with_stdio(false);
  cin.tie(NULL);
  cout.tie(NULL);
  ;
  long long int i, j, u, v;
  cin >> n >> m >> k >> w;
  char node[10010][11][11];
  for (i = 1; i <= k; i++) {
    for (j = 0; j < n; j++) {
      for (l = 0; l < m; l++) {
        cin >> node[i][j][l];
      }
    }
  }
  l = 0;
  make_set();
  for (i = 1; i <= k; i++) {
    p[l++] = {n * m, {0, i}};
  }
  for (i = 1; i <= k; i++) {
    for (j = i + 1; j <= k; j++) {
      long long int x = 0;
      for (u = 0; u < n; u++) {
        for (v = 0; v < m; v++) {
          if (node[i][u][v] != node[j][u][v]) {
            x++;
          }
        }
      }
      p[l++] = {min(x * w, n * m), {i, j}};
    }
  }
  sort(p, p + l);
  Kruskal();
  return 0;
}
