#include <stdio.h>
#define M_MAX 1000000
#define CAVE_WIDTH 1002
#define CAVE_HEIGHT 1002

typedef struct point{ int x; int y; } Point;  /* 座標を表す構造体 */
typedef struct result{ int num; int last; } Result;  /* 探索の戻り値のための構造体 */

/* 洞穴関連 */
int prime[M_MAX+1];  /* 素数か判定する配列 */
int cave[CAVE_WIDTH][CAVE_HEIGHT];  /* 洞穴番号 */
Point origin = {CAVE_WIDTH / 2, CAVE_HEIGHT / 2};  /* 原点の座標 */

/* 探索関連 */
Result dp[CAVE_WIDTH][CAVE_HEIGHT];  /* 探索のメモ */

/* 入力関連 */
int m;
int n;


/* 初期化する */
int init(){
	int i, j, x, y, l;

	/* i が素数か判定する配列 prime[i] を生成する */
	prime[0] = 0;
	prime[1] = 0;
	for (i = 2; i <= M_MAX; i++){
		prime[i] = 1;
	}
	for (i = 2; i <= M_MAX; i++){
		if (prime[i] == 1){
			for (j = i + i; j <= M_MAX; j += i){
				prime[j] = 0;
			}
		}
	}

	/* 縦横に並んだ洞穴に番号をふる */
	for (i = 0; i < CAVE_WIDTH; i++){
		for (j = 0; j < CAVE_HEIGHT; j++){
			cave[i][j] = 0;
		}
	}
	x = origin.x;
	y = origin.y;
	cave[x][y] = 1;
	x++;
	/* 渦巻きの一辺の長さは一周するごとに 2 ずつ増える */
	for (i = 2, l = 2; i <= M_MAX; l += 2){
		for (j = 0; j < l-1 && i <= M_MAX; j++, i++, y--) cave[x][y] = i;
		for (j = 0; j < l   && i <= M_MAX; j++, i++, x--) cave[x][y] = i;
		for (j = 0; j < l   && i <= M_MAX; j++, i++, y++) cave[x][y] = i;
		for (j = 0; j < l+1 && i <= M_MAX; j++, i++, x++) cave[x][y] = i;
	}
}

/* 指定された番号の洞穴の座標を返す */
Point toXY(int i){
	int x, y;
	if (i == 1) return origin;

	/* とりあえず探索 */
	for (x = 0; x < CAVE_WIDTH; x++){
		for (y = 0; y < CAVE_HEIGHT; y++){
			if (cave[x][y] == i){
				Point p = {x, y};
				return p;
			}
		}
	}
}

/* 探索関連の変数を初期化する */
int reset(){
	int i, j;
	for (i = 0; i < CAVE_WIDTH; i++){
		for (j = 0; j < CAVE_HEIGHT; j++){
			dp[i][j].num = -1;
		}
	}
}

/* 指定された座標から降下したときに通過できる素数洞穴の最大数を返す */
Result search(int x, int y){
	Result max = {0, 0};
	Result r;
	int  i;

	/* 探索終了 */
	if (x < 0 || x >= CAVE_WIDTH || y < 0 || y >= CAVE_HEIGHT || cave[x][y] > m) return max;
	if (dp[x][y].num != -1) return dp[x][y];

	if (prime[cave[x][y]]) max.last = cave[x][y];

	/* 次の洞穴を探索する */
	for (i = -1; i <= 1; i++){
		r = search(x + i, y + 1);
		/* 素数洞穴の最大数を保持する */
		if (r.num > max.num) max = r;
		else if (r.num == max.num && r.last > max.last) max.last = r.last;
	}

	max.num += prime[cave[x][y]];
	return dp[x][y] = max;
}

int main(void){
	Point p;
	Result r;

	init();  /* プログラムの初期化 */

	while (scanf("%d%d", &m, &n) == 2){
		if (m < 1 || m > 1000000 || n < 1 || n > m) break;

		reset();  /* このデータセットについての初期化 */

		p = toXY(n);
		r = search(p.x, p.y);  /* 探索 */
		printf("%d %d\n", r.num, r.last);  /* 出力 */
	}

    return 0;
}