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;

#define MAX 1100000

int main()
{
    int N, X;
    
    bool prime[MAX];
    fill(prime, prime + MAX, 1);
    prime[0] = prime[1] = 0;

    for (int i = 2; i < MAX; i++) {
        if (prime[i]) {
            for (int j = i * 2; j < MAX; j += i) {
                prime[j] = 0;
            }
        }
    }
    
    while (cin >> N >> X, N) {
        vector<int> a(N);
        for (int i = 0; i < N; i++) {
            cin >> a[i];
        }
        
        bool dp[MAX] = {};
        dp[0] = 1;

        for (int i = 0; i < N; i++) {
            for (int j = 0; j <= X-a[i]; j++) {
                if (dp[j]) {
                    dp[j+a[i]] = 1;
                }
            }
        }
        
        int res = -1;
        for (int i = X; i >= 0; i--) {
            if (prime[i] && dp[i]) {
                res = i;
                break;
            }
        }
        if (res == -1) {
            cout << "NA" << endl;
        } else {
            cout << res << endl;
        }
    }
    return 0;
}

C++: #include <iostream>
#include <cstring>

using namespace std;

#define MAX_X 1000001
#define MAX_N 30

bool is_prime[MAX_X];

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

bool can_make[MAX_X];

int n, x;
int dish[MAX_N];
bool input() {
    cin >> n >> x;
    if (n == 0 && x == 0) return false;
    for (int i = 0; i < n; i++) 
        cin >> dish[i];

    memset(can_make, 0, sizeof(can_make));
    can_make[0] = true;
    for (int i = 0; i < n; i++) {
        for (int j = 0; j <= x; j++) {
            if (j >= dish[i] && can_make[j-dish[i]])
                can_make[j] = true;
        }
    }
    return true;
}

int main() {
    init();
    while (input()) {
        bool found = false;
        while (x) {
            if (is_prime[x] && can_make[x]) {
                found = true;
                cout << x << endl;
                break;
            }
            x--;
        }
        if (!found) cout << "NA" << endl;
    }
    return 0;
}

C++: #include<algorithm>
#include<iostream>
#include<string>
#include<cstdlib>
#include<cstring>
#include<cmath>
using namespace std;
int main(){
  int i,j,k,l;
  int a[30],m,n;
  bool b[1000001],c[1000001];
  memset(c,0,1000001);
  c[2]=1;
  for(i=3;i<1000000;i+=2){
    l=(int)sqrt(i)+1;
    for(k=3;k<l;k+=2){
      if(i%k==0)
	break;
    }
    if(k>=l)
      c[i]=1;
  }
  while(cin>>m>>n&&m+n){
    for(i=0;i<m;i++)
      cin>>a[i];
    memset(b,0,1000001);
    b[0]=1;
    for(i=0;i<n;i++){
      if(b[i]){
	for(j=0;j<m;j++){
	  if(i+a[j]<=n)
	    b[i+a[j]]=1;
	}
      }
    }
    for(i=n;i>0;i--){
      if(b[i]&&c[i])
	break;
    }
    if(i)
      cout<<i<<endl;
    else
      cout<<"NA"<<endl;
  }
  return 0;
}

C++: #include <iostream>
#define FOR(i,a,b) for(int i=(a); i<(b); i++)
#define REP(i,a) FOR(i,0,a)
using namespace std;
const int MAXN = 1000005;

int main(void){
    // Sieve of Eratosthenes
    int prime[MAXN];
    REP(i,MAXN) prime[i] = 1;
    prime[0] = prime[1] = 0;
    REP(i,1000)
        if (prime[i])
            for (int j=2*i; j < MAXN; j += i) prime[j] = 0;

    while (true){
        int n,x;
        cin >> n >> x;
        if (n == 0 && x == 0) break;
        int cost[n];
        REP(i,n) cin >> cost[i];

        // calc costs list
        int costs[MAXN] = {};
        REP(i,n) costs[cost[i]] = 1;
        REP(i,n)
            REP(j,MAXN-cost[i])
                if (costs[j]) costs[j+cost[i]] = 1;
                
        for (int i=x; i > 0; i--){
            if (prime[i] && costs[i]){
                cout << i << endl;
                break;
            }
            if (i == 1){
                cout << "NA" << endl;
                break;
            }
        }
    }
    return 0;
}

C++: #include <iostream>
#include <algorithm>
#include <string>
#include <vector>
#include <map>
#include <sstream>
#include <functional>
#include <numeric>
#include <cmath>
#include <cstring>
#include <cstdio>
#include <queue>
#include <stack>
#include <set>

using namespace std;

#define ALL(co) co.begin(), co.end()
#define tpl(...) make_tuple(__VA_ARGS__)

typedef long long LL;
typedef pair<int, int> P; typedef pair<int, P> IP; typedef pair<P, P> PP;
typedef vector<int> Array; typedef vector<vector<int> > Array2;
typedef vector<LL> LArray; typedef vector<P> PArray; typedef vector<string> SArray;

const int INF = 1 << 29;
const LL LINF = 1LL << 60;

inline int getInt() { int itiv; return (cin >> itiv, itiv); }
template <typename T> void readAll(vector<T>& vec) { for (int i = 0, size = vec.size(); i < size; i++) cin >> vec[i]; }
template <typename T, typename U> void readAll(vector<pair<T, U> >& vec) { for (int i = 0, size = vec.size(); i < size; i++) cin >> vec[i].first >> vec[i].second; }
template < typename T > inline string toString( const T &a ){ ostringstream oss; oss << a; return oss.str(); };
inline bool between(int min, int max, int n) { return min <= n && n <= max; }
inline bool inRange(int begin, int end, int n) { return begin <= n && n < end; }
inline bool inRange(int size, int n) { return 0 <= n && n < size; }

int dx[] = { -1, 0, 1, 0 }, dy[] = { 0, -1, 0, 1 };
int dr[] = { 0, -1, 0, 1 }, dc[] = { -1, 0, 1, 0 };

const int MAX_X = 1000000;
bool values[MAX_X + 1];

const int MAX_N = MAX_X;
int prime[MAX_N];
bool is_prime[MAX_N + 1];
int eratos(int n)
{
	int p = 0;
	for (int i = 0; i <= n; i++) is_prime[i] = true;
	is_prime[0] = is_prime[1] = false;
	for (int i = 2; i <= n; i++)
	{
		if(is_prime[i])
		{
			prime[p++] = i;
			for (int j = 2*i; j <= n; j += i) is_prime[j] = false; 
		}
	}
	return p;
}

int main(void)
{
	ios::sync_with_stdio(false);
	eratos(MAX_X);
	int n, x;
	while (cin >> n >> x && n)
	{
		memset(values, false, sizeof(values));
		values[0] = true;
		int ans = 0;
		for (int i = 0; i < n; i++)
		{
			int v = getInt();
			for (int j = 0; j + v <= x; j++)
			{
				if(!values[j]) continue;
				values[j + v] = true;

				if(is_prime[j + v])
					ans = max(ans, j + v);
			}
		}

		cout << (ans ? toString(ans) : "NA") << endl;
	}
	return 0;
}