#include <vector>
#include <list>
#include <map>
#include <set>
#include <stack>
#include <queue>
#include <deque>
#include <algorithm>
#include <utility>
#include <functional>
#include <sstream>
#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <cctype>
#include <string>
#include <cstring>
#include <ctime>
#include <climits>
#include <cassert>
using namespace std;
inline int toInt(string s) {int v; istringstream sin(s);sin>>v;return v;}
template<class T> inline string toString(T x) {ostringstream sout;sout<<x;return sout.str();}
typedef vector<int> vi;
typedef vector<vi> vvi;
typedef vector<string> vs;
typedef pair<int, int> pii;
typedef long long ll;
#define ALL(a) (a).begin(),(a).end()
#define RALL(a) (a).rbegin(),(a).rend()
#define EXIST(s,e) ((s).find(e)!=(s).end())
#define FOR(i,a,b) for(int i=(a);i<(b);++i)
#define REP(i,n) FOR(i,0,n)
const double EPS = 1e-9;
const double PI  = acos(-1.0);

const int MAX_HW = 1010;

int dx[]={1,0,-1,0};
int dy[]={0,-1,0,1};

int main()
{

		vi p(1000000+1, 1);
		p[0] = p[1] = 0;
		FOR(i, 2, 1000+1) {
			if(p[i]) {
				for(int j = i*i; j <= 1000000; j += i) {
					p[j] = 0;
				}
			}
		}


	int m,n;
	while(cin>>m>>n,m){
		pii start;

		int sty, stx;
		int top=INT_MAX, bottom=INT_MIN, left=INT_MAX, right=INT_MIN;
		vvi exist(MAX_HW, vi(MAX_HW));
		vvi canuse(MAX_HW, vi(MAX_HW));

		int y=MAX_HW/2;
		int x=MAX_HW/2;
		int move=1,d=0;
		int num=1;
		int cnt=1;
		while(1){
			REP(_,move){
				if(num == n) {
					sty = y;
					stx = x;
				}
				if(p[num]){
					exist[y][x]=1;
				}
				canuse[y][x]=num;
				y+=dy[d];
				x+=dx[d];
				if(num==m){
					goto made;
				}
				num++;
				assert(y<MAX_HW&&y>=0&&x<MAX_HW&&x>=0);
			}
			d=(d+1)%4;
			if(cnt%2==0){
				move++;
			}
			cnt++;
		}
made:;

		REP(i,MAX_HW){
			REP(j,MAX_HW){
				if(canuse[i][j]){
					left=min(left,j);
					right=max(right,j);
					top=min(top,i);
					bottom=max(bottom,i);
				}
			}
		}

		vvi dp(MAX_HW, vi(MAX_HW));
		dp[sty][stx]=exist[sty][stx]+1;
		vvi last(MAX_HW, vi(MAX_HW));
		if(exist[sty][stx]){
			last[sty][stx]=canuse[sty][stx];
		}else{
			last[sty][stx]=-1;
		}

		FOR(i, sty+1, bottom+1) {
			FOR(j, left, right+1) {
				if(!canuse[i][j]) {
					continue;
				}
				int saiyou=INT_MIN;
				int best=0;
				for(int k=-1;k<2;k++){
					if(dp[i-1][j+k]>best||(saiyou!=INT_MIN&&dp[i-1][j+k]==best&&last[i-1][saiyou]<last[i-1][j+k])){
						assert(j+k>=left&&j+k<=right);
						best=dp[i-1][j+k];
						saiyou=j+k;
					}
				}

				if(saiyou!=INT_MIN){
					if(exist[i][j]){
						dp[i][j]=best+1;
						last[i][j]=canuse[i][j];
					}else{
						dp[i][j]=best;
						last[i][j]=last[i-1][saiyou];
					}
				}
				//if(dp[i-1][j-1]>=1||dp[i-1][j]>=1||dp[i-1][j+1]>=1){
				//	dp[i][j] = max(dp[i-1][j-1], max(dp[i-1][j], dp[i-1][j+1])) + exist[i][j];
				//}
				//if(exist[i][j]){
				//	last[i][j]=canuse[i][j];
				//}else{
				//	last[i][j]=max(last[i-1][j-1], max(last[i-1][j], last[i-1][j+1]));
				//}
			}
		}

		int ans = -1, ansx, ansy;
		FOR(j, left, right+1) {
			if(canuse[bottom][j]) {
				if(ans < dp[bottom][j]) {
					ans = dp[bottom][j];
					ansx = j;
					ansy = bottom;
				} else if(ans == dp[bottom][j] && last[bottom][j] > last[ansy][ansx]){
					ansx = j;
					ansy = bottom;
				}
			} else if(canuse[bottom-1][j]) {
				if(ans < dp[bottom-1][j]) {
					ans = dp[bottom-1][j];
					ansx = j;
					ansy = bottom-1;
				} else if(ans == dp[bottom-1][j] && last[bottom-1][j] > last[ansy][ansx]){
					ansx = j;
					ansy = bottom-1;
				}
			}
		}

		//REP(i,MAX_HW){
		//	REP(j,MAX_HW){
		//		cerr<<dp[i][j];
		//	}
		//	cerr<<endl;
		//}

		if(ans-1==0){
			cout<<"0 0"<<endl;
		}else{
			cout<<ans-1<<" "<<last[ansy][ansx]<<endl;
		}
	}
}

Measured memory_bytes: 21084