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 JAVA (judge verdict: Memory Limit Exceeded)

import java.io.InputStream;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.InputMismatchException;
import java.util.NoSuchElementException;
import java.math.BigInteger;

public class Main{

static PrintWriter out;
static InputReader ir;

static void solve(){
 ArrayList<Integer> buf=new ArrayList<>();
 boolean[] prime=sieveOfEratosthenes(170000);
 for(;;){
  int n=ir.nextInt(),p=ir.nextInt()-1;
  if(n<0&&p<0) return;
  for(int i=n;i<=n+600*p;i++){
   if(!prime[i]) continue;
   for(int j=n;j<=n+600*p;j++){
    if(prime[j]) buf.add(i+j);
   }
  }
  Collections.sort(buf);
  out.println(buf.get(p));
  buf.clear();
 }
}

public static boolean[] sieveOfEratosthenes(int a){
 boolean[] ret=new boolean[a+1];
 Arrays.fill(ret,true);
 ret[0]=ret[1]=true;
 for(int i=2;i<=Math.sqrt(a);i++){
  if(!ret[i]) continue;
  for(int j=i+i;j<=a;j+=i) ret[j]=false;
 }
 return ret;
}

public static void main(String[] args) throws Exception{
 ir=new InputReader(System.in);
 out=new PrintWriter(System.out);
 solve();
 out.flush();
}

static class InputReader {
 private InputStream in;
 private byte[] buffer=new byte[1024];
 private int curbuf;
 private int lenbuf;

 public InputReader(InputStream in) {this.in=in; this.curbuf=this.lenbuf=0;}
 
 public boolean hasNextByte() {
  if(curbuf>=lenbuf){
   curbuf= 0;
   try{
    lenbuf=in.read(buffer);
   }catch(IOException e) {
    throw new InputMismatchException();
   }
   if(lenbuf<=0) return false;
  }
  return true;
 }

 private int readByte(){if(hasNextByte()) return buffer[curbuf++]; else return -1;}
 
 private boolean isSpaceChar(int c){return !(c>=33&&c<=126);}
 
 private void skip(){while(hasNextByte()&&isSpaceChar(buffer[curbuf])) curbuf++;}
 
 public boolean hasNext(){skip(); return hasNextByte();}
 
 public String next(){
  if(!hasNext()) throw new NoSuchElementException();
  StringBuilder sb=new StringBuilder();
  int b=readByte();
  while(!isSpaceChar(b)){
   sb.appendCodePoint(b);
   b=readByte();
  }
  return sb.toString();
 }
 
 public int nextInt() {
  if(!hasNext()) throw new NoSuchElementException();
  int c=readByte();
  while (isSpaceChar(c)) c=readByte();
  boolean minus=false;
  if (c=='-') {
   minus=true;
   c=readByte();
  }
  int res=0;
  do{
   if(c<'0'||c>'9') throw new InputMismatchException();
   res=res*10+c-'0';
   c=readByte();
  }while(!isSpaceChar(c));
  return (minus)?-res:res;
 }
 
 public long nextLong() {
  if(!hasNext()) throw new NoSuchElementException();
  int c=readByte();
  while (isSpaceChar(c)) c=readByte();
  boolean minus=false;
  if (c=='-') {
   minus=true;
   c=readByte();
  }
  long res = 0;
  do{
   if(c<'0'||c>'9') throw new InputMismatchException();
   res=res*10+c-'0';
   c=readByte();
  }while(!isSpaceChar(c));
  return (minus)?-res:res;
 }

 public double nextDouble(){return Double.parseDouble(next());}

 public int[] nextIntArray(int n){
  int[] a=new int[n];
  for(int i=0;i<n;i++) a[i]=nextInt();
  return a;
 }

 public long[] nextLongArray(int n){
  long[] a=new long[n];
  for(int i=0;i<n;i++) a[i]=nextLong();
  return a;
 }

 public char[][] nextCharMap(int n,int m){
  char[][] map=new char[n][m];
  for(int i=0;i<n;i++) map[i]=next().toCharArray();
  return map;
 }
}
}