#include <bits/stdc++.h>
using namespace std;
void prepare() {}
int N;
struct Tree {
  long long t[10000];
  Tree() { memset((t), (0), sizeof(t)); }
  void build(long long *a, int i = 1, int l = 0, int r = N - 1) {
    if (i == 1) {
    }
    if (l == r)
      t[i] = a[l];
    else {
      int m = (l + r) / 2;
      build(a, i * 2, l, m);
      build(a, i * 2 + 1, m + 1, r);
      t[i] = max(t[i * 2], t[i * 2 + 1]);
    }
  }
  long long get_min(int l, int r, int i = 1, int tl = 0, int tr = N - 1) {
    if (l == tl && r == tr) return t[i];
    int m = (tl + tr) / 2;
    if (r <= m) return get_min(l, r, i * 2, tl, m);
    if (l > m) return get_min(l, r, i * 2 + 1, m + 1, tr);
    return max(get_min(l, m, i * 2, tl, m),
               get_min(m + 1, r, i * 2 + 1, m + 1, tr));
  }
  void update(int pos, int newval, int i = 1, int l = 0, int r = N - 1) {
    if (l == r)
      t[i] = newval;
    else {
      int m = (l + r) / 2;
      if (pos <= m)
        update(pos, newval, i * 2, l, m);
      else
        update(pos, newval, i * 2 + 1, m + 1, r);
      t[i] = t[i * 2] + t[i * 2 + 1];
    }
  }
};
long long a[1501][1501];
int n, m;
Tree t;
const long long INF = 1LL << 60;
bool solve() {
  scanf("%d%d", &n, &m);
  N = m;
  for (int i = 0; i < n; i++) {
    for (int j = 0; j < m; j++) scanf("%lld", &a[i][j]);
  }
  for (int i = 1; i < m; i++) a[0][i] = a[0][i - 1] + a[0][i];
  for (int i = 1; i < n; i++) {
    t = Tree();
    t.build(a[i - 1]);
    for (int j = 1; j < m; j++) a[i][j] += a[i][j - 1];
    for (int j = 0; j < m; j++) {
      if ((i & 1) && j + 1 < m) {
        long long x = t.get_min(j + 1, m - 1);
        a[i][j] += x;
      } else if (!(i & 1) && j > 0) {
        a[i][j] += t.get_min(0, j - 1);
      }
    }
    if (i & 1)
      a[i][m - 1] = -INF;
    else
      a[i][0] = -INF;
  }
  long long res = -INF;
  for (int i = 0; i < m; i++) res = max(res, a[n - 1][i]);
  cout << res << endl;
  return false;
}
int main() {
  prepare();
  while (solve())
    ;
  return 0;
}
