#include <bits/stdc++.h>
using namespace std;
long long int cost[61][30110];
const long long int sz = 4 * 1e5;
long long int segtree[sz * 4], lazy[sz * 4];
vector<long long int> dp(sz), prev2(sz);
void push(long long int node, long long int s, long long int e) {
  segtree[node] += lazy[node];
  if (s != e) {
    lazy[2 * node] += lazy[node];
    lazy[2 * node + 1] += lazy[node];
  }
  lazy[node] = 0;
}
void build(long long int node, long long int s, long long int e) {
  lazy[node] = 0;
  if (s == e) {
    segtree[node] = prev2[s];
    return;
  }
  long long int mid = (s + e) / 2;
  build(2 * node, s, mid);
  build(2 * node + 1, mid + 1, e);
  segtree[node] = max(segtree[2 * node], segtree[2 * node + 1]);
}
void update(long long int node, long long int s, long long int e,
            long long int l, long long int r, long long int val) {
  if (lazy[node] != 0) push(node, s, e);
  if (s > r || e < l) return;
  if (s >= l && e <= r) {
    lazy[node] += val;
    push(node, s, e);
    return;
  }
  long long int mid = (s + e) / 2;
  update(2 * node, s, mid, l, r, val);
  update(2 * node + 1, mid + 1, e, l, r, val);
  segtree[node] = max(segtree[2 * node], segtree[2 * node + 1]);
}
long long int query(long long int node, long long int s, long long int e,
                    long long int l, long long int r) {
  if (lazy[node] != 0) push(node, s, e);
  if (s > r || e < l) return 0;
  if (s >= l && e <= r) return segtree[node];
  long long int mid = (s + e) / 2;
  return max(query(2 * node, s, mid, l, r),
             query(2 * node + 1, mid + 1, e, l, r));
}
void print() {
  cout << "Printing max at each val" << '\n';
  long long int s = 1, e = 4;
  for (long long int i = 1; i <= 4; i++) {
    cout << query(1, 0, 4, i, i) << " ";
  }
  cout << '\n';
}
signed main() {
  ios_base::sync_with_stdio(false);
  cin.tie(NULL);
  long long int n, m, k;
  cin >> n >> m >> k;
  for (long long int i = 0; i < (long long int)(n); i++)
    for (long long int j = 0; j < (long long int)(m); j++) cin >> cost[i][j];
  for (long long int i = 0; i < (long long int)(n); i++) {
    long long int sum = 0, sum2 = 0;
    long long int first;
    for (long long int j = 0; j < (long long int)(k); j++)
      sum += cost[i][j], sum2 += cost[i + 1][j];
    first = sum;
    for (long long int j = k - 1; j < k - 1 + k && j < m; j++) {
      if (i >= 1) prev2[j] -= sum;
      sum -= cost[i][j - (k - 1)];
    }
    build(1, 0, m - 1);
    sum = first;
    for (long long int j = k - 1; j < m; j++) {
      dp[j] = query(1, 0, m - 1, k - 1, m - 1) + sum2 + sum;
      sum2 += cost[i + 1][j + 1] - cost[i + 1][j - (k - 1)];
      sum += cost[i][j + 1] - cost[i][j - (k - 1)];
      long long int toAdd = i >= 1 ? cost[i][j - (k - 1)] : 0;
      long long int toRemove = i >= 1 ? cost[i][j + 1] : 0;
      long long int e = j, s = max(j - (k - 1), k - 1);
      update(1, 0, m - 1, s, e, toAdd);
      s = j + 1, e = min(s + k - 1, m - 1);
      update(1, 0, m - 1, s, e, -toRemove);
    }
    swap(prev2, dp);
  }
  long long int ans = 0;
  for (long long int i = 0; i < (long long int)(m); i++)
    ans = max(ans, prev2[i]);
  cout << ans;
}
