#define LOCAL
#include <bits/stdc++.h>
#define rep(i, n) for(int i=0; i<(n); ++i)
#define rrep(i, n) for(int i=(n-1); i>=0; --i)
#define rep2(i, s, n) for(int i=s; i<(n); ++i)
#define ALL(v) (v).begin(), (v).end()
#define memr(dp, val) memset(dp, val, sizeof(dp))
using namespace std;
typedef long long ll;
static const int INTINF = (INT_MAX >> 1); // 10^9 + 10^7
static const ll LLINF = (LLONG_MAX >> 1);
static const int MAX = 100001;
static const ll MOD = 1000000007;
template<class T> inline bool chmax(T& a, T b) { if (a < b) { a = b; return 1; } return 0; }
template<class T> inline bool chmin(T& a, T b) { if (a > b) { a = b; return 1; } return 0; }
template<class T> inline bool int_ceil(T a, T b) { T res = a / b; if(a % b != 0) res++; return res; }
template<typename T>
using min_priority_queue = priority_queue<T, vector<T>, greater<T> >;
string to_string(string s) { return '"' + s + '"'; }
string to_string(bool b) { return b ? "true" : "false"; }
template <size_t N> string to_string(bitset<N> bs) {
  string res;
  for (size_t i = 0; i < N; ++i) res += '0' + bs[i];
  return res;
}
string to_string(vector<bool> v) {
  string res = "{";
  for (bool e : v) res += to_string(e) + ", ";
  return res += "}";
}
template <class T, class U> string to_string(pair<T, U> p);
template <class C> string to_string(C c) {
  string res = "{";
  for (auto e : c) res += to_string(e) + ", ";
  return res += "}";
}
template <class T, class U> string to_string(pair<T, U> p) {
  return "(" + to_string(p.first) + ", " + to_string(p.second) + ")";
}
void debug() { cerr << '\n'; }
template <class Head, class... Tail> void debug(Head head, Tail... tail) {
  cerr << '\t' << to_string(head), debug(tail...);
}
#ifdef LOCAL
#define print(...) cerr << "[" << #__VA_ARGS__ << "]:", debug(__VA_ARGS__)
#else
#define print(...)
#endif

vector<bool> sieve(long long max){ // 0 <= x <= max までの素数を調べ、返す。
    vector<bool> isPrime;
    isPrime.resize(max+1,true); // isPrimeに必要な要素数を確保
    isPrime[0] = false; // 0は素数ではない
    isPrime[1] = false; // 1は素数ではない

    for(int i=2; i*i<=max; ++i) // 0からsqrt(max)まで調べる
        if(isPrime[i])
            for(int j=2; i*j<=max; ++j)
                isPrime[i*j] = false;

    return isPrime;
}

int n, m;

pair<ll, ll> dp[1010][1010];
pair<int, int> numToPos[1000001];
vector<bool> primes;
bool dp2[1010][1010];

int main(int argc, const char * argv[]) {
	std::cout << std::fixed << std::setprecision(15);

	rep(i, 1010) rep(j, 1010) dp[i][j] = {-1, -1};
	primes = sieve(10000000);
	int base = 503;
	int num = 1;
	int x=0, y=0;
	int pattern = 0;
	int k=0;
	int dx[4] = {0, 0, 1, -1};
	int dy[4] = {1, -1, 0, 0};
	while(num <= 1000000){
		// print(x, y);
		numToPos[num] = {base+x, base+y};
		dp[base+y][base+x] = {num, 0};
		switch (pattern)
		{
		case 0:
			k=0;
			x++;
			break;
		case 1:
			k=3;
			y++;
			break;
		case 2:
			k=1;
			x--;
			break;
		case 3:
			k=2;
			y--;
			break;
		}
		if(dp[base+y+dy[k]][base+x+dx[k]].first == -1){
			pattern++; pattern %= 4;
		}
		num++;
	}
	// print(numToPos[1000000]);

	while(1){
		cin >> n >> m;
		if(!n && !m) break;

		rep(i, 1010) rep(j, 1010) dp[i][j].second = 0;
		memr(dp2, 0);

		// 書き直し

		auto s = numToPos[m];
		queue<pair<int, int> > q;
		q.push(s);
		dp[s.second][s.first].second = primes[m];
		ll ans = 0;
		ll last = 0;
		if(primes[m]){
			ans = dp[s.second][s.first].second;
			last = dp[s.second][s.first].first;
		}
		// print(dp[s.second][s.first].second);
		while(!q.empty()){
			auto f = q.front(); q.pop();
			int x = f.first, y = f.second;
			for(int i=0; i<3; i++){
				if(dp[y-1][x+i-1].first == -1) continue;
				if(n < dp[y-1][x+i-1].first) continue;
				// if(primes[dp[y-1][x+i-1].first]) print(dp[y-1][x+i-1].first);
				chmax(dp[y-1][x+i-1].second, dp[y][x].second + primes[dp[y-1][x+i-1].first]);
				if(primes[dp[y-1][x+i-1].first]){
					if(ans < dp[y-1][x+i-1].second){
						ans = dp[y-1][x+i-1].second;
						last = dp[y-1][x+i-1].first;
					}
					else if(ans == dp[y-1][x+i-1].second){
						chmax(last, dp[y-1][x+i-1].first);
					}
				}
				if(dp2[y-1][x+i-1]) continue;
				q.push({x+i-1, y-1});
				dp2[y-1][x+i-1] = true;
			}
		}
		cout << ans << " " << last << endl;
		// break;
	}

	return 0;
}



Measured memory_bytes: 28656