#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
  
using namespace std;
using namespace __gnu_pbds;
 
#define ll long long
#define uint unsigned int
#define ull  unsigned long long
#define pb push_back
#define mk make_pair
#define ins insert
#define all(x) (x).begin(), (x).end()
#define rall(x) (x).rbegin(),(x).rend()
#define X first
#define Y second
#define umap unordered_map
#define speed() ios_base::sync_with_stdio(0);cin.tie(0);cout.tie(0)
#define setvalue(d,s,e,n) for(int qwe = s; qwe < e; ++qwe) d[qwe] = n
#define mset multiset
#define pqueue priority_queue
   
template<class T> using oset = tree<T, null_type, less<T>, rb_tree_tag, tree_order_statistics_node_update>;
        
const int  N = 3e3 + 12;
const int INF = 1e9;
const double PI = acos(-1);
const int MOD = 1e9 + 7;
const double eps = 1e-9;
const long long LINF = 1e18 + 3141;
ll a[N][N];
ll dp[N][N][4];
int n, m, k;

void maxself(ll &a, ll c) {
    a = max(a, c);
}
ll get(int x, int y, int t) {
    if(t < 0)
        return 0;
    if(x <= 0 || x > n || y > m || y <= 0)
        return 0;
    if(dp[x][y][t] != -1)
        return dp[x][y][t];
    
    assert(false);

    return -1;
    // if(t == 0) {
    //     ll fromUp = get(x - 1, y, 0);
    //     maxself(fromUp, get(x - 1, y, 1));
    //     maxself(fromUp, get(x - 1, y, 2));
    //     maxself(fromUp, get(x - 1, y, 3));
    //     ll fromLeft = get(x, y - 1, 0);
    //     return dp[x][y][t] = max(fromLeft, fromUp);
    // }
    // ll fromUp = 0;
    // if(a[x][y] && t == 1) {
    //     fromUp = get(x - 1, y, 0);
    //     maxself(fromUp, get(x - 1, y, 1));
    //     maxself(fromUp, get(x - 1, y, 2));
    //     maxself(fromUp, get(x - 1, y, 3));
    //     fromUp += a[x][y];
    // }
    // // dont take
    // ll fromLeft = get(x, y - 1, t);
    // maxself(fromLeft, get(x, y - 1, t - 1) + a[x][y]);

    // return dp[x][y][t] = max(fromLeft, fromUp);

} 
void solve(){
    cin >> n >> m >> k;
    while(k --) {
        int x, y, v;
        cin >> x >> y >> v;
        a[x][y] = v;
    }
    for(int i = 1; i <= n; ++i)
        for(int j = 1; j <= m; ++j)
            for(int t = 0; t <= 3; ++t)
                dp[i][j][t] = -1;

    
    for(int x = 1; x  <= n; ++x) {
        for(int y = 1; y <= m; ++y) {
            for(int t = 0; t <= 3; ++t) {
                if(t == 0) {
                    ll fromUp = get(x - 1, y, 0);
                    maxself(fromUp, get(x - 1, y, 1));
                    maxself(fromUp, get(x - 1, y, 2));
                    maxself(fromUp, get(x - 1, y, 3));
                    ll fromLeft = get(x, y - 1, 0);
                    dp[x][y][t] = max(fromLeft, fromUp);
                }else {
                    ll fromUp = 0;
                    if(a[x][y] && t == 1) {
                        fromUp = get(x - 1, y, 0);
                        maxself(fromUp, get(x - 1, y, 1));
                        maxself(fromUp, get(x - 1, y, 2));
                        maxself(fromUp, get(x - 1, y, 3));
                        fromUp += a[x][y];
                    }
                     // dont take
                    ll fromLeft = get(x, y - 1, t);
                    if(t - 1 >= 0)
                        maxself(fromLeft, get(x, y - 1, t - 1) + a[x][y]);
                    dp[x][y][t] = max(fromUp, fromLeft);
                }
            }
        }
    }
    
    // dp[x][y][t]  -> dp[x][y][t]  x row took k items
    //
    // dp[n][m][3] ->   dp[]
    // for(int i = 1; i <= n; ++i) {
    //     for(int j = 1; j <= m; ++j) {
    //         if(a[i][j]) {
    //             for(int k = 1; k <= 3; ++k) {
    //                 maxself(dp[i + 1][j][0], dp[i][j][k - 1] + a[i][j]);
    //                 maxself(dp[i][j + 1][k], dp[i][j][k - 1] + a[i][j]);
    //             }
    //         }
    //         for(int k = 0; k <= 3; ++k) {
    //             maxself(dp[i + 1][j][0], dp[i][j][k]);
    //             maxself(dp[i][j + 1][k], dp[i][j][k]);
    //         }
    //     }
    // }
    ll mx = 0;
    for(int i = 0; i <= 3; ++i){
        mx = max(mx, get(n, m, i));
    }
    cout << mx;
}
 
int main(){
    // speed();
    int t = 1;
    // cin >> t;
    while(t--)solve();
}

Measured memory_bytes: 356508