#include <bits/stdc++.h>
using namespace std;
const int N = 51;
const int M = 2e4;
const int SZ = 1 << 16;
int n, m, k;
int a[N][M];
int arr[N][M];
int dp[N][M];
int d[SZ];
int tree[SZ];
void build(int pos, int l, int r, int i) {
  if (r - l == 1) {
    tree[pos] = dp[i][l];
  } else {
    build(2 * pos + 1, l, l + r >> 1, i);
    build(2 * pos + 2, l + r >> 1, r, i);
    tree[pos] = max(tree[2 * pos + 1], tree[2 * pos + 2]);
  }
}
void push(int pos, int l, int r) {
  if (d[pos]) {
    if (r - l != 1) {
      d[2 * pos + 1] += d[pos];
      d[2 * pos + 2] += d[pos];
    }
    tree[pos] += d[pos];
    d[pos] = 0;
  }
}
void add(int pos, int l, int r, int la, int ra, int x) {
  push(pos, l, r);
  if (r <= la || ra <= l) {
    return;
  } else if (la <= l && r <= ra) {
    d[pos] += x;
    push(pos, l, r);
  } else {
    add(2 * pos + 1, l, l + r >> 1, la, ra, x);
    add(2 * pos + 2, l + r >> 1, r, la, ra, x);
    tree[pos] = max(tree[2 * pos + 1], tree[2 * pos + 2]);
  }
}
int solve() {
  for (int i = 0; i < n; ++i) {
    bool flag = i;
    fill(tree, tree + SZ, 0);
    fill(d, d + SZ, 0);
    build(0, 0, m, i);
    for (int j = k; j < m; ++j) {
      add(0, 0, m, max(0, j - k + 1), j + 1, flag * a[i][j]);
    }
    int s = 0;
    for (int j = 0; j < k; ++j) {
      s += a[i][j];
    }
    for (int j = 0; j + k <= m; ++j) {
      push(0, 0, m);
      dp[i + 1][j] = tree[0] + s;
      s -= a[i][j];
      add(0, 0, m, max(0, j - k + 1), j + 1, flag * a[i][j]);
      if (j + k < m) {
        s += a[i][j + k];
        add(0, 0, m, j + 1, j + k + 1, flag * -a[i][j + k]);
      }
    }
  }
  int ans = 0;
  for (int j = 0; j + k <= m; ++j) {
    ans = max(ans, dp[n][j]);
  }
  return ans;
}
int stupid_solve() {
  for (int i = 0; i < n; ++i) {
    bool flag = i;
    for (int j = 0; j < m; ++j) {
      arr[i][j] = dp[i][j];
    }
    auto cmp = [](int x, int y) { return x > y; };
    auto f = multiset<int, decltype(cmp)>(cmp);
    for (int j = 0; j < m; ++j) {
      for (int l = max(j, k); l < min(j + k, m); ++l) {
        arr[i][j] += flag * a[i][l];
      }
      f.insert(arr[i][j]);
    }
    int s = 0;
    for (int j = 0; j < k; ++j) {
      s += a[i][j];
    }
    for (int j = 0; j + k <= m; ++j) {
      dp[i + 1][j] = *f.begin() + s;
      s -= a[i][j];
      for (int l = max(0, j - k + 1); l <= j; ++l) {
        f.erase(f.find(arr[i][l]));
        arr[i][l] += flag * a[i][j];
        f.insert(arr[i][l]);
      }
      if (j + k < m) {
        s += a[i][j + k];
        for (int l = j + 1; l <= j + k; ++l) {
          f.erase(f.find(arr[i][l]));
          arr[i][l] -= flag * a[i][j + k];
          f.insert(arr[i][l]);
        }
      }
    }
  }
  int ans = 0;
  for (int j = 0; j + k <= m; ++j) {
    ans = max(ans, dp[n][j]);
  }
  return ans;
}
void gen_test() {
  n = 3;
  m = 6;
  k = 3;
  for (int i = 0; i < n; ++i) {
    for (int j = 0; j < m; ++j) {
      a[i][j] = rand() % 10;
    }
  }
}
void print_test() {
  cout << n << ' ' << m << ' ' << k << '\n';
  for (int i = 0; i < n; ++i) {
    for (int j = 0; j < m; ++j) {
      cout << a[i][j] << ' ';
    }
    cout << '\n';
  }
}
void stresstest() {
  int n_test = 1;
  while (true) {
    cout << "TEST #" << n_test++ << '\n';
    gen_test();
    print_test();
    if (solve() != stupid_solve()) {
      cout << "FAIL\n";
      cout << "MY ANS: " << solve() << '\n';
      cout << "RIGHT ANS: " << stupid_solve() << '\n';
      system("pause");
    } else {
      cout << "SUCCES\n";
    }
  }
}
signed main() {
  ios_base::sync_with_stdio(false);
  cin.tie(NULL);
  cout.tie(NULL);
  cin >> n >> m >> k;
  for (int i = 0; i < n; ++i) {
    for (int j = 0; j < m; ++j) {
      cin >> a[i][j];
    }
  }
  cout << solve() << '\n';
  return 0;
}
