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<iostream>
#include<vector>
#include<cmath>
#include<algorithm>

using namespace std;

#define MAX 1000001

vector<int> vprimes;
bool *isPrime = new bool[MAX];

void MakePrime(){
  isPrime[0]=false;
  isPrime[1]=false;
  isPrime[2]=true;
  for(int i = 2; i < MAX; ++i){
    isPrime[i] = true;
  }
  for(long long int i = 2; i < MAX; ++i){
    if( isPrime[i] ){
      for(long long int j = 2; i * j < MAX; ++j) {
	isPrime[i*j] = false;
      }
    }
  }
  for(int i = 0; i < MAX; ++i){
    if( isPrime[i] ){
      vprimes.push_back( i );
    }
  }
}

int main()
{
  MakePrime();
  while(true){
    int n,x;
    int ans = 0;
    vector<int> menu;
    cin >> n >> x;
    if( n == 0 && x == 0 )break;
    int dp[1+x];
    for(int i = 0; i < n; ++i){
      int v;
      cin >> v;
      menu.push_back( v );
    }

    fill(dp,dp+1+x,0);
    dp[0]=1;
    for(int i = 0; i < 1+x; ++i){
      if( dp[i] ){
	//cout << i << endl;
	for(int k = 0; k < menu.size(); ++k){
	  if( i + menu[k] < 1+x ){

	    dp[ i + menu[k] ] = 1;
	  }
	}
      }
    }
    for(int i = x; i>=0; --i){
      if( dp[i] && isPrime[i] ){
	ans = max(ans, i);
	break;
      }
    }
    if( ans ==0 ){
      cout << "NA" << endl;
    }else{
      cout << ans << endl;
    }
  }
  return 0;
}

C++: #include<iostream>
#include<algorithm>
#define rep(i,n) for(int i=0;i<n;i++)
#define MC 1000001
using namespace std;
bool p[MC],V[MC]; int n,x,c[35],ans;
void rec(int a){
	rep(i,n)if(a+c[i]<x&&!V[a+c[i]])V[a+c[i]]=1,rec(a+c[i]);
}
int main(){
	for(int i=2;i*i<MC;i++)if(!p[i])for(int j=i+i;j<MC;j+=i)p[j]=1;
	p[0]=p[1]=1;
	while(cin>>n>>x,n){
		rep(i,n)cin>>c[i]; sort(c,c+n);
		fill(V,V+x,0); rec(0);
		for(ans=x;ans>=c[0];ans--)if(!p[ans]&&V[ans])break;
		if(ans<c[0])cout<<"NA"<<endl;
		else cout<<ans<<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 <cstdio>
#include <algorithm>
using namespace std;
#define REP(i, a, b) for (int i = (a); i < (b); ++i)
#define rep(i, n) REP(i, 0, n)
#define M 1000001
bool p[M];
int dish[31];
int dp[M];
int n, x;
int main()
{
	rep(i, M) p[i] = true;
	p[0] = p[1] = false;
	for (int i = 2; i * i < M; ++i)
		for (int j = 2 * i; j < M; j += i)
			if (p[j]) p[j] = false;

	while (true) {
		scanf("%d%d", &n, &x);
		if ((n | x) == 0) break;
		rep(i, n) scanf("%d", dish + i);
		
		rep(j, x+1) dp[j] = -1;
		dp[0] = (1<<20);

		int k = 1;
		rep(i, n) REP(j, 1, x+1) {
			if (dp[j] >= 0)
				dp[j] = (1<<20);
			else if (j < dish[i] || dp[j-dish[i]] <= 0)
				dp[j] = -1;
			else
				dp[j] = dp[j-dish[i]] - 1;
		}
		int res = 0;
		rep(j, x+1) if (p[j] && dp[j] >= 0) res = j;
		if (res > 0)
			printf("%d\n", res);
		else
			puts("NA");
	}
	return 0;
}

C++: #include <iostream>
#include <string>
#include <vector>
#include <algorithm>
#include <climits>

using namespace std;

int main() {
	bool p[1000001];
	int n, x;

	p[0] = false;
	p[1] = false;
	for(int i = 2; i <= 1000000; i++) {
		p[i] = true;
	}

	for(int i = 2; i * i <= 1000000; i++) {
		for(int j = 2; j * i <= 1000000; j++) {
			p[i * j] = false;
		}
	}

	while( true ) {
		cin >> n >> x;

		if(n == 0 && x == 0) {
			break;
		}

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

		for(int i = 0; i < n; i++) {
			cin >> money;
			for(int j = 0; j <= x; j++) {
				if(dp[j] && (j + money) < x) {
					dp[j + money] = true;
				}
			}
		}


		int ans = 0;
		for(int i = x; i > 0; --i) {
			if(p[i] && dp[i]) {
				ans = i;
				break;
			}
		}

		if( ans == 0 ) {
			cout << "NA" << endl;
		} else {
			cout << ans << endl;
		}
	}
}