import scala.collection.mutable.ArrayBuffer

object Main {

  val INF = Long.MaxValue
  case class Edge(to: Int, weight: Int)
  def main(args: Array[String]): Unit = {
    // 仮定, スコアが無限に増えるケースでは閉路が存在するから, inf
    // つまり, 正常な場合は閉路がないことから有効非巡回グラフになっているので
    // トポロジカルソート版ベルマンフォードが有効
    // 閉路検出は, トポロジカルソート順に再度緩和した時, 緩和できるかどうか?
    // なお, 1からVまで必ず到達できることを保証しているが, それ以外が連結かどうかを示していない
    val sc = new java.util.Scanner(System.in)

    val V, E = sc.nextInt()
    val G = Array.fill(V+1)(new ArrayBuffer[Edge]())
    for (_ <- 0 until E) {
      val u, v, w = sc.nextInt()
      G(u).append(Edge(v, -w))
    }

    bellmanFord(V, G, 1) match {
      case Some(v) => println(v)
      case _ => println("inf")
    }
  }

  def bellmanFord(V: Int, G: Array[ArrayBuffer[Edge]], s: Int): Option[Long] = {
    val dist = Array.fill(V+1)(INF)
    dist(s) = 0

    def relax(u: Int, v: Int, w: Int): Boolean =
      if (dist(u) != INF && dist(v) > dist(u) + w) {
        dist(v) = dist(u) + w
        true
      } else false

    val sorted = topologicalSort(V, G, 1)
    for {
      u <- sorted
      e <- G(u)
    } relax(u, e.to, e.weight)

    if (!sorted.exists(u => G(u).exists(e => relax(u, e.to, e.weight))))
      Some(-dist(V))
    else None
  }

  private def topologicalSort(V: Int, G: Array[ArrayBuffer[Edge]], s: Int): List[Int] = {
    val visited = new Array[Boolean](V+1)
    def dfs(stack: List[Int], sorted: List[Int]): List[Int] =
      if (stack.nonEmpty) {
        val u = stack.head
        if (u < 0) dfs(stack.tail, (-u)-1 :: sorted)
        else if (!visited(u)) {
          visited(u) = true
          dfs(
            G(u).foldLeft(-(u+1) :: stack.tail)(
              (stack, e) => e.to :: stack), sorted)
        } else dfs(stack.tail, sorted)
      } else sorted
    dfs(s :: Nil, Nil)
  }

}
