#include<bits/stdc++.h>
#define N 1000
using namespace std;
long long tot=0;
typedef struct{long long v,flow;}ss;
vector<long long>edges[N];
ss edg[N*N];
long long dis[N];
long long S,T;
long long current[N];
void addedge(long long u,long long v,long long flow)
{
edg[tot]=(ss){v,flow};
edges[u].push_back(tot++);
edg[tot]=(ss){u,0};
edges[v].push_back(tot++);
}
bool bfs()
{
queue<long long>q;
q.push(S);
for(long long i=0;i<N;i++)dis[i]=LLONG_MAX/2;
dis[S]=1;
while(!q.empty())
{
int now=q.front();
q.pop();
long long Size=edges[now].size();
for(long long i=0;i<Size;i++)
{
ss &e=edg[edges[now][i]];
if(e.flow>0&&dis[e.v]==LLONG_MAX/2)
{
dis[e.v]=dis[now]+1;
q.push(e.v);
}
}
}
if(dis[T]==LLONG_MAX/2)return 0;
return 1;
}
long long dfs(long long x,long long flow)
{
if(x==T)return flow;
long long Size=edges[x].size();
for(long long i=current[x];i<Size;i++)
{
current[x]=i;
ss &e=edg[edges[x][i]];
if(dis[x]+1==dis[e.v]&&e.flow>0)
{
long long Flow=dfs(e.v,min(flow,(long long)e.flow));
if(Flow!=0)
{
e.flow-=Flow;
edg[edges[x][i]^1].flow+=Flow;
return Flow;
}
}
}
return 0;
}
long long dinic()
{
long long ans=0;
while(bfs())
{
memset(current,0,sizeof(current));
long long flow;
while(flow=dfs(S,LLONG_MAX))ans+=flow;
}
return ans;
}
int main()
{
int m,n,t=0;
int Map[35][35];
int num[35][35];
long long ans=0;
scanf("%d %d",&m,&n);
for(int i=1;i<=m;i++)
for(int j=1;j<=n;j++)
{
scanf("%d",&Map[i][j]);
num[i][j]=t++;
ans+=Map[i][j];
}
S=t++;
T=t++;
for(int i=1;i<=m;i++)
{
for(int j=(i+1)%2+1;j<=n;j+=2)
{
addedge(S,num[i][j],Map[i][j]);
if(i-1>=1)addedge(num[i][j],num[i-1][j],LLONG_MAX/2);
if(i+1<=m)addedge(num[i][j],num[i+1][j],LLONG_MAX/2);
if(j-1>=1)addedge(num[i][j],num[i][j-1],LLONG_MAX/2);
if(j+1<=n)addedge(num[i][j],num[i][j+1],LLONG_MAX/2);
}
}
for(int i=1;i<=m;i++)
{
for(int j=i%2+1;j<=n;j+=2)
{
addedge(num[i][j],T,Map[i][j]);
}
}
printf("%lld",ans-dinic());
return 0;
}