#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
#include <cmath>
#include <cstdio>
#include <functional>
#include <numeric>
#include <stack>
#include <queue>
#include <map>
#include <set>
#include <utility>
#include <sstream>
#include <complex>
#include <fstream>
#include <bitset>
#include <time.h>
#include <tuple>

using namespace std;

typedef long long ll;
typedef pair<ll, ll> P;
typedef vector<ll> V;
typedef complex<double> Point;

#define PI acos(-1.0)
#define EPS 1e-10
const ll INF = (1LL << 60) - 1;
const ll MOD = 1e9 + 7;

#define FOR(i,a,b) for(int i=(a);i<(b);i++)
#define rep(i,N) for(int i=0;i<(N);i++)
#define ALL(s) (s).begin(),(s).end()
#define EQ(a,b) (abs((a)-(b))<EPS)
#define EQV(a,b) ( EQ((a).real(), (b).real()) && EQ((a).imag(), (b).imag()) )
#define fi first
#define se second
#define N_SIZE (1LL << 20)
#define NIL -1
#define MAX_N 100100 * 3

int n, m;
int f[2000][2000];
int dp[2000][2000];
int fdp[2000][2000];
bool F[2000][2000];

int posx[1000010];
int posy[1000010];

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

vector<int> prime;
bool is_prime[1000010 + 1];

int sieve(int n) {//n??\???????´???°?????°?????????
	int p = 0;
	for (int i = 0; i <= n; i++)is_prime[i] = 1;
	is_prime[0] = is_prime[1] = 0;
	for (int i = 2; i <= n; i++) {
		if (is_prime[i]) {
			prime.push_back(i);
			for (int j = 2 * i; j <= n; j += i)is_prime[j] = 0;
		}
	}
	return p;
}

int ddx[] = { 1,0,-1 };

int main() {
	sieve(1000010);
	ll y = 1000, x = 1000;
	int num = 1;
	int cnt = 1;
	int k = cnt;
	int dir = 0;
	while (num <= 1000000) {
		f[y][x] = num;
		posy[num] = y;
		posx[num] = x;
		num++;
		x += dx[dir], y += dy[dir];
		k--;
		if (k == 0) {
			dir = (dir + 1) % 4;
			if (dir % 2 == 0)cnt++;
			k = cnt;
		}
	}

	while (cin >> m >> n&&n + m) {
		rep(i, 2000)rep(j, 2000) {
			F[i][j] = 0;
			if (is_prime[f[i][j]]) {
				dp[i][j] = 1;
				fdp[i][j] = f[i][j];
			}
			else dp[i][j] = 0;
		}
		if (is_prime[f[posy[n]][posx[n]]]) {
			dp[posy[n]][posx[n]] = 1;
			fdp[posy[n]][posx[n]] = n;
			F[posy[n]][posx[n]] = 1;
		}
		int it = 1;
		FOR(i, posy[n] + 1, 2000) {
			FOR(j, max(0, posx[n] - it), min(2000, posx[n] + it + 1)) {
				int MAX = 0;
				rep(k, 3) {
					int ny = i - 1, nx = j + ddx[k];
					if (nx >= 0 && nx < 2000) {
						if (f[ny][nx] <= m&&abs(nx - posx[n]) <= abs(ny - posy[n])) {
							MAX = max(MAX, dp[ny][nx]);
						}
					}
				}
				dp[i][j] += MAX;
				F[i][j] = 1;
			}
			it++;
		}

		int ans[2] = {};
		rep(i, 2000) {
			rep(j, 2000) {
				if (f[i][j] > m || f[i][j] == 0 || F[i][j] == 0)continue;
				if (ans[0] < dp[i][j]) {
					ans[0] = dp[i][j];
					ans[1] = fdp[i][j];
				}
				else if (ans[0] == dp[i][j]) {
					ans[1] = max(ans[1], fdp[i][j]);
				}
			}
		}
		cout << ans[0] << " ";
		if (ans[0] == 0)cout << 0 << endl;
		else cout << ans[1] << endl;
	}
}

//if(is_prime[n])dp[posy[n]][posx[n]] = 1;
//for (int i = -20; i <= 20; i++) {
//	for (int j = -20; j <= 20; j++) {
//		if (is_prime[f[1000 + i][1000 + j]])cout << "!";
//		else cout << " ";
//		printf("%4d", f[1000 + i][1000 + j]);
//		printf("%4d", dp[1000 + i][1000 + j]);
//	}
//	cout << endl;
//}

//for (int i = -3; i <= 3; i++) {
//	for (int j = -3; j <= 3; j++) {
//		printf("%3d", fdp[1000 + i][1000 + j]);
//	}
//	cout << endl;
//}
//cout << endl;
//for (int i = -3; i <= 3; i++) {
//	for (int j = -3; j <= 3; j++) {
//		printf("%3d", dp[1000 + i][1000 + j]);
//	}
//	cout << endl;
//}

Measured memory_bytes: 47152