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])
		if n == 0 && x == 0 {
			break
		}
		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 <cstdio>
#include <algorithm>
#include <array>
#include <vector>
#include <cmath>

using namespace std;

int main() {
  const int lim = 1000000;
  vector<bool> primes( lim + 1 );
  fill( primes.begin(), primes.end(), true );
  primes[ 0 ] = primes[ 1 ] = false;
  const int l = (int)sqrt( lim );
  for ( int i = 2; i <= l; i++ ){
	if ( primes[ i ] ) {
	  for ( int j = i * i; j <= lim; j += i ) {
		primes[ j ] = false;
	  }
	}
  }
  
  while( true ) {
	int n, x;
	cin >> n >> x;
	if ( n == 0 and x == 0 ) break;
	
	vector<int> vs( n );
	for ( int i = 0; i < n; i++ ) {
	  cin >> vs[ i ];
	}
	sort( vs.begin(), vs.end() );
	vector<bool> cands( x + 1 );
	int ans = -1;
	fill( cands.begin(), cands.end(), false );
	cands[ 0 ] = true;
	for ( int i = 0; i <= x; i++ ) {
	  if ( cands[ i ] ) {
		for ( int v : vs ) {
		  if ( i + v <= x ) {
			cands[ i + v ] = true;
		  }
		}
		if ( primes[ i ] ) {
		  ans = i;
		}
	  }
	}
	if ( ans == -1 ) {
	  cout << "NA" << endl;	  
	} else {
	  cout << ans << endl;
	}
  }
}

C++: #include <cstdio>
#include <iostream>
#include <cstring>
#include <algorithm>
#include <vector>

using namespace std;

bool prime[1000001],dp[1000001];

void make_prime(){
  for(int i=0;i<1000001;i++) prime[i]=true;
  prime[0]=prime[1]=false;
  for(int i=2;i*i<=1000000;i++){
    if(prime[i]){
      for(int j=i*2;j<1000001;j+=i){
          prime[j]=false;
        }
    }
  }
}

int n,x;
vector<int> price;

