use std::io::*;
use std::str::FromStr;

#[allow(dead_code)]
fn read<T: FromStr>() -> T {
    let stdin = stdin();
    let stdin = stdin.lock();
    let token: String = stdin
        .bytes()
        .map(|c| c.expect("failed to read char") as char)
        .skip_while(|c| c.is_whitespace())
        .take_while(|c| !c.is_whitespace())
        .collect();
    token.parse().ok().expect("failed to parse token")
}

type Weight = i64;
#[allow(dead_code)]
#[derive(Clone, Debug, Eq, PartialEq)]
struct Edge {
    index: usize,
    src: usize,
    dest: usize,
    weight: Weight,
}
#[allow(dead_code)]
impl Edge {
    fn new(index: usize, src: usize, dest: usize, weight: Weight) -> Edge {
        Edge {
            index: index,
            src: src,
            dest: dest,
            weight: weight,
        }
    }
}
impl std::cmp::Ord for Edge {
    fn cmp(&self, other: &Self) -> std::cmp::Ordering {
        (self.weight, self.src, self.dest).cmp(&(other.weight, other.src, other.dest))
    }
}
impl std::cmp::PartialOrd for Edge {
    fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
        Some(self.cmp(other))
    }
}
type Edges = Vec<Edge>;
type Graph = Vec<Edges>;
#[allow(dead_code)]
fn graph_new(n: usize) -> Graph {
    vec![vec![]; n]
}
#[allow(dead_code)]
fn add_bi_edge(graph: &mut Graph, index: &mut usize, src: usize, dest: usize, weight: Weight) {
    graph[src].push(Edge::new(*index, src, dest, weight));
    graph[dest].push(Edge::new(*index, dest, src, weight));
    *index += 1;
}
#[allow(dead_code)]
fn add_uni_edge(graph: &mut Graph, index: &mut usize, src: usize, dest: usize, weight: Weight) {
    graph[src].push(Edge::new(*index, src, dest, weight));
    *index += 1;
}

const INF: Weight = 1 << 60;
fn bellman_ford(g: &Graph, visit: &Vec<bool>, s: usize, t: usize) -> Weight {
    let n = g.len();
    let mut dist = vec![INF; n];
    dist[s] = 0;
    for _iter in 0..n {
        let mut end = true;
        for i in 0..n {
            if !visit[i] {
                continue;
            }
            for edge in g[i].iter() {
                if !visit[edge.dest] {
                    continue;
                }
                let ncost = dist[i] + edge.weight;
                if dist[edge.dest] > ncost {
                    dist[edge.dest] = ncost;
                    end = false;
                }
            }
        }
        if end {
            return dist[t];
        }
    }
    -INF
}

fn dfs(g: &Graph, from: usize, visit: &mut Vec<bool>) {
    if visit[from] {
        return;
    }
    visit[from] = true;
    for edge in g[from].iter() {
        dfs(g, edge.dest, visit);
    }
}

fn main() {
    let n = read::<usize>();
    let m = read::<usize>();
    let mut g = graph_new(n);
    let mut e = 0;
    let mut rev_g = graph_new(n);
    for _ in 0..m {
        let f = read::<usize>() - 1;
        let t = read::<usize>() - 1;
        let c = read::<i64>();
        add_uni_edge(&mut g, &mut e, f, t, -c);
        e -= 1;
        add_uni_edge(&mut rev_g, &mut e, t, f, -c);
    }
    let mut visit = vec![false; n];
    dfs(&rev_g, n - 1, &mut visit);
    let ans = -bellman_ford(&g, &visit, 0, n - 1);
    if ans == INF {
        println!("inf");
    } else {
        println!("{}", ans);
    }
}


Measured memory_bytes: 4352