use std::collections::VecDeque; fn main() { let stdin = std::io::stdin(); let mut line = String::new(); stdin.read_line(&mut line).unwrap(); let line: Vec<&str> = line.split_whitespace().collect(); let n = line[0].parse::().unwrap(); let m = line[1].parse::().unwrap(); let mut line = String::new(); stdin.read_line(&mut line).unwrap(); let a: Vec<_> = line .split_whitespace() .map(|s| s.parse::().unwrap()) .collect(); let mut g: Vec> = vec![vec![]; n]; // 逆グラフ let mut inv_g: Vec> = vec![vec![]; n]; for _ in 0..m { let mut line = String::new(); stdin.read_line(&mut line).unwrap(); let line: Vec<_> = line.split_whitespace().collect(); let l = line[0].parse::().unwrap(); let r = line[1].parse::().unwrap(); let d = line[2].parse::().unwrap(); g[l - 1].push((r - 1, d)); inv_g[r - 1].push(l - 1); } // 終点からの到達可能性 let mut visited = vec![false; n]; visited[n - 1] = true; let mut queue = VecDeque::new(); queue.push_back(n - 1); while let Some(v) = queue.pop_front() { for &u in &inv_g[v] { if !visited[u] { visited[u] = true; queue.push_back(u); } } } assert!(visited[0]); // 始点からの最短コスト let mut min_cost = vec![None; n]; min_cost[0] = Some(-a[0]); for loop_count in 0..(n + 1) { let mut updated = false; for v in 0..n { let Some(current_min_cost) = min_cost[v] else { continue; }; for &(u, d) in &g[v] { if !visited[u] { // 終点に到達できない負閉路を除外する continue; } let next_cost = current_min_cost + d - a[u]; if let Some(min_cost_u) = min_cost[u] { if min_cost_u > next_cost { min_cost[u] = Some(next_cost); updated = true; } } else { min_cost[u] = Some(next_cost); updated = true; } } } if !updated { println!("{}", -min_cost[n - 1].unwrap()); break; } if loop_count == n { // 負閉路 println!("inf"); return; } } }