1 #include<bits/stdc++.h>
2 #define _for(i,a,b) for(register int i = (a);i < b;i ++)
3 #define _rep(i,a,b) for(register int i = (a);i > b;i --)
4 #define INF 0x3f3f3f3f
5 #define MOD 100000000
6 #define maxn 1000003
7 #define pb push_back
8 #define debug() printf("Miku Check OK!\n")
9 typedef long long ll;
10
11 using namespace std;
12 typedef pair<int,int> P;
13 inline ll read()
14 {
15 ll ans = 0;
16 char ch = getchar(), last = ' ';
17 while(!isdigit(ch)) last = ch, ch = getchar();
18 while(isdigit(ch)) ans = (ans << 1) + (ans << 3) + ch - '0', ch = getchar();
19 if(last == '-') ans = -ans;
20 return ans;
21 }
22 inline void write(ll x)
23 {
24 if(x < 0) x = -x, putchar('-');
25 if(x >= 10) write(x / 10);
26 putchar(x % 10 + '0');
27 }
28 int ver[maxn],Next[maxn],head[maxn],val[maxn];
29 int d[maxn];
30 int n,m,s,t,tot,maxflow;
31 const int N = 20000;
32 void add(int x,int y,int w)
33 {
34 ver[++tot] = y,Next[tot] = head[x],head[x] = tot,val[tot] = w;
35 }
36 bool bfs()
37 {
38 memset(d,0,sizeof(d));
39 queue<int> q;
40 q.push(s);
41 d[s] = 1;
42 while(!q.empty())
43 {
44 int x = q.front();
45 q.pop();
46 for(int i = head[x]; i; i = Next[i])
47 if(val[i] && !d[ver[i]])
48 {
49 q.push(ver[i]);
50 d[ver[i]] = d[x]+1;
51 if(ver[i]==t)
52 return true;
53 }
54 }
55 return false;
56 }
57 int dinic(int x,int flow)
58 {
59 if(x==t) return flow;
60 // k为子节点增量
61 int rest = flow, k;
62 for(int i = head[x]; i && rest; i = Next[i])
63 {
64 if(val[i] && d[ver[i]] == d[x]+1)
65 {
66 k = dinic(ver[i],min(rest,val[i]));
67 if(!k) d[ver[i]] = 0;
68 val[i] -= k;
69 val[i^1] += k;
70 rest -= k;
71 }
72 }
73 return flow - rest;
74 }
75 int a[103][103];
76 int getHash(int x,int y)
77 {
78 return x*m+y;
79 }
80 int main()
81 {
82 n = read();
83 m = read();
84 s = 0;
85 t = 2*N+1;
86 tot = 1;
87 maxflow = 0;
88 int zong = 0;
89
90 _for(i,1,n+1)
91 _for(j,1,m+1)
92 {
93 a[i][j] = read();
94 zong += a[i][j];
95 if((i+j)%2)
96 {
97 add(s,getHash(i,j),a[i][j]),add(getHash(i,j),s,0);
98 if(i > 1) {add(getHash(i,j),getHash(i-1,j),INF);add(getHash(i-1,j),getHash(i,j),0);}
99 if(i < n) {add(getHash(i,j),getHash(i+1,j),INF);add(getHash(i+1,j),getHash(i,j),0);}
100 if(j > 1) {add(getHash(i,j),getHash(i,j-1),INF);add(getHash(i,j-1),getHash(i,j),0);}
101 if(j < m) {add(getHash(i,j),getHash(i,j+1),INF);add(getHash(i,j+1),getHash(i,j),0);}
102 }
103 else
104 {add(getHash(i,j),t,a[i][j]);add(t,getHash(i,j),0);}
105 }
106
107 int flow = 0;
108 while(bfs())
109 while(flow = dinic(s,INF))
110 maxflow += flow;
111
112 write(zong-maxflow);
113 return 0;
114 }