#include <bits/stdc++.h>
using namespace std;
const int Max = 1100;
const int mov[4][2][2] = {
    {{1, 0}, {0, 1}}, {{-1, 0}, {0, 1}}, {{-1, 0}, {0, -1}}, {{1, 0}, {0, -1}}};
int ma[Max][Max];
int n, m;
int dp[4][Max][Max] = {0};
void input() {
  for (int i = 0; i < n; i++) {
    for (int j = 0; j < m; j++) {
      scanf("%d", &ma[i][j]);
    }
  }
}
void solve(int k, pair<int, int> b) {
  dp[k][b.first][b.second] = ma[b.first][b.second];
  queue<pair<int, int> > que;
  pair<int, int> temp;
  que.push(b);
  while (!que.empty()) {
    temp = que.front();
    que.pop();
    for (int i = 0; i < 2; i++) {
      int x = temp.first + mov[k][i][0];
      int y = temp.second + mov[k][i][1];
      if (x < n && x >= 0 && y < m && y >= 0) {
        if (dp[k][x][y] == 0) que.push(make_pair(x, y));
        dp[k][x][y] =
            max(dp[k][x][y], dp[k][temp.first][temp.second] + ma[x][y]);
      }
    }
  }
}
void brute_force() {
  int ans = 0, temp;
  for (int i = 1; i < n - 1; i++) {
    for (int j = 1; j < m - 1; j++) {
      temp =
          dp[0][i - 1][j] + dp[1][i][j - 1] + dp[2][i + 1][j] + dp[3][i][j + 1];
      ans = max(ans, temp);
      temp =
          dp[0][i][j - 1] + dp[1][i + 1][j] + dp[2][i][j + 1] + dp[3][i - 1][j];
      ans = max(ans, temp);
    }
  }
  printf("%d\n", ans);
}
void output(int k) {
  for (int i = 0; i < n; i++) {
    for (int j = 0; j < m; j++) {
      printf("%d ", dp[k][i][j]);
    }
    cout << endl;
  }
}
int main() {
  cin >> n >> m;
  input();
  solve(0, make_pair(0, 0));
  solve(1, make_pair(n - 1, 0));
  solve(2, make_pair(n - 1, m - 1));
  solve(3, make_pair(0, m - 1));
  brute_force();
  return 0;
}
