
import collection.mutable.ArrayBuffer
import scala.reflect.ClassTag
import scala.language.implicitConversions

trait Graph { 
    case class Edge[T:Numeric](from : Int, to : Int, cost : T)

    class Edges[T:Numeric](val data : ArrayBuffer[Edge[T]]) {
        def size = data.size
    }
    object Edges {
        def apply[T:Numeric](xs : Edge[T]*) = new Edges(ArrayBuffer(xs:_*))
        implicit def toUnderLying[T](x:Edges[T]) = x.data
    }

    class WeightedGraph[T:Numeric](val size : Int, val data : Array[Edges[T]]) {
        def this(size : Int) = this(size, Array.fill(size)(Edges()))
    }
    object WeightedGraph {
        // def apply[T:Numeric](size : Int) = new WeightedGraph[T](size)
        implicit def toUnderLying[T](x:WeightedGraph[T]) = x.data
    }

    class UnWeightedGraph[T:Numeric](val size : Int, val data: Array[ArrayBuffer[T]]) {
        def this(size : Int) = this(size, Array.fill(size)(ArrayBuffer[T]()))
    }
    object UnWeightedGraph {
        // def apply[T:Numeric](size : Int) = new UnWeightedGraph[T](size)
        implicit def toUnderLying[T](x:UnWeightedGraph[T]) = x.data
    }
   
    class Matrix[T:Numeric:ClassTag](val row : Int, val col : Int, val data : Array[Array[T]]) {
        def this(row : Int, col : Int) = this(row, col, Array.fill(row, col)(implicitly[Numeric[T]].zero))
        def this(size : Int) = this(size, size)
    }
    object Matrix {
        implicit def toUnderLying[T](x:Matrix[T]) = x.data
    }
}

// object BellmanFord extends Graph {
//     import Edges._

//     // return ArrayBuffer() when find a negative cycle
//     def bellmanFord[T:ClassTag](edges : Edges[T], V : Int, s : Int, INF : T)(implicit num : Numeric[T]) : Array[T] = {
//         val dist = Array.fill[T](V)(INF)
//         dist(s) = num.zero
//         for (_ <- 1 until V) {
//             for (e <- edges) {
//                 if(dist(e.from) != INF) 
//                     dist(e.to) = num.min(dist(e.to), num.plus(dist(e.from), e.cost))
//             }
//         }
//         // check a negative cycle
//         for (e <- edges) {
//             if(dist(e.from) != INF)
//                 if (num.lt(num.plus(dist(e.from), e.cost), dist(e.to)) && e.to == V-1)
//                     return Array.empty
//         }
//         dist
//     }
// }

object BellmanFord extends Graph {
    import Edges._

    // return ArrayBuffer() when find a negative cycle
    def bellmanFord(edges : Edges[Long], V : Int, s : Int, INF : Long) : Array[Long] = {
        val dist = Array.fill(V)(INF)
        dist(s) = 0
        for (_ <- 1 until V) {
            for (e <- edges) {
                if(dist(e.from) != INF) 
                    dist(e.to) = (dist(e.to) min (dist(e.from) + e.cost))
            }
        }
        // check a negative cycle
        for (e <- edges) {
            if(dist(e.from) != INF)
                if (((dist(e.from) + e.cost) < dist(e.to)) && e.to == V-1)
                    return Array.empty
        }
        dist
    }
}


import BellmanFord._

object Main {
    def main(args: Array[String]) = {
        val sc = new java.util.Scanner(System.in)
        val N, M = sc.nextInt
        val edges = Edges[Long]()
        for (_ <- 1 to M) {
            val s, t = sc.nextInt
            val c : Long = sc.nextLong
            edges += Edge[Long](s-1, t-1, -c)
        }
        println(edges.toList)
        val res = bellmanFord(edges, N, 0, Long.MaxValue)
        println(res.toList)
        if (res.isEmpty) println("inf")
        else {
            println(-res(N-1))
        }
    }
}