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 <stdio.h>

int n,m[30];
/*
bool prime[1000000];
*/
bool c[1000000];

void saiki(int total){
	int i;
	if(total<=0){
		return;
	}
	
	for( i=0 ; i<n ; i++){
		total-=m[i];
		if(c[total]==1)continue;
		if(total>=0){
			c[total]=1;
		}
		saiki(total);
	}
}

int check(int prime){
	int flg=0,i;
	if(prime%2==0)return 0;
	for(i=3;i<prime;i+=2){
		if(prime%i==0){
			flg=1;
		}
	}
	if(flg==1)return 0;
	return 1;
}

int main(void)
{
	int i,j;
	//f
	/*
	prime[0]=1;
	prime[1]=1;
	for(i=3;i<1000000;i++){
		if(i%2==0){
			prime[i]=1;
		}
	}
	for(i=3;i<1000000;i++){
		if(prime[i]==0){
			for(j=(i+i);j<1000000;j+=i){
				prime[j]=1;
			}
		}
	}
	*/
	//
	while(1){
		for(;;);
		int x;
		int flg=0;
		scanf("%d%d",&n,&x);
		if(n==0)break;
		
		for(i=0;i<n;i++){
			scanf("%d",&m[i]);
		}
		saiki(x);
		//
		for(i=0;i<x;i++){
			
			if(c[i]==1 && check(x-i)){
				flg=1;
				break;
			}
		}
		if(flg==1){
			printf("%d\n",x-i);
		}
		else puts("NA");
		for(i=0;i<1000000;i++){
			c[i]=0;
		}
		//
	}
	
	
	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;

		prime.clear();
	}

	return 0;
}

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

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

bool is_prime(int n) {
    if (n % 2 == 0) return false;
    for (int i = 3; i <= std::sqrt(n); i += 2)
        if (n % i == 0) return false;
    return true;
}

int main() {
    int n, x;
    while (std::cin >> n >> x && n > 0 && x > 0) {
        bool course[x + 1];
        rep(i, x + 1) course[i] = false;

        int prices[n];
        rep(i, n) {
            std::cin >> prices[i];
            course[prices[i]] = true;
        }
        course[0] = true;

        int max = -1;
        rep(i, x + 1) rep(j, n) {
            if (i - prices[j] >= 0 && course[i - prices[j]]) {
                if (is_prime(i)) max = i;
                course[i] = true;
                break;
            }
        }
        if (max < 0)
            std::cout << "NA" << std::endl;
        else
            std::cout << max << std::endl;
    }
}

C++: #include<iostream>
#include<algorithm>
using namespace std;
bool dp[1000001];
bool isprime(int& x){
  for(int i = 2 ; i * i <= x ; i++ ) if( x % i == 0) return true;
  return x == 1;
}
int solve(int i){
  while(true){
    if(dp[i] && !isprime(i)) return i;
    i--;
  }
}
int main(){
  int n,x,data,ans;
  dp[0] = true;
  while(cin >> n >> x , n){
    for(int i = 1 ; i <= x ; i++ ) dp[i] = false;
    for(int i = 0 ; i < n ; i++ ){
      cin >> data;
      for(int i = data ; i <= x ; i++ ) if(dp[i-data]) dp[i] = true;
    }
    if(ans = solve(x)) cout << ans << endl;
    else cout << "NA" << endl;
  }
}

C++: #include <cstdio>
#include <vector>
#include <algorithm>
using namespace std;
int n, x, a[30]; bool dp[1000001], prime[1000001]; vector<int> p;
int main() {
	for(int i = 2; i <= 1000000; i++) prime[i] = true;
	for(int i = 2; i <= 1000; i++) {
		if(!prime[i]) continue;
		for(int j = i * i; j <= 1000000; j += i) prime[j] = false;
	}
	p = {0};
	for(int i = 2; i <= 1000000; i++) {
		if(prime[i]) p.push_back(i);
	}
	while(scanf("%d%d", &n, &x), n) {
		for(int i = 0; i < n; i++) scanf("%d", &a[i]); sort(a, a + n);
		for(int i = 0; i < x; i++) dp[i + 1] = false; dp[0] = true;
		for(int i = 1; i <= x; i++) {
			for(int j = 0; j < n && i >= a[j]; j++) {
				if(dp[i - a[j]]) {
					dp[i] = true; break;
				}
			}
		}
		int pos = upper_bound(p.begin(), p.end(), x);
		for(int i = pos - 1; i >= 0; i--) {
			if(dp[p[i]]) {
				printf(i ? "%d\n" : "NA\n", p[i]); break;
			}
		}
	}
}

C++: #include <iostream>
#include <vector>
#include <set>
#include <algorithm>
#include <cmath>

using namespace std;
const int MAX = 1000000;
bool isPrime[MAX] = {0};

void sieve(){
    bool find[MAX] = {0};
    int i;
    for(i=2;i*i < MAX;i++){
        if(find[i]) continue;
        isPrime[i] = true;
        for(int j=i;j<MAX;j++){
            if(j%i == 0){
                find[j] = true;
                isPrime[j] = false;
            }
        }
    }
    for(;i<MAX;i++){
        if(!find[i]) isPrime[i] = true;;
    }
}

int main(){
    sieve();

    while(true){
        int n,x;
        cin >> n >> x;
        if(n==0 && x==0) return 0;
        vector<int> R(n);
        for(int i=0;i<n;i++){
            cin >> R[i];
        }

        set<int> S;
        S.insert(0);
        for(int i=0;i<R.size();i++){
            for(set<int>::iterator it=S.begin();it!=S.end();++it){
                int newe = *it + R[i];
                if(newe > x) continue;
                S.insert(newe);
            }
        }
        int maxn = -1;
        for(set<int>::iterator it=S.begin();it!=S.end();++it){
            if(isPrime[*it] && *it > maxn) maxn = *it;
        }
        if(maxn == -1) cout << "NA" << endl;
        else cout << maxn << endl;
    }
    return 0;
}

C++: #include<iostream>
using namespace std;
const int INF = (1<<25);

bool dp[1000001];
int price[31];
int n, x;

int checkprime(int num) {
  for(int i=2; i*i<=num; i++) {
    if( num%i == 0 ) return true;
  }
  return x == 1;
}

int main() {
  while( cin >> n >> x, n || x ) {
    for(int i=0; i<n; i++) {
      cin >> price[i];
    }

    dp[0] = true;
    for(int i=1; i<=x; i++) {
      dp[i] = false;
    }

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

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

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