Go: package main

import (
	"bufio"
	"fmt"
	"math"
	"os"
	"sort"
	"strconv"
	"strings"
)

func main() {
	io := NewIo()
	defer io.Flush()
	for {
		n, p := io.NextInt(), io.NextInt()
		if n == -1 {
			break
		}
		isPrime := SieveOpt(200000)
		prime := make([]int, p)
		cnt := 0
		if n < 2 {
			prime[0] = 2
			cnt++
		}
		for i := (n + 1) / 2; i < len(isPrime) && cnt < p; i++ {
			if isPrime[i] == true {
				prime[cnt] = 2*i + 1
				cnt++
			}
		}
		comb := make([]int, 0, p*p)
		for i := 0; i < p; i++ {
			for j := i; j < p; j++ {
				comb = append(comb, prime[i]+prime[j])
			}
		}
		sort.Ints(comb)
		io.Println(comb[p-1])
	}
}

func SieveOpt(x int) []bool {
	flags := make([]bool, x/2) // flags[i] := 2*j+1 is prime
	for i := 1; i < x/2; i++ {
		flags[i] = true
	}
	sqrtXi := int(math.Ceil(math.Sqrt(float64(x)))) / 2
	for i := 1; i < sqrtXi; i ++ {
		if !flags[i] {
			continue
		}
		for j := 2 * i * (i + 1); j < x/2; j += 2*i + 1 {
			flags[j] = false
		}
	}
	return flags
}

// I/O template
type Io struct {
	reader    *bufio.Reader
	writer    *bufio.Writer
	tokens    []string
	nextToken int
}

func NewIo() *Io {
	return &Io{
		reader: bufio.NewReader(os.Stdin),
		writer: bufio.NewWriter(os.Stdout),
	}
}

func (io *Io) Flush() {
	err := io.writer.Flush()
	if err != nil {
		panic(err)
	}
}

func (io *Io) NextLine() string {
	var buff []byte
	for {
		line, isPrefix, err := io.reader.ReadLine()
		if err != nil {
			panic(err)
		}
		buff = append(buff, line...)
		if !isPrefix {
			break
		}
	}
	return string(buff)
}

func (io *Io) Next() string {
	for io.nextToken >= len(io.tokens) {
		line := io.NextLine()
		io.tokens = strings.Fields(line)
		io.nextToken = 0
	}
	s := io.tokens[io.nextToken]
	io.nextToken++
	return s
}

func (io *Io) NextInt() int {
	i, err := strconv.Atoi(io.Next())
	if err != nil {
		panic(err)
	}
	return i
}

func (io *Io) NextFloat() float64 {
	i, err := strconv.ParseFloat(io.Next(), 64)
	if err != nil {
		panic(err)
	}
	return i
}

func (io *Io) Println(a ...interface{}) {
	fmt.Fprintln(io.writer, a...)
}

func (io *Io) Printf(format string, a ...interface{}) {
	fmt.Fprintf(io.writer, format, a...)
}

func (io *Io) PrintIntSlice(a []int) {
	b := []interface{}{}
	for _, x := range a {
		b = append(b, x)
	}
	io.Println(b...)
}

func (io *Io) PrintStringSlice(a []string) {
	b := []interface{}{}
	for _, x := range a {
		b = append(b, x)
	}
	io.Println(b...)
}

func Log(name string, value interface{}) {
	fmt.Fprintf(os.Stderr, "%s=%+v\n", name, value)
}

func ExampleIo() {
	io := NewIo()
	defer io.Flush()
	a := make([]int, 0, 3)
	a[0], a[1], a[2] = io.NextInt(), io.NextInt(), io.NextInt()
	io.Println(a)
	io.PrintIntSlice(a)
	Log("io", a)
}

C++: #include <bits/stdc++.h>
using namespace std;

#define fs first
#define sc second
#define all(v) v.begin(), v.end()
#define rall(v) v.rbegin(), v.rend()
#define rep(i, n) for (int i = 0; i < n; ++i)
#define pb emplace_back

using pii = pair<int, int>;
using vi = vector<int>;
using lint = long long;

const int inf = 1001001001;
const lint linf = 1001001001001001001ll;
const int mod = 1e9 + 7;
const int dx[]{0, 1, 0, -1, -1, -1, 1, 1}, dy[]{1, 0, -1, 0, -1, 1, -1, 1};

template<typename T> inline bool chmin(T &a, T b) { if (a > b) { a = b; } return a > b; }
template<typename T> inline bool chmax(T &a, T b) { if (a < b) { a = b; } return a < b; }
template<typename T> inline void print(const T &x, string s = "\n") { cout << x << s; }
template<typename T> inline void print(const vector<T> &v, string s = " ") 
{ rep(i, v.size()) cout << v[i] << (i + 1 == v.size() ? "\n" : s); }
inline bool inside(int y, int x, int H, int W) { return 0 <= y && y < H && 0 <= x && x < W; }
inline lint in() { lint x; std::cin>>x; return x; }

lint gcd(lint a, lint b) {
	if (b == 0) return a;
	return gcd(b, a % b);
}

lint lcm(lint a, lint b) {
	return a / gcd(a, b) * b;
}

// ?????????????????????????????????????????????
lint extgcd(lint a, lint b, lint& x, lint& y) {
	lint d = a;
	if (b != 0) {
		d = extgcd(b, a % b, y, x);
		y -= (a / b) * x;
	} else {
		x = 1; y = 0;
	}
	return d;
}

