Buggy python submission (verdict: Runtime Error):
# 抽象化をやめた場合
class Rmq(object):
    __slots__ = ["elem_size", "tree", "real_size"]

    def __init__(self, a):
        if hasattr(a, "__iter__"):
            self.real_size = len(a)
            self.elem_size = elem_size = 1 << (self.real_size-1).bit_length()
            self.tree = tree = [float("inf")] * (elem_size * 2)
            tree[elem_size:elem_size + self.real_size] = a
            for i in range(elem_size - 1, 0, -1):
                tree[i] = min(tree[i << 1], tree[(i << 1) + 1])
        elif isinstance(a, int):
            self.real_size = a
            self.elem_size = elem_size = 1 << (self.real_size-1).bit_length()
            self.tree = [float("inf")] * (elem_size * 2)

    def get_value(self, x: int, y: int) -> int:  # 半開区間
        l, r = x + self.elem_size, y + self.elem_size
        tree = self.tree
        result = float("inf")
        while l < r:
            if l & 1:
                result = min(tree[l], result)
                l += 1
            if r & 1:
                r -= 1
                result = min(tree[r], result)
            l, r = l >> 1, r >> 1
        return result

    def set_value(self, i: int, value: int) -> None:
        k = self.elem_size + i
        tree = self.tree
        tree[k] = value
        while k > 1:
            k >>= 1
            tree[k] = min(tree[k << 1], tree[(k << 1) + 1])

    def get_one_value(self, i):
        return self.tree[i+self.elem_size]

    def debug(self):
        print(self.tree[self.elem_size:self.elem_size+self.real_size])


from operator import itemgetter

N, M = map(int, input().split())
LRC = [list(map(int, input().split())) for _ in range(M)]
LRC.sort(key=itemgetter(0))

idx_LRC = 0
q = []

seg = SegmentTree(N+1, float("inf"), min)

seg.set_value(1, 0)
for v in range(1, N + 1):
    d = seg.get_value(v, N + 1)
    while idx_LRC < M:
        l, r, c = LRC[idx_LRC]
        if l <= v:
            seg.set_value(r, min(seg.tree[r + seg.elem_size], d + c))
            idx_LRC += 1
        else:
            break
ans = seg.tree[N + seg.elem_size]
print(ans if ans != float("inf") else -1)


Fixed submission:
# https://atcoder.jp/contests/abc014/submissions/3935971
class SegmentTree(object):
    __slots__ = ["elem_size", "tree", "default", "op"]
    def __init__(self, a: list, default: int, op):
        from math import ceil, log
        real_size = len(a)
        self.elem_size = elem_size = 1 << ceil(log(real_size, 2))
        self.tree = tree = [default] * (elem_size * 2)
        tree[elem_size:elem_size + real_size] = a
        self.default = default
        self.op = op
        for i in range(elem_size - 1, 0, -1):
            tree[i] = op(tree[i << 1], tree[(i << 1) + 1])

    def get_value(self, x: int, y: int) -> int:  # 半開区間
        l, r = x + self.elem_size, y + self.elem_size
        tree, result, op = self.tree, self.default, self.op
        while l < r:
            if l & 1:
                result = op(tree[l], result)
                l += 1
            if r & 1:
                r -= 1
                result = op(tree[r], result)
            l, r = l >> 1, r >> 1
        return result

    def set_value(self, i: int, value: int) -> None:
        k = self.elem_size + i
        self.tree[k] = value
        self.update(k)

    def update(self, i: int) -> None:
        op, tree = self.op, self.tree
        while i > 1:
            i >>= 1
            tree[i] = op(tree[i << 1], tree[(i << 1) + 1])

from operator import itemgetter
N, M = map(int, input().split())
LRC = [list(map(int, input().split())) for _ in range(M)]
LRC.sort(key=itemgetter(0))

idx_LRC = 0
q = []

seg = SegmentTree([float("inf")] * (N+1), float("inf"), min)

seg.set_value(1, 0)
for v in range(1, N+1):
    d = seg.get_value(v, N+1)
    while idx_LRC < M:
        l, r, c = LRC[idx_LRC]
        if l <= v:
            seg.set_value(r, min(seg.tree[r+seg.elem_size], d + c))
            idx_LRC += 1
        else:
            break
