#include <bits/stdc++.h>
using namespace std;
struct SegmentTree {
  struct Node {
    int sum;
  } t[20086 << 2];
  int a[20086];
  inline void up(int x) {
    t[x].sum = max(t[(x << 1)].sum, t[(x << 1 | 1)].sum);
  }
  void build(int x, int l, int r) {
    if (l == r) {
      t[x].sum = a[l];
      return;
    }
    int mid = l + r >> 1;
    build((x << 1), l, mid), build((x << 1 | 1), mid + 1, r), up(x);
  }
  int query(int x, int l, int r, int ll, int rr) {
    if (ll <= l && r <= rr) return t[x].sum;
    int mid = l + r >> 1, sum = -2e9;
    if (mid >= ll) sum = max(sum, query((x << 1), l, mid, ll, rr));
    if (mid < rr) sum = max(sum, query((x << 1 | 1), mid + 1, r, ll, rr));
    return sum;
  }
} F, X, Y;
int n, m, k, M;
int sum[60][20086];
int f[60][20086];
int ans;
int main() {
  scanf("%d%d%d", &n, &m, &k), M = m - k + 1;
  for (int i = 1; i <= n; i++)
    for (int j = 1; j <= m; j++)
      scanf("%d", &sum[i][j]), sum[i][j] += sum[i][j - 1];
  for (int i = 1; i <= n; i++) {
    if (i ^ 1) {
      for (int j = 1; j <= M; j++) F.a[j] = f[i - 1][j];
      F.build(1, 1, M);
      for (int j = 1; j <= M; j++) X.a[j] = f[i - 1][j] - sum[i][j + k - 1];
      X.build(1, 1, M);
      for (int j = 1; j <= M; j++) Y.a[j] = f[i - 1][j] + sum[i][j - 1];
      Y.build(1, 1, M);
    }
    for (int j = 1; j <= M; j++) {
      if (i ^ 1) {
        f[i][j] = max(X.query(1, 1, M, j - k + 1, j) + sum[i][j - 1],
                      Y.query(1, 1, M, j, j + k - 1) - sum[i][j + k - 1]);
        if (j - k + 1 > 1) f[i][j] = max(f[i][j], F.query(1, 1, M, 1, j - k));
        if (j + k - 1 < M) f[i][j] = max(f[i][j], F.query(1, 1, M, j + k, M));
      }
      f[i][j] += sum[i][j + k - 1] - sum[i][j - 1] + sum[i + 1][j + k - 1] -
                 sum[i + 1][j - 1];
      if (i == n) ans = max(ans, f[i][j]);
    }
  }
  printf("%d", ans);
}
