#include <bits/stdc++.h>
using namespace std;
const long double pi = acos(-1.0);
const long double eps = 1e-9;
const long long INF = 100000000000000;
const long long MAXN = 1024;
class Queue {
 public:
  void push(long long val) {
    long long mn = val;
    if (!s1.empty()) mn = min(mn, s1.top().second);
    s1.push(pair<long long, long long>(val, mn));
  }
  long long pop() {
    if (s2.empty()) {
      s2.push(pair<long long, long long>(s1.top().first, s1.top().first));
      s1.pop();
      while (!s1.empty()) {
        long long val = s1.top().first;
        long long mn = min(val, s2.top().second);
        s2.push(pair<long long, long long>(val, mn));
        s1.pop();
      }
    }
    long long res = s2.top().first;
    s2.pop();
    return res;
  }
  long long get_min() {
    long long res = INF;
    if (!s1.empty()) res = min(res, s1.top().second);
    if (!s2.empty()) res = min(res, s2.top().second);
    return res;
  }
  void clear() {
    while (!s1.empty()) s1.pop();
    while (!s2.empty()) s2.pop();
  }

 private:
  stack<pair<long long, long long> > s1, s2;
} q;
struct area {
  long long cost;
  long long x, y;
  area(long long cc, long long xx, long long yy) {
    cost = cc;
    x = xx;
    y = yy;
  }
};
bool cmp(const area& a, const area& b) {
  if (a.cost != b.cost) return a.cost < b.cost;
  if (a.x != b.x) return a.x < b.x;
  return a.y < b.y;
}
long long n, m, u, v;
long long min1[MAXN][MAXN];
long long min2[MAXN][MAXN];
bool used[MAXN][MAXN];
long long sum[MAXN][MAXN];
int a[MAXN][MAXN];
vector<area> areas;
vector<pair<long long, long long> > ans;
vector<long long> cost_ans;
int main() {
  cin >> n >> m >> u >> v;
  for (long long i = 1; i <= n; ++i)
    for (long long j = 1; j <= m; ++j) {
      scanf("%d", &a[i][j]);
      sum[i][j] = sum[i - 1][j] + sum[i][j - 1] - sum[i - 1][j - 1] + a[i][j];
    }
  for (long long j = 1; j <= m; ++j) {
    q.clear();
    for (long long i = 1; i <= u - 1; ++i) q.push(a[i][j]);
    for (long long i = u; i <= n; ++i) {
      q.push(a[i][j]);
      min1[i][j] = q.get_min();
      q.pop();
    }
  }
  for (long long i = u; i <= n; ++i) {
    q.clear();
    for (long long j = 1; j <= v - 1; ++j) q.push(min1[i][j]);
    for (long long j = v; j <= m; ++j) {
      q.push(min1[i][j]);
      min2[i][j] = q.get_min();
      q.pop();
    }
  }
  for (long long i = u; i <= n; ++i)
    for (long long j = v; j <= m; ++j) {
      long long c =
          (sum[i][j] - sum[i - u][j] - sum[i][j - v] + sum[i - u][j - v]) -
          (u * v) * min2[i][j];
      long long x = i - u + 1;
      long long y = j - v + 1;
      areas.push_back(area(c, x, y));
    }
  sort((areas).begin(), (areas).end(), cmp);
  for (long long i = 0; i < (long long)(areas).size(); ++i) {
    long long xx = areas[i].x;
    long long yy = areas[i].y;
    if (!used[xx][yy]) {
      ans.push_back(pair<long long, long long>(xx, yy));
      cost_ans.push_back(areas[i].cost);
      for (long long i1 = max(1ll, xx - u + 1); i1 <= min(n, xx + u - 1); ++i1)
        for (long long j1 = max(1ll, yy - v + 1); j1 <= min(m, yy + v - 1);
             ++j1)
          used[i1][j1] = true;
    }
  }
  cout << ans.size() << endl;
  for (long long i = 0; i < (long long)(ans).size(); ++i)
    printf("%I64u %I64u %I64u\n", ans[i].first, ans[i].second, cost_ans[i]);
}
