#include <bits/stdc++.h>
using namespace std;
const int MAXN = 1000 + 10;
int par[MAXN], _rank[MAXN], n, m;
long long d[MAXN][MAXN], k, w;
vector<int> adj[MAXN];
vector<pair<int, pair<int, int> > > vec;
char a[MAXN][10][10];
void dfs(int v, int p) {
  if (p != -1) cout << v << ' ' << p << endl;
  for (auto u : adj[v])
    if (u != p) dfs(u, v);
}
int find(int a) {
  if (par[a] == a) return a;
  return par[a] = find(par[a]);
}
void _union(int a, int b) {
  int r1 = find(a), r2 = find(b);
  if (_rank[r1] < _rank[r2]) swap(r1, r2);
  par[r2] = r1;
  if (_rank[r1] == _rank[r2]) _rank[r1]++;
  return;
}
int32_t main() {
  ios_base::sync_with_stdio(0);
  cin.tie(0), cout.tie(0);
  cin >> 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++) cin >> a[t + 1][i][j];
    }
  }
  for (int i = 1; i <= k; i++)
    d[0][i] = n * m, vec.push_back({d[0][i], {0, i}});
  for (int i = 1; i <= k; i++)
    for (int j = i + 1; j <= k; j++) {
      for (int l = 0; l < n; l++)
        for (int o = 0; o < m; o++) d[i][j] += (a[i][l][o] != a[j][l][o]) * w;
      vec.push_back({d[i][j], {i, j}});
    }
  sort(vec.begin(), vec.end());
  long long cnt = 0;
  for (int i = 0; i <= k; i++) par[i] = i;
  for (int i = 0; i < (int)vec.size(); i++) {
    auto e = vec[i];
    int w = e.first, u = e.second.first, v = e.second.second;
    if (find(u) != find(v)) {
      cnt += w;
      adj[u].push_back(v), adj[v].push_back(u);
      _union(u, v);
    }
  }
  cout << cnt << endl;
  dfs(0, -1);
  return 0;
}
