#include <bits/stdc++.h>
using namespace std;
long long int n, m, k, w;
char arr[1000][10][10];
vector<pair<long long int, pair<long long int, long long int>>> edge_list;
long long int parent[1001];
long long int size[1001];
vector<long long int> adj[1001];
bool v[1001];
long long int par[1001];
void dfs(long long int second) {
  v[second] = 1;
  if (second != 0) {
    cout << second << " " << par[second] << "\n";
  }
  for (auto &e : adj[second]) {
    if (v[e] == 0) {
      par[e] = second;
      dfs(e);
    }
  }
}
void make_set(long long int v) {
  parent[v] = v;
  size[v] = 1;
}
long long int find_set(long long int v) {
  if (v == parent[v]) return v;
  return parent[v] = find_set(parent[v]);
}
void union_sets(long long int a, long long int b) {
  a = find_set(a);
  b = find_set(b);
  if (a != b) {
    if (size[a] < size[b]) swap(a, b);
    parent[b] = a;
    size[a] += size[b];
  }
}
bool comp(const pair<long long int, pair<long long int, long long int>> &a,
          const pair<long long int, pair<long long int, long long int>> &b) {
  return a.first < b.first;
}
int main() {
  cin >> n >> m >> k >> w;
  for (long long int i = 0; i < k; i++) {
    for (long long int j = 0; j < n; j++) {
      for (long long int first = 0; first < m; first++) {
        cin >> arr[i][j][first];
      }
    }
  }
  for (long long int i = 0; i < k; i++) {
    for (long long int j = 0; j < i; j++) {
      long long int weight = 0;
      for (long long int first = 0; first < n; first++) {
        for (long long int p = 0; p < m; p++) {
          if (arr[i][first][p] != arr[j][first][p]) weight++;
        }
      }
      weight *= w;
      edge_list.push_back(make_pair(weight, make_pair(i + 1, j + 1)));
    }
    edge_list.push_back(make_pair(m * n, make_pair(0, i + 1)));
  }
  for (long long int i = 0; i <= k; i++) make_set(i);
  sort(edge_list.begin(), edge_list.end(), comp);
  long long int edges = 0;
  long long int total = 0;
  long long int si = edge_list.size();
  for (long long int i = 0; i < si; i++) {
    long long int w = edge_list[i].first;
    long long int u = edge_list[i].second.first;
    long long int v = edge_list[i].second.second;
    if (find_set(u) != find_set(v)) {
      union_sets(u, v);
      adj[u].push_back(v);
      adj[v].push_back(u);
      edges++;
      total += w;
      if (edges == k) break;
    }
  }
  cout << total << "\n";
  par[0] = -1;
  dfs(0);
  return 0;
}
