R, C, K, *RCV = [int(_) for _ in open(0).read().split()]
RCV = sorted([(r, -c, v) for r, c, v in zip(RCV[::3], RCV[1::3], RCV[2::3])])


class SegmentTree():
    def __init__(self, array, f, ti):
        """
        Parameters
        ----------
        array : list
            to construct segment tree from
        f : func
            binary operation of the monoid
        ti : 
            identity element of the monoid
        """
        self.f = f
        self.ti = ti
        self.n = n = 2**(len(array).bit_length())
        self.dat = dat = [ti] * n + array + [ti] * (n - len(array))
        for i in range(n - 1, 0, -1):  # build
            dat[i] = f(dat[i << 1], dat[i << 1 | 1])

    def update(self, p, v):  # set value at position p (0-indexed)
        f, n, dat = self.f, self.n, self.dat
        p += n
        dat[p] = v
        while p > 1:
            p >>= 1
            dat[p] = f(dat[p << 1], dat[p << 1 | 1])

    def operate_right(self, p, v):  # apply operator from the right side
        f, n, dat = self.f, self.n, self.dat
        p += n
        dat[p] = f(dat[p], v)
        while p > 1:
            p >>= 1
            dat[p] = f(dat[p << 1], dat[p << 1 | 1])

    def operate_left(self, p, v):  # apply operator from the left side
        f, n, dat = self.f, self.n, self.dat
        p += n
        dat[p] = f(v, dat[p])
        while p > 1:
            p >>= 1
            dat[p] = f(dat[p << 1], dat[p << 1 | 1])

    def query(self, l, r):  # result on interval [l, r) (0-indexed)
        f, ti, n, dat = self.f, self.ti, self.n, self.dat
        vl = vr = ti
        l += n
        r += n
        while l < r:
            if l & 1:
                vl = f(vl, dat[l])
                l += 1
            if r & 1:
                r -= 1
                vr = f(dat[r], vr)
            l >>= 1
            r >>= 1
        return f(vl, vr)


dp1 = SegmentTree([0] * (C + 1), max, -1)
dp2 = SegmentTree([0] * (C + 1), max, -1)
dp3 = SegmentTree([0] * (C + 1), max, -1)

rnow = 0
rcv = {}
for r, c, v in RCV:
    if rnow != r:
        rnow = r
        rcv[r] = []
    rcv[r] += [(-c, v)]
for r in sorted(rcv.keys()):
    cv = rcv[r]
    for c, v in cv:
        dp1.update(c, dp3.query(0, c + 1) + v)
    for c, v in cv:
        dp2.update(c, max(dp1.query(c, c + 1), dp1.query(0, c) + v))
    for c, v in cv:
        dp3.update(c, max(dp2.query(c, c + 1), dp2.query(0, c) + v))
