Problem: There is an area map that is a rectangular matrix n × m, each cell of the matrix contains the average height of a corresponding area part. Peter works for a company that has to build several cities within this area, each of the cities will occupy a rectangle a × b cells on the map. To start construction works in a particular place Peter needs to remove excess ground from the construction site where a new city will be built. To do so he chooses a cell of the minimum height within this site, and removes excess ground from other cells of the site down to this minimum level. Let's consider that to lower the ground level from h2 to h1 (h1 ≤ h2) they need to remove h2 - h1 ground units.

Let's call a site's position optimal, if the amount of the ground removed from this site is minimal compared to other possible positions. Peter constructs cities according to the following algorithm: from all the optimum site's positions he chooses the uppermost one. If this position is not unique, he chooses the leftmost one. Then he builds a city on this site. Peter repeats this process untill he can build at least one more city. For sure, he cannot carry out construction works on the occupied cells. Would you, please, help Peter place cities according to the algorithm? 

Input

The first line contains four space-separated integers: map sizes n, m and city sizes a, b (1 ≤ a ≤ n ≤ 1000, 1 ≤ b ≤ m ≤ 1000). Then there follow n lines, each contains m non-negative space-separated numbers, describing the height matrix. Each number doesn't exceed 109. 

Output

In the first line output k — the amount of constructed cities. In each of the following k lines output 3 space-separated numbers — the row number and the column number of the upper-left corner of a subsequent construction site, and the amount of the ground to remove from it. Output the sites in the order of their building up.

Examples

Input

2 2 1 2
1 2
3 5


Output

2
1 1 1
2 1 2


Input

4 4 2 2
1 5 3 4
2 7 6 1
1 1 2 2
2 2 1 2


Output

3
3 1 2
3 3 3
1 2 9

Solution (in CPP):

Solution:
#include <bits/stdc++.h>
#pragma GCC optimize(1)
#pragma G++ optimize(1)
#pragma GCC optimize(2)
#pragma G++ optimize(2)
#pragma GCC optimize(3)
#pragma G++ optimize(3)
#pragma GCC optimize(4)
#pragma G++ optimize(4)
#pragma GCC optimize(5)
#pragma G++ optimize(5)
#pragma GCC optimize(6)
#pragma G++ optimize(6)
#pragma GCC optimize(7)
#pragma G++ optimize(7)
#pragma GCC optimize(8)
#pragma G++ optimize(8)
#pragma GCC optimize(9)
#pragma G++ optimize(9)
#pragma GCC optimize("-funsafe-loop-optimizations")
#pragma GCC optimize("-funroll-loops")
#pragma GCC optimize("-fwhole-program")
#pragma GCC optimize("Ofast,no-stack-protector")
#pragma GCC optimize("-fthread-jumps")
#pragma GCC optimize("-falign-functions")
#pragma GCC optimize("-falign-jumps")
#pragma GCC optimize("-falign-loops")
#pragma GCC optimize("-falign-labels")
#pragma GCC optimize("-fcaller-saves")
#pragma GCC optimize("-fcrossjumping")
#pragma GCC optimize("-fcse-follow-jumps")
#pragma GCC optimize("-fcse-skip-blocks")
#pragma GCC optimize("-fdelete-null-pointer-checks")
#pragma GCC optimize("-fdevirtualize")
#pragma GCC optimize("-fexpensive-optimizations")
#pragma GCC optimize("-fgcse")
#pragma GCC optimize("-fgcse-lm")
#pragma GCC optimize("-fhoist-adjacent-loads")
#pragma GCC optimize("-finline-small-functions")
#pragma GCC optimize("-findirect-inlining")
#pragma GCC optimize("-fipa-sra")
#pragma GCC optimize("-foptimize-sibling-calls")
#pragma GCC optimize("-fpartial-inlining")
#pragma GCC optimize("-fpeephole2")
#pragma GCC optimize("-freorder-blocks")
#pragma GCC optimize("-freorder-functions")
#pragma GCC optimize("-frerun-cse-after-loop")
#pragma GCC optimize("-fsched-interblock")
#pragma GCC optimize("-fsched-spec")
#pragma GCC optimize("-fschedule-insns")
#pragma GCC optimize("-fschedule-insns2")
#pragma GCC optimize("-fstrict-aliasing")
#pragma GCC optimize("-fstrict-overflow")
#pragma GCC optimize("-ftree-switch-conversion")
#pragma GCC optimize("-ftree-tail-merge")
#pragma GCC optimize("-ftree-pre")
#pragma GCC optimize("-ftree-vrp")
using namespace std;
const int INF = 2147483647;
const double PI =
    3.141592653589793238462643383279502884197169399375105820974944592307816406286208998628034825342117067982148086513282306647093844609550582231725359408128481117450284102701938521105559644622948954930381964428810975665933446128475648233786783165271201909145648566923460348610454326648213393607260249141273724587006606315588174881520920962829254091715364367892590360011330530548820466521384146951941511609433057270365759591953092186117381932611793105118548074462379962749567351885752724891227938183011949129833673362440656643086021394946395224737190702179860943702770539217176293176752384674818467669405132000568127145263560827785771342757789609173637178721468440901224953430146549585371050792279689258923542019956112129021960864034418159813629774771309960518707211349999998372978049951059731732816096318595024459455346908302642522308253344685035261931188171010003137838752886587533208381420617177669147303598253490428755468731159562863882353787593751957781857780532171226806613001927876611195909216420198938095257201065485863278865936153381827968230301952;
