Buggy python submission (verdict: Time Limit Exceeded):
## coding: UTF-8
R,C,K = map(int,input().split())
rcv = []
for i in range(K):
    rcv.append(list(map(int,input().split())))

#print(rcv)

#available = [False] * (R*C+1) #アイテムの有無を示す
item = [0] * (R*C+1)
for i in range(K):
    index = (rcv[i][0] - 1) * C + (rcv[i][1] - 1) +1
    #available[index] = True
    item[index] = rcv[i][2]
#print(available, item)


def solver(R,C,K,rcv):
    #その場所にいる段階での最大スコアを出力
    #その行で獲得した個数も格納
    #DPの都合上0番目の要素を追加
    #グリッドは1次元で処理(1行目は1~C, 2行目はC+1~2C, ...)
    dp = []
    for i in range(R*C+1):
        dp.append([0] * 4)
    #print(dp)
    for i in range(1, R*C+1):
        #print(item[i])
        if(i == 1):
            #左上なら
            #dp[i][0] = dp[i-1][0] #左から(何も持ってこない)
            #if(available[i]):
            #itemがある場合は取得するときと取得しない二通りに分けられる
            dp[i][1] = dp[i-1][0] + item[i]
        elif(i <= C):
            #左上以外の上(左からくる場合に限られる)
            dp[i][0] = dp[i-1][0] #itemを取得しない場合
            #if(available[i]):
            dp[i][1] = max(dp[i-1][1], dp[i-1][0] + item[i])
                #if(dp[i-1][1] > 0): #左ですでに一個以上所持している場合にのみ、このマスで二個目ということが可能
            dp[i][2] = max(dp[i-1][2], dp[i-1][1] + item[i])
                #else:
                    #dp[i][2] = 0
                #if(dp[i-1][2] > 0): #左ですでに二個以上所持している場合にのみ、このマスで三個目ということが可能
            dp[i][3] = max(dp[i-1][3], dp[i-1][2] + item[i])
                #else:
                    #dp[i][3] = 0
            #else:
                #dp[i][1] = dp[i-1][1]
                #dp[i][2] = dp[i-1][2]
                #dp[i][3] = dp[i-1][3]
        elif(i % C == 1):
            #左上以外の左(上からくる場合に限られる)
            dp[i][0] = max(dp[i-C]) #下に降りてくる場合は、行で取得したアイテム数はリセットされる
            #if(available[i]):
                #dp[i][1] = max(dp[i-C]) + item[i]
            dp[i][1] = dp[i][0] + item[i]
        else:
            #左でも上でもない場合
            dp[i][0] = max(dp[i-1][0], max(dp[i-C])) #左からくる場合は0限定だが、上からくる場合は、上の行で何個拾っててもいい
            #if(available[i]):
                #dp[i][1] = max(dp[i-1][1], dp[i-1][0] + item[i], max(dp[i-C]) + item[i] ) #左から一個持った状態で来て拾わないor左から何も持たずに来て拾うor上から来て(所持数関係無し)拾う
            dp[i][1] = max(dp[i-1][1], dp[i][0] + item[i])
                #if(dp[i-1][1] > 0): #左ですでに一個以上所持している場合にのみ、このマスで二個目ということが可能
            dp[i][2] = max(dp[i-1][2], dp[i-1][1] + item[i]) #上から来て二個目は不可能
                #else:
                    #dp[i][2] = 0
                #if(dp[i-1][2] > 0):
            dp[i][3] = max(dp[i-1][3], dp[i-1][2] + item[i])
                #else:
                    #dp[i][3] = 0
            #else:
                #dp[i][1] = dp[i-1][1]
                #dp[i][2] = dp[i-1][2]
                #dp[i][3] = dp[i-1][3]

         

        #print(i, dp)
    print(max(dp[R*C]))


solver(R,C,K,rcv)
#print(-1)







Fixed submission:
## coding: UTF-8


R,C,K = map(int,input().split())
rcv = []
for i in range(K):
    rcv.append(list(map(int,input().split())))

