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 <queue>
#include <functional>

using namespace std;

int main() {
	int n, x;
	vector<int> furui(1000000+1, 0);
	furui[0] = furui[1] = 1;
	for (int i = 2; i*i <= 1000000; i++) {
		if (furui[i] == 0) {
			for (int j = 2; i*j <= 1000000; j++) {
				furui[i*j] = 1;
			}
		}
	}
	while (cin >> n >> x) {
		if (n == 0 && x == 0) {
			break;
		}
		vector<int> en;
		priority_queue<int, vector<int>, greater<int> > pq;
		vector<int> dp(x+1, 0);
		for (int i = 0; i < n; i++) {
			int k;
			cin >> k;
			if (k > x || k == 0) {
				continue;
			}
			dp[k] = 1;
			pq.push(k);
		}
		en.push_back(pq.top());
		pq.pop();
		/*
		while (!pq.empty()) {
			int k = pq.top();
			pq.pop();
			bool hantei2 = true;
			for (int i = 0; i < en.size(); i++) {
				if (k % en[i] == 0) {
					hantei2 = false;
					break;
				}
			}
			if (hantei2) {
				en.push_back(k);
			}
		}
		for (int i = 0; i < en.size(); i++) {
			for (int j = 0; j <= x; j++) {
				if (j < en[i]) {
				} else {
					dp[j] = max(dp[j], dp[j-en[i]]);
				}
			}
		}
		bool hantei = true;
		for (int i = x; i >= 0; i--) {
			if (dp[i] > 0 && furui[i] == 0) {
				cout << i << endl;
				hantei = false;
				break;
			}
		}
		if (hantei) {
			cout << "NA" << endl;
		}*/
	}
	return 0;
}

C++: #include <iostream>
#include <fstream>
#include <vector>
#include <string>
#include <map>
#include <sstream>
#include <queue>
#include <cstdlib>
#include <algorithm>
#include <iterator>
#include <stack>
#include <list>
using namespace std;
#define INF 100000000
typedef long long int lli;
typedef pair<int,int> P;
bool dp[30][1000001];
bool pn[1000001];

void eratos(bool f[]){
	for(int i=0; i<1000001; ++i){
		f[i]=true;
	}
	pn[0]=false;
	pn[1]=false;
	for(int i=2; i*i<1000001; ++i){
		if(f[i]){
			for(int j=2; i*j<1000001; ++j){
				f[i*j]=false;
			}
		}
	}
}
int main(){
	int n,x;
	while(cin >> n >> x){
		if(n==0&&x==0) break;
		vector<int> cost(n);
		for(int i=0; i<n; ++i){
			cin >> cost[i];
		}
		for(int i=0; i<n; ++i){
			for(int j=0; j<=x; ++j){
				dp[i][j]=false;
			}
		}
		for(int i=0; i*cost[0]<=x; ++i){
			dp[0][cost[0]*i]=true;
		}
		for(int i=1; i<n; ++i){
			for(int j=0; j<=x; ++j){
				if(dp[i-1][j]){
					for(int k=0;j+cost[i]*k<=x ; ++k){
						dp[i][j+cost[i]*k]=true;
					}
				}
			}
		}
		eratos(pn);
		bool flag=false;
		int ans;
		for(int i=x; i>=0; --i){
			if(dp[n-1][i]&&pn[i]){
				flag=true;
				ans=i;
				break;
			}
		}
		if(flag) {
			cout << ans << "\n";
		} else {
			cout << "NA\n";
		}
	}
	return 0;
}

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

const int MOD = 1e9 + 7;
const int iINF = 1000000000;
const long long int llINF = 1000000000000000000;
const double PI = acos(-1.0);
#define rep(i, n) for (int i = 0; i < (n); i++)

using namespace std;
using ll = long long int;
using P = pair<int, int>;
using T = tuple<int, int, int>;
using edge = struct
{
    int to;
    int cost;
};

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

bool isPrime[1000010];
bool dp[1000010];