ans = dp3.query(0, C + 1)
print(ans) int(_) for _ in open(0).read().split() for _ in open(0).read().split() _ open(0).read().split() (0).read().split (0).read() (0).read (0) open 0 read split for _ in open(0).read().split() int(_) int _ R, C, K, *RCV = [int(_) for _ in open(0).read().split()] R [int(_) for _ in open(0).read().split()] C K *RCV RCV (r, -c, v) for r, c, v in zip(RCV[::3], RCV[1::3], RCV[2::3]) for r, c, v in zip(RCV[::3], RCV[1::3], RCV[2::3]) r c v zip(RCV[::3], RCV[1::3], RCV[2::3]) zip RCV[::3] RCV ::3 3 RCV[1::3] RCV 1::3 1 3 RCV[2::3] RCV 2::3 2 3 for r, c, v in zip(RCV[::3], RCV[1::3], RCV[2::3]) (r, -c, v) r -c c v RCV = sorted([(r, -c, v) for r, c, v in zip(RCV[::3], RCV[1::3], RCV[2::3])]) RCV sorted([(r, -c, v) for r, c, v in zip(RCV[::3], RCV[1::3], RCV[2::3])]) sorted [(r, -c, v) for r, c, v in zip(RCV[::3], RCV[1::3], RCV[2::3])] class SegmentTree():
    def __init__(self, array, f, ti):
        """
        Parameters
        ----------
        array : list
            to construct segment tree from
        f : func
            binary operation of the monoid
        ti : 
            identity element of the monoid
        """
        self.f = f
        self.ti = ti
        self.n = n = 2**(len(array).bit_length())
        self.dat = dat = [ti] * n + array + [ti] * (n - len(array))
        for i in range(n - 1, 0, -1):  # build
            dat[i] = f(dat[i << 1], dat[i << 1 | 1])

    def update(self, p, v):  # set value at position p (0-indexed)
        f, n, dat = self.f, self.n, self.dat
        p += n
        dat[p] = v
        while p > 1:
            p >>= 1
            dat[p] = f(dat[p << 1], dat[p << 1 | 1])

    def operate_right(self, p, v):  # apply operator from the right side
        f, n, dat = self.f, self.n, self.dat
        p += n
        dat[p] = f(dat[p], v)
        while p > 1:
            p >>= 1
            dat[p] = f(dat[p << 1], dat[p << 1 | 1])

    def operate_left(self, p, v):  # apply operator from the left side
        f, n, dat = self.f, self.n, self.dat
        p += n
        dat[p] = f(v, dat[p])
        while p > 1:
            p >>= 1
            dat[p] = f(dat[p << 1], dat[p << 1 | 1])

    def query(self, l, r):  # result on interval [l, r) (0-indexed)
        f, ti, n, dat = self.f, self.ti, self.n, self.dat
        vl = vr = ti
        l += n
        r += n
        while l < r:
            if l & 1:
                vl = f(vl, dat[l])
                l += 1
            if r & 1:
                r -= 1
                vr = f(dat[r], vr)
            l >>= 1
            r >>= 1
        return f(vl, vr) SegmentTree def __init__(self, array, f, ti):
        """
        Parameters
        ----------
        array : list
            to construct segment tree from
        f : func
            binary operation of the monoid
        ti : 
            identity element of the monoid
        """
        self.f = f
        self.ti = ti
        self.n = n = 2**(len(array).bit_length())
        self.dat = dat = [ti] * n + array + [ti] * (n - len(array))
        for i in range(n - 1, 0, -1):  # build
            dat[i] = f(dat[i << 1], dat[i << 1 | 1])

     __init__ """
        Parameters
        ----------
        array : list
            to construct segment tree from
        f : func
            binary operation of the monoid
        ti : 
            identity element of the monoid
        """ self.f = f self.f self f f self.ti = ti self.ti self ti ti self.n = n = 2**(len(array).bit_length()) self.n self n 2**(len(array).bit_length()) 2 len(array).bit_length() (array).bit_length (array) len array bit_length = n = 2**(len(array).bit_length()) n 2**(len(array).bit_length()) self.dat = dat = [ti] * n + array + [ti] * (n - len(array)) self.dat self dat [ti] * n + array + [ti] * (n - len(array)) [ti] * n + array [ti] * n [ti] ti n array [ti] * (n - len(array)) [ti] ti n - len(array) n len(array) len array = dat = [ti] * n + array + [ti] * (n - len(array)) dat [ti] * n + array + [ti] * (n - len(array)) for i in range(n - 1, 0, -1):  # build
            dat[i] = f(dat[i << 1], dat[i << 1 | 1])

     i range(n - 1, 0, -1) range n - 1 n 1 0 -1 dat[i] = f(dat[i << 1], dat[i << 1 | 1]) dat[i] dat i f(dat[i << 1], dat[i << 1 | 1]) f dat[i << 1] dat i << 1 i 1 dat[i << 1 | 1] dat i << 1 | 1 i << 1 i 1 1 self self array array f f ti ti def update(self, p, v):  # set value at position p (0-indexed)
        f, n, dat = self.f, self.n, self.dat
        p += n
        dat[p] = v
        while p > 1:
            p >>= 1
            dat[p] = f(dat[p << 1], dat[p << 1 | 1])

     update f, n, dat = self.f, self.n, self.dat f self.f self f n self.n self n dat self.dat self dat p += n p n dat[p] = v dat[p] dat p v while p > 1:
            p >>= 1
            dat[p] = f(dat[p << 1], dat[p << 1 | 1])

     p > 1 p 1 p >>= 1 p 1 dat[p] = f(dat[p << 1], dat[p << 1 | 1]) dat[p] dat p f(dat[p << 1], dat[p << 1 | 1]) f dat[p << 1] dat p << 1 p 1 dat[p << 1 | 1] dat p << 1 | 1 p << 1 p 1 1 self self p p v v def operate_right(self, p, v):  # apply operator from the right side
        f, n, dat = self.f, self.n, self.dat
        p += n
        dat[p] = f(dat[p], v)
        while p > 1:
            p >>= 1
            dat[p] = f(dat[p << 1], dat[p << 1 | 1])

     operate_right f, n, dat = self.f, self.n, self.dat f self.f self f n self.n self n dat self.dat self dat p += n p n dat[p] = f(dat[p], v) dat[p] dat p f(dat[p], v) f dat[p] dat p v while p > 1:
            p >>= 1
            dat[p] = f(dat[p << 1], dat[p << 1 | 1])

     p > 1 p 1 p >>= 1 p 1 dat[p] = f(dat[p << 1], dat[p << 1 | 1]) dat[p] dat p f(dat[p << 1], dat[p << 1 | 1]) f dat[p << 1] dat p << 1 p 1 dat[p << 1 | 1] dat p << 1 | 1 p << 1 p 1 1 self self p p v v def operate_left(self, p, v):  # apply operator from the left side
        f, n, dat = self.f, self.n, self.dat
        p += n
        dat[p] = f(v, dat[p])
        while p > 1:
            p >>= 1
            dat[p] = f(dat[p << 1], dat[p << 1 | 1])

     operate_left f, n, dat = self.f, self.n, self.dat f self.f self f n self.n self n dat self.dat self dat p += n p n dat[p] = f(v, dat[p]) dat[p] dat p f(v, dat[p]) f v dat[p] dat p while p > 1:
            p >>= 1
            dat[p] = f(dat[p << 1], dat[p << 1 | 1])

     p > 1 p 1 p >>= 1 p 1 dat[p] = f(dat[p << 1], dat[p << 1 | 1]) dat[p] dat p f(dat[p << 1], dat[p << 1 | 1]) f dat[p << 1] dat p << 1 p 1 dat[p << 1 | 1] dat p << 1 | 1 p << 1 p 1 1 self self p p v v def query(self, l, r):  # result on interval [l, r) (0-indexed)
        f, ti, n, dat = self.f, self.ti, self.n, self.dat
        vl = vr = ti
        l += n
        r += n
        while l < r:
            if l & 1:
                vl = f(vl, dat[l])
                l += 1
            if r & 1:
                r -= 1
                vr = f(dat[r], vr)
            l >>= 1
            r >>= 1
        return f(vl, vr) query f, ti, n, dat = self.f, self.ti, self.n, self.dat f self.f self f ti self.ti self ti n self.n self n dat self.dat self dat vl = vr = ti vl ti = vr = ti vr ti l += n l n r += n r n while l < r:
            if l & 1:
                vl = f(vl, dat[l])
                l += 1
            if r & 1:
                r -= 1
                vr = f(dat[r], vr)
            l >>= 1
            r >>= 1
         l < r l r if l & 1:
                vl = f(vl, dat[l])
                l += 1
             l & 1 l 1 vl = f(vl, dat[l]) vl f(vl, dat[l]) f vl dat[l] dat l l += 1 l 1 if r & 1:
                r -= 1
                vr = f(dat[r], vr)
             r & 1 r 1 r -= 1 r 1 vr = f(dat[r], vr) vr f(dat[r], vr) f dat[r] dat r vr l >>= 1 l 1 r >>= 1 r 1 return f(vl, vr) f(vl, vr) f vl vr self self l l r r dp1 = SegmentTree([0] * (C + 1), max, -1) dp1 SegmentTree([0] * (C + 1), max, -1) SegmentTree [0] * (C + 1) [0] 0 C + 1 C 1 max -1 dp2 = SegmentTree([0] * (C + 1), max, -1) dp2 SegmentTree([0] * (C + 1), max, -1) SegmentTree [0] * (C + 1) [0] 0 C + 1 C 1 max -1 dp3 = SegmentTree([0] * (C + 1), max, -1) dp3 SegmentTree([0] * (C + 1), max, -1) SegmentTree [0] * (C + 1) [0] 0 C + 1 C 1 max -1 rnow = 0 rnow 0 rcv = {} rcv {} for r, c, v in RCV:
    if rnow != r:
        rnow = r
        rcv[r] = []
    rcv[r] += [(-c, v)] r c v RCV if rnow != r:
        rnow = r
        rcv[r] = []
     rnow != r rnow r rnow = r rnow r rcv[r] = [] rcv[r] rcv r [] rcv[r] += [(-c, v)] rcv[r] rcv r [(-c, v)] (-c, v) -c c v for r in sorted(rcv.keys()):
    cv = rcv[r]
    for c, v in cv:
        dp1.update(c, dp3.query(0, c + 1) + v)
    for c, v in cv:
        dp2.update(c, max(dp1.query(c, c + 1), dp1.query(0, c) + v))
    for c, v in cv:
        dp3.update(c, max(dp2.query(c, c + 1), dp2.query(0, c) + v)) r sorted(rcv.keys()) sorted rcv.keys() rcv.keys rcv keys cv = rcv[r] cv rcv[r] rcv r for c, v in cv:
        dp1.update(c, dp3.query(0, c + 1) + v)
     c v cv dp1.update(c, dp3.query(0, c + 1) + v) dp1.update dp1 update c dp3.query(0, c + 1) + v dp3.query(0, c + 1) dp3.query dp3 query 0 c + 1 c 1 v for c, v in cv:
        dp2.update(c, max(dp1.query(c, c + 1), dp1.query(0, c) + v))
     c v cv dp2.update(c, max(dp1.query(c, c + 1), dp1.query(0, c) + v)) dp2.update dp2 update c max(dp1.query(c, c + 1), dp1.query(0, c) + v) max dp1.query(c, c + 1) dp1.query dp1 query c c + 1 c 1 dp1.query(0, c) + v dp1.query(0, c) dp1.query dp1 query 0 c v for c, v in cv:
        dp3.update(c, max(dp2.query(c, c + 1), dp2.query(0, c) + v)) c v cv dp3.update(c, max(dp2.query(c, c + 1), dp2.query(0, c) + v)) dp3.update dp3 update c max(dp2.query(c, c + 1), dp2.query(0, c) + v) max dp2.query(c, c + 1) dp2.query dp2 query c c + 1 c 1 dp2.query(0, c) + v dp2.query(0, c) dp2.query dp2 query 0 c v ans = dp3.query(0, C + 1) ans dp3.query(0, C + 1) dp3.query dp3 query 0 C + 1 C 1 print(ans) print ans rnow = r r rnow rnow = 0 0 rnow rcv = {} {} rcv dp1 = SegmentTree([0] * (C + 1), max, -1) SegmentTree([0] * (C + 1), max, -1) dp1 R, C, K, *RCV = [int(_) for _ in open(0).read().split()] [int(_) for _ in open(0).read().split()] R cv = rcv[r] rcv[r] cv RCV = sorted([(r, -c, v) for r, c, v in zip(RCV[::3], RCV[1::3], RCV[2::3])]) sorted([(r, -c, v) for r, c, v in zip(RCV[::3], RCV[1::3], RCV[2::3])]) RCV class SegmentTree():
    def __init__(self, array, f, ti):
        """
        Parameters
        ----------
        array : list
            to construct segment tree from
        f : func
            binary operation of the monoid
        ti : 
            identity element of the monoid
        """
        self.f = f
        self.ti = ti
        self.n = n = 2**(len(array).bit_length())
        self.dat = dat = [ti] * n + array + [ti] * (n - len(array))
        for i in range(n - 1, 0, -1):  # build
            dat[i] = f(dat[i << 1], dat[i << 1 | 1])

    def update(self, p, v):  # set value at position p (0-indexed)
        f, n, dat = self.f, self.n, self.dat
        p += n
        dat[p] = v
        while p > 1:
            p >>= 1
            dat[p] = f(dat[p << 1], dat[p << 1 | 1])

    def operate_right(self, p, v):  # apply operator from the right side
        f, n, dat = self.f, self.n, self.dat
        p += n
        dat[p] = f(dat[p], v)
        while p > 1:
            p >>= 1
            dat[p] = f(dat[p << 1], dat[p << 1 | 1])

    def operate_left(self, p, v):  # apply operator from the left side
        f, n, dat = self.f, self.n, self.dat
        p += n
        dat[p] = f(v, dat[p])
        while p > 1:
            p >>= 1
            dat[p] = f(dat[p << 1], dat[p << 1 | 1])

    def query(self, l, r):  # result on interval [l, r) (0-indexed)
        f, ti, n, dat = self.f, self.ti, self.n, self.dat
        vl = vr = ti
        l += n
        r += n
        while l < r:
            if l & 1:
                vl = f(vl, dat[l])
                l += 1
            if r & 1:
                r -= 1
                vr = f(dat[r], vr)
            l >>= 1
            r >>= 1
        return f(vl, vr) class SegmentTree():
    def __init__(self, array, f, ti):
        """
        Parameters
        ----------
        array : list
            to construct segment tree from
        f : func
            binary operation of the monoid
        ti : 
            identity element of the monoid
        """
        self.f = f
        self.ti = ti
        self.n = n = 2**(len(array).bit_length())
        self.dat = dat = [ti] * n + array + [ti] * (n - len(array))
        for i in range(n - 1, 0, -1):  # build
            dat[i] = f(dat[i << 1], dat[i << 1 | 1])

    def update(self, p, v):  # set value at position p (0-indexed)
        f, n, dat = self.f, self.n, self.dat
        p += n
        dat[p] = v
        while p > 1:
            p >>= 1
            dat[p] = f(dat[p << 1], dat[p << 1 | 1])

    def operate_right(self, p, v):  # apply operator from the right side
        f, n, dat = self.f, self.n, self.dat
        p += n
        dat[p] = f(dat[p], v)
        while p > 1:
            p >>= 1
            dat[p] = f(dat[p << 1], dat[p << 1 | 1])

    def operate_left(self, p, v):  # apply operator from the left side
        f, n, dat = self.f, self.n, self.dat
        p += n
        dat[p] = f(v, dat[p])
        while p > 1:
            p >>= 1
            dat[p] = f(dat[p << 1], dat[p << 1 | 1])

    def query(self, l, r):  # result on interval [l, r) (0-indexed)
        f, ti, n, dat = self.f, self.ti, self.n, self.dat
        vl = vr = ti
        l += n
        r += n
        while l < r:
            if l & 1:
                vl = f(vl, dat[l])
                l += 1
            if r & 1:
                r -= 1
                vr = f(dat[r], vr)
            l >>= 1
            r >>= 1
        return f(vl, vr) SegmentTree C, K, *RCV = [int(_) for _ in open(0).read().split()] [int(_) for _ in open(0).read().split()] C ans = dp3.query(0, C + 1) dp3.query(0, C + 1) ans K, *RCV = [int(_) for _ in open(0).read().split()] [int(_) for _ in open(0).read().split()] K dp2 = SegmentTree([0] * (C + 1), max, -1) SegmentTree([0] * (C + 1), max, -1) dp2 dp3 = SegmentTree([0] * (C + 1), max, -1) SegmentTree([0] * (C + 1), max, -1) dp3