item = [0] * (R*C+1)
for i in range(K):
    index = (rcv[i][0] - 1) * C + (rcv[i][1] - 1) 
    #available[index] = True
    item[index] = rcv[i][2]

#print(item)



def solver(R,C,K):
    empty = []
    prev = []
    for i in range(C):
        empty.append([0] * 4)
        prev.append([0] * 4)
    
    for i in range(R):
        #print('prev', prev)
        now = []
        #ret = []
        zero = max(prev[0])
        now.append([zero, zero+item[i*C], 0, 0]) #一番左
        for j in range(1, C):
            index = i * C + j
            point = item[index]
            #print(i,j,index)
            ret = []
            left = now[-1]
            zero = max(left[0], max(prev[j])) #左からor上から
            ret.append(zero) #0
            one = max(zero + point, left[1]) #左からor上からきてアイテム取得 or 左から一個持った状態で拾わない
            two = max(left[1] + point, left[2])
            three = max(left[2] + point, left[3])
            ret.append(one)
            ret.append(two)
            ret.append(three)
            now.append(ret)
        prev = now
        #print(now)
    
    print(max(now[-1]))


solver(R,C,K)

Buggy python submission (verdict: Time Limit Exceeded):
## coding: UTF-8
R,C,K = map(int,input().split())
rcv = []
for i in range(K):
    rcv.append(list(map(int,input().split())))

#print(rcv)

available = [False] * (R*C+1) #アイテムの有無を示す
item = [0] * (R*C+1)
for i in range(K):
    index = (rcv[i][0] - 1) * C + (rcv[i][1] - 1) +1
    available[index] = True
    item[index] = rcv[i][2]
#print(available, item)


def solver(R,C,K,rcv):
    #その場所にいる段階での最大スコアを出力
    #その行で獲得した個数も格納
    #DPの都合上0番目の要素を追加
    #グリッドは1次元で処理(1行目は1~C, 2行目はC+1~2C, ...)
    dp = []
    for i in range(R*C+1):
        dp.append([0] * 4)
    #print(dp)
    for i in range(1, R*C+1):
        #print(item[i])
        if(i == 1):
            #左上なら
            #dp[i][0] = dp[i-1][0] #左から(何も持ってこない)
            if(available[i]):
                #itemがある場合は取得するときと取得しない二通りに分けられる
                dp[i][1] = dp[i-1][0] + item[i]
        elif(i <= C):
            #左上以外の上(左からくる場合に限られる)
            dp[i][0] = dp[i-1][0] #itemを取得しない場合
            if(available[i]):
                dp[i][1] = max(dp[i-1][1], dp[i-1][0] + item[i])
                #if(dp[i-1][1] > 0): #左ですでに一個以上所持している場合にのみ、このマスで二個目ということが可能
                dp[i][2] = max(dp[i-1][2], dp[i-1][1] + item[i])
                #else:
                    #dp[i][2] = 0
                #if(dp[i-1][2] > 0): #左ですでに二個以上所持している場合にのみ、このマスで三個目ということが可能
                dp[i][3] = max(dp[i-1][3], dp[i-1][2] + item[i])
                #else:
                    #dp[i][3] = 0
            else:
                dp[i][1] = dp[i-1][1]
                dp[i][2] = dp[i-1][2]
                dp[i][3] = dp[i-1][3]
        elif(i % C == 1):
            #左上以外の左(上からくる場合に限られる)
            dp[i][0] = max(dp[i-C]) #下に降りてくる場合は、行で取得したアイテム数はリセットされる
            if(available[i]):
                #dp[i][1] = max(dp[i-C]) + item[i]
                dp[i][1] = dp[i][0] + item[i]
        else:
            #左でも上でもない場合
            dp[i][0] = max(dp[i-1][0], max(dp[i-C])) #左からくる場合は0限定だが、上からくる場合は、上の行で何個拾っててもいい
            if(available[i]):
                #dp[i][1] = max(dp[i-1][1], dp[i-1][0] + item[i], max(dp[i-C]) + item[i] ) #左から一個持った状態で来て拾わないor左から何も持たずに来て拾うor上から来て(所持数関係無し)拾う
                dp[i][1] = max(dp[i-1][1], dp[i][0] + item[i])
                #if(dp[i-1][1] > 0): #左ですでに一個以上所持している場合にのみ、このマスで二個目ということが可能
                dp[i][2] = max(dp[i-1][2], dp[i-1][1] + item[i]) #上から来て二個目は不可能
                #else:
                    #dp[i][2] = 0
                #if(dp[i-1][2] > 0):
                dp[i][3] = max(dp[i-1][3], dp[i-1][2] + item[i])
                #else:
                    #dp[i][3] = 0
            else:
                dp[i][1] = dp[i-1][1]
                dp[i][2] = dp[i-1][2]
                dp[i][3] = dp[i-1][3]

         

        #print(i, dp)
    print(max(dp[R*C]))


