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] != -1 {
				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 <cstring>
#include <cmath>
#include <algorithm>
#include <vector>

#define REP(i,k,n) for(int i=0;i<n;i++)
#define rep(i,n) for(int i=0;i<n;i++)

using namespace std;

int prime[1000001];
int dp[1000001];

void CreatePrime()
{
	rep(i,1000001) prime[i] = 1;

	prime[0] = 0;

	for(int i=0;i<1000001;i++)
	{
		if(prime[i] == 1)
		{
			int num = i+1;
			for(int j=num*2-1;j <1000001;j += num)
			{
				prime[j] = 0;
			}
		}
	}
}

int main()
{
	CreatePrime();

	int a[31];
	int n,x,ans = 0;
	
	
	while(cin >> n >> x)
	{
		if(n == 0 || x == 0)
		{
			break;
		}

		memset(a,0,sizeof(a));
		memset(dp,0,sizeof(dp));

		ans = 0;
		rep(i,n) 
		{
			cin >> a[i];
			dp[a[i]] = 1;
		}

		rep(i,n)
		{
			rep(j,x+1)
			{
				if(dp[j] == 1 && j+a[i] <= x)
				{
					dp[j+a[i]] = 1;
				}
			}
		}

		rep(i,x+1)
		{
			if(dp[i] == 1 && prime[i-1] == 1)
			{
				ans = i;
			}
		}

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


	}
	
	return 0;
}

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

#define MAX_X 1000001

int n;
int x;
vector<int> p;

bool table[MAX_X];
vector<int> prime;

void init() {
    memset(table, 1, sizeof(table));
    table[0] = table[1] = false;
    for (int i = 2; i < MAX_X; i++) {
        if (table[i]) {
            prime.push_back(i);
            for (int j = i + i; j < MAX_X; j += i) {
                table[j] = false;
            }
        }
    }
}

bool cache[MAX_X];
bool cached[MAX_X];

bool can_make(int t) {
//    cout << t << endl;
    if (t == 0) return true;
    else if (t < 0) return false;
    if (cached[t]) return cache[t];

    bool can = false;
    for (int i = 0; i < p.size(); i++) {
        if (can_make(t-p[i])) {
            can = true;
            break;
        }
    }
    cache[t] = can;
    cached[t] = true;
    return can;
}

int main() {
    init();
//    for (int i = 0; i < prime.size(); i++) {
//        cout << prime[i] << ' ';
//    }

    while (cin >> n >> x, n || x) {
        memset(cache, 0, sizeof(cache));
        memset(cached, 0, sizeof(cached));

        p.clear();
        p.resize(n);
        for (int i = 0; i < n; i++) {
            cin >> p[i];
        }
        sort(p.begin(), p.end(), greater<int>());

        bool exist = false;

        int ub = prime.size()-1;
        int lb = 0;
        int mid;

        while (lb != ub - 1) {
            mid = (lb + ub) / 2;
            if (prime[mid] < x) {
                lb = mid;
            } else {
                ub = mid;
            }
        }

//        cout << "ub: " << ub << endl;
        for (int i = mid; 0 <= i; i--) {
            if (can_make(prime[i])) {
                cout << prime[i] << endl;
                exist = true;
                break;
            }
        }

        if (!exist) {
            cout << "NA" << endl;
        }

    }
    return 0;
}

C++: #include <iostream>
#include <algorithm>
#include <vector>
#define rep(i, a, n) for(int i = a;i < n;i++)
using namespace std;


int n, x;
int m[40];
int dp[40][1000010];
vector<int> prime;


void makeList(){
	rep(i, 1, n+1){
		rep(j, 0, x+1){
			if(1 < dp[i][j] && dp[i][j] <= x)
				prime.push_back(dp[i][j]);
		}
	}
}


void sieve(){
	makeList();
	for(int i = 2;i*i <= x;i++){
		prime.erase(remove_if(prime.begin(), prime.end(), [&](int v){ return (v % i == 0); }), prime.end());
	}
	sort(prime.begin(), prime.end());
}


void makeDP(){
	rep(i, 1, n+1){
		rep(j, 0, x+1){
			if(j - m[i] >= 0) dp[i][j] = max(dp[i-1][j], dp[i][j - m[i]] + m[i]);
			else dp[i][j] = dp[i-1][j];
		}
	}
}


int main(){
	while(cin >> n >> x, n || x){
		rep(i, 1, n+1) cin >> m[i];

		makeDP();

		sieve();

		if(prime.size()) cout << prime.back() << endl;
		else cout << "NA" << endl;
	}

	return 0;
}