#include <bits/stdc++.h>
using namespace std;
const int N = 50, M = 2e4;
int num[N + 3][M + 3], dp[N + 3][M + 3], sum[M + 3];
struct SEGTREE {
  int mx[M * 2 + 10], add[M * 2 + 10];
  void PushUp(int lef, int rig) {
    int mid = (lef + rig) >> 1;
    mx[((lef + rig) | (lef != rig))] =
        max(mx[((lef + mid) | (lef != mid))],
            mx[((mid + 1 + rig) | (mid + 1 != rig))]);
  }
  void Build(int lef, int rig, int i) {
    int u = ((lef + rig) | (lef != rig));
    add[u] = 0;
    if (lef == rig) {
      mx[u] = dp[i][lef];
      return;
    }
    int mid = (lef + rig) >> 1;
    Build(lef, mid, i);
    Build(mid + 1, rig, i);
    PushUp(lef, rig);
  }
  void PushDown(int lef, int rig) {
    int u = ((lef + rig) | (lef != rig));
    int mid = (lef + rig) >> 1, vl = ((lef + mid) | (lef != mid)),
        vr = ((mid + 1 + rig) | (mid + 1 != rig));
    if (add[u]) {
      add[vl] += add[u];
      mx[vl] += add[u];
      add[vr] += add[u];
      mx[vr] += add[u];
      add[u] = 0;
    }
  }
  void Modify(int lef, int rig, int Le, int Ri, int val) {
    if (Le > Ri) return;
    int u = ((lef + rig) | (lef != rig));
    if (Le <= lef && rig <= Ri) {
      mx[u] += val;
      add[u] += val;
      return;
    }
    PushDown(lef, rig);
    int mid = (lef + rig) >> 1;
    if (Le <= mid) Modify(lef, mid, Le, Ri, val);
    if (Ri > mid) Modify(mid + 1, rig, Le, Ri, val);
    PushUp(lef, rig);
  }
};
SEGTREE Se;
int main() {
  int n, m, K;
  scanf("%d%d%d", &n, &m, &K);
  for (int i = 1; i <= n; i++) {
    for (int j = 1; j <= m; j++) {
      scanf("%d", &num[i][j]);
      sum[j] = sum[j - 1] + num[i][j];
    }
    if (i == 1) {
      for (int j = 1; j <= m - K + 1; j++)
        dp[i][j] = sum[j + K - 1] - sum[j - 1];
      continue;
    }
    Se.Build(1, m - K + 1, i - 1);
    for (int Le = 1; Le <= m - K + 1; Le++) {
      Se.Modify(1, m - K + 1, max(1, Le - K), Le - 1, num[i][Le - 1]);
      dp[i][Le] = max(dp[i][Le], Se.mx[((1 + m - K + 1) | (1 != m - K + 1))] +
                                     sum[min(Le + K - 1, m)] - sum[Le - 1]);
    }
    Se.Build(1, m - K + 1, i - 1);
    for (int Le = m - K + 1; Le >= 1; Le--) {
      Se.Modify(1, m - K + 1, Le + 1, min(m - K + 1, Le + K), num[i][Le + K]);
      dp[i][Le] = max(dp[i][Le], Se.mx[((1 + m - K + 1) | (1 != m - K + 1))] +
                                     sum[min(Le + K - 1, m)] - sum[Le - 1]);
    }
  }
  int ans = 0;
  for (int i = 1; i <= m - K + 1; i++) ans = max(ans, dp[n][i]);
  printf("%d\n", ans);
  return 0;
}
