#include <iostream>
#include <stdio.h>
#include <string>
#include <sstream>
#include <vector>
#include <stdlib.h>
#include <math.h>
#include <list>
#include <algorithm>

using namespace std;

//平方数かどうか調べる
int isSq(int n) {
	if(n <= 0) return 0;

	for(int i = 1; i <= (int)sqrt( (double)n ) + 1; i++) {
		if( n % i == 0 && n / i == i ) return i;
	}
	
	return 0;
}
//素数かどうか調べる
int isPrime(int n) {
	if(n <= 1) return 0;
	int flg = 1;
	for(int i = 2; i <= (int)sqrt((double)n) + 1; i++) {
		if( n % i == 0) {
			flg = 0;
			break;
		}
	}
	return flg;
}

struct memo{
	int last;
	int pts;
};
struct cave{
	int x;
	int y;
	int flg;
	int num;
};
struct indx{
	int last;
	int pts;
	bool operator<( const indx& right ) const {
        return pts == right.pts ? last < right.last : pts < right.pts;
    }
};

//動的計画法で探査
//番号が決まれば得点がきまるはず
void search_cave(int n, int xpos, int ypos, vector<memo>*m, vector<vector<int>> *cv, vector<cave> *cl, int h, int w){

	if( m -> at(n).last != -1 ) {
		//探索済みの場合
		return;
	} else {
		//未探索の場合
		//直下の三洞窟を探索する
		//直下三通りはすでに探索済みとする

		if( ypos == h - 1 ) {
			//一番下ならば？
			m->at(n).pts = cl->at(n).flg;
			m->at(n).last = 0;
			if(cl->at(n).flg == 1) m->at(n).last = n;
		} else {
			//降りられる洞穴がある場合
			indx index[3];
			for(int i = 0; i < 3; i++) {
				index[i].pts = -1;
				index[i].last = -1;
			}

			//左右移動できるか確認する
			if( xpos > 0 )	{	//左下
				int tmp = cv->at( xpos - 1 ).at( ypos + 1 );
				index[0].pts = m->at( tmp ).pts;
				index[0].last = m->at(tmp).last;
			}
			if( xpos < w - 1) { //右下
				int tmp = cv->at( xpos + 1 ).at( ypos + 1 );
				index[1].pts = m->at( tmp ).pts;
				index[1].last = m->at( tmp ).last;
			}
			if( 1 ) {			//真下
				int tmp = cv -> at( xpos ).at( ypos + 1 );
				index[2].pts = m -> at( tmp ).pts;
				index[2].last = m -> at( tmp ).last;
			}

			//大小比較する
			sort(index,index+3);

			m -> at(n).pts = index[2].pts + cl -> at(n).flg ;
			m -> at(n).last = index[2].last;
			if(index[2].last <= 0 && cl -> at(n).flg > 0) m -> at(n).last = n;

		}
	}
}

int main(void){
	//FILE* fp_in = freopen("data.txt", "r", stdin);
	while(1){
		int m, n;
		vector<cave> clist;

		cin >> m >> n;
		if( m == 0 && n == 0 ) break;
		
		cave c;
		c.x = -1;
		c.y = 0;
		c.flg = 0;
		c.num = 0;
		clist.push_back(c);

		//洞窟の大きさを調べる
		int dir = 0, sq = 1;
		for(int i = 1; i <= m; i ++) {
			if( isSq(i) != 0 ) 
				sq = isSq(i);
			//進む
			switch(dir) {
				case 0:
					c.x ++;
					break;
				case 1:
					c.y --;
					break;
				case 2:
					c.x --;
					break;
				case 3:
					c.y ++;
					break;
			}
			//方向転換
			if( ( isSq( i - 1 ) != 0 ) || ( i == sq*sq + sq + 1 ) ) { 
				dir ++;
				if( dir > 3 ) dir = 0;
			}
			c.flg = isPrime(i);
			c.num = i;
			clist.push_back(c);
		}

		//洞窟の大きさを取得する
		int x_max = 0, x_min = 0, y_max = 0, y_min = 0;
		for(int i = 1; i < clist.size(); i++) {
			if( clist.at(i).x < x_min ) x_min = clist.at(i).x;
			if( clist.at(i).x > x_max ) x_max = clist.at(i).x;
			if( clist.at(i).y < y_min ) y_min = clist.at(i).y;
			if( clist.at(i).y > y_max ) y_max = clist.at(i).y;
		}

		//上端のy座標を0にセット
		for(int i = 1; i < clist.size(); i++) {
			clist.at(i).y -= y_min;
			clist.at(i).x -= x_min;
		}
		
		//洞穴を意味するvector
		vector<vector<int>> caves;
		for(int i = 0; i <= x_max - x_min; i++) {
			vector<int> newcave;
			for(int j = 0; j <= y_max - y_min; j++)
				newcave.push_back(0);
			caves.push_back(newcave);
		}

		//番号をセットする
		for(int i = 1; i < clist.size(); i++) 
			caves.at( clist.at(i).x ).at( clist.at(i).y ) = clist.at(i).num;

		//メモ用vector
		vector<memo> memory;
		for(int i = 0; i < clist.size() + 2; i++) {
			memo newmemo;
			newmemo.last = -1;
			newmemo.pts = 0;
			memory.push_back(newmemo);
		}

		int height = caves.at(0).size();
		int width = caves.size();
		int ans[2];
		int flg = 0;
	

		//一番下から調べる
		for(int i = height - 1; i >= 0; i--) {
			for(int j = 0; j < width; j++) {
				int num = caves.at(j).at(i);
				search_cave(num, j, i, &memory, &caves, &clist, height, width);
				if( num == n ) {
					flg = 1;
					break;
				}
			}
			if(flg) break;
		}
		

		ans[0] = memory.at(n).pts;
		ans[1] = memory.at(n).last;
		if( ans[0] == 0 ) ans[1] = 0;

		cout << ans[0] << " " << ans[1] << endl;
	}

	//while(1){}
	return 0;
}

Measured memory_bytes: 37200