#include <bits/stdc++.h>
#pragma GCC optimize(3, "Ofast", "inline")
using namespace std;
mt19937 rng_32(chrono::steady_clock::now().time_since_epoch().count());
const int mod = 1e9 + 7;
const int seed = 233;
const double PI = acos(-1.0);
const double eps = 1e-7;
const int inf = 0x3f3f3f3f;
const int max_n = 100005;
long long ceil(long long x, long long y) {
  if (x == 0) return 0;
  if (y < 0) x = -x, y = -y;
  bool sign = x > 0;
  x = abs(x);
  return sign ? (x + y - 1) / y : -x / y;
}
long long floor(long long x, long long y) {
  if (x == 0) return 0;
  if (y < 0) x = -x, y = -y;
  bool sign = x > 0;
  x = abs(x);
  return sign ? x / y : -(x + y - 1) / y;
}
namespace {
inline int Add(int x, int y) { return (x += y) >= mod ? x - mod : x; }
inline int Sub(int x, int y) { return (x -= y) < 0 ? x + mod : x; }
inline int Mul(int x, int y) { return 1ll * x * y % mod; }
inline int Pow(int x, int y = mod - 2) {
  if (y == 0) return 1;
  int res = 1;
  while (y) {
    if (y & 1) res = 1ll * res * x % mod;
    x = 1ll * x * x % mod;
    y >>= 1;
  }
  return res;
}
}  // namespace
struct Seg {
  int d[1 << 20], lazy[1 << 20];
  void pushup(int rt) { d[rt] = min(d[rt << 1], d[rt << 1 | 1]); }
  void pushdown(int rt, int ln = 1, int rn = 1) {
    if (lazy[rt]) {
      d[rt << 1] += lazy[rt] * ln;
      d[rt << 1 | 1] += lazy[rt] * rn;
      lazy[rt << 1] += lazy[rt];
      lazy[rt << 1 | 1] += lazy[rt];
      lazy[rt] = 0;
    }
  }
  void init(int l, int r, int rt) {
    d[rt] = inf, lazy[rt] = 0;
    if (l == r) return;
    int mid = l + r >> 1;
    init(l, mid, rt << 1), init(mid + 1, r, rt << 1 | 1);
  }
  void ins(int x, int c, int l, int r, int rt) {
    if (l == r) {
      d[rt] = c;
      return;
    }
    int mid = l + r >> 1;
    pushdown(rt);
    if (x <= mid)
      ins(x, c, l, mid, rt << 1);
    else
      ins(x, c, mid + 1, r, rt << 1 | 1);
    pushup(rt);
  }
  void update(int L, int R, int C, int l, int r, int rt) {
    if (L > R) return;
    if (l >= L && r <= R) {
      d[rt] += C;
      lazy[rt] += C;
      return;
    }
    int mid = l + r >> 1;
    pushdown(rt);
    if (mid >= L) update(L, R, C, l, mid, rt << 1);
    if (mid < R) update(L, R, C, mid + 1, r, rt << 1 | 1);
    pushup(rt);
  }
  int query(int L, int R, int l, int r, int rt) {
    if (L > R || L > r || R < l) return inf;
    if (l >= L && r <= R) return d[rt];
    int mid = l + r >> 1;
    pushdown(rt);
    return min(query(L, R, l, mid, rt << 1),
               query(L, R, mid + 1, r, rt << 1 | 1));
  }
} Tree1, Tree2, Tree3;
int n, m, k;
int dp[52][20005];
int a[52][20005];
int main() {
  scanf("%d%d%d", &n, &m, &k);
  for (int i = 1; i <= n; i++) {
    for (int j = 1; j <= m; j++) scanf("%d", &a[i][j]);
  }
  for (int i = 1; i <= n + 1; i++) {
    for (int j = 1; j <= m; j++) a[i][j] += a[i][j - 1];
  }
  for (int j = 1; j + k - 1 <= m; j++)
    dp[1][j] = a[1][j + k - 1] - a[1][j - 1] + a[2][j + k - 1] - a[2][j - 1];
  Tree1.init(1, m, 1);
  Tree2.init(1, m, 1);
  Tree3.init(1, m, 1);
  for (int j = 1; j + k - 1 <= m; j++) {
    Tree1.ins(j, -dp[1][j], 1, m, 1),
        Tree2.ins(j, a[2][j + k - 1] - dp[1][j], 1, m, 1);
    Tree3.ins(j, -dp[1][j] - a[2][j - 1], 1, m, 1);
  }
  for (int i = 2; i <= n; i++) {
    for (int j = 1; j + k - 1 <= m; j++) {
      int mx = 0;
      int val =
          a[i][j + k - 1] - a[i][j - 1] + a[i + 1][j + k - 1] - a[i + 1][j - 1];
      mx = max(mx, -Tree1.query(1, j - k, 1, m, 1) + val);
      mx = max(mx, -Tree1.query(j + k, m, 1, m, 1) + val);
      val += a[i][j - 1];
      mx = max(mx, -Tree2.query(max(j - k + 1, 1), j, 1, m, 1) + val);
      val = a[i + 1][j + k - 1] - a[i + 1][j - 1] - a[i][j - 1];
      mx = max(mx, -Tree3.query(j + 1, j + k - 1, 1, m, 1) + val);
      dp[i][j] = mx;
    }
    Tree1.init(1, m, 1), Tree2.init(1, m, 1);
    Tree3.init(1, m, 1);
    for (int j = 1; j + k - 1 <= m; j++) {
      Tree1.ins(j, -dp[i][j], 1, m, 1),
          Tree2.ins(j, a[i + 1][j + k - 1] - dp[i][j], 1, m, 1);
      Tree3.ins(j, -dp[i][j] - a[i + 1][j - 1], 1, m, 1);
    }
  }
  int ans = 0;
  for (int j = 1; j + k - 1 <= m; j++) ans = max(ans, dp[n][j]);
  printf("%d\n", ans);
  return 0;
}
