// EbTech's Rust template. Thanks EbTech!
#![allow(unused_imports)]
use std::cmp::{max, min, Reverse};
use std::collections::{BinaryHeap, HashMap, HashSet};
use std::io::{self, prelude::*};
use std::str;

struct Scanner<R> {
    reader: R,
    buf_str: Vec<u8>,
    buf_iter: str::SplitWhitespace<'static>,
}
impl<R: BufRead> Scanner<R> {
    fn new(reader: R) -> Self {
        Self {
            reader,
            buf_str: vec![],
            buf_iter: "".split_whitespace(),
        }
    }
    fn next<T: str::FromStr>(&mut self) -> T {
        loop {
            if let Some(token) = self.buf_iter.next() {
                return token.parse().ok().expect("Failed parse");
            }
            self.buf_str.clear();
            self.reader
                .read_until(b'\n', &mut self.buf_str)
                .expect("Failed read");
            self.buf_iter = unsafe {
                let slice = str::from_utf8_unchecked(&self.buf_str);
                std::mem::transmute(slice.split_whitespace())
            }
        }
    }
}

fn solve<R: BufRead, W: Write>(scan: &mut Scanner<R>, w: &mut W) {
    let n: usize = scan.next();
    let m: usize = scan.next();
    let k: usize = scan.next();
    let mut grid = vec![vec![0; m]; n];
    for _ in 0..k {
        let r: usize = scan.next();
        let c: usize = scan.next();
        grid[r - 1][c - 1] = scan.next::<u64>();
    }
    let grid = grid;
    // (Best when (r, c) is not taken, Best when only (r,c) is taken; (r, c), one other is taken; (r,c) and 2 others are taken, best overall (for top to down transition)
    let mut opt = vec![vec![(0, 0, 0, 0, 0); m]; n];
    opt[0][0] = (0, grid[0][0], grid[0][0], grid[0][0], grid[0][0]);
    for r in 1..n {
        let c = 0;
        let co = opt[r-1][0].4;
        opt[r][0] = (co+0, co+grid[r][c], co+grid[r][c], co+grid[r][c] ,co+grid[r][c]);
    }
    let mut seen = (
        BinaryHeap::new(),
        BinaryHeap::new(),
        BinaryHeap::new(),
        BinaryHeap::new(),
    );
    seen.0.push(opt[0][0].0);
    seen.1.push(opt[0][0].1);
    seen.2.push(opt[0][0].2);
    seen.3.push(opt[0][0].3);
    for c in 1..m {
        let r = 0;
        let ans = (
            seen.0.pop().unwrap_or_default(),
            seen.1.pop().unwrap_or_default(),
            seen.2.pop().unwrap_or_default(),
            seen.3.pop().unwrap_or_default(),
        );
        let ref mut curr = opt[r][c];

        curr.0 = ans.0;
        curr.1 = ans.0 + grid[r][c];
        curr.2 = ans.1 + grid[r][c];
        curr.3 = ans.2 + grid[r][c];
            curr.4 = max(max(curr.0, max(curr.1, max(curr.2, curr.3))),
            max(ans.0, max(ans.1, max(ans.2, ans.3))));

        seen.0.push(ans.0);
        seen.1.push(ans.1);
        seen.2.push(ans.2);
        seen.3.push(ans.3);

        seen.0.push(curr.0);
        seen.1.push(curr.1);
        seen.2.push(curr.2);
        seen.3.push(curr.3);
    }
    for r in 1..n {
        let mut seen = (
            BinaryHeap::new(),
            BinaryHeap::new(),
            BinaryHeap::new(),
            BinaryHeap::new(),
        );
        seen.0.push(opt[r][0].0);
        seen.1.push(opt[r][0].1);
        seen.2.push(opt[r][0].2);
        seen.3.push(opt[r][0].3);
        for c in 1..m {
            let ans = (
                seen.0.pop().unwrap_or_default(),
                seen.1.pop().unwrap_or_default(),
                seen.2.pop().unwrap_or_default(),
                seen.3.pop().unwrap_or_default(),
            );
            let last = opt[r - 1][c].clone();
            let ref mut curr = opt[r][c];

            let ml = last.4;
            
            curr.0 = max(ans.0, ml);
            curr.1 = max(ml + grid[r][c], ans.0 + grid[r][c]);
            curr.2 = ans.1 + grid[r][c];
            curr.3 = ans.2 + grid[r][c];

            curr.4 = max(max(curr.0, max(curr.1, max(curr.2, curr.3))),
            max(ans.0, max(ans.1, max(ans.2, ans.3))));

            seen.0.push(ans.0);
            seen.1.push(ans.1);
            seen.2.push(ans.2);
            seen.3.push(ans.3);

            seen.0.push(curr.0);
            seen.1.push(curr.1);
            seen.2.push(curr.2);
            seen.3.push(curr.3);
        }
    }

    let ref last = opt[n - 1][m - 1];
    writeln!(w, "{}", max(last.0, max(last.1, max(last.2, max(last.4, last.3))))).unwrap();
}

fn main() {
    let (stdin, stdout) = (io::stdin(), io::stdout());
    let mut scan = Scanner::new(stdin.lock());
    let mut out = io::BufWriter::new(stdout.lock());
    // let t: u64 = scan.next();
    let t = 1;
    for _ in 0..t {
        solve(&mut scan, &mut out);
    }
}


Measured memory_bytes: 424440