/*
AUTHOR: Aman Raj
LANG: C++
*/

using namespace std;

typedef   long long  int ll;
#include <bits/stdc++.h>


//setbase - cout << setbase (16); cout << 100 << endl; Prints 64
//setfill -   cout << setfill ('x') << setw (5); cout << 77 << endl; prints xxx77
//setprecision - cout << setprecision (14) << f << endl; Prints x.xxxx
//cout.precision(x)  cout<<fixed<<val;  // prints x digits after decimal in val
#define fast  ios_base::sync_with_stdio(false); cin.tie(0);  cout.tie(0);
#define all(a) a.begin(),a.end()
//#define mod 998244353


#define mod   1000000007

#define inf 1e18
//#define mod 3
#define flush fflush(stdout)

#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
using namespace __gnu_pbds;
typedef cc_hash_table<ll, ll, hash< ll > > ht;

// find_by_order()  // order_of_key
typedef tree<
    ll,
    null_type,
    less<ll>,
    rb_tree_tag,
    tree_order_statistics_node_update>
    ordered_set;






ll power1(ll a, ll b)//a raised to power b
   {  if(b<=0) return 1; if(b==1) return a;
       ll c=power1(a,b/2);
        c*=c;c%=mod;if(b%2==1) c*=a;c%=mod;
        return c;
   }
   ll mi(ll a,ll m)
   { ll c= power1(a,m-2);

     return c;
   }



 struct less_then_greater {
    template<typename T, typename U>
    bool operator()(T const& lhs, U const& rhs) const {
        if (lhs.first < rhs.first) return true;
        if (rhs.first < lhs.first) return false;
        return lhs.second > rhs.second;
    }
};

 /*std::priority_queue<std::pair<int, int>,
                    std::vector<std::pair<int, int>>,
                    less_then_greater
                   > pq;*/
  /*   #define MAXN 1000001
ll spf[MAXN];
void sieve()
{
    spf[1] = 1;
    for (int i=2; i<MAXN; i++)

        // marking smallest prime factor for every
        // number to be itself.
        spf[i] = i;

    // separately marking spf for every even
    // number as 2
    for (int i=4; i<MAXN; i+=2)
        spf[i] = 2;

    for (int i=3; i*i<MAXN; i++)
    {
        // checking if i is prime
        if (spf[i] == i)
        {
            // marking SPF for all numbers divisible by i
            for (int j=i*i; j<MAXN; j+=i)

                // marking spf[j] if it is not
                // previously marked
                if (spf[j]==j)
                    spf[j] = i;
        }
    }
}
vector<ll> getFactorization(ll x)
{
    vector<ll> ret;
    while (x != 1)
    {
        ret.push_back(spf[x]);
        x = x / spf[x];
    }
    return ret;
}
*/
/*vector<ll > vseg;//max and min
vector<pair<ll,ll> > vsegpr;// contains border values
ll N;

void build()
{
    for(ll i=N-1;i>0;i--)
    {   vseg[i]=max(max(vseg[i<<1],vseg[(i<<1)|1]),vsegpr[(i<<1)|1].first-vsegpr[i<<1].second);
        vsegpr[i]={vsegpr[i<<1].first,vsegpr[(i<<1)|1].second};
    }
}

ll get(ll l,ll r)
{  ll res1=-1,res2=-1;
   ll res=0;
   for(l+=N,r+=N;l<r;l>>=1,r>>=1)
   {
       if(l&1){res=max(res,vseg[l]);if(res1!=-1)res=max(res,vsegpr[l].first-res1);res1=vsegpr[l++].second;}
       if(r&1){res=max(res,vseg[r-1]);if(res2!=-1)res=max(res,res2-vsegpr[r-1].second);res2=vsegpr[--r].first;}
   }

   if(res1!=-1&&res2!=-1)return max(res,res2-res1);
   return res;
}
*/
int main()
{  fast;
    /* ll n;cin>>n;
       vector<ll> v(n);for(auto &x:v)cin>>x;
    N=1;
   while(N<n)N*=2;
    vseg.resize(2*N);
    vsegpr.resize(2*N);
    for(ll i=0;i<n;i++)vsegpr[i+N]={v[i],v[i]};
    for(ll i=n+N;i<2*N;i++)vsegpr[i]={v[n-1],v[n-1]};
    build();*/
    ll r,c,k;cin>>r>>c>>k;
     vector<vector<vector<ll > > > vdp(r+1,vector<vector<ll> >(c+1,vector<ll> (4,0) ) );
      vector<vector<ll> > v(r+1,vector<ll> (c+1,0) );
     while(k--)
     {
         ll r,c,val;cin>>r>>c>>val;
         v[r][c]=val;

     }
     vector<vector<ll> > vans(r+1,vector<ll> (c+1,0) );
    /* for(ll i=1;i<=r;i++)
     {
         for(ll j=1;j<=c;j++)cout<<v[i][j]<<" ";cout<<endl;
     }*/
     for(ll i=1;i<=r;i++)
     {
         for(ll j=1;j<=c;j++)
         {   ll ans=0;
             vdp[i][j][0]=max(vans[i-1][j],vdp[i][j-1][0]);
             //cout<<i<<" "<<j<<" "<<0<<" "<<vdp[i][j][0]<<endl;
             ans=vdp[i][j][0];
             for(ll p=1;p<4;p++)
             {
                 vdp[i][j][p]=max(vdp[i][j-1][p],vans[i-1][j]+v[i][j]);
                 if(v[i][j]>0)vdp[i][j][p]=max(vdp[i][j][p],vdp[i][j-1][p-1]+v[i][j]);
                 ans=max(ans,vdp[i][j][p]);
                 //cout<<i<<" "<<j<<" "<<p<<" "<<vdp[i][j][p]<<endl;
             }
             vans[i][j]=ans;

         }
     }

      cout<<vans[r][c]<<endl;

    return 0;
}


Measured memory_bytes: 777464