#include <iostream>
#include <fstream>
#include <stdio.h>
#include <cstdlib>
#include <string>
#include <tuple>
#include <vector>
#include <map>
#include <list>
#include <set>
#include <queue>
#include <stack>
#include <algorithm>
#include <math.h>
#include <random>
#include <time.h>
#include <cassert>
using namespace std;
#define LL long long
#undef INT_MIN
#undef INT_MAX
#define INT_MIN -2147483648
#define INT_MAX 2147483647
#define LL_MIN -9223372036854775808
#define LL_MAX 9223372036854775807

int main(){
    iostream::sync_with_stdio(false);
    
    int H, W;
    cin >> H >> W;
    int A[30][30];
    for(int i=0; i<H; i++){
        for(int j=0; j<W; j++){
            cin >> A[i][j];
        }
    }

    int cost[30][30][900];//y, x, そこまでの道の長さ
    for(int i=0; i<H; i++){
        for(int j=0; j<W; j++){
            for(int k=0; k<H*W; k++){
                cost[i][j][k] = INT_MAX;
            }
        }
    }
    cost[0][0][0] = 0;
    bool already[30][30][900] = {};

    priority_queue<pair<int, pair<pair<int, int>, int>>> que;
    que.push({INT_MAX-0, {{0, 0}, 0}});
    int ans = INT_MAX;
    while(!que.empty()){
        int i = que.top().second.first.first;
        int j = que.top().second.first.second;
        int c = INT_MAX-que.top().first;
        int d = que.top().second.second;
        if(already[i][j][d] || d==W*H-1){
            que.pop();
            continue;
        }
        if(c >= ans) break;

        //上
        if(i != 0){
            int t = A[i-1][j] * (1+2*d) + 1;//切って、往復して、最後は一歩前へ
            if(cost[i-1][j][d+1] > c + t){
                cost[i-1][j][d+1] = c + t;
                que.push({INT_MAX-cost[i-1][j][d+1], {{i-1, j}, d+1}});
            }
        }
        //下
        if(i != H-1){
            int t = A[i+1][j] * (1+2*d) + 1;//切って、往復して、最後は一歩前へ
            if(cost[i+1][j][d+1] > c + t){
                cost[i+1][j][d+1] = c + t;
                que.push({INT_MAX-cost[i+1][j][d+1], {{i+1, j}, d+1}});
            }
            if(i+1==H-1 && j==W-1) ans = min(ans, c + A[i+1][j] * (1+2*d) - d);
        }
        //左
        if(j != 0){
            int t = A[i][j-1] * (1+2*d) + 1;//切って、往復して、最後は一歩前へ
            if(cost[i][j-1][d+1] > c + t){
                cost[i][j-1][d+1] = c + t;
                que.push({INT_MAX-cost[i][j-1][d+1], {{i, j-1}, d+1}});
            }
        }
        //右
        if(j != W-1){
            int t = A[i][j+1] * (1+2*d) + 1;//切って、往復して、最後は一歩前へ
            if(cost[i][j+1][d+1] > c + t){
                cost[i][j+1][d+1] = c + t;
                que.push({INT_MAX-cost[i][j+1][d+1], {{i, j+1}, d+1}});
            }
            if(i==H-1 && j+1==W-1) ans = min(ans, c + A[i][j+1] * (1+2*d) - d);
        }

        already[i][j][d] = true;
        que.pop();
    }
    cout << ans << endl;
    
    return 0;
}


/*
#include <iostream>
#include <fstream>
#include <stdio.h>
#include <math.h>
#include <time.h>
#include <string>
#include <tuple>
#include <vector>
#include <map>
#include <list>
#include <set>
#include <stack>
#include <queue>
#include <cstdlib>
#include <algorithm>
#include <random>
#include <cassert>
using namespace std;
#define LL long long
#undef INT_MIN
#undef INT_MAX
#define INT_MIN -2147483648
#define INT_MAX 2147483647
#define LL_MIN -9223372036854775808
#define LL_MAX 9223372036854775807

int main(){
    iostream::sync_with_stdio(false);
    
    
    return 0;
}
*/


Measured memory_bytes: 11004