#include <bits/stdc++.h>
using namespace std;
const int MAXN = 4e5 + 5;
int n, m, t;
int dp[51][MAXN];
int qian[51][MAXN];
int v[51][MAXN];
struct Segment_Tree {
  int maxm[MAXN], lazy[MAXN];
  void build(int p, int l, int r) {
    maxm[p] = lazy[p] = 0;
    if (l == r) {
      return;
    }
    int mid = l + r >> 1;
    build((p << 1), l, mid);
    build((p << 1 | 1), mid + 1, r);
    push_up(p);
  }
  void push_up(int p) { maxm[p] = max(maxm[(p << 1)], maxm[(p << 1 | 1)]); }
  void push_down(int p, int l, int r) {
    lazy[(p << 1)] += lazy[p];
    lazy[(p << 1 | 1)] += lazy[p];
    maxm[(p << 1)] += lazy[p];
    maxm[(p << 1 | 1)] += lazy[p];
    lazy[p] = 0;
  }
  void update(int p, int l, int r, int L, int R, int x) {
    if (l >= L && r <= R) {
      maxm[p] += x;
      lazy[p] += x;
      return;
    }
    push_down(p, l, r);
    int mid = l + r >> 1;
    if (mid >= L) update((p << 1), l, mid, L, R, x);
    if (mid < R) update((p << 1 | 1), mid + 1, r, L, R, x);
    push_up(p);
  }
} ans;
int main() {
  cin >> n >> m >> t;
  for (int i = 1; i <= n; i++)
    for (int j = 1; j <= m; j++)
      scanf("%d", &v[i][j]), qian[i][j] = qian[i][j - 1] + v[i][j];
  for (int i = 1; i <= m - t + 1; i++)
    dp[1][i] = qian[1][i + t - 1] - qian[1][i - 1] + qian[2][i + t - 1] -
               qian[2][i - 1];
  for (int i = 2; i <= n; i++) {
    ans.build(1, 1, m);
    for (int j = 1; j <= m; j++) ans.update(1, 1, m, j, j, dp[i - 1][j]);
    for (int j = 1; j <= t; j++) ans.update(1, 1, m, 1, j, -v[i][j]);
    for (int j = 1; j <= m - t + 1; j++) {
      dp[i][j] = ans.maxm[1] + qian[i][j + t - 1] - qian[i][j - 1] +
                 qian[i + 1][j + t - 1] - qian[i + 1][j - 1];
      ans.update(1, 1, m, max(1, j - t + 1), j, v[i][j]);
      ans.update(1, 1, m, j + 1, j + t, -v[i][j + t]);
    }
  }
  int maxm = 0;
  for (int i = 1; i <= m; i++) maxm = max(maxm, dp[n][i]);
  cout << maxm;
}
