use std::collections::HashSet; const DX: [isize; 2] = [1, 0]; const DY: [isize; 2] = [0, 1]; fn main() { let mut hw = String::new(); std::io::stdin().read_line(&mut hw).ok(); let hw: Vec = hw.trim().split_whitespace().map(|s| s.parse().unwrap()).collect(); let h = hw[0]; let w = hw[1]; let grid = (0..h).map(|_| { let mut temp = String::new(); std::io::stdin().read_line(&mut temp).ok(); let temp: Vec = temp.trim().split_whitespace().map(|s| s.parse().unwrap()).collect(); temp }) .collect::>>(); let mut mapping = vec![vec![vec![0usize; w]; h]; 2]; mapping[0][0][0] = grid[0][0]; let mut frontier = HashSet::new(); frontier.insert((0, 0)); for _ in 0..(h+w-2) { let mut next_frontier = HashSet::new(); for &(cx, cy) in frontier.iter() { for dir in 0..2 { let nx = cx as isize + DX[dir]; let ny = cy as isize + DY[dir]; if nx < h as isize && ny < w as isize { let nx = nx as usize; let ny = ny as usize; for time in 0..2 { let current_attack = mapping[time][cx][cy]; if current_attack == 0 { continue; } let next_attack = current_attack + grid[nx][ny]; if current_attack > grid[nx][ny] { mapping[time][nx][ny] = mapping[time][nx][ny].max(next_attack) } else if time == 0 && !(nx == h-1 && ny == w-1) { mapping[time+1][nx][ny] = mapping[time+1][nx][ny].max(current_attack); } else { continue; } next_frontier.insert((nx, ny)); } } } } frontier = next_frontier; } if mapping[0][h-1][w-1] + mapping[1][h-1][w-1] > 0 { println!("Yes"); } else { println!("No"); } }