import sys

input = sys.stdin.readline



def I(): return int(eval(input()))

def MI(): return list(map(int, input().split()))

def LI(): return list(map(int, input().split()))



def main():

    N,M=MI()

    inf=10**16

    class SegTree:

        def __init__(self,N,ide,segfunc=min):

            self.ide_ele = ide

            """

            ex)

             最小値のセグ木 → +inf

              和のセグ木 → 0

              積のセグ木 → 1

              gcdのセグ木 → 0

            """

            

            self.segfunc=segfunc

            

            #num:N以上の最小の2のべき乗

            self.num =2**(N-1).bit_length()

            self.seg=[self.ide_ele]*2*self.num









        #リストで初期化する

        def setL(self,init_val):

            #init_valは操作する数列

            for i in range(N):

                self.seg[i+self.num-1]=init_val[i]    

            #built

            for i in range(self.num-2,-1,-1) :

                self.seg[i]=self.segfunc(self.seg[2*i+1],self.seg[2*i+2]) 





        #k番目の値をxに更新

        def update(self,k,x):

            k += self.num-1

            self.seg[k] = x

            while k:

                k = (k-1)//2

                self.seg[k] = self.segfunc(self.seg[k*2+1],self.seg[k*2+2])





        #[p,q)の区間に対するクエリへの応答

        def query(self,p,q):

            if q<=p:

                return self.ide_ele

            p += self.num-1

            q += self.num-2

            res=self.ide_ele

            while q-p>1:

                if p&1 == 0:

                    res = self.segfunc(res,self.seg[p])

                if q&1 == 1:

                    res = self.segfunc(res,self.seg[q])

                    q -= 1

                p = p//2

                q = (q-1)//2

            if p == q:

                res = self.segfunc(res,self.seg[p])

            else:

                res = self.segfunc(self.segfunc(res,self.seg[p]),self.seg[q])

            return res





    seg=SegTree(N+1,inf,min)

    

    L=[0]*M

    R=[0]*M

    C=[0]*M

    for i in range(M):

        l,r,c=MI()

        l-=1

        r-=1

        L[i]=l

        R[i]=r

        C[i]=c

        

    R,C,L=list(zip(*sorted(zip(R,C,L))))

        

    

    

    #rが小さいものから見て(rが同じならcが小さい)確定させていく

    now=0#確定させたとこと

    seg.update(0,0)

    

    for i in range(M):

        r=R[i]

        l=L[i]

        c=C[i]

        m=seg.query(l,now+1)#移動もとの範囲での最小値

        #seg.update(r,m+c)

        now=r

        

        #このままだと入力例3みたいに，コストは低いけどl,rがちかいみたいなのを先に処理してしまう

        #とりあえず右端だけ更新しとけばokか?

        

        if m+c<seg.query(now,now+1):

            seg.update(now,m+c)

        

        #print((l+1,r+1,c),now+1,m,m+c)

        """

        for ii in range(N):

            print(seg.query(ii,ii+1))"""

        

    ans=seg.query(N-1,N)



    

    

    if ans>=inf:

        print((-1))

    else:

        print(ans)

    

        

    

        

        

    



main()

import sys

input = sys.stdin.readline



def I(): return int(eval(input()))

def MI(): return list(map(int, input().split()))

def LI(): return list(map(int, input().split()))



