#include <bits/stdc++.h>
using namespace std;
const int maxn = 1010;
long long mapp[maxn][maxn];
long long G[maxn][maxn], G2[maxn][maxn], M_G[maxn][maxn];
long long n, m, a, b;
multiset<long long> S;
struct node {
  long long v, x, y;
} tt[maxn * maxn], ans[maxn * maxn];
bool cmp(node a, node b) {
  return a.v < b.v || ((a.v == b.v) && a.x < b.x) ||
         ((a.v == b.v) && (a.x == b.x) && (a.y < b.y));
}
long long vis[maxn][maxn];
int main() {
  scanf("%lld%lld%lld%lld", &n, &m, &a, &b);
  for (int i = 1; i <= n; i++)
    for (int j = 1; j <= m; j++) scanf("%lld", &mapp[i][j]);
  for (int i = 1; i <= n; i++) {
    long long cur = 1, sum = 0;
    S.clear();
    for (int j = 1; j <= m; j++) {
      S.insert(mapp[i][j]);
      sum += mapp[i][j];
      if (S.size() > b) S.erase(S.find(mapp[i][j - b])), sum -= mapp[i][j - b];
      if (S.size() == b) G[i][cur] = sum, M_G[i][cur++] = *S.begin();
    }
  }
  for (int j = 1; j <= m - b + 1; j++) {
    long long cur = 1, sum = 0;
    S.clear();
    for (int i = 1; i <= n; i++) {
      S.insert(M_G[i][j]);
      sum += G[i][j];
      if (S.size() > a) S.erase(S.find(M_G[i - a][j])), sum -= G[i - a][j];
      if (S.size() == a) G2[cur++][j] = sum - a * b * (*S.begin());
    }
  }
  long long cur = 0;
  memset(vis, 0, sizeof(vis));
  for (int i = 1; i <= n - a + 1; i++) {
    for (int j = 1; j <= m - b + 1; j++) tt[cur++] = (node){G2[i][j], i, j};
  }
  sort(tt, tt + cur, cmp);
  long long tot = 0;
  for (int i = 0; i < cur; i++)
    if (!vis[tt[i].x][tt[i].y]) {
      ans[tot].x = tt[i].x, ans[tot].y = tt[i].y, ans[tot++].v = tt[i].v;
      for (int x = max(1LL, tt[i].x - a + 1); x <= tt[i].x + a - 1; x++)
        for (int y = max(1LL, tt[i].y - b + 1); y <= tt[i].y + b - 1; y++)
          vis[x][y] = 1;
    }
  printf("%lld\n", tot);
  for (int i = 0; i < tot; i++)
    printf("%lld %lld %lld\n", ans[i].x, ans[i].y, ans[i].v);
  return 0;
}