solver(R,C,K,rcv)








Fixed submission:
## coding: UTF-8


R,C,K = map(int,input().split())
rcv = []
for i in range(K):
    rcv.append(list(map(int,input().split())))

item = [0] * (R*C+1)
for i in range(K):
    index = (rcv[i][0] - 1) * C + (rcv[i][1] - 1) 
    #available[index] = True
    item[index] = rcv[i][2]

#print(item)



def solver(R,C,K):
    empty = []
    prev = []
    for i in range(C):
        empty.append([0] * 4)
        prev.append([0] * 4)
    
    for i in range(R):
        #print('prev', prev)
        now = []
        #ret = []
        zero = max(prev[0])
        now.append([zero, zero+item[i*C], 0, 0]) #一番左
        for j in range(1, C):
            index = i * C + j
            point = item[index]
            #print(i,j,index)
            ret = []
            left = now[-1]
            zero = max(left[0], max(prev[j])) #左からor上から
            ret.append(zero) #0
            one = max(zero + point, left[1]) #左からor上からきてアイテム取得 or 左から一個持った状態で拾わない
            two = max(left[1] + point, left[2])
            three = max(left[2] + point, left[3])
            ret.append(one)
            ret.append(two)
            ret.append(three)
            now.append(ret)
        prev = now
        #print(now)
    
    print(max(now[-1]))


solver(R,C,K)

Buggy python submission (verdict: Time Limit Exceeded):
## coding: UTF-8
R,C,K = map(int,input().split())
rcv = []
for i in range(K):
    rcv.append(list(map(int,input().split())))

#print(rcv)

available = [False] * (R*C+1) #アイテムの有無を示す
item = [0] * (R*C+1)
for i in range(K):
    index = (rcv[i][0] - 1) * C + (rcv[i][1] - 1) +1
    available[index] = True
    item[index] = rcv[i][2]
#print(available, item)


