#include <bits/stdc++.h>
using namespace std;

const int N = 1000000;
const int WIDTH = 1005;
const int S = 500;
const int INF = 100000000;

int prime[N];
int ma[WIDTH][WIDTH];
int dis[WIDTH][WIDTH];
int did[WIDTH][WIDTH];
const int dirx[4] = {1, 0, -1, 0};
const int diry[4] = {0, -1, 0, 1};
typedef pair<int, int> P;

int sx, sy;
int ans, fin;

void BFS_prime();
void BFS_ans(int n);

void Eratos(){
	for(int i=0; i<N; i++){
		prime[i] = 1;
	}

	prime[0] = prime[1] = 0;
	for(int i=2; i*i <= N; i++){
		for(int j=i*2; j<N; j += i){
			prime[j] = 0;
		}
	}

}

void create(int m, int n){
	memset(ma, 0, sizeof(ma));
	int cnt = 1;
	int dx = 0;
	int dy = 0;
	int ndir = 0;
	int lim = 1;
	bool f = false;
	while(1){
		for(int i=0; i<lim; i++){

			ma[S + dy][S + dx] = cnt;
			if(cnt == n){
				sx = S + dx;
				sy = S + dy;
			}
			cnt++;
			if(cnt == m+1){
				f = true;
				break;
			}

			dx += dirx[ndir % 4];
			dy += diry[ndir % 4];
		}
		if(f) break;
		ndir++;
		for(int i=0; i<lim; i++){

			ma[S + dy][S + dx] = cnt;
			if(cnt == n){
				sx = S + dx;
				sy = S + dy;
			}
			cnt++;
			if(cnt == m+1){
				f = true;
				break;
			}

			dx += dirx[ndir % 4];
			dy += diry[ndir % 4];
		}
		ndir++;
		lim++;
		if(f) break;
	}
}

int main(void){
	Eratos();

	while(1){
		ans = 0;
		fin = 0;
		int m, n;
		cin >> m >> n;
		if(m == 0 && n == 0) break;
		create(m, n);

		/*
		for(int i=S-30; i<S+30; i++){
			for(int j=S-30; j<S+30; j++){
				printf("%3d ", ma[i][j]);
			}
			puts("");
		}
		*/

		BFS_prime();
		/*
		for(int i=S-30; i<S+30; i++){
			for(int j=S-30; j<S+30; j++){
				if(dis[i][j] == INF){
				 if(i == sy && j == sx) printf("S ");
				 else printf("* ");

				}else printf("%1d ", dis[i][j]);
			}
			puts("");
		}
		*/
		BFS_ans(m);
		/*
		for(int i=S-30; i<S+30; i++){
			for(int j=S-30; j<S+30; j++){
				if(dis[i][j] == INF) printf("* ");
				else printf("%1d ", dis[i][j]);
			}
			puts("");
		}
		*/
		printf("%d %d\n", ans, fin);

	}

	return 0;
}

void BFS_prime(){
	queue<P> que;
	for(int i=0; i<WIDTH; i++){
		for(int j=0; j<WIDTH; j++){
			dis[i][j] = INF;
		}
	}

	//printf("%d %d\n", sy, sx);
	que.push(P(sy, sx));
	if(prime[ma[sy][sx]] == 1) dis[sy][sx] = 1;

	while(que.size()){
		P p = que.front(); que.pop();

		//printf("%d %d\n", p.first, p.second);
		if(ma[p.first][p.second] == 0) continue;

		for(int i=-1; i <= 1; i++){
			int nx = p.second + i;
			int ny = p.first + 1;

			if(dis[ny][nx] == INF){
				//printf("nynx:%d %d\n", ny, nx);

				que.push(P(ny, nx));
				if(prime[ma[ny][nx]] == 1) dis[ny][nx] = 1;
				else dis[ny][nx] = 0;
			}
		}
	}
}

void BFS_ans(int n){
	queue<P> que;
	for(int i=0; i<WIDTH; i++){
		for(int j=0; j<WIDTH; j++){
			if(dis[i][j] == INF) dis[i][j] = 0;
		}
	}
	for(int i=0; i<WIDTH; i++){
		for(int j=0; j<WIDTH; j++){
			did[i][j] = 0;
		}
	}

	que.push(P(sy, sx));
	if(prime[ma[sy][sx]] == 1){
		dis[sy][sx] = 1;
		if(ans < dis[sy][sx]){
			ans = dis[sy][sx];
			fin = ma[sy][sx];
		}
	}

	while(que.size()){
		P p = que.front(); que.pop();

		if(ma[p.first][p.second] == 0) continue;

		for(int i=-1; i <= 1; i++){
			int nx = p.second + i;
			int ny = p.first + 1;

			if(did[ny][nx] == 0){
				did[ny][nx] = 1;
				que.push(P(ny, nx));
				if(dis[ny][nx] == 1) {
					dis[ny][nx] = 1 + max(dis[ny-1][nx-1], max(dis[ny-1][nx], dis[ny-1][nx+1]));
				}else{
					dis[ny][nx] = max(dis[ny-1][nx-1], max(dis[ny-1][nx], dis[ny-1][nx+1]));
				}
				if(ma[ny][nx] <= n && ma[ny][nx] != 0){
					//printf("%d %d %d\n", dis[ny][nx], ma[ny][nx], n);
					if(ans < dis[ny][nx]){
						ans = dis[ny][nx];
						fin = ma[ny][nx];
					}else if(ans == dis[ny][nx] && fin < ma[ny][nx] && prime[ma[ny][nx]] == 1){
						fin = ma[ny][nx];
					}
				}
			}
		}
	}
}

Measured memory_bytes: 16944