#include <bits/stdc++.h>
using namespace std;
const int MAXN = 55, MAXM = 2e4 + 5;
struct SegmentTree {
  int maxVal, lazy;
  int l, r;
  SegmentTree *L, *R;
  SegmentTree() {}
  SegmentTree(int l, int r) {
    this->maxVal = this->lazy = 0;
    this->l = l;
    this->r = r;
    this->L = this->R = nullptr;
  }
  void build() {
    if (l == r) return;
    L = new SegmentTree(l, (l + r) / 2);
    R = new SegmentTree((l + r) / 2 + 1, r);
    L->build();
    R->build();
  }
  void reset() {
    maxVal = lazy = 0;
    if (L != nullptr) L->reset();
    if (R != nullptr) R->reset();
  }
  void updateLazy() {
    maxVal += lazy;
    if (L != nullptr) {
      L->lazy += lazy;
      R->lazy += lazy;
    }
    lazy = 0;
  }
  int query(int ql, int qr) {
    updateLazy();
    if (l >= ql && qr <= r) return maxVal;
    if (r < ql || l > qr) return 0;
    return max(L->query(ql, qr), R->query(ql, qr));
  }
  void update(int ql, int qr, int val) {
    updateLazy();
    if (l >= ql && r <= qr) {
      lazy += val;
      updateLazy();
      return;
    }
    if (r < ql || l > qr) return;
    L->update(ql, qr, val);
    R->update(ql, qr, val);
    maxVal = max(L->maxVal, R->maxVal);
  }
};
int n, m, k;
int a[MAXN][MAXM];
int dp[MAXN][MAXM];
int pref[MAXN][MAXM];
void init() {
  for (int i = 0; i < n; i++) {
    pref[i][0] = a[i][0];
    for (int j = 1; j < m; j++) pref[i][j] = pref[i][j - 1] + a[i][j];
  }
}
int getSum(int row, int l, int r) {
  if (l == 0) return pref[row][r];
  return pref[row][r] - pref[row][l - 1];
}
int getPosVal(int i, int j) {
  return getSum(i, j, j + k - 1) +
         ((i == n - 1) ? 0 : getSum(i + 1, j, j + k - 1));
}
int main() {
  ios::sync_with_stdio(false);
  cin.tie(NULL);
  cin >> n >> m >> k;
  for (int i = 0; i < n; i++) {
    for (int j = 0; j < m; j++) cin >> a[i][j];
  }
  init();
  for (int j = 0; j < m - k + 1; j++) dp[0][j] = getPosVal(0, j);
  SegmentTree *T = new SegmentTree(0, m - 1);
  T->build();
  for (int i = 1; i < n; i++) {
    T->reset();
    for (int j = 0; j < m - k + 1; j++) T->update(j, j, dp[i - 1][j]);
    for (int j = 0; j < k; j++) T->update(0, j, -a[i][j]);
    for (int j = 0; j < m - k + 1; j++) {
      dp[i][j] = T->query(0, m - 1) + getPosVal(i, j);
      T->update(max(0, j - k + 1), j, +a[i][j]);
      T->update(j + 1, j + k, -a[i][j + k]);
    }
  }
  int answer = 0;
  for (int j = 0; j < m; j++) answer = max(answer, dp[n - 1][j]);
  cout << answer << '\n';
}
