//http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=1189&lang=jp

#include<iostream>
#include<fstream>
#include<math.h>

//#define MAX 1020000

#define MAX 1002

int n, first;
int a[MAX][MAX] = {};
static bool initial;

class Pair{
public:
	int count;
	int last;
	Pair operator + (Pair p){//	@Override (+)
		this->count += p.count;
		if (p.last != 0)this->last = p.last;
		return *this;
	}
	void setPair(int _x, int _y){
		count = _x;
		last = _y;
	}
};

Pair pair(int a, int b){
	Pair p;
	p.setPair(a, b);
	return p;
}

bool isPrime(int n){
	if (n == 1)return false;
	if (n == 2)return true;
	if (n % 2 == 0)return false;

	for (int i = 3; i * i <= n; i += 2){
		if (n % i == 0)return false;
	}
	return true;
}

Pair search(int y, int x){
	static Pair p[MAX*MAX];

	Pair u_right = pair(-10, 0);
	Pair u_left = pair(-10, 0);

	static bool isReached[MAX*MAX];


	if (initial){//初期化
		for (int i = 0; i < MAX*MAX; i++){
			isReached[i] = false;
			p[i].count = p[i].last = 0;
		}
		initial = false;
	}

	if (n < a[y][x] || a[y][x] == 0)
		return p[0];//上限を超えていた場合,,, p[0].count = p[0].last = 0

	//以下特殊例処理
	if (a[y][x] == 2){
		p[2].last = 2;
		if (a[y][x] == first)initial = true;
		return pair(1, 2) + search(y + 1, x);
	}

	if (n <= 6 && a[y][x] == 3){
		p[3].last = 2;
		if (a[y][x] == first)initial = true;
		return pair(2, 2);
	}
	if (a[y][x] == 4){
		if (u_right.count == -10)u_right = search(y + 1, x + 1);
		if (u_left.count == -10)u_left = search(y + 1, x);

		if (u_right.count == u_left.count){
			if (u_right.last < u_left.last)u_right.count--;
		}
		if (u_right.count < u_left.count){
			isReached[4] = true;
			if (a[y][x] == first)initial = true;
			return p[4] = p[4] + u_left;
		}
		else{
			isReached[4] = true;
			if (a[y][x] == first)initial = true;
			return p[4] = p[4] + u_right;
		}
	}
	//ここまで特例処理

	//偶数の時
	if (a[y][x] % 2 == 0){
		if (a[y][x] == first){
			initial = true;
			if (n == first)return p[a[y][x]] = search(y + 1, x + 1) + search(y + 1, x - 1);// +p[a[y + 1][x - 1]];
		}
	return p[a[y + 1][x]] = search(y + 1, x);
	}

	//枝刈り
	if (isReached[a[y][x]]){
		if (a[y][x] == first)initial = true;
		return p[a[y][x]];
	}

	if (u_right.count == -10)u_right = search(y + 1, x + 1);//under.rightの計算
	if (u_left.count == -10)u_left = search(y + 1, x - 1);//under.leftの計算

	//素数の時
	if (isPrime(a[y][x])){
		p[a[y][x]].count = 1;
		p[a[y][x]].last = a[y][x];
	}

	if (u_right.count == u_left.count){
		if (u_right.last < u_left.last)u_right.count--;
	}
	//leftのコストが大きい時
	if (u_right.count < u_left.count){
		isReached[a[y][x]] = true;
		if (a[y][x] == first)initial = true;//最初に入った時のみ、次のために初期化
		return p[a[y][x]] = p[a[y][x]] + u_left;
	}
	//rightのコストが大きい時
	else{
		isReached[a[y][x]] = true;
		if (a[y][x] == first)initial = true;//最初に入った時のみ、次のために初期化
		return p[a[y][x]] = p[a[y][x]] + u_right;
	}
}

int main(){

	using namespace std;

	int x = MAX / 2;
	int y = MAX / 2;
	int N = 1;
	a[MAX / 2][MAX / 2] = 1;

	for (int i = 0; i < MAX*MAX; i++){

		for (int n = 0; n < (int)sqrt((double)N); n++){
			a[y][x] = N;
			N++;
			x++;
		}
		if (N >= (MAX)*(MAX))break;
		for (int n = 0; n < (int)sqrt((double)N); n++){
			a[y][x] = N;
			N++;
			y--;
		}
		if (N >= (MAX)*(MAX))break;
		for (int n = 0; n < (int)sqrt((double)N); n++){
			a[y][x] = N;
			N++;
			x--;
		}
		if (N >= (MAX)*(MAX))break;
		for (int n = 0; n < (int)sqrt((double)N); n++){
			a[y][x] = N;
			N++;
			y++;
		}
		if (N >= (MAX)*(MAX))break;
	}

	ifstream fin;
	fin.open("input.txt");

	while (true){
		cin >> n >> first;
		if (n == 0)break;

		initial = true;

		for (int i = 0; i < MAX; i++){
			for (int j = 0; j < MAX; j++){
				if (a[i][j] == first){
					x = j;
					y = i;
					break;
				}
			}
		}

		Pair p = search(y, x);

		cout << p.count << " " << p.last << endl;
		
	}
	return 0;
}

Measured memory_bytes: 14032