def main():

    N,M=MI()

    inf=10**16



    ##########################################

    import heapq

    class Dijkstra():

        """

        ・有向 / 無向は問わない(無向の場合は，逆向きの辺もたす)

        ・負のコストがない場合のみ

        ・計算量はO(E log|V|)　

        ・heapを使うことで頂点を走査する必要がなくなる（代わりに，距離更新したものは確定でなくともqueに入れておく）

        """

        

        #最短のpathをたす

        

        

        class Edge():

            #重み付き有向辺

            

            def __init__(self, _to, _cost):

                self.to =_to

                self.cost = _cost

        

        def __init__(self, V):

            #引数Vは頂点数

            self.G = [[] for _ in range(V)] #隣接リストG[u][i]が頂点uのi番目の辺

            self. _E = 0 #辺の数

            self._V = V #頂点数

        

        #proparty - 辺の数

        def E(self):

            return self._E

        

        #proparty - 頂点数

        def V(self):

            return self._V

        

        def add(self, _from, _to, _cost):

            #2頂点と辺のコストを追加

            self.G[_from].append(self.Edge(_to,_cost))

            self._E +=1

            

        def add2(self, _from, _to, _cost):

            #2頂点と辺のコスト（無向）を追加

            self.G[_from].append(self.Edge(_to, _cost))

            self.G[_to].append(self.Edge(_from, _cost))

            self._E +=2

            

        def shortest_path(self,s):#,g):

            #始点sから頂点iまでの最短経路長のリストを返す

            

            que = [] #priority queue

            d = [inf] * self.V()

            prev = [None]*self.V() #prev[j]は，sからjへ最短経路で行くときのjの一つ前の場所

            d[s] = 0

            heapq.heappush(que,(0,s)) #始点の距離と頂点番号をヒープに追加

            

            while len(que)!=0:

                #キューに格納されてある中で一番コストが小さい頂点を取り出す

                cost,v = heapq.heappop(que)

                

                #キューに格納された最短経路長候補がdの距離よりも大きい場合に処理をスキップ

                if d[v] < cost:

                    continue

                    

                #頂点vに隣接する各頂点iに対して，vを経由した場合の距離を計算して，これがd[i]よりも小さい場合に更新

                for i in range(len(self.G[v])):

                    e = self.G[v][i] #vのi個目の隣接辺

                    if d[e.to] > d[v] + e.cost:

                        d[e.to] = d[v] + e.cost #更新

                        prev[e.to] = v

                        heapq.heappush(que,(d[e.to],e.to)) #queに新たな最短経路長候補を追加

            

            """#sからgまでの最短経路

            path = []

            pos = g #今いる場所，ゴールで初期化

            for _ in range(self.V()+1):

                path.append(pos)

                if pos == s:

                    break

                #print("pos:",format(pos))

                pos = prev[pos]

            path.reverse()

            #print(path)"""

                        

            return d#,path

    ########################

    

    djk=Dijkstra(N)



    for i in range(M):

        l,r,c=MI()

        l-=1

        r-=1

        djk.add(l,r,c)

        

    for i in range(1,N):

        djk.add(i,i-1,0)



        

    d=djk.shortest_path(0)

    ans=d[-1]







    

    

    if ans>=inf:

        print((-1))

    else:

        print(ans)

    

        

    

        

        

    



main()

import sys

input = sys.stdin.readline


def I():
    return int(eval(input()))


def MI():
    return list(map(int, input().split()))


def LI():
    return list(map(int, input().split()))


def main():
    N, M = MI()
    inf = 10**16

    class SegTree:
        def __init__(self, N, ide, segfunc=min):
            self.ide_ele = ide
            """
            ex)
             最小値のセグ木 → +inf
              和のセグ木 → 0
              積のセグ木 → 1
              gcdのセグ木 → 0
            """
            self.segfunc = segfunc
            # num:N以上の最小の2のべき乗
            self.num = 2 ** (N - 1).bit_length()
            self.seg = [self.ide_ele] * 2 * self.num

        # リストで初期化する
        def setL(self, init_val):
            # init_valは操作する数列
            for i in range(N):
                self.seg[i + self.num - 1] = init_val[i]
            # built
            for i in range(self.num - 2, -1, -1):
                self.seg[i] = self.segfunc(self.seg[2 * i + 1], self.seg[2 * i + 2])

        # k番目の値をxに更新
        def update(self, k, x):
            k += self.num - 1
            self.seg[k] = x
            while k:
                k = (k - 1) // 2
                self.seg[k] = self.segfunc(self.seg[k * 2 + 1], self.seg[k * 2 + 2])

        # [p,q)の区間に対するクエリへの応答
        def query(self, p, q):
            if q <= p:
                return self.ide_ele
            p += self.num - 1
            q += self.num - 2
            res = self.ide_ele
            while q - p > 1:
                if p & 1 == 0:
                    res = self.segfunc(res, self.seg[p])
                if q & 1 == 1:
                    res = self.segfunc(res, self.seg[q])
                    q -= 1
                p = p // 2
                q = (q - 1) // 2
            if p == q:
                res = self.segfunc(res, self.seg[p])
            else:
                res = self.segfunc(self.segfunc(res, self.seg[p]), self.seg[q])
            return res

    seg = SegTree(N + 1, inf, min)
    L = [0] * M
    R = [0] * M
    C = [0] * M
    for i in range(M):
        l, r, c = MI()
        l -= 1
        r -= 1
        L[i] = l
        R[i] = r
        C[i] = c
    R, C, L = list(zip(*sorted(zip(R, C, L))))
    # rが小さいものから見て(rが同じならcが小さい)確定させていく
    now = 0  # 確定させたとこと
    seg.update(0, 0)
    for i in range(M):
        r = R[i]
        l = L[i]
        c = C[i]
        m = seg.query(l, now + 1)  # 移動もとの範囲での最小値
        # seg.update(r,m+c)
        now = r
        # このままだと入力例3みたいに，コストは低いけどl,rがちかいみたいなのを先に処理してしまう
        # とりあえず右端だけ更新しとけばokか?
        if m + c < seg.query(now, now + 1):
            seg.update(now, m + c)
        # print((l+1,r+1,c),now+1,m,m+c)
        """
        for ii in range(N):
            print(seg.query(ii,ii+1))"""
    ans = seg.query(N - 1, N)
    if ans >= inf:
        print((-1))
    else:
        print(ans)


