#include <iostream>
#include <cstring>
#include <algorithm>
#include <cstdio>
#include <cmath>
#include <vector>
#include <queue>
using namespace std;
const int N = 10005;
typedef long long ll;
int n , m , s , t , tot = 0;
int sum = 0 , head[N];
struct edge{
int to , wei , nxt;
}e[8*N];
int dx[4] = { 0 , 1 , 0 , -1 };
int dy[4] = { 1 , 0 , -1 , 0 };
int dep[N];
void add( int u , int v , int w ){
e[++tot].to = v ; e[tot].wei = w ; e[tot].nxt = head[u] ; head[u] = tot;
e[++tot].to = u ; e[tot].wei = 0 ; e[tot].nxt = head[v] ; head[v] = tot;
}
bool bfs( ){
queue<int> q;
memset( dep , 0 , sizeof( dep ) );
dep[s] = 1;
q.push( s );
while( !q.empty( ) ){
int u = q.front( );
q.pop( );
for( int i = head[u] ; i ; i = e[i].nxt ){
int v = e[i].to;
if( !dep[v] && e[i].wei ){
dep[v] = dep[u] + 1;
q.push( v );
}
}
}
if( dep[t] == 0 ) return 0;
else return 1;
}
int dfs( int u , int dis ){
if( u == t ) return dis;
for( int i = head[u] ; i ; i = e[i].nxt ){
int v = e[i].to;
if( e[i].wei != 0 && ( dep[v] == dep[u] + 1 ) ){
int di = dfs( v , min( dis , e[i].wei ) );
if( di > 0 ){
e[i].wei -= di;
e[i^1].wei += di;
return di;
}
}
}
return 0;
}
int dinic( ){
int ans = 0;
while( bfs( ) ){
while( int d = dfs( s , 0x3f3f3f3f ) ){
ans += d;
}
}
return ans;
}
int main( ) {
cin >> n >> m;
s = 0;
t = n*m+1;
int w;
for( int i = 1 ; i <= n ; i++ ){
for( int j = 1 ; j <= m ; j++ ){
cin >> w;
sum += w;
if( (i + j)&1 ){
for( int k = 0 ; k < 4 ; k++ ){
int ii = i + dx[k] , jj = j + dy[k];
if( ii < 1 || ii > n || jj < 1 || jj > m ) continue;
add( ( i - 1 )*m + j , ( ii - 1 )*m + jj , 0x3f3f3f3f );
}
add( s , ( i - 1 )*m + j , w );
}else{
add( ( i - 1 )*m + j , t , w );
}
}
}
int ans = dinic( );
cout << sum-ans <<endl;
return 0;
}