fn main() { let stdin = std::io::read_to_string(std::io::stdin().lock()).unwrap(); let mut stdin = stdin.split_ascii_whitespace(); let n: usize = stdin.next().unwrap().parse().unwrap(); use std::io::Write; std::io::stdout() .lock() .write_all(output(solve(n)).as_bytes()) .unwrap(); } const fn prepare() -> [bool; 200_001] { const MAX_N: usize = 200_000; let mut is_prime = [true; MAX_N + 1]; (is_prime[0], is_prime[1]) = (false, false); let mut i = 2; while i <= MAX_N { if is_prime[i] { let mut j = i.pow(2); while j <= MAX_N { is_prime[j] = false; j += i; } } i += 1; } is_prime } fn solve(n: usize) -> Option { let is_prime = prepare(); let mut dp_cur = vec![i16::MIN; n + 1]; let mut dp_next = vec![i16::MIN; n + 1]; dp_next[0] = 0; is_prime .into_iter() .enumerate() .filter(|&(_, b)| b) .map(|(i, _)| i) .for_each(|p| { std::mem::swap(&mut dp_cur, &mut dp_next); let dp_cur = &dp_cur; dp_next.copy_from_slice(&dp_cur[..]); (p..dp_next.len()).for_each(|i| dp_next[i] = dp_next[i].max(dp_cur[i - p] + 1)); }); if dp_next[n] < 0 { None } else { Some(dp_next[n] as u16) } } fn output(ans: Option) -> String { match ans { Some(ans) => ans.to_string() + "\n", None => String::from("-1\n"), } }