#include <bits/stdc++.h>
using namespace std;
void solve() {
  int n, m;
  scanf("%d%d", &n, &m);
  long long gym[n + 2][m + 2];
  memset(gym, 0, sizeof(gym));
  for (int i = 1; i < n + 1; i += 1)
    for (int j = 1; j < m + 1; j += 1) cin >> gym[i][j];
  long long dp1[n + 2][m + 2], dp2[n + 2][m + 2];
  long long dp1rev[n + 2][m + 2], dp2rev[n + 2][m + 2];
  memset(dp1, 0, sizeof(dp1));
  memset(dp1rev, 0, sizeof(dp1rev));
  memset(dp2, 0, sizeof(dp2));
  memset(dp2rev, 0, sizeof(dp2rev));
  for (int i = n; i > 1 - 1; i -= 1)
    for (int j = m; j > 1 - 1; j -= 1)
      dp1[i][j] = gym[i][j] + max(dp1[i + 1][j], dp1[i][j + 1]);
  for (int i = 1; i < n + 1; i += 1)
    for (int j = m; j > 1 - 1; j -= 1)
      dp2[i][j] = gym[i][j] + max(dp2[i - 1][j], dp2[i][j + 1]);
  for (int i = 1; i < n + 1; i += 1)
    for (int j = 1; j < m + 1; j += 1)
      dp1rev[i][j] = gym[i][j] + max(dp1rev[i][j - 1], dp1rev[i - 1][j]);
  for (int i = n; i > 1 - 1; i -= 1)
    for (int j = 1; j < m + 1; j += 1)
      dp2rev[i][j] = gym[i][j] + max(dp2rev[i][j - 1], dp2rev[i + 1][j]);
  long long mx = 0;
  for (int i = 2; i < n - 1 + 1; i += 1)
    for (int j = 2; j < m - 1 + 1; j += 1) {
      mx = max(mx, dp1rev[i - 1][j] + dp1[i + 1][j] + dp2[i][j + 1] +
                       dp2rev[i][j - 1]);
      mx = max(mx, dp1rev[i][j - 1] + dp1[i][j + 1] + dp2[i - 1][j] +
                       dp2rev[i + 1][j]);
    }
  cout << mx << endl;
}
int main() {
  if (0) {
    double _time = clock();
    freopen("input.txt", "r", stdin);
    solve();
    printf("%0.4f sec\n", (clock() - _time) / CLOCKS_PER_SEC);
    return 0;
  }
  solve();
  return 0;
}
