#include <iostream>
#include <queue>
#include <cstring>
using namespace std;
#define ios ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
const int N = 20010, M = 100010;
typedef long long LL;
struct edge{
LL v, c, ne;
}e[M * 2];
int h[N], idx = 1, cur[N], d[N];
int n, m, S, T;
void add(int u, int v, int w){
e[++ idx] = {v, w, h[u]};
h[u] = idx;
}
bool bfs(){
memset(d, 0, sizeof d);
queue<int> q;
d[S] = 1, q.push(S);
while(q.size()){
int u = q.front(); q.pop();
for(int i = h[u]; i; i = e[i].ne){
int v = e[i].v;
if(d[v] == 0 && e[i].c){
d[v] = d[u] + 1;
q.push(v);
if(v == T) return true;
}
}
}
return false;
}
LL dfs(int u, LL mf){
if(u == T) return mf;
LL s = 0;
for(int i = cur[u]; i; i = e[i].ne){
cur[u] = i;
int v = e[i].v;
if(d[v] == d[u] + 1 && e[i].c){
int f = dfs(v, min(mf, e[i].c));
e[i].c -= f, e[i ^ 1].c += f;
s += f, mf -= f;
if(mf == 0) break;
}
}
if(s == 0) d[u] = 0;
return s;
}
LL dinic(){
LL res = 0;
while(bfs()){
memcpy(cur, h, sizeof h);
res += dfs(S, 1e9);
}
return res;
}
int dir[4][2] = {
{0, 1}, {1, 0}, {0, -1}, {-1, 0}
};
int main(){
ios
cin >> n >> m;
S = 0, T = n * m + 1;
LL s = 0;
for(int i = 1; i <= n; i++)
for(int j = 1; j <= m; j++){
int x; cin >> x;
s += x;
int u = (i - 1) * m + j;
if((i + j) & 1){
add(S, u, x), add(u, S, 0);
for(int k = 0; k <= 4; k++){
int x = i + dir[k][0], y = j + dir[k][1];
if(x >= 1 && x <= n && y >= 1 && y <= m){
int v = (x - 1) * m + y;
add(u, v, 1e9), add(v, u, 0);
}
}
}
else add(u, T, x), add(T, u, 0);
}
cout << s - dinic();
return 0;
}