#include<iostream>
#include<cstdio>
#include<cstring>
#include<vector>
#include<queue>
#include<algorithm>
#include<cmath>
#include<map>
#define min(a,b) ((a) < (b) ? (a) : (b))
using namespace std;
const int INF = ~0U>>1;
const int maxn = 2E5 + 20;
const int maxm = 2E6 + 20;
struct E{
int to,cap,flow; E(){}
E(int to,int cap,int flow): to(to),cap(cap),flow(flow){}
}edgs[maxm];
struct Point{
int x,y; Point(){}
Point(int x,int y): x(x),y(y){}
bool operator < (const Point &B) const
{
if (x < B.x) return 1;
if (x > B.x) return 0;
return y < B.y;
}
}p[maxn];
int C,R,n,m,s,t,cnt,tot,L[maxn],cur[maxn],w[maxn],A[maxn],B[maxn];
queue <int> Q;
map <Point,int> M;
vector <int> v[maxn];
inline int getint()
{
char ch = getchar(); int ret = 0;
while (ch < '0' || '9' < ch) ch = getchar();
while ('0' <= ch && ch <= '9')
ret = ret * 10 + ch - '0',ch = getchar();
return ret;
}
inline void Add(int x,int y,int cap)
{
v[x].push_back(cnt); edgs[cnt++] = E(y,cap,0);
v[y].push_back(cnt); edgs[cnt++] = E(x,0,0);
}
void Build()
{
for (int i = 1; i <= n; i++)
{
Add(A[i],B[i],w[i]);
if (p[i].x % 4 == 1 && !(p[i].y & 1))
{
Add(s,A[i],INF);
if (M.count(Point(p[i].x,p[i].y - 1)))
Add(B[i],A[M[Point(p[i].x,p[i].y - 1)]],w[i]);
if (M.count(Point(p[i].x,p[i].y + 1)))
Add(B[i],A[M[Point(p[i].x,p[i].y + 1)]],w[i]);
if (M.count(Point(p[i].x - 1,p[i].y)))
Add(B[i],A[M[Point(p[i].x - 1,p[i].y)]],w[i]);
}
else if (p[i].x % 4 == 0 && (p[i].y & 1))
{
Add(s,A[i],INF);
if (M.count(Point(p[i].x,p[i].y - 1)))
Add(B[i],A[M[Point(p[i].x,p[i].y - 1)]],w[i]);
if (M.count(Point(p[i].x,p[i].y + 1)))
Add(B[i],A[M[Point(p[i].x,p[i].y + 1)]],w[i]);
if (M.count(Point(p[i].x + 1,p[i].y)))
Add(B[i],A[M[Point(p[i].x + 1,p[i].y)]],w[i]);
}
else if (p[i].x % 4 == 1 && (p[i].y & 1))
{
if (M.count(Point(p[i].x + 1,p[i].y)))
Add(B[i],A[M[Point(p[i].x + 1,p[i].y)]],w[i]);
}
else if (p[i].x % 4 == 0 && !(p[i].y & 1))
{
if (M.count(Point(p[i].x - 1,p[i].y)))
Add(B[i],A[M[Point(p[i].x - 1,p[i].y)]],w[i]);
}
else if (p[i].x % 4 == 2 && (p[i].y & 1))
{
if (M.count(Point(p[i].x + 1,p[i].y)))
Add(B[i],A[M[Point(p[i].x + 1,p[i].y)]],w[i]);
if (M.count(Point(p[i].x,p[i].y - 1)))
Add(B[i],A[M[Point(p[i].x,p[i].y - 1)]],w[i]);
if (M.count(Point(p[i].x,p[i].y + 1)))
Add(B[i],A[M[Point(p[i].x,p[i].y + 1)]],w[i]);
}
else if (p[i].x % 4 == 3 && !(p[i].y & 1))
{
if (M.count(Point(p[i].x - 1,p[i].y)))
Add(B[i],A[M[Point(p[i].x - 1,p[i].y)]],w[i]);
if (M.count(Point(p[i].x,p[i].y - 1)))
Add(B[i],A[M[Point(p[i].x,p[i].y - 1)]],w[i]);
if (M.count(Point(p[i].x,p[i].y + 1)))
Add(B[i],A[M[Point(p[i].x,p[i].y + 1)]],w[i]);
}
else if ((p[i].x % 4 == 2 && !(p[i].y & 1)) || (p[i].x % 4 == 3 && (p[i].y & 1))) Add(B[i],t,w[i]);
}
}
inline bool BFS()
{
for (int i = 1; i <= t; i++) L[i] = 0;
Q.push(s); L[s] = 1;
while (!Q.empty())
{
int k = Q.front(); Q.pop();
for (int i = 0; i < v[k].size(); i++)
{
E e = edgs[v[k][i]];
if (e.cap == e.flow || L[e.to]) continue;
L[e.to] = L[k] + 1; Q.push(e.to);
}
}
return L[t];
}
inline int Dinic(int x,int a)
{
if (x == t) return a; int flow = 0;
for (int &i = cur[x]; i < v[x].size(); i++)
{
E &e = edgs[v[x][i]];
if (e.cap == e.flow || L[e.to] != L[x] + 1) continue;
int f = Dinic(e.to,min(e.cap - e.flow,a));
if (!f) continue; flow += f; e.flow += f;
edgs[v[x][i]^1].flow -= f; a -= f;
if (!a) return flow;
}
if (!flow) L[x] = -1; return flow;
}
int main()
{
#ifdef DMC
freopen("DMC.txt","r",stdin);
#endif
C = getint(); R = getint(); n = getint();
for (int i = 1; i <= n; i++)
{
int x = getint(),y;
y = getint(); w[i] = getint();
M[p[i] = Point(x,y)] = i;
A[i] = ++tot; B[i] = ++tot;
}
s = ++tot; t = ++tot;
Build(); int MinCut = 0;
while (BFS())
{
for (int i = 1; i <= t; i++) cur[i] = 0;
MinCut += Dinic(s,INF);
}
cout << MinCut << endl;
return 0;
}