#include <stdio.h>
#include <math.h>
#include <string.h>
int dp[1500][1500];
int max=0;
int Max(int a0,int b0,int c0){
    if(a0>=b0&&a0>=c0){
        return a0;
    }
    else if(b0>=a0&&b0>=c0){
        return b0;
    }
    return c0;
}
int large(int a,int b){
    if(abs(a)>abs(b)) return a;
    else return b;
}
struct position{
    int x1;
    int y1;
};
int isPrime(int x){
    int i;
    if(x==1) return 0;
    for(i=2;i<=(int)sqrt(x);i++){
        if(x%i==0) return 0;
    }
    return 1;
}
int find(int x){
    int i;
    for(i=0;i<=x;i++){
        if(i*i>=x&&i%2==1) return i;
    }
    return -1;
}
struct position encode(int x){
    int i,a,x1,x2,x3;
    i=find(x);
    a=(i-1)/2;
    x1=i*i-i+1;
    x2=x1-i+1;
    x3=x2-i+1;
    struct position p;
    if(x>=x1){
        p.x1=a+x-i*i;
        p.y1=-a;
    }
    else if(x>=x2){
        p.x1=-a;
        p.y1=-a+x1-x;
    }
    else if(x>=x3&&x<x2){
        p.x1=a-x+x3;
        p.y1=a;
    }
    else{
        p.x1=a;
        p.y1=a-x3+x;
    }
    return p;
}
int decode(int x,int y){
    if(x==0&&y==0) return 1;
    int big,huge,i,x1,x2,x3;
    big=large(x,y);
    huge=abs(big);
    i=abs(big)*2+1;
    x1=i*i-i+1;
    x2=x1-i+1;
    x3=x2-i+1;
    if(x>=0&&y>=0) {
        if(x<huge)return x3+huge-x;
        else if(y<=huge) return x3+y-huge;
    }
    else if(x<=0&&y>=0){
if(x>-huge) return x2-huge-x;
else if(y<=huge) return x2-y+huge;
    }
    else if(x<=0&&y<=0){
        if(x>(-huge)) return x1+x+huge;
        else if(y>=(-huge)) return x1-y-huge;
    } else {
        if (x < huge) return i * i - huge + x;
        else if (y>(-huge)) return x3-huge+y;
        if(y==-huge) return i*i;
    }
    return -1;
}
int main(void){
    int x,goal;
    while(scanf("%d %d",&goal,&x)==2) {
        if(x==0&&goal==0) break;
        int count=0,maxprime=0;
        memset(dp,0, sizeof(dp));
        int i,j;
        int maxX;
        int s=1,ss=1;
        struct position p,p1;
        p=encode(x);
        p1=encode(goal);
        maxX=Max(abs(p1.x1),abs(p1.y1),-1);
        dp[p.x1+maxX][p.y1+maxX]=isPrime(x);
        count=dp[p.x1+maxX][p.y1+maxX];
        if(dp[p.x1+maxX][p.y1+maxX]==1) maxprime=x;
        if(p.x1==maxX) ss=0;
        if(p.x1==-maxX) s=0;
        for(j=p.y1-1;j>=-maxX;j--){
            for(i=p.x1-s;i<=p.x1+ss;i++){
                if(decode(i,j)<=goal) {
                    if (i == maxX) {
                        dp[i + maxX][j + maxX] = Max(dp[i + maxX][j + 1 + maxX], dp[i - 1 + maxX][j + 1 + maxX], -100) +
                                                 isPrime(decode(i, j));
                    } else if (i == -maxX) {
                        dp[i + maxX][j + maxX] = Max(dp[i + maxX][j + 1 + maxX], dp[i + 1 + maxX][j + 1 + maxX], -100) +
                                                 isPrime(decode(i, j));
                    } else {
                        dp[i + maxX][j + maxX] = Max(dp[i + maxX][j + 1 + maxX], dp[i + 1 + maxX][j + maxX + 1],
                                                     dp[i + maxX - 1][j + maxX + 1]) + isPrime(decode(i, j));
                    }
                    if (dp[i + maxX][j + maxX] > count && decode(i, j) <= goal) {
                        count = dp[i + maxX][j + maxX];
                        maxprime = decode(i, j);
                    }
                    if (dp[i + maxX][j + maxX] == count && decode(i, j) <= goal) {
                        if (maxprime < decode(i, j) && isPrime(decode(i, j)) == 1) maxprime = decode(i, j);
                    }
                }
            }
            if(p.x1-s>-maxX) s++;
            if(p.x1+ss<maxX) ss++;
        }
        printf("%d %d\n",count, maxprime);
    }
    return 0;
}



Measured memory_bytes: 10600