void Eratostenes(int N)
{
    rep(i, 1e6 + 1) isPrime[i] = true;

    isPrime[0] = false;
    isPrime[1] = false;

    for(int i = 2; i <= sqrt(N); i++)
    {
        if(isPrime[i])
        {
            for(int j = i * 2; j <= N; j += i)
                isPrime[j] = false;
        }
    }   
}

int main()
{
    int N, X;
    Eratostenes(1000000);   

    while(cin >> N >> X && N)
    {
        vector<int> v(N);
        rep(i, N) cin >> v[i];
        rep(i, X + 1) dp[i] = false;

        dp[0] = true;

        rep(i, N)
        {
            rep(j, X + 1)
            {
                if(!dp[j]) continue;

                dp[j + v[i]] = true;
            }
        }

        int ans = 0;

        rep(i, X + 1)
        {
            if(dp[i] && isPrime[i])
                ans = max(ans, i);
        }

        cout << (ans == 0 ? "NA" : to_string(ans)) << endl;

    }

    return 0;
}

C++: #include<iostream>
#include<string>
#include<vector>
#include<utility>
#include<queue>
#include<algorithm>
#include<cmath>
#define INF 2147483647
#define llINF 9223372036854775807
#define pb push_back
#define mp make_pair 
#define F first
#define S second
#define ll long long

using namespace std;
int main(){
  int n,x;
  while(cin>>n>>x,n+x){
    int ans=-1;
    bool dp[x+1000]={};
    vector<int>v(n);
    for(int i=0;i<n;i++){
      cin>>v[i];
      dp[v[i]]=true;
    }
    sort(v.begin(),v.end());
    for(int i=1;i<x;i++){
      for(int j=0;j<v.size();j++){
	if(dp[i]==true){
	  if(i+v[j]>x){
	    v.pop_back();
	    j--;
	  }else{
	    dp[i+v[j]]=true;
	  }
	}
      }
    }
    int num=x;
    if(num%2==0)num--;
    for(int i=num;i>1;i-=2){
      bool flag=true;
      if(dp[i]==true){
	for(int j=2;j<=sqrt(i);j++){
	  if(i%j==0){
	    flag=false;
	    break;
	  }
	}
	if(flag){
	  ans=i;break;
	}
      }
    }
    if(ans==-1&&dp[2]==false)
      cout<<"NA"<<endl;
    else if(ans!=-1)
      cout<<ans<<endl;
    else
      cout<<2<<endl;
  }
  return 0;
}

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

using namespace std;

int dp[1000001];
int kind[31];


const int MAX_SIZE = 10000;
const int MAX_PRIME = 1000000;


int prime[MAX_PRIME+1];
bool isPrime[MAX_PRIME+1];
int p;

void erats(){
	// primeXgðú»
	fill(isPrime,isPrime+MAX_PRIME,true);
	p = 0;
	isPrime[0] = isPrime[1] = false;

	for(int i = 2; i <= MAX_PRIME; i++){
		if(isPrime[i]){
			prime[p++] = i;
		}
		else
			continue;

		// Óé¢É©¯é
		for(int j = 2*i; j <= MAX_PRIME; j+=i){
			isPrime[j] = false;
		}
	}
}


int main(){

	int n;
	int x;
	erats();
	while(cin>>n>>x&&!(n==0&&x==0)){
		for(int i = 0; i < n; i++){
			cin>>kind[i];
		}
		// eàzÌ¥¢ûª½íÞ é©ðßé
		dp[0]=1;
		int maxCost=-1;


		for(int i = 1; i <= x; i++){
			dp[i]=0;
			for(int j = 0; j < n; j++){
				if(i-kind[j]>=0){
					dp[i]+=dp[i-kind[j]];
				}
			}
			if(dp[i]>=1&&(isPrime[i]||i==1)){
				maxCost=max(i,maxCost);
			}
		}


		if(maxCost==-1)
			cout<<"NA"<<endl;
		else
			cout<<maxCost<<endl;
	}

	return 0;
}