main()

import sys

input = sys.stdin.readline


def I():
    return int(eval(input()))


def MI():
    return list(map(int, input().split()))


def LI():
    return list(map(int, input().split()))


def main():
    N, M = MI()
    inf = 10**16
    ##########################################
    import heapq

    class Dijkstra:
        """
        ・有向 / 無向は問わない(無向の場合は，逆向きの辺もたす)
        ・負のコストがない場合のみ
        ・計算量はO(E log|V|)
        ・heapを使うことで頂点を走査する必要がなくなる（代わりに，距離更新したものは確定でなくともqueに入れておく）
        """

        # 最短のpathをたす
        class Edge:
            # 重み付き有向辺
            def __init__(self, _to, _cost):
                self.to = _to
                self.cost = _cost

        def __init__(self, V):
            # 引数Vは頂点数
            self.G = [[] for _ in range(V)]  # 隣接リストG[u][i]が頂点uのi番目の辺
            self._E = 0  # 辺の数
            self._V = V  # 頂点数

        # proparty - 辺の数
        def E(self):
            return self._E

        # proparty - 頂点数
        def V(self):
            return self._V

        def add(self, _from, _to, _cost):
            # 2頂点と辺のコストを追加
            self.G[_from].append(self.Edge(_to, _cost))
            self._E += 1

        def add2(self, _from, _to, _cost):
            # 2頂点と辺のコスト（無向）を追加
            self.G[_from].append(self.Edge(_to, _cost))
            self.G[_to].append(self.Edge(_from, _cost))
            self._E += 2

        def shortest_path(self, s):  # ,g):
            # 始点sから頂点iまでの最短経路長のリストを返す
            que = []  # priority queue
            d = [inf] * self.V()
            prev = [None] * self.V()  # prev[j]は，sからjへ最短経路で行くときのjの一つ前の場所
            d[s] = 0
            heapq.heappush(que, (0, s))  # 始点の距離と頂点番号をヒープに追加
            while len(que) != 0:
                # キューに格納されてある中で一番コストが小さい頂点を取り出す
                cost, v = heapq.heappop(que)
                # キューに格納された最短経路長候補がdの距離よりも大きい場合に処理をスキップ
                if d[v] < cost:
                    continue
                # 頂点vに隣接する各頂点iに対して，vを経由した場合の距離を計算して，これがd[i]よりも小さい場合に更新
                for i in range(len(self.G[v])):
                    e = self.G[v][i]  # vのi個目の隣接辺
                    if d[e.to] > d[v] + e.cost:
                        d[e.to] = d[v] + e.cost  # 更新
                        prev[e.to] = v
                        heapq.heappush(que, (d[e.to], e.to))  # queに新たな最短経路長候補を追加
            """#sからgまでの最短経路
            path = []
            pos = g #今いる場所，ゴールで初期化
            for _ in range(self.V()+1):
                path.append(pos)
                if pos == s:
                    break
                #print("pos:",format(pos))
                pos = prev[pos]
            path.reverse()
            #print(path)"""
            return d  # ,path

    ########################
    djk = Dijkstra(N)
    for i in range(M):
        l, r, c = MI()
        l -= 1
        r -= 1
        djk.add(l, r, c)
    for i in range(1, N):
        djk.add(i, i - 1, 0)
    d = djk.shortest_path(0)
    ans = d[-1]
    if ans >= inf:
        print((-1))
    else:
        print(ans)


main()

