/*
 * D.cpp
 *
 *  Created on: 2017/06/25
 *      Author: LitMc
 */

#include <bits/stdc++.h>

#define rep(i, from, to) for (int i = from; i < to; ++i)
#define REP(i, from, to) for (int i = from; i <= to; ++i)
#define dbp(x) cout<<#x<<": "<<x<<endl;
#define dbp2(x,y) cout<<#x<<","<<#y<<": "<<x<<","<<y<<endl;
#define dbp3(x,y,z) cout<<#x<<","<<#y<<","<<#z<<": "<<x<<","<<y<<","<<z<<endl;
#define dbp4(w,x,y,z) cout<<#w<<","<<#x<<","<<#y<<","<<#z<<": "<<w<<","<<x<<","<<y<<","<<z<<endl;

using namespace std;

struct answer {
	int num, last;
	answer() {
		num = -1;
		last = -1;
	}
	answer(int n, int l) {
		num = n;
		last = l;
	}
	bool operator<(const answer &a) const {
		if (num == a.num) {
			return last < a.last;
		} else {
			return num < a.num;
		}
	}
};
typedef struct answer answer;
const int MAX_M = 1000010;
const int MAX_W = 1011;
const int SIZE = MAX_W * MAX_W + 1000;
int g[MAX_W][MAX_W];
bool p[MAX_W][MAX_W];
bool isprime[SIZE];
int center = MAX_W / 2;
answer ans;
int di[3] = { -1, -1, -1 };
int dj[3] = { -1, 0, 1 };
int n, m;
typedef pair<int, int> P;
P n2ij[SIZE];

void eratos() {
	isprime[0] = isprime[1] = true;
	for (int i = 2; i < SIZE; ++i) {
		if (isprime[i]) {
			continue;
		}
		for (int j = i + i; j < SIZE; j += i) {
			isprime[j] = true;
		}
	}
}

bool ok(int &i, int &j) {
	return 0 <= i && i < MAX_W && 0 <= j && j < MAX_W;
}

void up(int &i, int &j, int cnt, int &k) {
	rep(u,0,cnt+1)
	{
		if (ok(i, j)) {
			g[i][j] = k;
			p[i][j] = isprime[k];
			n2ij[k] = P(i, j);
			k++;
			i--;
		} else {
			//error!
		}
	}
	i++;
	j--;
}

void left(int &i, int &j, int cnt, int &k) {
	rep(l,0,cnt+1)
	{
		if (ok(i, j)) {
			g[i][j] = k;
			p[i][j] = isprime[k];
			n2ij[k] = P(i, j);
			k++;
			j--;
		} else {
			//error!
		}
	}
	j++;
	i++;
}

void down(int &i, int &j, int cnt, int &k) {
	rep(l,0,cnt+1)
	{
		if (ok(i, j)) {
			g[i][j] = k;
			p[i][j] = isprime[k];
			n2ij[k] = P(i, j);
			k++;
			i++;
		} else {
			//error!
		}
	}
	i--;
	j++;
}

void right(int &i, int &j, int cnt, int &k) {
	rep(l,0,cnt+1)
	{
		if (ok(i, j)) {
			g[i][j] = k;
			p[i][j] = isprime[k];
			n2ij[k] = P(i, j);
			k++;
			j++;
		} else {
			//error!
		}
	}
	j--;
	i--;
}

void makeHole() {
	int i = center, j = center;
	int k = 1, cnt = 1;
	g[i][j] = k;
	p[i][j] = isprime[k];
	n2ij[k] = P(i, j);
	j++;
	k++;
	while (ok(i, j) && k < MAX_W * MAX_W) {
//		dbp4(i - center, j - center, g[i][j], k);
		up(i, j, cnt, k);
//		dbp4(i - center, j - center, g[i][j], k);
		left(i, j, cnt, k);
//		dbp4(i - center, j - center, g[i][j], k);
		down(i, j, cnt, k);
//		dbp4(i - center, j - center, g[i][j], k);
		right(i, j, cnt, k);
//		dbp4(i - center, j - center, g[i][j], k);
		i++;
		j++;
		cnt += 2;
	}
}

answer dp[MAX_W][MAX_W];
void doDP(int si, int sj) {
	ans = answer(-1, -1);
	if (!p[si][sj]) {
		dp[si][sj] = answer(1, g[si][sj]);
	} else {
		dp[si][sj] = answer(0, 0);
	}
	ans = max(ans, dp[si][sj]);
	int l = max(0, sj - 1), r = min(MAX_W - 1, sj + 1);
	int pl = sj, pr = sj;
	rep(i,si+1,MAX_W)
	{
		REP(j, l, r)
		{
			answer a;
			rep(k, 0, 3) //
			{
				int pi = i + di[k], pj = j + dj[k];
				if (ok(i, j) && ok(pi, pj) && dp[pi][pj].num != -1 && pl <= pj
						&& pj <= pr && g[i][j] <= m && g[pi][pj] <= m) {
					answer a = dp[pi][pj];
					if (!p[i][j]) {
						a.num++;
						a.last = g[i][j];
					}
					dp[i][j] = max(dp[i][j], a);
				}
			}
			if (g[i][j] <= m) {
				ans = max(ans, dp[i][j]);

			}
		}
		pl = l;
		pr = r;
		l = max(l - 1, 0);
		r = min(r + 1, MAX_W - 1);

	}
}

void solve() {
	eratos();
	makeHole();
	while (cin >> m >> n, m || n) {

		rep(i,0,MAX_W)
		{
			fill(dp[i], dp[i] + MAX_W, answer());
		}
		doDP(n2ij[n].first, n2ij[n].second);
		cout << ans.num << " " << ans.last << endl;
	}
}

int main() {
	solve();
	return 0;
}

Measured memory_bytes: 25024