int main(){
  make_prime();

  while(cin>>n && n){
    cin>>x;
    for(int i=0;i<1000001;i++){
      dp[i]=false;
    }
    for(int i=0;i<n;i++){
      int tmp;
      cin>>tmp;
      price.push_back(tmp);
      dp[tmp]=true;
    }

    sort(price.begin(),price.end());

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

    int ans=0;

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

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

C++: #include<iostream>
#include<cmath>
using namespace std;
#define KMAX 30
#define VMAX 1000000
int K[KMAX];
unsigned char T[KMAX][VMAX+1];
void eratos ( int n, bool prime[]){
 for ( int i = 0; i <= n; i++ ) prime[i] = false;
 for ( int i = 3; i <= n; i += 2 ) prime[i] = true;
 prime[2] = true;
 int limit = (int)sqrt((double)n) + 1;
 for ( int i = 3; i <= limit; i += 2 ){
if ( !prime[i] ) continue;
for ( int j = i + i; j <= n; j += i ) prime[j] = false;
 }
}
main(){
 bool prime[VMAX + 1];
 eratos( VMAX, prime );
 int k, v;
 while( cin >> k >> v && !(k == 0 && v == 0) ){
for ( int i = 0; i < k; i++ ) cin >> K[i];
for ( int j = 0; j <= v; j++ ) T[0][j] = 0;
for ( int j = K[0]; j <= v; j += K[0] ) T[0][j] = 1;
for ( int i = 0; i < k; i++ ) T[i][0] = 1;
for ( int i = 1; i < k; i++ ){
 for ( int j = 1; j < K[i]; j++ ) T[i][j] = T[i-1][j];
 for ( int j = K[i]; j <= v; j++ ){
T[i][j] = (T[i-1][j] | T[i][j-K[i]]);
 }
}
int ans = -1;
for ( int i = v; i >= 2; i-- ){
 if ( prime[i] && T[k-1][i] ) { ans = i; break; }
}
if ( ans == -1 ) cout << "NA" << endl;
else cout << ans << endl;
 }
}

C++: #include <iostream>
using namespace std;
int n, x;
int primeTable[1000001];

void makePrimeTable(void) {

    primeTable[0] = false;
    primeTable[1] = false;
    for(int i = 2; i < 1000001; i++) {
        primeTable[i] = true;
    }
    
    for(int i = 2; i < 1000001; i++) {
        if(primeTable[i]) {
            for(int j = i + i; j < 1000001; j += i) {
                primeTable[j] = false;
            }
        }
    }
}


void search(int k, int * price, bool * numbers) {
    
    for(int i = 0; i < n; i++) {
        if(k + price[i] < x + 1) {
            if(!numbers[k + price[i]]) {
                numbers[k + price[i]] = true;
                search(k + price[i], price, numbers);
            }
        }
    }
}

int main(void){
    // Your code here!
    makePrimeTable();
    
    while(cin >> n >> x) {
        if(n == 0 && x == 0) break;
        
        int price[n];
        bool numbers[x+1];
        
        for(int i = 0; i < n; i++) {
            cin >> price[i];
        }
        for(int i = 0; i < x+1; i++) {
            numbers[i] = false;
        }
        numbers[0] = true;

        search(0, price, numbers);
        
        bool flag = true;
        for(int i = x; i >= 0; i--) {
            if(numbers[i] && primeTable[i]) {
                flag = false;
                cout << i << endl;
                break;
            }
        }
        if(flag) cout << "NA" << endl;
        
    }
}

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

constexpr int MAX_X = 1000001;
constexpr int MAX_N = 31;

int n, x, values[MAX_N];
bool is_prime_number[MAX_X] = {true};

void initialize();

void solve();

int main(){
    initialize();
    while(true){
        memset(values, 0, MAX_N);

        std::cin >> n >> x;
        
        if(n + x == 0) break;
        
        for(int i = 0; i < n; ++i)
            std::cin >> values[i];

        solve();
    }
}

void initialize(){
    for(int i = 0; i <= MAX_X; ++i) is_prime_number[i] = true;
    is_prime_number[0] = false, is_prime_number[1] = false;
    for(int i = 2; i * i <= MAX_X; ++i){
        if(is_prime_number[i]){
            for(int j = i + 1; j < MAX_X; ++j){
                if(j % i == 0)
                    is_prime_number[j] = false;
            }
        }
    }
}

void solve(){
    int ans = 0;
    int dp[MAX_X];
    memset(dp, 0, MAX_X);

    /*
    std::cout << "x : " << x << std::endl << "n : " << n << std::endl;
    for(int i = 0; i < (x > 1000 ? 1000 : x); ++i){
        std::cout << i << " dp : " << dp[i] << std::endl;
    }
    */

    for(int i = 1; i <= x; ++i){
        int res = 0;
        for(int j = 0; j < n; ++j){
            if(values[j] <= i){
                res = std::max(dp[i - values[j]] + values[j], res);
            }
        }
        dp[i] = std::max(dp[i], res);
        if(is_prime_number[dp[i]]){
            ans = std::max(dp[i], ans);
        }
    }

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

}

C++: #include<stdio.h>
int n,x;
int kin;
int i,j;
int dp[1000050],flg[1000050];
int main(void){
	for(i=1;i<=1000000;i++){
		flg[i]=1;
	}
	for(i=2;i*i<=1000000;i++){
		if(flg[i]==1){
			for(j=2;j*i<=1000000;j++){
				flg[i*j]=0;
			}
		}
	}
	scanf("%d %d",&n,&x);
	while(n!=0 && x!=0){
		for(j=0;j<=x;j++){
			dp[j]=-1;
		}
		dp[0]=0;
		for(i=0;i<n;i++){
			scanf("%d",&kin);
			for(j=0;j<=x;j++){
				if(dp[j]!=-1){
					dp[j+kin]=1;
				}
			}
		}
		int max=0;
		for(i=0;i<=x;i++){
			if(dp[i]==1 && flg[i]==1){
				max=i;
			}
		}
		if(max==0){
			printf("NA\n");
		}
		else {
			printf("%d\n",max);
		}
		scanf("%d %d",&n,&x);
	}
	return 0;
}