const int maxn = 10005;
struct bign {
  int d[maxn], len;
  inline void clean() {
    while (len > 1 && !d[len - 1]) len--;
  }
  inline bign() {
    memset(d, 0, sizeof(d));
    len = 1;
  }
  inline bign(int num) { *this = num; }
  inline bign(char* num) { *this = num; }
  inline bign operator=(const char* num) {
    memset(d, 0, sizeof(d));
    len = strlen(num);
    for (int i = 0; i < len; i++) d[i] = num[len - 1 - i] - '0';
    clean();
    return *this;
  }
  inline bign operator=(int num) {
    char s[20];
    sprintf(s, "%d", num);
    *this = s;
    return *this;
  }
  inline bign operator+(const bign& b) {
    bign c = *this;
    int i;
    for (i = 0; i < b.len; i++) {
      c.d[i] += b.d[i];
      if (c.d[i] > 9) c.d[i] %= 10, c.d[i + 1]++;
    }
    while (c.d[i] > 9) c.d[i++] %= 10, c.d[i]++;
    c.len = max(len, b.len);
    if (c.d[i] && c.len <= i) c.len = i + 1;
    return c;
  }
  inline bign operator-(const bign& b) {
    bign c = *this;
    int i;
    for (i = 0; i < b.len; i++) {
      c.d[i] -= b.d[i];
      if (c.d[i] < 0) c.d[i] += 10, c.d[i + 1]--;
    }
    while (c.d[i] < 0) c.d[i++] += 10, c.d[i]--;
    for (i = c.len - 1; i > 0; i--)
      if (c.d[i] != 0) break;
    c.len = i + 1;
    return c;
  }
  inline bign operator*(const bign& b) const {
    int i, j;
    bign c;
    c.len = len + b.len;
    for (j = 0; j < b.len; j++)
      for (i = 0; i < len; i++) c.d[i + j] += d[i] * b.d[j];
    for (i = 0; i < c.len - 1; i++) c.d[i + 1] += c.d[i] / 10, c.d[i] %= 10;
    c.clean();
    return c;
  }
  inline bign operator/(const bign& b) {
    int i, j;
    bign c = *this, a = 0;
    for (i = len - 1; i >= 0; i--) {
      a = a * 10 + d[i];
      for (j = 0; j < 10; j++)
        if (a < b * (j + 1)) break;
      c.d[i] = j;
      a = a - b * j;
    }
    c.clean();
    return c;
  }
  inline bign operator%(const bign& b) {
    int i, j;
    bign a = 0;
    for (i = len - 1; i >= 0; i--) {
      a = a * 10 + d[i];
      for (j = 0; j < 10; j++)
        if (a < b * (j + 1)) break;
      a = a - b * j;
    }
    return a;
  }
  inline bign operator+=(const bign& b) {
    *this = *this + b;
    return *this;
  }
  inline bign operator*=(const bign& b) {
    *this = *this * b;
    return *this;
  }
  inline bign operator-=(const bign& b) {
    *this = *this - b;
    return *this;
  }
  inline bign operator/=(const bign& b) {
    *this = *this / b;
    return *this;
  }
  inline bool operator<(const bign& b) const {
    if (len != b.len) return len < b.len;
    for (int i = len - 1; i >= 0; i--)
      if (d[i] != b.d[i]) return d[i] < b.d[i];
    return false;
  }
  inline bool operator>(const bign& b) const { return b < *this; }
  inline bool operator<=(const bign& b) const { return !(b < *this); }
  inline bool operator>=(const bign& b) const { return !(*this < b); }
  inline bool operator!=(const bign& b) const { return b < *this || *this < b; }
  inline bool operator==(const bign& b) const {
    return !(b < *this) && !(b > *this);
  }
  inline string str() const {
    char s[maxn] = {};
    for (int i = 0; i < len; i++) s[len - 1 - i] = d[i] + '0';
    return s;
  }
};
inline istream& operator>>(istream& in, bign& x) {
  string s;
  in >> s;
  x = s.c_str();
  return in;
}
inline ostream& operator<<(ostream& out, const bign& x) {
  out << x.str();
  return out;
}
inline void write(long long x) {
  if (x < 0) putchar('-'), x = -x;
  if (x > 9) write(x / 10);
  putchar(x % 10 + '0');
}
inline int pt(int a[], int l, int r) {
  int p, i, j;
  p = a[l];
  i = l;
  j = r + 1;
  for (;;) {
    while (a[++i] < p)
      if (i >= r) break;
    while (a[--j] > p)
      if (j <= l) break;
    if (i >= j)
      break;
    else
      swap(a[i], a[j]);
  }
  if (j == l) return j;
  swap(a[l], a[j]);
  return j;
}
inline void q_sort(int a[], int l, int r) {
  int q;
  if (r > l) {
    q = pt(a, l, r);
    q_sort(a, l, q - 1);
    q_sort(a, q + 1, r);
  }
}
inline void write(int x) {
  if (x < 0) putchar('-'), x = -x;
  if (x > 9) write(x / 10);
  putchar(x % 10 + '0');
}
inline void rd(long long& val) {
  long long x = 0;
  int f = 1;
  char ch = getchar();
  while ((ch < '0' || ch > '9') && ch != '-') ch = getchar();
  if (ch == '-') {
    f = -1;
    ch = getchar();
  }
  while (ch >= '0' && ch <= '9') {
    x = x * 10 + ch - '0';
    ch = getchar();
  }
  val = x * f;
}
inline void rd(int& val) {
  int x = 0;
  int f = 1;
  char ch = getchar();
  while ((ch < '0' || ch > '9') && ch != '-') ch = getchar();
  if (ch == '-') {
    f = -1;
    ch = getchar();
  }
  while (ch >= '0' && ch <= '9') {
    x = x * 10 + ch - '0';
    ch = getchar();
  }
  val = x * f;
}
inline void _write(long long x) {
  write(x);
  putchar(' ');
}
inline void print(long long x) {
  write(x);
  putchar('\n');
}
int n, m, a, b;
int x[1002][1002], ok[1002][1002];
long long s[1002][1002];
int main() {
  ios_base::sync_with_stdio(false);
  cin.tie(0);
  cout.tie(0);
  int i, j, f, p, q;
  rd(n), rd(m), rd(a), rd(b);
  for (i = 1; i <= n; i++) {
    deque<pair<int, int> > deq;
    for (j = 1; j <= m; j++) {
      rd(x[i][j]);
      while (deq.size() && deq[0].second + b <= j) deq.pop_front();
      while (deq.size() && x[i][j] <= deq.back().first) deq.pop_back();
      deq.push_back({x[i][j], j});
      s[i][j] = s[i - 1][j] + s[i][j - 1] - s[i - 1][j - 1] + x[i][j];
      x[i][j] = deq[0].first;
    }
  }
  for (j = 1; j <= m; j++) {
    deque<pair<int, int> > deq;
    for (i = 1; i <= n; i++) {
      while (deq.size() && deq[0].second + a <= i) deq.pop_front();
      while (deq.size() && x[i][j] <= deq.back().first) deq.pop_back();
      deq.push_back(make_pair(x[i][j], i));
      x[i][j] = deq[0].first;
    }
  }
  deque<pair<long long, pair<int, int> > > ans, deq;
  long long sum;
  for (i = a; i <= n; i++) {
    for (j = b; j <= m; j++) {
      sum = s[i][j] - s[i - a][j] - s[i][j - b] + s[i - a][j - b];
      deq.push_back(make_pair(sum - 1ll * x[i][j] * a * b, make_pair(i, j)));
    }
  }
  sort(deq.begin(), deq.end());
  pair<long long, pair<int, int> > it;
  for (auto it : deq) {
    p = it.second.first;
    q = it.second.second;
    if (ok[p][q]) continue;
    for (i = p - a + 1; i <= p + a - 1; i++)
      for (j = q - b + 1; j <= q + b - 1; j++) ok[i][j] = 1;
    ans.push_back(make_pair(it.first, make_pair(p - a + 1, q - b + 1)));
  }
  print(ans.size());
  for (auto it : ans)
    _write(it.second.first), _write(it.second.second), print(it.first);
  return 0;
}