#include <bits/stdc++.h>
using namespace std;
/*{{{*/  //template
#define REP(i,n) for(int i=0;i<n;i++)
#define rep(i,n) for(int i=0;i<n;i++)
#define INF 1<<29
#define LINF LLONG_MAX/3
#define MP make_pair
#define PB push_back
#define EB emplace_back
#define ALL(v) (v).begin(),(v).end()
#define all(v) ALL(v)
#define debug(x) cerr<<#x<<":"<<x<<endl
#define debug2(x,y) cerr<<#x<<","<<#y":"<<x<<","<<y<<endl
#define CININIT cin.tie(0),ios::sync_with_stdio(false)
//struct fin{ fin(){ cin.tie(0); ios::sync_with_stdio(false); } } fin_;
struct Double{ double d; explicit Double(double x) : d(x){} };
ostream& operator<<(ostream& os,const Double x){ os << fixed << setprecision(20) << x.d; return os; }
template<typename T> ostream& operator<<(ostream& os,const vector<T>& vec){ os << "["; for(const auto& v : vec){ os << v << ","; } os << "]"; return os; }
template<typename T,typename U> ostream& operator<<(ostream& os,const pair<T,U>& p){ os << "(" << p.first << ","<< p.second <<")"; return os; }
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int> pii;
typedef vector<int> vi;
typedef vector<vi> vvi;
ll gcd(ll a,ll b){ if(b==0) return a; else return gcd(b,a%b); }
 
constexpr ll mod = 1e9+7;
const int dx[]={1,0,-1,0} ,dy[] = {0,1,0,-1};
/*}}}*/

int n,m;
int table[1500][1500];
vector<bool> is_prime;

bool ok(int x,int y){
    if(x<0 or x>=1500 or y<0 or y>=1500) return false;
    if(table[x][y]==0) return false;
    if(table[x][y]>m) return false;
    return true;
}

void solve(){
    vector<vector<int>> dp(1500,vi(1500,0));
    vector<vector<bool>> vis(1500,vector<bool>(1500,false));
    vector<vector<int>> pre(1500,vector<int>(1500,0));
    int sx=0,sy=0;
    [&]{
        for(int i=0;i<1500;i++) for(int j=0;j<1500;j++) if(table[i][j]==n){
            sx=i;
            sy=j;
            return;
        }
    }();

    vis[sx][sy]=true;
    if(is_prime[table[sx][sy]]) pre[sx][sy]=table[sx][sy];
    if(is_prime[table[sx][sy]]) dp[sx][sy]++;


    for(int x=0;x<1500;x++){
        for(int y=0;y<1500;y++){
            if(!vis[x][y]) continue;
            int nx=x+1;
            for(int i=-1;i<=1;i++){
                int ny=y+i;
                if(!ok(nx,ny)) continue;
                vis[nx][ny]=true;
                if(is_prime[table[nx][ny]]){
                    dp[nx][ny] = max(dp[nx][ny],dp[x][y]+1);
                    pre[nx][ny] = table[nx][ny];
                }else{
                    if(dp[nx][ny] < dp[x][y]){
                        dp[nx][ny] = dp[x][y];
                        pre[nx][ny] = pre[x][y];
                    }else if(dp[nx][ny]==dp[x][y]){
                        pre[nx][ny] = max(pre[nx][ny],pre[x][y]);
                    }
                }
            }
        }
    }

    int ans=-1;
    for(int i=0;i<1500;i++) for(int j=0;j<1500;j++){
        ans=max(ans,dp[i][j]);
    }
    if(ans==0){
        cout << ans << " " << 0 << endl;
        return;
    }

    int p=-1;
    for(int i=0;i<1500;i++) for(int j=0;j<1500;j++){
        if(ans==dp[i][j]){
            p=max(p,pre[i][j]);
        }
    }
    cout << ans << " " << p << endl;
}

int main(){
    int x=750,y=750;
    int dir=1;
    int cnt=0;
    int upper=1;
    bool f=false;
    for(int i=1;i<=1000000;i++){
        if(x<0 or x>=1500 or y<0 or y>=1500){
            cout << x << " " << y << endl;
            return 0;
        }
        table[x][y]=i;
        x+=dx[dir];
        y+=dy[dir];
        cnt++;
        if(cnt==upper){
            cnt=0;
            dir = (dir+1) % 4;
            if(f){
                upper++;
                f=false;
            }else{
                f=true;
            }
        }
    }

    is_prime = vector<bool>(1000001,true);
    is_prime[0]=false;
    is_prime[1]=false;
    for(int i=0;i<=1000000;i++){
        if(!is_prime[i]) continue;
        for(int j=2;i*j<=1000000;j++){
            is_prime[i*j] = false;
        }
    }

    // m : number of all
    // n : from n
    while(cin>>m>>n){
        if(m==0 and n==0) break;
        solve();
    }
}

Measured memory_bytes: 27068