Problem:
上司のおごり

会津太郎さんの会社には、割り切れない事が大嫌いな上司がいます。太郎さんがその上司と食事に行くときは、割り勘で会計をしているのですが、支払金額が参加人数で割り切れないときは、いつも上司がおごってくれています。

ある日、太郎さんは食事会の幹事になりました。お金の少ない太郎さんは、その上司を誘ってなんとかおごってもらえるように出来ないか考えました。もう料理屋に注文をしなければならないのですが、まだ何人参加するかは分からないので、どんな人数が参加してもおごってもらえるような注文をしておきたいようです。太郎さんの同期で、同じく食事会に参加する予定のあなたは、太郎さんに協力して、予算額以下で最大のどんな人数でも割り切れない金額を算出することにしました。

料理の種類、各料理の料金、予算額を入力とし、予算額以下で最大のどんな数字でも割り切れない合計金額(ただし、 1 と合計金額は除く)を出力するプログラムを作成してください。なお、各種類の料理は複数個注文できますが、全種類の料理を注文する必要はありません。ただし、このような合計金額がない場合は、 NA と出力してください。

Input

複数のデータセットの並びが入力として与えられます。 入力の終わりはゼロふたつの行で示されます。
各データセットは以下の形式で与えられます。

n x
v1
v2
:
vn

1 行目に料理の種類 n (1 ≤ n ≤ 30) と予算額 x (1 ≤ x ≤ 1000000) が空白区切りで与えられます。続くn 行に i 種類目の料理の金額を表す整数 vi (1 ≤ vi ≤ 1000000) が与えられます。

データセットの数は 100 を超えません。

Output

入力データセットごとに、予算額に最も近い合計金額、または NA を１行に出力します。

Sample Input

4 15000
305
260
129
500
3 400
10
20
30
3 200909
5
9
12
0 0

Output for the Sample Input

14983
NA
200909

Solution in OCaml (judge verdict: Wrong Answer)

open Scanf

let iota ?(init=0) ?(step=1) n =
  let rec iota i n acc =
    if i = 0 then List.rev acc
    else iota (i - 1) (n + step) (n :: acc) in
  iota n init []

let rec primes last =
  if last < 2 then []
  else if last = 2 then [2]
  else if last mod 2 = 0 then primes (last - 1)
  else
    let index n = (n - 3) / 2 in
    let value i = 2 * i + 3 in
    let last_index = index last in
    let sieve = Array.make (last_index + 1) true in
    let rec mark i step =
      if i < Array.length sieve then begin
        sieve.(i) <- false;
        mark (i + step) step
      end
      else () in
    let primes = ref [2] in
    for i = 0 to last_index do
      if sieve.(i) then begin
        primes := (value i) :: !primes;
        mark (2 * i * i + 6 * i + 3) (value i)
      end
    done;
    !primes

let rec matches budget prices =
  if budget = 0 then true
  else
    match prices with
      | [] -> false
      | price :: prices when price > budget -> matches budget prices
      | price :: prices' ->
         try
           List.rev_map
             (fun m -> budget - price * m)
             (iota ~init:1 (budget / price))
           |> List.exists (fun budget -> matches budget prices')
         with Not_found -> matches budget prices'

let read_lines n =
  let rec read_lines n acc =
    if n = 0 then List.rev acc
    else read_lines (pred n) ((read_line ())::acc) in
  read_lines n []

let rec solve () =
  sscanf
    (read_line ()) "%d %d"
    (fun n budget ->
     if n = 0 && budget = 0 then ()
     else
       let prices =
         List.map int_of_string (read_lines n)
         |> List.sort (fun (a : int) b -> compare b a) in
       let result =
         try
           List.find (fun prime -> matches prime prices) (primes budget)
           |> string_of_int
         with Not_found -> "NA" in
       print_endline result;
       solve ())

let () = solve ()