#include <bits/stdc++.h>
using namespace std;
const int N = 3050;
int F[N][N];
char buf[N];
vector<int> row[N];
short S[N][N];
inline short get(int y1, int x1, int y2, int x2) {
  return S[y2][x2] + S[y1][x1] - S[y2][x1] - S[y1][x2];
}
int A[N];
int n, m, k;
short to_L[N], to_R[N];
short path[N];
int pt = 0;
inline short getL(short x) {
  if (x == -1) return -1;
  if (to_L[x] == -1 || A[to_L[x]]) return to_L[x];
  pt = 0;
  path[pt++] = x;
  while (true) {
    x = to_L[x];
    if (x == -1 || A[x] != 0)
      break;
    else
      path[pt++] = x;
  }
  for (int i = 0; i < pt - 1; i++) to_L[path[i]] = x;
  return x;
}
short getR(short x) {
  if (x == m) return m;
  if (to_R[x] == m || A[to_R[x]]) return to_R[x];
  pt = 0;
  path[pt++] = x;
  while (true) {
    x = to_R[x];
    if (x == m || A[x] != 0)
      break;
    else
      path[pt++] = x;
  }
  for (int i = 0; i < pt - 1; i++) to_R[path[i]] = x;
  return x;
}
vector<short> visited;
short Rpos[N];
short calcRpos(short x, bool write = false) {
  if (write) visited.clear();
  short cur = 0;
  while (true) {
    if (write) visited.push_back(x);
    if (x == m) return m;
    cur += A[x];
    if (cur >= k) {
      visited.push_back(getR(x));
      return x;
    }
    x = getR(x);
  }
  assert(false);
}
short calcLpos(short x, bool write = false) {
  if (write) visited.clear();
  short cur = 0;
  while (true) {
    if (write) visited.push_back(x);
    if (x == -1) return -1;
    cur += A[x];
    if (cur >= k) {
      visited.push_back(getL(x));
      return x;
    }
    x = getL(x);
  }
  assert(false);
}
int used[N];
int curver = 0;
long long start(short r) {
  for (short j = 0; j < m; j++) {
    A[j] = get(r, j, n, j + 1);
  }
  short lst = m;
  for (short j = m - 1; j >= 0; j--) {
    to_R[j] = lst;
    if (A[j]) lst = j;
  }
  lst = -1;
  for (short j = 0; j < m; j++) {
    to_L[j] = lst;
    if (A[j]) lst = j;
  }
  for (short j = 0; j < m; j++) Rpos[j] = calcRpos(j);
  int curval = 0;
  for (short j = 0; j < m; j++) {
    if (A[j]) {
      short pj = getL(j);
      short from = Rpos[j];
      curval += (int)(j - pj) * (m - from);
    }
  }
  long long ans = 0;
  ans += curval;
  vector<short> interesting;
  for (int i = n - 1; i > r; i--) {
    interesting.clear();
    ++curver;
    for (short x : row[i]) {
      calcLpos(x, true);
      reverse(visited.begin(), visited.end());
      for (int w : visited) {
        if (w == -1 || used[w] == curver) continue;
        used[w] = curver;
        interesting.push_back(w);
      }
      short r = getR(x);
      if (r != m && used[r] != curver) {
        used[r] = curver;
        interesting.push_back(r);
      }
    }
    for (short j : interesting) {
      short pj = getL(j);
      short from = Rpos[j];
      curval -= (int)(j - pj) * (m - from);
    }
    for (short x : row[i]) {
      A[x]--;
    }
    short lst = -1;
    for (int j : interesting) {
      if (!A[j]) continue;
      short pj = getL(j);
      Rpos[j] = max(Rpos[j], lst);
      while (true) {
        short nrpos = getR(Rpos[j]);
        if (Rpos[j] == m || get(r, j, i, Rpos[j] + 1) >= k) {
          break;
        } else {
          Rpos[j] = nrpos;
        }
      }
      lst = Rpos[j];
      short from = Rpos[j];
      curval += (int)(j - pj) * (m - from);
    }
    ans += curval;
  }
  return ans;
}
int main() {
  int tmp;
  scanf("%d %d %d %d ", &n, &m, &tmp, &k);
  for (int i = 0; i < tmp; i++) {
    int y, x;
    scanf("%d %d", &y, &x);
    --y, --x;
    F[y][x] = 1;
    row[y].push_back(x);
  }
  for (int i = 0; i < n; i++) {
    sort(row[i].begin(), row[i].end());
  }
  for (int i = 0; i < n; i++) {
    for (int j = 0; j < m; j++) {
      S[i + 1][j + 1] = S[i + 1][j] + S[i][j + 1] - S[i][j] + F[i][j];
    }
  }
  long long ans = 0;
  long long last = start(n - 1);
  ans = last;
  for (int i = n - 2; i >= 0; i--) {
    if (i % 10 == 0) {
    }
    if (row[i].empty())
      ans += last;
    else {
      ans += (last = start(i));
    }
  }
  printf("%lld\n", ans);
}
