#include <bits/stdc++.h>
using namespace std;
const int N = 55, M = 20010, mod = 1e9 + 7, INF = 0x3f3f3f3f;
const double eps = 1e-6;
int n, m, k;
int a[N][M], s[N][M], f[N][M];
struct Node {
  int l, r;
  int val, lazy;
} tr[M << 2];
void pushup(int u) { tr[u].val = max(tr[(u << 1)].val, tr[(u << 1 | 1)].val); }
void pushdown(int u) {
  int lazy = tr[u].lazy;
  tr[u].lazy = 0;
  tr[(u << 1)].val += lazy;
  tr[(u << 1)].lazy += lazy;
  tr[(u << 1 | 1)].val += lazy;
  tr[(u << 1 | 1)].lazy += lazy;
}
void build(int u, int l, int r, int pos) {
  tr[u] = {l, r};
  if (l == r) {
    tr[u].val = f[pos][l] + s[pos + 1][l + k - 1] - s[pos + 1][l - 1];
    tr[u].lazy = 0;
    return;
  }
  build((u << 1), l, (tr[u].l + tr[u].r >> 1), pos);
  build((u << 1 | 1), (tr[u].l + tr[u].r >> 1) + 1, r, pos);
  pushup(u);
}
void modify(int u, int l, int r, int val) {
  if (tr[u].l >= l && tr[u].r <= r) {
    tr[u].val += val;
    tr[u].lazy += val;
    return;
  }
  pushdown(u);
  if (l <= (tr[u].l + tr[u].r >> 1)) modify((u << 1), l, r, val);
  if (r > (tr[u].l + tr[u].r >> 1)) modify((u << 1 | 1), l, r, val);
  pushup(u);
}
void add(int val, int pos) {
  if (pos >= 1)
    modify(1, max(1, pos - k + 1), min(pos, m - k + 1), -a[val][pos]);
}
void del(int val, int pos) {
  if (pos >= 1)
    modify(1, max(1, pos - k + 1), min(pos, m - k + 1), a[val][pos]);
}
int main() {
  int ans = 0;
  scanf("%d%d%d", &n, &m, &k);
  for (int i = 1; i <= n; i++)
    for (int j = 1; j <= m; j++)
      scanf("%d", &a[i][j]), s[i][j] = s[i][j - 1] + a[i][j];
  for (int i = 1; i <= n; i++) {
    if (i > 1)
      for (int j = 1; j < k; j++) add(i, j);
    for (int j = 1; j <= m - k + 1; j++) {
      int l = j, r = j + k - 1;
      if (i == 1)
        f[i][j] = s[i][r] - s[i][l - 1];
      else
        del(i, l - 1), add(i, r), f[i][j] = s[i][r] - s[i][l - 1] + tr[1].val;
    }
    build(1, 1, m - k + 1, i);
  }
  for (int i = 1; i <= m; i++) ans = max(ans, f[n][i]);
  printf("%d\n", ans);
  return 0;
}
