#pragma warning disable using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Runtime.Serialization.Formatters.Binary; using System.Text; using System.Text.RegularExpressions; using System.Diagnostics; using System.Numerics; using System.Collections; using System.Timers; static class MainClass { public static void Main(string[] args) { var N = Console.ReadLine().ToInt32(); var ls = GeneratePrimes().Take(2300).ToList(); var count = ls.Count(); var dp = new int[count + 10,20010]; for (int i = 0; i < count; i++) { for (int j = 0; j < 20010; j++) { dp[i, j] = -INF; } } dp[0, 0] = 0; for (int i = 0; i < count; i++) { for (int j = 0; j < 20010; j++) { var item = ls[i]; if (j - item < 0) { dp[i + 1, j] = dp[i, j]; } else { dp[i + 1, j] = Math.Max(dp[i, j], dp[i, j - ls[i]] + 1); } } } var num = dp[count, N]; Console.WriteLine(num < 0 ? -1 : num); } public class BoundedBoolArray { private BitArray _array; private int _lower; public BoundedBoolArray(int lower, int upper) { _array = new BitArray(upper - lower + 1); _lower = lower; } public bool this[int index] { get { return _array[index - _lower]; } set { _array[index - _lower] = value; } } } public static IEnumerable GeneratePrimes() { var primes = new List() { 2, 3 }; foreach (var p in primes) yield return p; int ix = 0; while (true) { int prime1st = primes[ix]; int prime2nd = primes[++ix]; var lower = prime1st * prime1st; var upper = prime2nd * prime2nd - 1; var sieve = new BoundedBoolArray(lower, upper); foreach (var prime in primes.Take(ix)) { var start = (int)Math.Ceiling((double)lower / prime) * prime; for (int index = start; index <= upper; index += prime) sieve[index] = true; } for (int i = lower; i <= upper; i++) { if (sieve[i] == false) { primes.Add(i); yield return i; } } } } #region ライブラリ public static long ToInt64(this string str) => long.Parse(str); public static int ToInt32(this string str) => int.Parse(str); public static BigInteger ToBigInteger(this string str) => BigInteger.Parse(str); public static List SplittedStringToList(this string str) => str.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries).ToList(); public static List SplittedStringToInt32List(this string str) => str.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries).Select(x => int.Parse(x)).ToList(); public static List SplittedStringToBigInteger(this string str) => str.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries).Select(x => BigInteger.Parse(x)).ToList(); public const int INF = int.MaxValue / 2; #endregion }