#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <queue>
using namespace std;
 
#define DEBUG(x) cerr << #x << " = " << x << endl
 
const int MAX_M = 1000000;
 
bool prime[MAX_M + 1];
int field[2000][2000];
int dp[2000][2000];
int dp2[2000][2000];
 
struct Node {
    int y, x, val;
    Node(int Y, int X, int V) : y(Y), x(X), val(V) { }
};
 
int main() {
    memset(prime, -1, sizeof(prime));
    prime[0] = prime[1] = false;
    for(int i = 2; i * i <= MAX_M; i++) {
        if(prime[i])
            for(int j = 2 * i; j <= MAX_M; j += i) prime[j] = false;
    }
 
    for(int m, n; cin >> m >> n, m || n; ) {
 
    memset(field, 0, sizeof(field));
 
    int x = 1000, y = 1000;
    int k = 1;
    int cur = 1;
    field[y][x] = 1;
    while(true) {
        if(k % 2 == 1) {
            bool f = true;
            for(int i = 0; i < k; i++) {
                x++;
                cur++;
                field[y][x] = cur;
                if(cur >= m) {
                    f = false;
                    break;
                }
            }
            if(f == false) break;
            for(int i = 0; i < k; i++) {
                y--;
                cur++;
                field[y][x] = cur;
                if(cur >= m) {
                    f = false;
                    break;
                }
            }
            if(f == false) {
                break;
            }
        }
        else {
            bool f = true;
            for(int i = 0; i < k; i++) {
                x--;
                cur++;
                field[y][x] = cur;
                if(cur >= m) {
                    f = false;
                    break;
                }
            }
            if(f == false) break;
            for(int i = 0; i < k; i++) {
                y++;
                cur++;
                field[y][x] = cur;
                if(cur >= m) {
                    f = false;
                    break;
                }
            }
            if(f == false) break;
        }
        k++;
    }
#if 0
    for(int y = 500 - m/4; y <= 500+m/4; y++) {
        for(int x = 500-m/4; x <= 500+m/4; x++) {
            printf("%2d ", field[y][x]);
        }
        printf("\n");
    }
#endif
 
    for(int i = 0; i < 2000; i++) {
        for(int j = 0; j < 2000; j++) {
            if(field[i][j] == n) {
                y = i;
                x = j;
            }
        }
    }
 
#if 0
    for(int y = 1490; y <= 1510; y++) {
        for(int x = 1020; x <= 1040; x++) {
            printf("%6d ", field[y][x]);
        }
        printf("\n");
    }
#endif
 
    int resNum = 0;
    int resPos = 0;
 
    queue<Node> Q;
    if(prime[field[y][x]]) Q.push(Node(y,x,field[y][x]));
    else Q.push(Node(y,x,0));
 
    memset(dp, 0, sizeof(dp));
    dp[y][x] = (prime[field[y][x]] ? 1 : 0);
 
    memset(dp2, 0, sizeof(dp2));
 
    dp2[y][x] = (prime[field[y][x]] ? field[y][x] : 0);
 
    while(!Q.empty()) {
        Node p = Q.front(); Q.pop();
        x = p.x, y = p.y;
#if 0
        // cerr << "(" << y << "," << x << ")" << endl;
        if(field[y][x] == 993541) {
            DEBUG(993541);
            DEBUG(x);
            DEBUG(y);
        }
 
        if(field[y][x] == 997533) {
            DEBUG(997533);
            DEBUG(x);
            DEBUG(y);
        }
#endif
 
        if(field[y+1][x] == 0) {
            if(resNum < dp[y][x] ) {
                resNum = dp[y][x];
                resPos = dp2[y][x];
            }
 
            if(resNum == dp[y][x] && resPos < dp2[y][x]) {
                resNum = dp[y][x];
                resPos = dp2[y][x];
            }
        }
 
        for(int i = -1; i <= 1; i++) {
            if(field[y+1][x+i] == 0) continue;
            // DEBUG(y+1); DEBUG(x+i);
            int tmp = 0;
            if(prime[field[y+1][x+i]]) tmp = 1;
 
            int newValue = dp[y][x] + tmp;
 
            int np = dp2[y][x];
            if(tmp) np = field[y+1][x+i];
 
            if(dp[y+1][x+i] == 0) {
                dp[y+1][x+i] = newValue;
                Q.push(Node(y+1,x+i,np));
                dp2[y+1][x+i] = np;
            }
 
            if(dp[y+1][x+i] == newValue && dp2[y+1][x+i] < np) {
                dp[y+1][x+i] = newValue;
                Q.push(Node(y+1,x+i,np));
                dp2[y+1][x+i] = np;
            }
 
            if(dp[y+1][x+i] < newValue) {
                dp[y+1][x+i] = newValue;
                Q.push(Node(y+1,x+i,np));
                dp2[y+1][x+i] = np;
            }
        }
    }
 
#if 0
    for(int y = 500 - m/4; y <= 500+m/4; y++) {
        for(int x = 500-m/4; x <= 500+m/4; x++) {
            printf("%2d ", dp[y][x]);
        }
        printf("\n");
    }
#endif
 
    if(resNum == 0) {
        cout << "0 0" << endl;
    }
    else {
        cout << resNum << ' ' << resPos << endl;
    }
    }
}
 

Measured memory_bytes: 49096