#include <bits/stdc++.h>
using namespace std;
const int max_n = 300;
int noise[max_n][max_n], N, M, Q;
char m[max_n][max_n];
bool viz[max_n][max_n];
void bfs(int row, int col) {
  queue<tuple<int, int, int>> q;
  q.emplace(row, col, (int)((m[row][col] - 'A' + 1) * Q));
  noise[row][col] += (m[row][col] - 'A' + 1) * Q;
  viz[row][col] = true;
  int dr[] = {0, 0, 1, -1};
  int dc[] = {1, -1, 0, 0};
  while (!q.empty()) {
    int row, col, n;
    tie(row, col, n) = q.front();
    q.pop();
    if (n == 0) continue;
    for (int k = 0; k < 4; ++k) {
      int new_r = row + dr[k];
      int new_c = col + dc[k];
      if (new_r >= 0 && new_r < N && new_c >= 0 && new_c < M &&
          !viz[new_r][new_c] && m[new_r][new_c] != '*') {
        noise[new_r][new_c] += n / 2;
        viz[new_r][new_c] = true;
        q.emplace(new_r, new_c, n / 2);
      }
    }
  }
}
int main() {
  int p;
  cin >> N >> M >> Q >> p;
  for (int i = 0; i < N; ++i) {
    cin >> m[i];
  }
  for (int i = 0; i < N; ++i) {
    for (int j = 0; j < M; ++j) {
      if (m[i][j] >= 'A' && m[i][j] <= 'Z') {
        memset(viz, 0, sizeof(viz));
        bfs(i, j);
      }
    }
  }
  int result = 0;
  for (int i = 0; i < N; ++i) {
    for (int j = 0; j < M; ++j) {
      if (noise[i][j] > p) {
        result++;
      }
    }
  }
  cout << result << endl;
  return 0;
}