def solver(R,C,K,rcv):
    #その場所にいる段階での最大スコアを出力
    #その行で獲得した個数も格納
    #DPの都合上0番目の要素を追加
    #グリッドは1次元で処理(1行目は1~C, 2行目はC+1~2C, ...)
    dp = []
    for i in range(R*C+1):
        dp.append([0] * 4)
    #print(dp)
    for i in range(1, R*C+1):
        #print(item[i])
        if(i == 1):
            #左上なら
            #dp[i][0] = dp[i-1][0] #左から(何も持ってこない)
            if(available[i]):
                #itemがある場合は取得するときと取得しない二通りに分けられる
                dp[i][1] = dp[i-1][0] + item[i]
        elif(i <= C):
            #左上以外の上(左からくる場合に限られる)
            dp[i][0] = dp[i-1][0] #itemを取得しない場合
            if(available[i]):
                dp[i][1] = max(dp[i-1][1], dp[i-1][0] + item[i])
                #if(dp[i-1][1] > 0): #左ですでに一個以上所持している場合にのみ、このマスで二個目ということが可能
                dp[i][2] = max(dp[i-1][2], dp[i-1][1] + item[i])
                #else:
                    #dp[i][2] = 0
                #if(dp[i-1][2] > 0): #左ですでに二個以上所持している場合にのみ、このマスで三個目ということが可能
                dp[i][3] = max(dp[i-1][3], dp[i-1][2] + item[i])
                #else:
                    #dp[i][3] = 0
            else:
                dp[i][1] = dp[i-1][1]
                dp[i][2] = dp[i-1][2]
                dp[i][3] = dp[i-1][3]
        elif(i % C == 1):
            #左上以外の左(上からくる場合に限られる)
            dp[i][0] = max(dp[i-C]) #下に降りてくる場合は、行で取得したアイテム数はリセットされる
            if(available[i]):
                dp[i][1] = max(dp[i-C]) + item[i]
        else:
            #左でも上でもない場合
            dp[i][0] = max(dp[i-1][0], max(dp[i-C])) #左からくる場合は0限定だが、上からくる場合は、上の行で何個拾っててもいい
            if(available[i]):
                dp[i][1] = max(dp[i-1][1], dp[i-1][0] + item[i], max(dp[i-C]) + item[i] ) #左から一個持った状態で来て拾わないor左から何も持たずに来て拾うor上から来て(所持数関係無し)拾う
                #if(dp[i-1][1] > 0): #左ですでに一個以上所持している場合にのみ、このマスで二個目ということが可能
                dp[i][2] = max(dp[i-1][2], dp[i-1][1] + item[i]) #上から来て二個目は不可能
                #else:
                    #dp[i][2] = 0
                #if(dp[i-1][2] > 0):
                dp[i][3] = max(dp[i-1][3], dp[i-1][2] + item[i])
                #else:
                    #dp[i][3] = 0
            else:
                dp[i][1] = dp[i-1][1]
                dp[i][2] = dp[i-1][2]
                dp[i][3] = dp[i-1][3]

         

        #print(i, dp)
    print(max(dp[R*C]))


solver(R,C,K,rcv)








Fixed submission:
## coding: UTF-8


R,C,K = map(int,input().split())
rcv = []
for i in range(K):
    rcv.append(list(map(int,input().split())))

item = [0] * (R*C+1)
for i in range(K):
    index = (rcv[i][0] - 1) * C + (rcv[i][1] - 1) 
    #available[index] = True
    item[index] = rcv[i][2]

#print(item)



def solver(R,C,K):
    empty = []
    prev = []
    for i in range(C):
        empty.append([0] * 4)
        prev.append([0] * 4)
    
    for i in range(R):
        #print('prev', prev)
        now = []
        #ret = []
        zero = max(prev[0])
        now.append([zero, zero+item[i*C], 0, 0]) #一番左
        for j in range(1, C):
            index = i * C + j
            point = item[index]
            #print(i,j,index)
            ret = []
            left = now[-1]
            zero = max(left[0], max(prev[j])) #左からor上から
            ret.append(zero) #0
            one = max(zero + point, left[1]) #左からor上からきてアイテム取得 or 左から一個持った状態で拾わない
            two = max(left[1] + point, left[2])
            three = max(left[2] + point, left[3])
            ret.append(one)
            ret.append(two)
            ret.append(three)
            now.append(ret)
        prev = now
        #print(now)
    
    print(max(now[-1]))


solver(R,C,K)

Buggy python submission (verdict: Time Limit Exceeded):
## coding: UTF-8
R,C,K = map(int,input().split())
rcv = []
for i in range(K):
    rcv.append(list(map(int,input().split())))

#print(rcv)

available = [False] * (R*C+1) #アイテムの有無を示す
item = [0] * (R*C+1)
for i in range(K):
    index = (rcv[i][0] - 1) * C + (rcv[i][1] - 1) +1
    available[index] = True
    item[index] = rcv[i][2]
#print(available, item)


