#include <iostream>
#include <iomanip>
#include <cstdio>
#include <string>
#include <cstring>
#include <deque>
#include <list>
#include <queue>
#include <stack>
#include <vector>
#include <utility>
#include <algorithm>
#include <map>
#include <set>
#include <complex>
#include <cmath>
#include <limits>
#include <cfloat>
#include <climits>
#include <ctime>
#include <cassert>
#include <numeric>
#include <fstream>
#include <functional>
#include <bitset>

using namespace std;

const int MAXN = 2001024;

// 結果を格納する変数
int prime[MAXN]; // n 以下の素数のうち i 番目の素数
bool is_prime[MAXN]; // 整数 i が素数であるかどうか

int sieve(int n) {
    int res = 0;
    fill(is_prime, is_prime + MAXN, true);
    is_prime[0] = is_prime[1] = false; // 0 と 1 は素数ではない。
    for(int i = 2; i <= n; ++i) {
        if(!is_prime[i]) continue;
        prime[res++] = i;
        for(int j = 2 * i; j <= n; j += i) is_prime[j] = false; // 素数 i の倍数は素数ではない (ふるい(篩)にかける)
    }
    return res;
}

signed main(){
    
    sieve(MAXN - 1);
    vector<vector<int> > g(2000, vector<int> (2000));
    vector<pair<int, int> > toC(2000 * 2000);
    int delta = 1000;
    int num = 2;
    int i = 0;
    int j = 0;
    g[i + delta][j + delta] = 1;
    toC[1] = {i + delta, j + delta};
    int step = 1;
    int max_i = 0;
    int max_j = 0;
    int min_i = 0;
    int min_j = 0;
    
    while(num <= 2000000){
        
        // 右に step
        for(int h = 0; h < step; h++){
            j++;
            g[i + delta][j + delta] = num;
            toC[num] = {i + delta, j + delta};
            num++;
            min_j = min(min_j, j);
            max_j = max(max_j, j);
        }

        // 上に step
        for(int h = 0; h < step; h++){
            i--;
            g[i + delta][j + delta] = num;
            toC[num] = {i + delta, j + delta};
            num++;
            min_i = min(min_i, i);
            max_i = max(max_i, i);
        }

        step++;

        // 左に step
        for(int h = 0; h < step; h++){
            j--;
            g[i + delta][j + delta] = num;
            toC[num] = {i + delta, j + delta};
            num++;
            min_j = min(min_j, j);
            max_j = max(max_j, j);
        }

        // 下に step
        for(int h = 0; h < step; h++){
            i++;
            g[i + delta][j + delta] = num;
            toC[num] = {i + delta, j + delta};
            num++;
            min_i = min(min_i, i);
            max_i = max(max_i, i);
        }
        step++;
    }
    
    while(1){
        
        int m, n; cin >> m >> n;
        if(m == 0 && n == 0) break;

        int si = toC[n].first;
        int sj = toC[n].second;
        
        vector<vector<int> > dp(2000, vector<int> (2000, -1));
        dp[si][sj] = is_prime[n];
        
        int ans = 0;
        int ansval = 0;

        for(int i = 0; i < 1999; i++){
            for(int j = 1; j < 1998; j++){
                
                if(dp[i][j] == -1) continue;
                int val = g[i][j];
                if(val > m) continue;
                if((ans < dp[i][j] || (ans == dp[i][j] && ansval < val)) && is_prime[val]){
                    ans = dp[i][j];
                    ansval = val;
                }

                int ni = i + 1;
                for(int h = -1; h <= 1; h++){
                    int nj = j + h;
                    int nnum = g[ni][nj];
                    dp[ni][nj] = max(dp[ni][nj], dp[i][j] + is_prime[nnum]);
                }
            }
        }
        
        /*
        for(int i = -3; i <= 3; i++){
            for(int j = -3; j <= 3; j++){
                cerr << dp[i + delta][j + delta] << " ";
            }
            cerr << endl;
        }
        
        */
        
        cout << ans << " " << ansval << endl;
    
    }   

    return 0;
}



Measured memory_bytes: 68216