#pragma comment(linker, "/STACK:36777216")

#ifdef _MSC_VER
#define _CRT_SECURE_NO_WARNINGS
#endif

#ifdef __ASD__
#undef NDEBUG
#endif

#include <thread>
#include <unordered_set>
#include <vector>
#include <memory.h>
#include <list>
#include <map>
#include <unordered_map>
#include <set>
#include <queue>
#include <deque>
#include <stack>
#include <string>
#include <bitset>
#include <algorithm>
#include <functional>
#include <numeric>
#include <stdio.h>
#include <utility>
#include <sstream>
#include <iostream>
#include <iomanip>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <ctime>
#include <random>
#include <string>
#include <cassert>


#define getcx _getchar_nolock

using namespace std;

namespace std {
    string to_string(string const& s) { return '"' + s + '"'; }

    string to_string(char c) { return string(1, c); }

    string to_string(const char* s) { return to_string((string) s); }

    string to_string(bool b) { return (b ? "true" : "false"); }

    template<class T1, class T2>
    string to_string(pair<T1, T2> p) { return "(" + to_string(p.first) + ", " + to_string(p.second) + ")"; }

    template<class T>
    string to_string(vector<vector<T>> c) {
        string s = "\n";
        for (auto v : c) {
            s += "[";
            for (auto x : v) {
                string t = to_string(x);
                s += t;
                s += ",";
            }
            if (s.size() > 1)s.pop_back();
            s += "]\n";
        }

        if (!c.empty()) { s.pop_back(); }
        return s;
    }

    template<class T>
    string to_string(T c) {
        string s = "[";
        for (auto vvv : c) { s += to_string(vvv) + ","; }
        s += "]";
        return s;
    }

    void debug_impl() { cerr << endl; };

    template<typename T1, typename... T2>
    void debug_impl(T1 a, T2 ... b) {
        cerr << " " << to_string(a);
        debug_impl(b...);
    }
}

template<typename T>
struct reversion_wrapper {
    T& iterable;
};


template<typename T>
auto begin(reversion_wrapper<T> w) { return std::rbegin(w.iterable); }

template<typename T>
auto end(reversion_wrapper<T> w) { return std::rend(w.iterable); }

template<typename T>
reversion_wrapper<T> reverse(T&& iterable) { return { iterable }; }

template<class T>
T gcd(T a, T b) {
    while (a && b)if (a > b)a %= b; else b %= a;
    return a + b;
}

template<class T>
T powmod(T a, T b, T mod) {
    if (b == 0)return 1 % mod;
    T res = powmod(a, b / 2, mod);
    res *= res;
    res %= mod;
    if (b & 1) {
        res *= a;
        res %= mod;
    }
    return res;
}

template<class T>
T inv(T a, T mod) { return powmod(a, mod - 2, mod); }

#ifdef __ASD__
#define dbg(...) cerr << "[" << #__VA_ARGS__ << "]: ", debug_impl(__VA_ARGS__)
//#define endl "\n"
#else
#define dbg(...) ;
#define endl "\n"
#endif

typedef long long lng;
typedef vector<int> vi;
typedef vector<string> vs;
typedef vector<lng> vll;
typedef pair<int, int> pii;
typedef vector<pair<int, int>> vpii;
typedef vector<pair<lng, lng>> vpll;
#define forn(i, n) for(int i=0;i<static_cast<int>(n);i++)
#define pb push_back
#define all(a) a.begin(), a.end()
#define yesno(p) if((p))cout<<"Yes"<<endl; else cout <<"No"<<endl;

lng dp[3000][3000][4];
lng grid[3000][3000];

lng calc(int x, int y, int k, int n, int m) {
    lng& res = dp[x][y][k];

    if (res != -1) {
        return res;
    }

    if (k && grid[x][y]) {
        if (x) {
            for (int i = 0; i <= 3; i++) {
                lng t = calc(x - 1, y, i, n, m);
                t += grid[x][y];
                res = max(res, t);
            }
        }

        if (y) {
            lng t = calc(x, y - 1, k - 1, n, m);
            t += grid[x][y];
            res = max(res, t);
        }
    }

    {
        if (y) {
            lng t = calc(x, y - 1, k, n, m);
            res = max(res, t);
        }

    }

    if (x) {
        for (int i = 0; i <= 3; i++) {
            lng t = calc(x - 1, y, i, n, m);
            res = max(res, t);
        }

    }


    return res;
}

lng solve(int n, int m, vector<tuple<int, int, int>> items) {
    memset(grid, 0, sizeof(grid));

    for (auto t:items) {
        int x = std::get<0>(t);
        int y = std::get<1>(t);
        int c = std::get<2>(t);
        grid[x][y] = c;
    }


    memset(dp, -1, sizeof(dp));
    dp[0][0][0] = 0;
    if (grid[0][0]) {
        dp[0][0][1] = grid[0][0];
    }

    lng res = 0;
    for (int i = 0; i <= 3; i++) {
        lng cur = calc(n - 1, m - 1, i, n, m);
        res = max(res, cur);
    }

    return res;
}


int main() {

#ifdef __ASD__
    auto start_t = chrono::steady_clock::now();
    freopen("input.txt", "rb", stdin);
    //        freopen("1nul", "w", stderr);
    //    freopen("output.txt", "w", stdout);
#else
    ios_base::sync_with_stdio(false);
#endif


    int n, m, k;
    while (cin >> n >> m >> k) {
        vector<tuple<int, int, int>> v;
        while (k--) {
            int x, y, c;
            cin >> x >> y >> c;
            x--;
            y--;
            v.emplace_back(x, y, c);
        }

        lng res = solve(n, m, v);

        cout << res << endl;
    }

#ifdef __ASD__
    auto finish_t = chrono::steady_clock::now();
    cerr << "Elapsed " << chrono::duration_cast<chrono::milliseconds>(finish_t - start_t).count() << " ms" << endl;
#endif
    return 0;

}

Measured memory_bytes: 359628