#include <bits/stdc++.h>
using namespace std;
struct seg {
  int lf, rt, dc;
} S[20005 << 2];
int n, m, k;
int a[55][20005];
int dp[2][20005];
int crt[2][20005], clf[2][20005], disc[2][20005];
seg merge(seg a, seg b) {
  seg res;
  res.lf = max(a.lf, b.lf);
  res.rt = max(a.rt, b.rt);
  res.dc = max(a.dc, b.dc);
  return res;
}
seg get(int node, int bas, int son, int l, int r) {
  if (l > r) {
    return {-1000000005, -1000000005, -1000000005};
  }
  if (bas >= l && son <= r) return S[node];
  if (((bas + son) >> 1) >= l && ((bas + son) >> 1) + 1 <= r)
    return merge(get(node << 1, bas, ((bas + son) >> 1), l, r),
                 get(node << 1 | 1, ((bas + son) >> 1) + 1, son, l, r));
  if (((bas + son) >> 1) >= l)
    return get(node << 1, bas, ((bas + son) >> 1), l, r);
  return get(node << 1 | 1, ((bas + son) >> 1) + 1, son, l, r);
}
void build(int node, int bas, int son, int cur) {
  if (bas == son) {
    S[node] = {clf[cur][bas], crt[cur][bas], disc[cur][bas]};
    return;
  }
  build(node << 1, bas, ((bas + son) >> 1), cur);
  build(node << 1 | 1, ((bas + son) >> 1) + 1, son, cur);
  S[node] = merge(S[node << 1], S[node << 1 | 1]);
}
void calc(int i) {
  int cur = i & 1;
  for (int j = 1; j <= m - k + 1; j++) {
    disc[cur][j] = dp[cur][j] + a[i + 1][j + k - 1] - a[i + 1][j - 1];
    clf[cur][j] = dp[cur][j] - a[i + 1][j - 1];
    crt[cur][j] = dp[cur][j] + a[i + 1][j + k - 1];
  }
  build(1, 1, m - k + 1, cur);
}
int main() {
  ios_base::sync_with_stdio(0);
  cin.tie(0);
  cout.tie(0);
  cin >> n >> m >> k;
  for (int i = 1; i <= n; i++)
    for (int j = 1; j <= m; j++) cin >> a[i][j], a[i][j] += a[i][j - 1];
  for (int i = 1; i <= m - k + 1; i++) dp[1][i] = a[1][i + k - 1] - a[1][i - 1];
  calc(1);
  for (int i = 2; i <= n; i++) {
    for (int j = 1; j <= m - k + 1; j++) {
      int cur = i & 1;
      int bf = !cur;
      dp[cur][j] = -1000000005;
      if (j - k >= 1) {
        dp[cur][j] = max(dp[cur][j], get(1, 1, m - k + 1, 1, j - k).dc +
                                         a[i][j + k - 1] - a[i][j - 1]);
      }
      if (j + k <= m - k + 1) {
        dp[cur][j] = max(dp[cur][j], get(1, 1, m - k + 1, j + k, m - k + 1).dc +
                                         a[i][j + k - 1] - a[i][j - 1]);
      }
      int l = max(1, j - k + 1);
      int r = j;
      dp[cur][j] =
          max(dp[cur][j], get(1, 1, m - k + 1, l, r).lf + a[i][j + k - 1]);
      l = j;
      r = min(m - k + 1, j + k - 1);
      dp[cur][j] = max(dp[cur][j], get(1, 1, m - k + 1, l, r).rt - a[i][j - 1]);
    }
    calc(i);
  }
  printf("%d\n", *max_element(dp[n & 1] + 1, dp[n & 1] + 1 + m - k + 1));
}
