import std.stdio, std.array, std.string, std.conv, std.algorithm;
import std.typecons, std.range, std.random, std.math, std.container;
import std.numeric, std.bigint, core.bitop, core.stdc.string;

void main() {
    auto s = readln.split.map!(to!int);
    auto H = s[0];
    auto W = s[1];
    auto A = H.iota.map!(_ => readln.split.to!(long[])).array;

    auto dp = new long[][][](H+W-1, H, H);
    dp[0][0][0] = A[0][0];

    foreach (i; 0..H+W-2) {
        foreach (r1; 0..H) {
            foreach (r2; 0..H) {
                int c1 = i - r1;
                int c2 = i - r2;
                if (c1 < 0 || c2 < 0 || c1 >= W || c2 >= W) continue;
                foreach (j; 0..2) {
                    foreach (k; 0..2) {
                        int nr1 = r1 + j;
                        int nc1 = c1 + 1 - j;
                        int nr2 = r2 + k;
                        int nc2 = c2 + 1 - k;
                        if (nr1 >= H || nc1 >= W || nr2 >= H || nc2 >= W) continue;
                        if (nr1 == nr2 && nc1 == nc2) {
                            dp[i+1][nr1][nr2] = max(dp[i+1][nr1][nr2], dp[i][r1][r2] + A[nr1][nc1]);
                        } else {
                            dp[i+1][nr1][nr2] = max(dp[i+1][nr1][nr2], dp[i][r1][r2] + A[nr1][nc1] + A[nr2][nc2]);
                        }
                    }
                }
            }
        }
    }

    dp[H+W-2].map!(d => d.reduce!max).reduce!max.writeln;
}