+    ########################################## +    import heapq -    class SegTree: -        def __init__(self, N, ide, segfunc=min): -            self.ide_ele = ide -            """ -            ex) -             最小値のセグ木 → +inf -              和のセグ木 → 0 -              積のセグ木 → 1 -              gcdのセグ木 → 0 -            """ -            self.segfunc = segfunc -            # num:N以上の最小の2のべき乗 -            self.num = 2 ** (N - 1).bit_length() -            self.seg = [self.ide_ele] * 2 * self.num +    class Dijkstra: +        """ +        ・有向 / 無向は問わない(無向の場合は，逆向きの辺もたす) +        ・負のコストがない場合のみ +        ・計算量はO(E log|V|) +        ・heapを使うことで頂点を走査する必要がなくなる（代わりに，距離更新したものは確定でなくともqueに入れておく） +        """ -        # リストで初期化する -        def setL(self, init_val): -            # init_valは操作する数列 -            for i in range(N): -                self.seg[i + self.num - 1] = init_val[i] -            # built -            for i in range(self.num - 2, -1, -1): -                self.seg[i] = self.segfunc(self.seg[2 * i + 1], self.seg[2 * i + 2]) +        # 最短のpathをたす +        class Edge: +            # 重み付き有向辺 +            def __init__(self, _to, _cost): +                self.to = _to +                self.cost = _cost -        # k番目の値をxに更新 -        def update(self, k, x): -            k += self.num - 1 -            self.seg[k] = x -            while k: -                k = (k - 1) // 2 -                self.seg[k] = self.segfunc(self.seg[k * 2 + 1], self.seg[k * 2 + 2]) +        def __init__(self, V): +            # 引数Vは頂点数 +            self.G = [[] for _ in range(V)]  # 隣接リストG[u][i]が頂点uのi番目の辺 +            self._E = 0  # 辺の数 +            self._V = V  # 頂点数 -        # [p,q)の区間に対するクエリへの応答 -        def query(self, p, q): -            if q <= p: -                return self.ide_ele -            p += self.num - 1 -            q += self.num - 2 -            res = self.ide_ele -            while q - p > 1: -                if p & 1 == 0: -                    res = self.segfunc(res, self.seg[p]) -                if q & 1 == 1: -                    res = self.segfunc(res, self.seg[q]) -                    q -= 1 -                p = p // 2 -                q = (q - 1) // 2 -            if p == q: -                res = self.segfunc(res, self.seg[p]) -            else: -                res = self.segfunc(self.segfunc(res, self.seg[p]), self.seg[q]) -            return res +        # proparty - 辺の数 +        def E(self): +            return self._E -    seg = SegTree(N + 1, inf, min) -    L = [0] * M -    R = [0] * M -    C = [0] * M +        # proparty - 頂点数 +        def V(self): +            return self._V + +        def add(self, _from, _to, _cost): +            # 2頂点と辺のコストを追加 +            self.G[_from].append(self.Edge(_to, _cost)) +            self._E += 1 + +        def add2(self, _from, _to, _cost): +            # 2頂点と辺のコスト（無向）を追加 +            self.G[_from].append(self.Edge(_to, _cost)) +            self.G[_to].append(self.Edge(_from, _cost)) +            self._E += 2 + +        def shortest_path(self, s):  # ,g): +            # 始点sから頂点iまでの最短経路長のリストを返す +            que = []  # priority queue +            d = [inf] * self.V() +            prev = [None] * self.V()  # prev[j]は，sからjへ最短経路で行くときのjの一つ前の場所 +            d[s] = 0 +            heapq.heappush(que, (0, s))  # 始点の距離と頂点番号をヒープに追加 +            while len(que) != 0: +                # キューに格納されてある中で一番コストが小さい頂点を取り出す +                cost, v = heapq.heappop(que) +                # キューに格納された最短経路長候補がdの距離よりも大きい場合に処理をスキップ +                if d[v] < cost: +                    continue +                # 頂点vに隣接する各頂点iに対して，vを経由した場合の距離を計算して，これがd[i]よりも小さい場合に更新 +                for i in range(len(self.G[v])): +                    e = self.G[v][i]  # vのi個目の隣接辺 +                    if d[e.to] > d[v] + e.cost: +                        d[e.to] = d[v] + e.cost  # 更新 +                        prev[e.to] = v +                        heapq.heappush(que, (d[e.to], e.to))  # queに新たな最短経路長候補を追加 +            """#sからgまでの最短経路 +            path = [] +            pos = g #今いる場所，ゴールで初期化 +            for _ in range(self.V()+1): +                path.append(pos) +                if pos == s: +                    break +                #print("pos:",format(pos)) +                pos = prev[pos] +            path.reverse() +            #print(path)""" +            return d  # ,path + +    ######################## +    djk = Dijkstra(N) -        L[i] = l -        R[i] = r -        C[i] = c -    R, C, L = list(zip(*sorted(zip(R, C, L)))) -    # rが小さいものから見て(rが同じならcが小さい)確定させていく -    now = 0  # 確定させたとこと -    seg.update(0, 0) -    for i in range(M): -        r = R[i] -        l = L[i] -        c = C[i] -        m = seg.query(l, now + 1)  # 移動もとの範囲での最小値 -        # seg.update(r,m+c) -        now = r -        # このままだと入力例3みたいに，コストは低いけどl,rがちかいみたいなのを先に処理してしまう -        # とりあえず右端だけ更新しとけばokか? -        if m + c < seg.query(now, now + 1): -            seg.update(now, m + c) -        # print((l+1,r+1,c),now+1,m,m+c) -        """ -        for ii in range(N): -            print(seg.query(ii,ii+1))""" -    ans = seg.query(N - 1, N) +        djk.add(l, r, c) +    for i in range(1, N): +        djk.add(i, i - 1, 0) +    d = djk.shortest_path(0) +    ans = d[-1]