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 C# (judge verdict: Time Limit Exceeded)

using System;
using System.Linq;
using System.Collections.Generic;

public class Hello{
    public static bool[] PrimeCheck{get;set;}
    public static List<int> Primes;
    public static bool[] CanMakePrimes;
    
    public static void Main(){
        // Make Primes
        PrimeCheck = Enumerable.Repeat(true, Consts.MAXBADGET + 1).ToArray();
        Primes = new List<int>();
        for(int i = 0; i < Consts.MAXBADGET + 1; i++){
            if(i == 0){
                PrimeCheck[i] = false;
                continue;
            }
            if(i == 1){
                Primes.Add(i); // iclude 1 when this problem.
            }
            else if(PrimeCheck[i] == false){
                continue;
            }
            else{
                Primes.Add(i);
                for(int n = i * 2; n < Consts.MAXBADGET + 1; n += i){
                    PrimeCheck[n] = false;
                }
            }
        }
        CanMakePrimes = Enumerable.Repeat(false, Primes.Count).ToArray();

        while(true){
            // Input MenuNum and Badget
            string[] n_x = System.Console.ReadLine().Split(' ');
            int MenuNum = int.Parse(n_x[0]);
            int Badget = int.Parse(n_x[1]);
            if(MenuNum == 0 && Badget == 0) break;
            
            // Input MenuPrices
            int[] MenuPrices = new int[MenuNum];
            bool ContainsOdd = false;
            for(int i = 0; i < MenuNum; i++){
                MenuPrices[i] = int.Parse(System.Console.ReadLine());
                ContainsOdd = MenuPrices[i] % 2 != 0 ? true : ContainsOdd;
            }
              
            // Cant make Prime Number when all given numbers are Even.
            if(ContainsOdd == false){ 
                System.Console.WriteLine("NA");
            }
            // when given single number
            else if(MenuPrices.Length == 1){
                // it is not Prime number, then cant maek Prime Number.
                if(Primes.FindIndex(item => item == MenuPrices[0]) < 0){
                    System.Console.WriteLine("NA");
                }
                // it is Prime Number, then Max Prime Number is it Number.
                else{
                    System.Console.WriteLine(MenuPrices[0]);
                }
            }            
            else{
                // Desc
                Array.Sort(MenuPrices, (a, b) => b - a);
                // Asc
                //Array.Sort(MenuPrices, (a, b) => a - b);
                System.Console.WriteLine(Solve(Badget, MenuPrices));
            }
        }
    }
    
    public static string Solve(int Badget, int[] MenuPrices){
        string Result = "NA";
        int CurrentPrime = Primes.FindLast(item => item <= Badget);
        while(true){
            if(Search(CurrentPrime, MenuPrices)){
                Result = CurrentPrime.ToString();
                return Result;
            }
            else{
                CurrentPrime = Primes.FindLast(item => item < CurrentPrime);
                if(CurrentPrime == 0) break;
            }
        }
        return Result;
    }

    
    
    
    
    public static bool Search(int Prime, int[] MenuPrices){

        int Modulo = Prime;
        int TmpModulo;
        bool[] AllowanceLimit = Enumerable.Repeat(false, MenuPrices.Length).ToArray();
        AllowanceLimit[MenuPrices.Length - 1] = true;
        int[] Allowance = Enumerable.Repeat(0, MenuPrices.Length).ToArray();
        
//int cnt = 0;
//System.Text.StringBuilder sb = new System.Text.StringBuilder();
        while(true){
//sb.Clear();
            Modulo = Prime;
//sb.Append("Modulo:" + Modulo + " LoopCount:" + ++cnt + "\n");
            for(int i = 0; i < MenuPrices.Length; i++){
                if(i != MenuPrices.Length - 1){
                    TmpModulo = Modulo % MenuPrices[i] + MenuPrices[i] * Allowance[i];
//sb.Append(Modulo  + " / " + MenuPrices[i] + " = " + (Modulo / MenuPrices[i] - Allowance[i]) + " ... " + TmpModulo + "\n");
                    if(Modulo == TmpModulo){
                        AllowanceLimit[i] = true;
                    }
                    else if(TmpModulo == 0){
                        return true;
                    }
                    else{
                        Modulo = TmpModulo;
                    }
                }
                else{
//sb.Append(Modulo + " / " + MenuPrices[i] + " = " + Modulo / MenuPrices[i] + " ... " + Modulo % MenuPrices[i] + "\n");
                    if(Modulo % MenuPrices[i] == 0){
//System.Console.WriteLine(sb.ToString());
                        return true;
                    }
                    else if(Modulo == Prime){
                        return false;
                    }
                    else{
                        for(int a = 0; a < AllowanceLimit.Length; a++){
                            if(Array.FindIndex(AllowanceLimit, a + 1, (item => item == false)) < 0){
                                Allowance[a]++;
                                for(int a2 = a + 1; a2 < AllowanceLimit.Length - 1; a2++){
                                    Allowance[a2] = 0;
                                    AllowanceLimit[a2] = false;
                                }
                                break;
                            }
                        }
                    }
                }
            }
        }
    }

}

public static class Consts{
    public static int MAXBADGET = 1000000;
}