Buggy python submission (verdict: Time Limit Exceeded):
import operator
import os
import sys

if os.getenv("LOCAL"):
    sys.stdin = open("_in.txt", "r")

sys.setrecursionlimit(10 ** 9)
INF = float("inf")
IINF = 10 ** 18
MOD = 10 ** 9 + 7


# MOD = 998244353

class SegmentTree:
    # http://tsutaj.hatenablog.com/entry/2017/03/29/204841
    def __init__(self, size, fn=operator.add, default=None, initial_values=None):
        """
        :param int size:
        :param callable fn: 区間に適用する関数。引数を 2 つ取る。min, max, operator.xor など
        :param default:
        :param list initial_values:
        """
        default = default or 0

        # size 以上である最小の 2 冪を size とする
        n = 1
        while n < size:
            n *= 2
        self._size = n
        self._fn = fn

        self._tree = [default] * (self._size * 2 - 1)
        if initial_values:
            i = self._size - 1
            for v in initial_values:
                self._tree[i] = v
                i += 1
            i = self._size - 2
            while i >= 0:
                self._tree[i] = self._fn(self._tree[i * 2 + 1], self._tree[i * 2 + 2])
                i -= 1

    def set(self, i, value):
        """
        i 番目に value を設定
        :param int i:
        :param value:
        :return:
        """
        x = self._size - 1 + i
        self._tree[x] = value

        while x > 0:
            x = (x - 1) // 2
            self._tree[x] = self._fn(self._tree[x * 2 + 1], self._tree[x * 2 + 2])

    def add(self, i, value):
        """
        もとの i 番目と value に fn を適用したものを i 番目に設定
        :param int i:
        :param value:
        :return:
        """
        x = self._size - 1 + i
        self.set(i, self._fn(self._tree[x], value))

    def get(self, from_i, to_i=None, k=0, L=None, r=None):
        """
        [from_i, to_i) に fn を適用した結果を返す
        :param int from_i:
        :param int to_i:
        :param int k: self._tree[k] が、[L, r) に fn を適用した結果を持つ
        :param int L:
        :param int r:
        :return:
        """
        if to_i is None:
            to_i = from_i + 1
        L = 0 if L is None else L
        r = self._size if r is None else r

        if from_i <= L and r <= to_i:
            return self._tree[k]

        if to_i <= L or r <= from_i:
            return None

        ret_L = self.get(from_i, to_i, k * 2 + 1, L, (L + r) // 2)
        ret_r = self.get(from_i, to_i, k * 2 + 2, (L + r) // 2, r)
        if ret_L is None:
            return ret_r
        if ret_r is None:
            return ret_L
        return self._fn(ret_L, ret_r)

    def __len__(self):
        return self._size


N, M = list(map(int, sys.stdin.readline().split()))
LRC = [list(map(int, sys.stdin.readline().split())) for _ in range(M)]

LRC.sort()
LRC = [(l - 1, r - 1, c) for l, r, c in LRC]
i = 0

# dp[pos]: pos までの最短距離
dp = SegmentTree(N, fn=min, initial_values=[INF] * N)
dp.set(0, 0)
for pos in range(N):
    d = dp.get(pos, N)
    while i < M and LRC[i][0] == pos:
        l, r, c = LRC[i]
        dp.set(r, min(d + c, dp.get(r)))
        i += 1
ans = dp.get(N - 1)
if ans == INF:
    print(-1)
else:
    print(ans)


Fixed submission:
import heapq
import os
import sys

if os.getenv("LOCAL"):
    sys.stdin = open("_in.txt", "r")

sys.setrecursionlimit(10 ** 9)
INF = float("inf")
IINF = 10 ** 18
MOD = 10 ** 9 + 7
# MOD = 998244353

N, M = list(map(int, sys.stdin.readline().split()))
LRC = [list(map(int, sys.stdin.readline().split())) for _ in range(M)]


def test():
    LRC.sort()
    dp = [INF] * N
    dp[0] = 0
    for l, r, c in LRC:
        l -= 1
        r -= 1
        for i in range(l, r + 1):
            dp[i] = min(dp[i], dp[l] + c)
    if dp[-1] == INF:
        print(-1)
    else:
        print(dp[-1])


# test()

heap = []
LRC.sort()
LRC = [(l - 1, r - 1, c) for l, r, c in LRC]
mi = 0
dp = [INF] * N
dp[0] = 0
for pos in range(N):
    if dp[pos] == INF:
        break
    while mi < M and LRC[mi][0] <= pos:
        l, r, c = LRC[mi]
        heapq.heappush(heap, (dp[pos] + c, r))
        mi += 1
    while heap and heap[0][1] <= pos:
        heapq.heappop(heap)
    if not heap:
        break
    dp[pos + 1] = heap[0][0]


if dp[-1] == INF:
    print(-1)
else:
    print(dp[-1])

Buggy python submission (verdict: Time Limit Exceeded):
import operator
import os
import sys

if os.getenv("LOCAL"):
    sys.stdin = open("_in.txt", "r")

sys.setrecursionlimit(10 ** 9)
INF = float("inf")
IINF = 10 ** 18
MOD = 10 ** 9 + 7


# MOD = 998244353

class SegmentTree:
    # http://tsutaj.hatenablog.com/entry/2017/03/29/204841
    def __init__(self, size, fn=operator.add, default=None, initial_values=None):
        """
        :param int size:
        :param callable fn: 区間に適用する関数。引数を 2 つ取る。min, max, operator.xor など
        :param default:
        :param list initial_values:
        """
        default = default or 0

        # size 以上である最小の 2 冪を size とする
        n = 1
        while n < size:
            n *= 2
        self._size = n
        self._fn = fn

        self._tree = [default] * (self._size * 2 - 1)
        if initial_values:
            i = self._size - 1
            for v in initial_values:
                self._tree[i] = v
                i += 1
            i = self._size - 2
            while i >= 0:
                self._tree[i] = self._fn(self._tree[i * 2 + 1], self._tree[i * 2 + 2])
                i -= 1

    def set(self, i, value):
        """
        i 番目に value を設定
        :param int i:
        :param value:
        :return:
        """
        x = self._size - 1 + i
        self._tree[x] = value

        while x > 0:
            x = (x - 1) // 2
            self._tree[x] = self._fn(self._tree[x * 2 + 1], self._tree[x * 2 + 2])

    def add(self, i, value):
        """
        もとの i 番目と value に fn を適用したものを i 番目に設定
        :param int i:
        :param value:
        :return:
        """
        x = self._size - 1 + i
        self.set(i, self._fn(self._tree[x], value))

    def get(self, from_i, to_i=None, k=0, L=None, r=None):
        """
        [from_i, to_i) に fn を適用した結果を返す
        :param int from_i:
        :param int to_i:
        :param int k: self._tree[k] が、[L, r) に fn を適用した結果を持つ
        :param int L:
        :param int r:
        :return:
        """
        if to_i is None:
            to_i = from_i + 1
        L = 0 if L is None else L
        r = self._size if r is None else r

        if from_i <= L and r <= to_i:
            return self._tree[k]

        if to_i <= L or r <= from_i:
            return None

        ret_L = self.get(from_i, to_i, k * 2 + 1, L, (L + r) // 2)
        ret_r = self.get(from_i, to_i, k * 2 + 2, (L + r) // 2, r)
        if ret_L is None:
            return ret_r
        if ret_r is None:
            return ret_L
        return self._fn(ret_L, ret_r)

    def __len__(self):
        return self._size


N, M = list(map(int, sys.stdin.readline().split()))
LRC = [list(map(int, sys.stdin.readline().split())) for _ in range(M)]

LRC.sort()
LRC = [(l - 1, r - 1, c) for l, r, c in LRC]
i = 0

# dp[pos]: pos までの最短距離
dp = SegmentTree(N, fn=min, initial_values=[INF] * N)
dp.set(0, 0)
for pos in range(N):
    d = dp.get(pos, N)
    while i < M and LRC[i][0] == pos:
        l, r, c = LRC[i]
        dp.set(r, min(d + c, dp.get(r)))
        i += 1
ans = dp.get(N - 1)
if ans == INF:
    print(-1)
else:
    print(ans)


Fixed submission:
import heapq
import os
import sys

if os.getenv("LOCAL"):
    sys.stdin = open("_in.txt", "r")

sys.setrecursionlimit(10 ** 9)
INF = float("inf")
IINF = 10 ** 18
MOD = 10 ** 9 + 7
# MOD = 998244353

N, M = list(map(int, sys.stdin.readline().split()))
LRC = [list(map(int, sys.stdin.readline().split())) for _ in range(M)]


def test():
    LRC.sort()
    dp = [INF] * N
    dp[0] = 0
    for l, r, c in LRC:
        l -= 1
        r -= 1
        for i in range(l, r + 1):
            dp[i] = min(dp[i], dp[l] + c)
    if dp[-1] == INF:
        print(-1)
    else:
        print(dp[-1])


# test()

heap = []
LRC.sort()
LRC = [(l - 1, r - 1, c) for l, r, c in LRC]
mi = 0
dp = [INF] * N
dp[0] = 0
for pos in range(N):
    if dp[pos] == INF:
        break
    while mi < M and LRC[mi][0] <= pos:
        l, r, c = LRC[mi]
        heapq.heappush(heap, (dp[pos] + c, r))
        mi += 1
    while heap and heap[0][1] <= pos:
        heapq.heappop(heap)
    if not heap:
        break
    dp[pos + 1] = heap[0][0]


if dp[-1] == INF:
    print(-1)
else:
    print(dp[-1])