#include <bits/stdc++.h>
using namespace std;
int n, m, k;
long long w;
char arr[1001][11][11];
bool done[1001][1001];
int parent[1001];
bool visited[1001];
int ra[1001];
int fi(int x) {
  if (parent[x] == x) return x;
  return parent[x] = fi(parent[x]);
}
bool uni(int x, int y) {
  int px = fi(x), py = fi(y);
  if (px == py) return false;
  if (ra[px] > ra[py]) {
    parent[py] = px;
  } else if (ra[px] < ra[py]) {
    parent[px] = py;
  } else {
    parent[py] = px;
    ra[px]++;
  }
  return true;
}
vector<pair<long long, pair<int, int> > > edges;
vector<int> nodes[1001];
int main() {
  ios::sync_with_stdio(false);
  cin >> n >> m >> k >> w;
  for (int i = 0; i <= k; i++) {
    ra[i] = 0;
    parent[i] = i;
  }
  for (int i = 1; i <= k; i++) {
    for (int j = 0; j < n; j++) cin >> arr[i][j];
    edges.push_back({n * m, {i, 0}});
    for (int j = 1; j < i; j++) {
      long long c = 0;
      for (int ti = 0; ti < n; ti++) {
        for (int tj = 0; tj < m; tj++) {
          if (arr[i][ti][tj] != arr[j][ti][tj]) c++;
        }
      }
      edges.push_back({c * w, {i, j}});
    }
  }
  sort(edges.begin(), edges.end());
  int s = edges.size();
  long long ans = 0;
  for (int a = 0; a < s; a++) {
    int i = edges[a].second.first;
    int j = edges[a].second.second;
    long long c = edges[a].first;
    if (uni(i, j)) {
      ans += c;
      nodes[i].push_back(j);
      nodes[j].push_back(i);
    }
  }
  cout << ans << endl;
  queue<int> q;
  q.push(0);
  while (!q.empty()) {
    int i = q.front();
    q.pop();
    if (visited[i]) continue;
    visited[i] = true;
    int s = nodes[i].size();
    for (int a = 0; a < s; a++) {
      int j = nodes[i][a];
      if (!done[i][j]) {
        cout << j << " " << i << endl;
        done[i][j] = true, done[j][i] = true;
        q.push(j);
      }
    }
  }
  return 0;
}
