Problem:
Max Score: $600$ Points

Problem Statement

Sigma and his brother Sugim are in the $H \times W$ grid. They wants to buy some souvenirs.

Their start position is upper-left cell, and the goal position is lower-right cell.

Some cells has a souvenir shop. At $i$-th row and $j$-th column, there is $a_{i, j}$ souvenirs.

In one move, they can go left, right, down, and up cell.

But they have little time, so they can move only $H+W-2$ times.

They wanted to buy souvenirs as many as possible, but they had no computer, so they couldn't get the maximal numbers of souvenirs.

Write a program and calculate the maximum souvenirs they can get, and help them.

Input

The input is given from standard input in the following format.

$H \ W$
$a_{1, 1} \ a_{1, 2} \ \cdots \ a_{1, W}$
$a_{2, 1} \ a_{2, 2} \ \cdots \ a_{2, W}$
$\vdots \ \ \ \ \ \ \ \ \ \ \vdots \ \ \ \ \ \ \ \ \ \ \vdots$
$a_{H, 1} \ a_{H, 2} \ \cdots \ a_{H, W}$

Output

Print the maximum number of souvenirs they can get.

Constraints

$1 \le H, W \le 200$

$0 \le a_{i, j} \le 10^5$

Subtasks

Subtask 1 [ 50 points ]

The testcase in the subtask satisfies $1 \le H \le 2$.

Subtask 2 [ 80 points ]

The testcase in the subtask satisfies $1 \le H \le 3$.

Subtask 3 [ 120 points ]

The testcase in the subtask satisfies $1 \le H, W \le 7$.

Subtask 4 [ 150 points ]

The testcase in the subtask satisfies $1 \le H, W \le 30$.

Subtask 5 [ 200 points ]

There are no additional constraints.

Sample Input 1

3 3
1 0 5
2 2 3
4 2 4

Sample Output 1

21

The cell at $i$-th row and $j$-th column is denoted $(i, j)$.

In this case, one of the optimal solution is this:

Sigma moves $(1, 1) -> (1, 2) -> (1, 3) -> (2, 3) -> (3, 3)$.

Sugim moves $(1, 1) -> (2, 1) -> (3, 1) -> (3, 2) -> (3, 3)$.

Then, they can get $21$ souvernirs.

Sample Input 2

6 6
1 2 3 4 5 6
8 6 9 1 2 0
3 1 4 1 5 9
2 6 5 3 5 8
1 4 1 4 2 1
2 7 1 8 2 8

Sample Output 2

97

Writer : square1001

Solution in Java8 (OpenJDK 1.8.0) (judge verdict: Time Limit Exceeded)

import java.util.*;

public class Main {
    static HashMap<Integer, Integer> dp = new HashMap<>();
    static int h;
    static int w;
    static int[][] field;
    public static void main(String[] args) throws Exception {
        Scanner sc = new Scanner(System.in);
        h = sc.nextInt();
        w = sc.nextInt();
        field = new int[h][w];
        for (int i = 0; i < h; i++) {
            for (int j = 0; j < w; j++) {
                field[i][j] = sc.nextInt();
            }
        }
        System.out.println(dfw(h - 1, w - 1, h - 1, w - 1));
    }
    
    static int dfw(int h1, int w1, int h2, int w2) {
        if (h1 == 0 && w1 == 0 && h2 == 0 && w2 == 0) {
            return field[0][0];
        }
        if (h1 < 0 || w1 < 0 || h2 < 0 || w2 < 0) {
            return -1;
        }
        int first = h1 * w + w1;
        int second = h2 * w + w2;
        int key = Math.min(first, second) * h * w + Math.max(first, second);
        if (dp.containsKey(key)) {
            return dp.get(key);
        }
        int max = 0;
        int now;
        if (h1 == h - 1 && w1 == w - 1 && h2 == h - 1 && w2 == w - 1) {
            now = field[h - 1][w - 1];
        } else if (h1 == h2 && w1 == w2) {
            return -1;
        } else {
            now = field[h1][w1] + field[h2][w2];
        }
        max = Math.max(max, dfw(h1 - 1, w1, h2 - 1, w2));
        max = Math.max(max, dfw(h1 - 1, w1, h2, w2 - 1));
        max = Math.max(max, dfw(h1, w1 - 1, h2 - 1, w2));
        max = Math.max(max, dfw(h1, w1 - 1, h2, w2 - 1));
        dp.put(key, max + now);
        return max + now;
    }
}