#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;
}
}
}