#include <bits/stdc++.h>
#pragma warning(disable : 4996)
using namespace std;
int mp[1005][1005], n, m, st, ed;
int dx[4][2] = {0, 1, 1, 0, -1, 0, -1, 0};
int dy[4][2] = {1, 0, 0, -1, 0, 1, 0, -1};
long long ul[1005][1005], dl[1005][1005], ur[1005][1005], dr[1005][1005];
bool in[1005][1005];
struct Node {
  int x, y;
  Node() {}
  Node(int xx, int yy) : x(xx), y(yy) {}
};
void bfs(Node node, long long value[1005][1005], int i, int n, int m) {
  memset(in, 0, sizeof(in));
  queue<Node> q;
  q.push(node);
  in[node.x][node.y];
  value[node.x][node.y] = mp[node.x][node.y];
  while (!q.empty()) {
    Node t = q.front();
    q.pop();
    in[t.x][t.y] = 0;
    for (int j = 0; j < 2; j++) {
      int xx = t.x + dx[i][j];
      int yy = t.y + dy[i][j];
      if (xx < 1 || xx > n || yy < 1 || yy > m) continue;
      if (value[t.x][t.y] + mp[xx][yy] > value[xx][yy]) {
        value[xx][yy] = value[t.x][t.y] + mp[xx][yy];
        if (!in[xx][yy]) {
          q.push(Node(xx, yy));
          in[xx][yy] = 1;
        }
      }
    }
  }
}
int main() {
  int n, m;
  cin >> n >> m;
  memset(mp, -1, sizeof(mp));
  for (int i = 1; i <= n; i++)
    for (int j = 1; j <= m; j++) {
      ul[i][j] = dl[i][j] = ur[i][j] = dr[i][j] = 0;
      cin >> mp[i][j];
    }
  bfs(Node(1, 1), ul, 0, n, m);
  bfs(Node(1, m), ur, 1, n, m);
  bfs(Node(n, 1), dl, 2, n, m);
  bfs(Node(n, m), dr, 3, n, m);
  long long ans = 0;
  for (int i = 2; i < n; i++)
    for (int j = 2; j < m; j++) {
      long long temp =
          ul[i - 1][j] + ur[i][j + 1] + dl[i][j - 1] + dr[i + 1][j];
      ans = max(ans, temp);
      temp = ul[i][j - 1] + dr[i][j + 1] + ur[i - 1][j] + dl[i + 1][j];
      ans = max(ans, temp);
    }
  cout << ans << endl;
}