R, C, K, *RCV = [int(_) for _ in open(0).read().split()]
RCV = sorted([(r, -c, v) for r, c, v in zip(RCV[::3], RCV[1::3], RCV[2::3])])


class SegmentTree():
    def __init__(self, array, f, ti):
        """
        Parameters
        ----------
        array : list
            to construct segment tree from
        f : func
            binary operation of the monoid
        ti : 
            identity element of the monoid
        """
        self.f = f
        self.ti = ti
        self.n = n = 2**(len(array).bit_length())
        self.dat = dat = [ti] * n + array + [ti] * (n - len(array))
        for i in range(n - 1, 0, -1):  # build
            dat[i] = f(dat[i << 1], dat[i << 1 | 1])

    def update(self, p, v):  # set value at position p (0-indexed)
        f, n, dat = self.f, self.n, self.dat
        p += n
        dat[p] = v
        while p > 1:
            p >>= 1
            dat[p] = f(dat[p << 1], dat[p << 1 | 1])

    def operate_right(self, p, v):  # apply operator from the right side
        f, n, dat = self.f, self.n, self.dat
        p += n
        dat[p] = f(dat[p], v)
        while p > 1:
            p >>= 1
            dat[p] = f(dat[p << 1], dat[p << 1 | 1])

    def operate_left(self, p, v):  # apply operator from the left side
        f, n, dat = self.f, self.n, self.dat
        p += n
        dat[p] = f(v, dat[p])
        while p > 1:
            p >>= 1
            dat[p] = f(dat[p << 1], dat[p << 1 | 1])

    def query(self, l, r):  # result on interval [l, r) (0-indexed)
        f, ti, n, dat = self.f, self.ti, self.n, self.dat
        vl = vr = ti
        l += n
        r += n
        while l < r:
            if l & 1:
                vl = f(vl, dat[l])
                l += 1
            if r & 1:
                r -= 1
                vr = f(dat[r], vr)
            l >>= 1
            r >>= 1
        return f(vl, vr)


dp1 = SegmentTree([0] * (C + 1), max, -1)
dp2 = SegmentTree([0] * (C + 1), max, -1)
dp3 = SegmentTree([0] * (C + 1), max, -1)

rnow = 0
rcv = {}
for r, c, v in RCV:
    if rnow != r:
        rnow = r
        rcv[r] = []
    rcv[r] += [(-c, v)]
for r in sorted(rcv.keys()):
    cv = rcv[r]
    for c, v in cv:
        dp1.update(c, dp3.query(0, c + 1) + v)
    for c, v in cv:
        dp2.update(c, max(dp1.query(c, c + 1), dp1.query(0, c) + v))
    for c, v in cv:
        dp3.update(c, max(dp2.query(c, c + 1), dp2.query(0, c) + v))
ans = dp3.query(0, C + 1)
print(ans)
