Go: package main

import (
	"bufio"
	"os"
	"strings"
	"strconv"
	"fmt"
	)

var scanner = bufio.NewScanner(os.Stdin)

func main() {
	for scanner.Scan() {
		buf := strings.Split(scanner.Text(), " ")
		n, _ := strconv.Atoi(buf[0])
		x, _ := strconv.Atoi(buf[1])
		prime_table := make([]int, 1000001)
		prime_table[0] = -1
		prime_table[1] = -1
		for i := 2; i < 1000001; i++ {
			if ^prime_table[i] != 0 {
				prime_table[i] = 1
				for j := 2*i; j < 1000001; j += i {
					prime_table[j] = -1 // -1 means "not prime"
				}
			}
		}
		dp := make([]int, x+1)
		dp[0] = 1
		menu := make([]int, n)
		for i := 0; i < n; i++ {
			scanner.Scan()
			menu[i], _ = strconv.Atoi(scanner.Text())
		}
		for i := 0; i < n; i++ {
			for j := 0; j <= x; j++ {
				if menu[i] <= j && dp[j-menu[i]] != 0 {
					// log.Println(dp)
					dp[j] = 1
				}
			}
		}
		flag := true
		for j := x; j >= 0; j-- {
			if prime_table[j] == 1 && dp[j] == 1 {
				flag = false
				fmt.Println(j)
				break
			}
		}
		if flag {
			fmt.Println("NA")
		}
	}
}

C++: #include <bits/stdc++.h>

using namespace std;

typedef long long ll;
typedef long double ld;
typedef tuple<int, int> duo;
const int dx[] = {0, 0, 1, -1, 1, 1, -1, -1};
const int dy[] = {1, -1, 0, 0, 1, -1, 1, -1};
const int Mod = 1000000000 + 0;
//{{{ templates
#define TT_ template<typename T>inline
#define TTF_ template<typename T,typename F>inline
TT_ T sq(T x){return x*x;}
TT_ T In(){T x;cin>>x;return x;}
TT_ void Out(T&x){cout<<x;}
TT_ void sort(T&v){sort(begin(v),end(v));}
TT_ void revs(T&v){reverse(begin(v),end(v));}
TT_ void uniq(T&v){sort(v);v.erase(unique(begin(v),end(v)),end(v));}
TT_ int ubnd(T&v,typename T::value_type x){return upper_bound(begin(v),end(v),x)-begin(v);}
TT_ int lbnd(T&v,typename T::value_type x){return lower_bound(begin(v),end(v),x)-begin(v);}
TTF_ void inpt(T&v,int n,F f){for(v.reserve(n);n--;v.emplace_back(f()));}
TTF_ void show(T&v,F f,string d=" ",string e="\n"){int i=0;for(auto&x:v)i++&&(cout<<d),f(x);cout<<e;}
TT_ typename T::iterator minel(T&v){return min_element(begin(v),end(v));}
TT_ typename T::iterator maxel(T&v){return max_element(begin(v),end(v));}

inline void fast_io(){ios_base::sync_with_stdio(0);cin.tie(0);}
inline int in(){int x;scanf("%d",&x);return x;}
inline ll pow_mod(ll a,ll k,ll m){ll r=1;for(;k>0;a=a*a%m,k>>=1)if(k&1)r=r*a%m;return r;}
inline ll mod_inv(ll a,ll p){return pow_mod(a,p-2,p);}
//}}} priority_queue queue deque front stringstream max_element min_element insert count make_tuple

const int MAX_N = 10100100;
int dp[MAX_N];
bool sieve[MAX_N];

int main()
{
  sieve[0] = sieve[1] = true;
  for (int i = 2; i * i <= MAX_N; i++){
    if (sieve[i]) continue;
    for (int j = i * i; j <= MAX_N; j += i){
      sieve[j] = true;
    }
  }

  int n, x, K = 1;
  while (n = in(), x = in(), n){
    int ans = -1;

    dp[0] = K;
    for (int i = 0; i < n; i++){
      int cost = in();
      for (int j = 0; j + cost <= x; j++){
        if (dp[j] == K){
          dp[j + cost] = K;
          if (!sieve[j + cost]) ans = max(ans, j + cost);
        }
      }
    }
    if (ans < 0) puts("NA");
    else printf("%d\n", ans);
  }
  return 0;
}

C++: #include <cstring>
#include <iostream>
using namespace std;

const int PRIME_MAX = 1000001;
bool isPrime[PRIME_MAX];
void init() {
	fill(isPrime, isPrime + PRIME_MAX, true);
	isPrime[0] = isPrime[1] = false;
	for (int i = 2; i * i <= PRIME_MAX; i++) {
		if (!isPrime[i]) continue;
		for (int j = (i << 1); j < PRIME_MAX; j += i) {
			isPrime[j] = false;
		}
	}
}

