#include <bits/stdc++.h>
using namespace std;
const int N = 53, M = 20005;
const long long inf = 1000000000000000;
int n, m, k;
long long a[N][M], dp[N][M];
template <class T>
bool checkmin(T &a, T b) {
  return (b < a ? a = b, 1 : 0);
}
template <class T>
bool checkmax(T &a, T b) {
  return (b > a ? a = b, 1 : 0);
}
template <class T>
T _min(T a, T b) {
  return (a < b ? a : b);
}
template <class T>
T _max(T a, T b) {
  return (a > b ? a : b);
}
struct segment_tree {
  long long mx[M << 2];
  void init() {
    for (int i = 0; i < (N << 2); ++i) mx[i] = -inf;
  }
  void update(int x, int l, int r, int pos, int num) {
    if (l == r) {
      mx[x] = num;
      return;
    }
    int mid = (l + r) >> 1;
    if (pos <= mid)
      update(x + x, l, mid, pos, num);
    else
      update(x + x + 1, mid + 1, r, pos, num);
    mx[x] = _max(mx[x + x], mx[x + x + 1]);
  }
  long long query(int x, int l, int r, int L, int R) {
    if (L <= l && r <= R) {
      return mx[x];
    }
    int mid = (l + r) >> 1;
    long long ans = -inf;
    if (L <= mid) checkmax(ans, query(x + x, l, mid, L, R));
    if (R > mid) checkmax(ans, query(x + x + 1, mid + 1, r, L, R));
    return ans;
  }
} t[3];
void init() {
  scanf("%d%d%d", &n, &m, &k);
  for (int i = 1; i <= n; ++i) {
    for (int j = 1; j <= m; ++j) {
      scanf("%lld", &a[i][j]);
      a[i][j] += a[i][j - 1];
    }
  }
}
void solve() {
  int new_m = m - k + 1;
  for (int i = 0; i < 3; ++i) t[i].init();
  for (int i = 1; i <= n; ++i) {
    if (i == 1) {
      for (int j = 1; j <= new_m; ++j) {
        dp[i][j] = a[i][j + k - 1] - a[i][j - 1] + a[i + 1][j + k - 1] -
                   a[i + 1][j - 1];
        t[0].update(1, 1, new_m, j, dp[i][j] - a[i + 1][j + k - 1]);
        t[1].update(1, 1, new_m, j, dp[i][j] + a[i + 1][j - 1]);
        t[2].update(1, 1, new_m, j, dp[i][j]);
      }
    } else {
      for (int j = 1; j <= new_m; ++j) {
        checkmax(dp[i][j], t[0].query(1, 1, new_m, _max(1, j - k + 1), j) +
                               a[i][j + k - 1] + a[i + 1][j + k - 1] -
                               a[i + 1][j - 1]);
        checkmax(dp[i][j], t[1].query(1, 1, new_m, j, _min(j + k - 1, new_m)) -
                               a[i][j - 1] + a[i + 1][j + k - 1] -
                               a[i + 1][j - 1]);
        if (1 <= j - k)
          checkmax(dp[i][j], t[2].query(1, 1, new_m, 1, j - k) +
                                 a[i][j + k - 1] - a[i][j - 1] +
                                 a[i + 1][j + k - 1] - a[i + 1][j - 1]);
        if (j + k <= new_m)
          checkmax(dp[i][j], t[2].query(1, 1, new_m, j + k, new_m) +
                                 a[i][j + k - 1] - a[i][j - 1] +
                                 a[i + 1][j + k - 1] - a[i + 1][j - 1]);
      }
      for (int j = 1; j <= new_m; ++j) {
        t[0].update(1, 1, new_m, j, dp[i][j] - a[i + 1][j + k - 1]);
        t[1].update(1, 1, new_m, j, dp[i][j] + a[i + 1][j - 1]);
        t[2].update(1, 1, new_m, j, dp[i][j]);
      }
    }
  }
  long long ans = 0;
  for (int i = 1; i <= new_m; ++i) {
    checkmax(ans, dp[n][i]);
  }
  for (int i = 1; i <= n; ++i) {
  }
  printf("%lld\n", ans);
}
int main() {
  init();
  solve();
  return 0;
}
