Problem:
Problem B: Matsuzaki Number

Matsuzaki 教授は，宇宙の真理を研究している科学者である．人生，宇宙，すべての答えは 42 であると言われているが，Matsuzaki 教授はこれだけでは宇宙の真理を解明するには不十分であると考えている．Matsuzaki 教授は，宇宙の真理は 2 つのパラメータからなる関数で表されると考えており，42 はその 1 つに過ぎないというのである．

Matsuzaki 教授の定義した関数 M(N, P) は，N より大きい素数を 2 つ選んで（同じ数を 2 つでも構わない）和をとることで得られる数の全体を，小さいほうから順番に並べたときに，P 番目に現れる数を表す．ここで，2 通り以上の和で表されるような数も存在するが，そういった数は和の組み合わせの数と同じ個数だけ並べられる．

例として N = 0 の場合を考えよう．このときは素数全体から 2 つを選んで和をとることになる．そういった和のうちで最小の数を考えると，同じ数を 2 回選ぶことも許されていることから，2 + 2 = 4 であることがわかる．すなわち M(0, 1) = 4 である．次に小さい数は 2 + 3 = 5 であるから M(0, 2) = 5 となる．同様にして考えると，和を並べたものは 4, 5, 6, 7, 8, 9, 10, 10, 12, 13, 14, 14, 16, ... のようになることがわかる．すなわち，たとえば M(0, 9) = 12 である．

同じようにして N = 10 の場合を考えると，このときは 10 より大きい素数 {11, 13, 17, 19, ...} から 2 つを選ぶことになり，得られる和を小さいほうから並べると 22, 24, 26, 28, 30, 30, 32, ... のようになる．

あなたの仕事は，N と P が与えられた時に M(N, P) を計算するプログラムを書くことである．

Input

入力は複数のデータセットからなる．データセットは 1 行であり，2 つの整数 N (0 ≤ N ≤ 100,000) と P (1 ≤ P ≤ 100) が 1 つの空白で区切られて与えられる．

入力の終わりは，空白で区切られた 2 つの -1 を含む 1 行で示される．

Output

各データセットに対して，M(N, P) の値を 1 行に出力せよ．出力に余計な空白や改行を含めてはならない．

Sample Input

0 55
0 1
0 2
0 3
10 1
10 2
10 3
10 4
10 5
10 6
11 1
11 2
11 3
100000 100
-1 -1

Output for the Sample Input

42
4
5
6
22
24
26
28
30
30
26
30
32
200274

Solution in C (judge verdict: Accepted)

/* 
   AOJ 2150
   Matshzaki Number
   2015/7/23
*/

#include<stdio.h>
#include<stdlib.h>

#define MAX_PRIME 200000
#define MAX_P 100

void make_prime_list(int *prime_list)
{
  int i, j;

  for(i = 0; i < MAX_PRIME; i++)
    {
      prime_list[i] = 1;
    }

  prime_list[0] = 0;
  prime_list[1] = 0;

  for(i = 0; i < MAX_PRIME; i++)
    {
      if(prime_list[i] == 1)
	{
	  for(j = i; i * j < MAX_PRIME && i * j > 0; j++)
	    {
	      prime_list[i * j] = 0;
	    }
	}
    }
}

void make_next_prime_list(int* prime_list, int* next_prime_list)
{
  int i, next_prime = -1;

  for(i = MAX_PRIME - 1; i >= 0; i--)
    {
      if(prime_list[i] == 1)
	{
	  break;
	}
      next_prime_list[i] = -1;
    }

  for(; i >= 0; i--)
    {
      next_prime_list[i] = next_prime;

      if(prime_list[i] == 1)
	{
	  next_prime = i;
	}
    }
}

void get_next_prime_set(int n, int* prime_list, int* next_prime_set)
{
  int i, j = 0;
  
  for(i = n + 1; i < MAX_PRIME; i++)
    {
      if(prime_list[i] == 1)
	{
	  next_prime_set[j] = i;
	  j++;
	}
    }
}

void get_sum_list(int* next_prime_set, int* sum_list, int p)
{
  int i, j, k = 0;

  for(i = 0; i < p; i++)
    {
      for(j = i; j < p; j++)
	{
	  sum_list[k] = next_prime_set[i] + next_prime_set[j];
	  k++;
	}
    }
}

int from_one_to_p_sum(int p, int n)
{
  if(p >= 1)
    {
      return from_one_to_p_sum(p - 1, n + p);
    }
  return n;
}

int sort(const void * a, const void * b)
{
  if(*(int *)a < *(int *)b)
    {
      return -1;
    }
  else if(*(int *)a == *(int *)b)
    {
      return 0;
    }
  return 1;
}

int ans_f(int n, int p, int* prime_list)
{

  /* 
     --------next_prime_set is a prime list from the prime that is next to 'n' to MAX_PRIME

     next_prime_set[0] + next_prime_set[0], nps[0] + nps[1],....nps[0] + nps[p]
     nps[1] + nps[1], nps[1] + nps[2],...nps[1] + nps[p]
     .......
     nps[p-1] + nps[p-1], nps[p-1] + nps[p]
     nps[p] + nps[p]
     
     ---------------------------------------------------------------------------------------
  */


  int i, num_of_sum_list = 0, next_prime_set[MAX_PRIME], sum_list[MAX_PRIME];
  
  get_next_prime_set(n, prime_list, next_prime_set);

  /* for(i = 0; i < 20; i++) */
  /*   { */
  /*     printf("%3d", next_prime_set[i]); */
  /*   } */
  /* printf("\n"); */

  get_sum_list(next_prime_set, sum_list, p);

  /* for(i = 0; i < 20; i++) */
  /*   { */
  /*     printf("%3d", sum_list[i]); */
  /*   } */
  /* printf("\n"); */

  num_of_sum_list = from_one_to_p_sum(p, 0);

  qsort((void *) sum_list, num_of_sum_list, sizeof(int), sort);

  /* for(i = 0; i < 20; i++) */
  /*   { */
  /*     printf("%3d", sum_list[i]); */
  /*   } */
  /* printf("\n"); */
  
  return sum_list[p - 1];
}

int main(void)
{
  int n, p, ans, prime_list[MAX_PRIME], next_prime_list[MAX_PRIME], i;

  make_prime_list(prime_list);
  //make_next_prime_list(prime_list, next_prime_list);

  while(1)
    {
      scanf("%d %d", &n, &p);
      if(n == -1 && p == -1)
	{
	  break;
	}
      ans = ans_f(n, p, prime_list);
      printf("%d\n", ans);
    }
  return 0;
}