bool is_prime(lint n) {
	if (n < 2) return false;
	for (lint i = 2; i * i <= n; ++i) {
		if (n % i == 0) return false;
	}
	return true;
}

// n????´???° ???????????????sorted
vector<lint> divisor(lint n) {
	vector<lint> res;
	deque<lint> d;

	lint i = sqrt(n);
	if (i * i == n) {
		d.push_back(i);
		i--;
	}
	for (; i > 0; --i) {
		if (n % i == 0){
			d.push_front(i);
			d.push_back(n / i);
		}
	}

	res.insert(res.begin(), d.begin(), d.end());
	return res;
}


// 2 * 2 * 3 * 5 * 5 * 5 = {2:2, 3:1,5:3} ???????????? map ?????????
map<int, int> prime_mod_factor(lint n) {
	map<int, int> res;
	for (int i = 2; i * i <= n; ++i) {
		while (n % i == 0) {
			++res[i];
			n /= i;
		}
	}

	if (n != 1) res[n] = 1;
	return res;
}

const int MAX_N = 2020202;
vi prime;
bool memo[MAX_N + 1];

// ?´???°?????¨?????? n??\???????´???°????????°?????????
int sieve(int n) {
	prime.clear();
	memset(memo, true, sizeof(memo));
	memo[0] = memo[1] = false;

	for (int i = 2; i <= n; ++i) {
		if (memo[i]) {
			prime.pb(i);
			for (int j = i + i; j <= n; j += i) {
				memo[j] = false;
			}
		}
	}

	return prime.size();
}

const lint MAX_LEN = 1000000;
const lint MAX_SQRT_B = 1000000;
bool memo_alint[MAX_LEN];         //i means i + a
bool memo_smalint[MAX_SQRT_B];

// [a, b)????´???°????????°???????????????
lint count_prime(lint a, lint b) {
	for (int i = 0; (lint)i * i < b; i++) memo_smalint[i] = true;
	for (int i = 0; i < b - a; i++)     memo_alint[i] = true;

	for (int i = 2; (lint)i * i < b; i++) {
		if (memo_smalint[i]) {
			for (int j = 2; (lint)j * j < b; j += i) memo_smalint[j] = false;
			for (lint j = max(2LL, (a + i - 1) / i) * i; j < b; j += i) memo_alint[j - a] = false;
		}
	}

	lint ret = 0;
	for (lint i = a; i < b; i++) {
		if (memo_alint[i]) ret++;
	}
	return ret;
}

// k???????????§????????£??????????????°??????{a_0 : 0, a_1 : 1, a_2 : 1, ... }
lint Fib[101010];
int calcFib(int k) {
	Fib[0] = 0;
	Fib[1] = Fib[2] = 1;
	for (int i = 3; i <= k; ++i) {
		Fib[i] = Fib[i - 1] + Fib[i - 2];
		// Fib[i] %= mod;
	}

	return Fib[k];
}

lint mod_pow(lint a, lint x) {
	lint ret = 1;
	for (lint i  = 1ll << 60; i; i >>= 1) {
		ret *= ret;
		ret %= mod;
		if (x & i) { ret *= a; ret %= mod; }
	}

	return ret;
}

lint mod_fact(lint n) {
	lint ret = 1;
	for (lint i = 1; i <= n; ++i) {
		ret *= i;
		ret %= mod;
	}
	return ret;
}

lint mod_inverse(lint n) {
	return mod_pow(n, mod - 2);
}

// nCk ???mod
lint mod_Combination(lint n, lint k) {
	return mod_fact(n) * mod_inverse(mod_fact(k)) % mod * mod_inverse(mod_fact(n - k)) % mod;
}

int main() {
	sieve(MAX_N);
	//print(prime);

	int n, p;
	while (cin >> n >> p) {
		if (n == -1) break;
		
		vi a;
		for (int i = n + 1; a.size() < 110; ++i) {
			if (memo[i]) a.pb(i);
		}

	//	print(a);

		vi ans;
		rep(i, a.size()) for (int j = i; j < a.size(); ++j) {
			ans.pb(a[i] + a[j]);
		}

		sort(all(ans));

		print(ans[p - 1]);
	}
}

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

using namespace std;

typedef long long ll;
typedef vector<int> vint;
typedef pair<int, int> pii;

#define abs(a) ((a) < (0)? -(a):(a))
#define rep(i, n) REP(i, 0, (n))
#define REP(i, a, n) for(int i=(a); i<(n); i++)
#define pb push_back

int N = 110000;
bool is_prime[110000];

void set_prime() {
    rep(i, N) is_prime[i] = true;
    is_prime[0] = is_prime[1] = false;
    REP(i, 2, sqrt(N)) {
        if(is_prime[i]) {
            for(int j=0; i*(j+2)<N; j++) {
                is_prime[i*(j+2)] = false;
            }
        }
    }
}

int main() {
    set_prime();
    int n, p;
    while(cin>>n>>p, n+p>0) {
        vint v;
        for(int i=n+1, j=0; j<100; i++) {
            if(is_prime[i]) j++, v.pb(i);
        }
        vint w;
        rep(i, v.size()) REP(j, i, v.size()) {
            w.pb(v[i]+v[j]);
        }
        sort(w.begin(), w.end());
        cout << w[p-1] << endl;
    }
}