#include <bits/stdc++.h>
using namespace std;
void dout() { cerr << '\n'; }
template <typename Head, typename... Tail>
void dout(Head H, Tail... T) {
  cerr << " " << H;
  dout(T...);
}
mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
const int N = 53, M = 20003, inf = 1e9;
int n, m, k, a[N][M], p[N][M], rec[N][M], dp[N][M];
struct node {
  int l = 0, r = 0, lazy = 0;
  int mx[3];
  node() { memset(&mx, 0, sizeof(mx)); }
  void merge(const node& x, const node& y) {
    for (int i = 0; i < 3; i++) {
      mx[i] = max(x.mx[i], y.mx[i]);
    }
  }
  void upd(int x) {
    for (int i = 0; i < 3; i++) {
      mx[i] += x;
    }
    lazy += x;
  }
};
node t[(1 << 16)];
void build(int c, int v, int l, int r) {
  t[v].l = l, t[v].r = r;
  t[v].lazy = 0;
  if (l == r) {
    t[v].mx[0] = dp[c - 1][l] - p[c][l + k];
    t[v].mx[1] = dp[c - 1][l] + p[c][l - 1];
    t[v].mx[2] = dp[c - 1][l];
    return;
  }
  int m = l + r >> 1;
  build(c, v << 1, l, m);
  build(c, v << 1 | 1, m + 1, r);
  t[v].merge(t[v << 1], t[v << 1 | 1]);
}
void push(int v) {
  if (t[v].lazy) {
    t[v << 1].upd(t[v].lazy);
    t[v << 1 | 1].upd(t[v].lazy);
    t[v].lazy = 0;
  }
}
void update(int v, int l, int r, int x) {
  if (t[v].l > r || t[v].r < l) {
    return;
  }
  if (t[v].l >= l && t[v].r <= r) {
    t[v].upd(x);
    return;
  }
  push(v);
  update(v << 1, l, r, x);
  update(v << 1 | 1, l, r, x);
  t[v].merge(t[v << 1], t[v << 1 | 1]);
}
int getmax(int c, int v, int l, int r) {
  if (t[v].l > r || t[v].r < l) {
    return -inf;
  }
  if (t[v].l >= l && t[v].r <= r) {
    return t[v].mx[c];
  }
  push(v);
  return max(getmax(c, v << 1, l, r), getmax(c, v << 1 | 1, l, r));
}
int main() {
  ios_base::sync_with_stdio(false), cin.tie(NULL);
  cin >> n >> m >> k;
  k--;
  for (int i = 1; i <= n; i++) {
    for (int j = 1; j <= m; j++) {
      cin >> a[i][j];
      p[i][j] = p[i][j - 1] + a[i][j];
    }
  }
  for (int i = 1; i <= n; i++) {
    for (int j = 1; j <= m - k; j++) {
      rec[i][j] = p[i][j + k] - p[i][j - 1];
      if (i < n) {
        rec[i][j] += p[i + 1][j + k] - p[i + 1][j - 1];
      }
    }
  }
  for (int i = 1; i <= m - k; i++) {
    dp[1][i] = rec[1][i];
  }
  for (int i = 2; i <= n; i++) {
    build(i, 1, 1, m - k);
    for (int j = 1; j <= m - k; j++) {
      dp[i][j] = rec[i][j] + max(getmax(2, 1, 1, j - k - 1),
                                 getmax(2, 1, j + k + 1, m - k));
      dp[i][j] =
          max(dp[i][j], getmax(0, 1, j - k, j) + rec[i][j] + p[i][j - 1]);
      dp[i][j] =
          max(dp[i][j], getmax(1, 1, j + 1, j + k) + rec[i][j] - p[i][j + k]);
    }
  }
  int res = 0;
  for (int i = 1; i <= m - k; i++) {
    res = max(res, dp[n][i]);
  }
  cout << res;
}