ans = seg.tree[N+seg.elem_size]
print(ans if ans!=float("inf") else -1)

Buggy python submission (verdict: Time Limit Exceeded):
class Rmq:
    # 平方分割
    # 値を変更すると元のリストの値も書き換わる
    def __init__(self, a, sqrt_n=500):
        from itertools import zip_longest
        self.n = len(a)
        self.sqrt_n = sqrt_n
        self.layer1 = a
        self.layer0 = [min(values) for values in zip_longest(*[iter(a)]*sqrt_n, fillvalue=float("inf"))]

    def get_min(self, l, r):
        sqrt_n = self.sqrt_n
        parent_l, parent_r = l//sqrt_n+1, (r+1)//sqrt_n
        if parent_l < parent_r:
            return min(min(self.layer0[parent_l:parent_r]),
                       min(self.layer1[l:parent_l*sqrt_n]),
                       min(self.layer1[parent_r*sqrt_n:r]))
        else:
            return min(self.layer1[l:r])

    def set_value(self, idx, val):
        self.layer1[idx] = val
        idx //= self.sqrt_n
        self.layer0[idx] = min(self.layer0[idx], val)

    def chmin(self, idx, val):
        if self.layer1[idx] > val:
            self.set_value(idx, val)

    def debug(self):
        print("layer0=", self.layer0)
        print("layer1=", self.layer1)

    def __getitem__(self, item):
        return self.layer1[item]

    def __setitem__(self, key, value):
        self.set_value(key, value)


from operator import itemgetter
import sys

def main():
    N, M = map(int, input().split())
    LRC = list(zip(*[iter(map(int, sys.stdin.read().split()))]*3))
    LRC.sort(key=itemgetter(0))
    idx_LRC = 0

    rmq = Rmq([float("inf")] * (N+1))
    rmq.set_value(1, 0)
    for v in range(1, N+1):
        d = rmq.get_min(v, N+1)
        while idx_LRC < M:
            l, r, c = LRC[idx_LRC]
            if l <= v:
                rmq.chmin(r, d+c)
                idx_LRC += 1
            else:
                break
    ans = rmq[N]
    print(ans if ans != float("inf") else -1)

main()


Fixed submission:
# https://atcoder.jp/contests/abc014/submissions/3935971
class SegmentTree(object):
    __slots__ = ["elem_size", "tree", "default", "op"]
    def __init__(self, a: list, default: int, op):
        from math import ceil, log
        real_size = len(a)
        self.elem_size = elem_size = 1 << ceil(log(real_size, 2))
        self.tree = tree = [default] * (elem_size * 2)
        tree[elem_size:elem_size + real_size] = a
        self.default = default
        self.op = op
        for i in range(elem_size - 1, 0, -1):
            tree[i] = op(tree[i << 1], tree[(i << 1) + 1])

    def get_value(self, x: int, y: int) -> int:  # 半開区間
        l, r = x + self.elem_size, y + self.elem_size
        tree, result, op = self.tree, self.default, self.op
        while l < r:
            if l & 1:
                result = op(tree[l], result)
                l += 1
            if r & 1:
                r -= 1
                result = op(tree[r], result)
            l, r = l >> 1, r >> 1
        return result

    def set_value(self, i: int, value: int) -> None:
        k = self.elem_size + i
        self.tree[k] = value
        self.update(k)

    def update(self, i: int) -> None:
        op, tree = self.op, self.tree
        while i > 1:
            i >>= 1
            tree[i] = op(tree[i << 1], tree[(i << 1) + 1])

from operator import itemgetter
N, M = map(int, input().split())
LRC = [list(map(int, input().split())) for _ in range(M)]
LRC.sort(key=itemgetter(0))

idx_LRC = 0
q = []

seg = SegmentTree([float("inf")] * (N+1), float("inf"), min)

seg.set_value(1, 0)
for v in range(1, N+1):
    d = seg.get_value(v, N+1)
    while idx_LRC < M:
        l, r, c = LRC[idx_LRC]
        if l <= v:
            seg.set_value(r, min(seg.tree[r+seg.elem_size], d + c))
            idx_LRC += 1
        else:
            break
ans = seg.tree[N+seg.elem_size]
print(ans if ans!=float("inf") else -1)