def solver(R,C,K,rcv):
    #その場所にいる段階での最大スコアを出力
    #その行で獲得した個数も格納
    #DPの都合上0番目の要素を追加
    #グリッドは1次元で処理(1行目は1~C, 2行目はC+1~2C, ...)
    dp = []
    for i in range(R*C+1):
        dp.append([0] * 4)
    #print(dp)
    for i in range(1, R*C+1):
        #print(item[i])
        if(i == 1):
            #左上なら
            #dp[i][0] = dp[i-1][0] #左から(何も持ってこない)
            if(available[i]):
                #itemがある場合は取得するときと取得しない二通りに分けられる
                dp[i][1] = dp[i-1][0] + item[i]
        elif(i <= C):
            #左上以外の上(左からくる場合に限られる)
            dp[i][0] = dp[i-1][0] #itemを取得しない場合
            if(available[i]):
                dp[i][1] = max(dp[i-1][1], dp[i-1][0] + item[i])
                if(dp[i-1][1] > 0): #左ですでに一個以上所持している場合にのみ、このマスで二個目ということが可能
                    dp[i][2] = max(dp[i-1][2], dp[i-1][1] + item[i])
                else:
                    dp[i][2] = 0
                if(dp[i-1][2] > 0): #左ですでに二個以上所持している場合にのみ、このマスで三個目ということが可能
                    dp[i][3] = max(dp[i-1][3], dp[i-1][2] + item[i])
                else:
                    dp[i][3] = 0
            else:
                dp[i][1] = dp[i-1][1]
                dp[i][2] = dp[i-1][2]
                dp[i][3] = dp[i-1][3]
        elif(i % C == 1):
            #左上以外の左(上からくる場合に限られる)
            dp[i][0] = max(dp[i-C]) #下に降りてくる場合は、行で取得したアイテム数はリセットされる
            if(available[i]):
                dp[i][1] = max(dp[i-C]) + item[i]
        else:
            #左でも上でもない場合
            dp[i][0] = max(dp[i-1][0], max(dp[i-C])) #左からくる場合は0限定だが、上からくる場合は、上の行で何個拾っててもいい
            if(available[i]):
                dp[i][1] = max(dp[i-1][1], dp[i-1][0] + item[i], max(dp[i-C]) + item[i] ) #左から一個持った状態で来て拾わないor左から何も持たずに来て拾うor上から来て(所持数関係無し)拾う
                if(dp[i-1][1] > 0): #左ですでに一個以上所持している場合にのみ、このマスで二個目ということが可能
                    dp[i][2] = max(dp[i-1][2], dp[i-1][1] + item[i]) #上から来て二個目は不可能
                else:
                    dp[i][2] = 0
                if(dp[i-1][2] > 0):
                    dp[i][3] = max(dp[i-1][3], dp[i-1][2] + item[i])
                else:
                    dp[i][3] = 0
            else:
                dp[i][1] = dp[i-1][1]
                dp[i][2] = dp[i-1][2]
                dp[i][3] = dp[i-1][3]

         

        #print(i, dp)
    print(max(dp[R*C]))


solver(R,C,K,rcv)








Fixed submission:
## coding: UTF-8


R,C,K = map(int,input().split())
rcv = []
for i in range(K):
    rcv.append(list(map(int,input().split())))

item = [0] * (R*C+1)
for i in range(K):
    index = (rcv[i][0] - 1) * C + (rcv[i][1] - 1) 
    #available[index] = True
    item[index] = rcv[i][2]

#print(item)



def solver(R,C,K):
    empty = []
    prev = []
    for i in range(C):
        empty.append([0] * 4)
        prev.append([0] * 4)
    
    for i in range(R):
        #print('prev', prev)
        now = []
        #ret = []
        zero = max(prev[0])
        now.append([zero, zero+item[i*C], 0, 0]) #一番左
        for j in range(1, C):
            index = i * C + j
            point = item[index]
            #print(i,j,index)
            ret = []
            left = now[-1]
            zero = max(left[0], max(prev[j])) #左からor上から
            ret.append(zero) #0
            one = max(zero + point, left[1]) #左からor上からきてアイテム取得 or 左から一個持った状態で拾わない
            two = max(left[1] + point, left[2])
            three = max(left[2] + point, left[3])
            ret.append(one)
            ret.append(two)
            ret.append(three)
            now.append(ret)
        prev = now
        #print(now)
    
    print(max(now[-1]))


solver(R,C,K)