int main () {
	init();
	int n, x;
	while (cin >> n >> x, n || x) {
		int menu[n];
		bool dp[x + 1];
		memset(dp, 0, sizeof(dp));
		for (int i = 0; i < n; i++) {
			cin >> menu[i];
		}
		dp[0] = true;
		int result = 0;
		for (int i = 0; i <= x; ++i) {
			if (dp[i]) {
				for (int j = 0; j < n; ++j) {
					if (i + menu[j] <= x) {
						dp[i + menu[j]] = true;
					}
				}
				if (isPrime[i]) result = i;
			}
		}
		if (result == 0) {
			cout << "NA" << endl;
		}
		else {
			cout << result << endl;
		}
	}
	return 0;
}

C++: #include <bits/stdc++.h>

#define LL long long
#define VI vector<int>
#define VVI vector<vector<int>>
#define VVVI vector<vector<vector<int>>>
#define VL vector<LL>
#define VVL vector<vector<LL>>
#define VVVL vector<vector<vector<LL>>>
#define VB vector<bool>
#define FOR(i,a,b) for(int i= (a); i<((int)b); ++i)
#define RFOR(i,a) for(int i=(a); i >= 0; --i)
#define FOE(i,a) for(auto i : a)
#define ALL(c) (c).begin(), (c).end()
#define RALL(c) (c).rbegin(), (c).rend()
#define DUMP(x)  cerr << #x << " = " << (x) << endl;
#define SUM(x) std::accumulate(ALL(x), 0LL)
#define MIN(v) *std::min_element(v.begin(), v.end())
#define MAX(v) *std::max_element(v.begin(), v.end())
#define EXIST(v,x) (std::find(v.begin(), v.end(), x) != v.end())
#define BIT(n) (1LL<<(n))
#define UNIQUE(v) v.erase(unique(v.begin(), v.end()), v.end());
#define EPS 1e-14

template<class T> T ceil(T a, T b) { return (a + b - 1) / b; }
template<class T> void print(T x) { std::cout << x << std::endl; }

const std::string YES = "YES", Yes = "Yes", NO = "NO", No = "No";
const std::vector<int> dy = { 0, -1, 0, 1 }, dx = { 1, 0, -1, 0 };    // 4近傍（右, 下, 左, 上）

using namespace std;

// nまでの素数のリストを作成(nを含む) O(N log log N)
vector<int> make_prime_list(int n) {
    vector<bool> is_prime(n + 1, true);
    is_prime[0] = false;
    is_prime[1] = false;

    vector<int> prime_list;
    for (int i = 2; i < n + 1; ++i) {
        if (!is_prime[i]) { continue; }
        prime_list.emplace_back(i);

        for (int j = i + i; j < n + 1; j += i) {
            is_prime[j] = false;
        }
    }
    return prime_list;  // 素数のリスト
    //return is_prime;  // すべての数値について素数かどうか
}

int main() {
    cin.tie(0);
    ios::sync_with_stdio(false);

    while (true) {
        int n, x;
        cin >> n >> x;
        if (n == 0 and x == 0) { break; }

        VI v(n);
        FOR(i, 0, n) {
            cin >> v[i];
        }


        vector<bool> dp(x + 1, false);
        dp[0] = true;

        FOR(i, 0, dp.size()) {
            FOE(x, v) {
                if (dp[i] and i + x < dp.size()) {
                    dp[i + x] = true;
                }
            }
        }

        auto prime_list = make_prime_list(x + 1);
        int ans = 0;
        FOE(p, prime_list) {
            if (p <= x and dp[p]) {
                ans = max(ans, p);
            }
        }
        if (ans == 0) {
            print("NA");
        }
        else {
            print(ans);
        }
    }
}

C++: #include<iostream>
using namespace std;

const int size = 1000001;
bool a[size],DP[size];
int n,x;
int m[30];

void eratos(){
	if(size>=1)
		a[0] = false;
	if(size>=2)
		a[1] = false;
	for(int i=2; i<size; i++)
		a[i] = true;
	for(int i=2; i*i<size; i++)
		if(a[i])
			for(int j=i*i; j<size; j+=i)
				a[j] = false;
}

int main(){
	eratos();
	while(true){
		cin >> n >> x;
		if(!n&&!x)
			return 0;
		for(int i=0; i<n; i++)
			cin >> m[i];
		DP[0] = true;
		for(int i=1; i<=x; i++)
			DP[i] = false;
		for(int i=0; i<n; i++)
			for(int k=0; k<=x; k++)
				if(DP[k]&&k+m[i]<=x)
					DP[k+m[i]] = true;
		bool flag = true;
		for(int i=x; i>2; i-=2){
			if(!(i%2))
				i--;
			if(DP[i] && a[i]){
				cout << i << endl;
				flag = false;
				break;
			}
		}
		if(flag)
			cout << "NA\n";
	}
}