Buggy python submission (verdict: Time Limit Exceeded):
# https://atcoder.jp/contests/nikkei2019-2-qual/submissions/8357999 を
# 平方分割に書き換えた

class Rmq:
    # 平方分割
    # 値を変更すると元のリストの値も書き換わる
    def __init__(self, a, sqrt_n=500):
        from itertools import zip_longest
        self.n = len(a)
        self.sqrt_n = sqrt_n
        self.layer1 = a
        self.layer0 = [min(values) for values in zip_longest(*[iter(a)]*sqrt_n, fillvalue=float("inf"))]

    def get_min(self, l, r):
        sqrt_n = self.sqrt_n
        parent_l, parent_r = l//sqrt_n+1, (r+1)//sqrt_n
        if parent_l < parent_r:
            return min(min(self.layer0[parent_l:parent_r]),
                       min(self.layer1[l:parent_l*sqrt_n]),
                       min(self.layer1[parent_r*sqrt_n:r]))
        else:
            return min(self.layer1[l:r])

    def set_value(self, idx, val):
        self.layer1[idx] = val
        idx //= self.sqrt_n
        self.layer0[idx] = min(self.layer0[idx], val)

    def chmin(self, idx, val):
        if self.layer1[idx] > val:
            self.set_value(idx, val)

    def debug(self):
        print("layer0=", self.layer0)
        print("layer1=", self.layer1)

    def __getitem__(self, item):
        return self.layer1[item]

    def __setitem__(self, key, value):
        self.set_value(key, value)


from operator import itemgetter

N, M = map(int, input().split())
LRC = [list(map(int, input().split())) for _ in range(M)]
LRC.sort(key=itemgetter(0))

idx_LRC = 0
q = []

rmq = Rmq([float("inf")] * (N+1))

rmq.set_value(1, 0)
for v in range(1, N+1):
    d = rmq.get_min(v, N+1)
    while idx_LRC < M:
        l, r, c = LRC[idx_LRC]
        if l <= v:
            rmq.chmin(r, d+c)
            idx_LRC += 1
        else:
            break
ans = rmq[N]
print(ans if ans != float("inf") else -1)


Fixed submission:
# https://atcoder.jp/contests/abc014/submissions/3935971
class SegmentTree(object):
    __slots__ = ["elem_size", "tree", "default", "op"]
    def __init__(self, a: list, default: int, op):
        from math import ceil, log
        real_size = len(a)
        self.elem_size = elem_size = 1 << ceil(log(real_size, 2))
        self.tree = tree = [default] * (elem_size * 2)
        tree[elem_size:elem_size + real_size] = a
        self.default = default
        self.op = op
        for i in range(elem_size - 1, 0, -1):
            tree[i] = op(tree[i << 1], tree[(i << 1) + 1])

    def get_value(self, x: int, y: int) -> int:  # 半開区間
        l, r = x + self.elem_size, y + self.elem_size
        tree, result, op = self.tree, self.default, self.op
        while l < r:
            if l & 1:
                result = op(tree[l], result)
                l += 1
            if r & 1:
                r -= 1
                result = op(tree[r], result)
            l, r = l >> 1, r >> 1
        return result

    def set_value(self, i: int, value: int) -> None:
        k = self.elem_size + i
        self.tree[k] = value
        self.update(k)

    def update(self, i: int) -> None:
        op, tree = self.op, self.tree
        while i > 1:
            i >>= 1
            tree[i] = op(tree[i << 1], tree[(i << 1) + 1])

from operator import itemgetter
N, M = map(int, input().split())
LRC = [list(map(int, input().split())) for _ in range(M)]
LRC.sort(key=itemgetter(0))

idx_LRC = 0
q = []

seg = SegmentTree([float("inf")] * (N+1), float("inf"), min)

seg.set_value(1, 0)
for v in range(1, N+1):
    d = seg.get_value(v, N+1)
    while idx_LRC < M:
        l, r, c = LRC[idx_LRC]
        if l <= v:
            seg.set_value(r, min(seg.tree[r+seg.elem_size], d + c))
            idx_LRC += 1
        else:
            break
ans = seg.tree[N+seg.elem_size]
print(ans if ans!=float("inf") else -1)