#include <sstream>
#include <string>
#include <vector>
#include <map>
#include <algorithm>
#include <iostream>
#include <utility>
#include <set>
#include <cctype>
#include <queue>
#include <stack>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <climits>
using namespace std;
#define INF 100000000

typedef long long ll;
const int dx[] = {0, 1, 0, -1};
const int dy[] = {1, 0, -1, 0};
const int MAXM = 1000100;
bool isPrime[MAXM];
int dp[1500][1500];
int last[1500][1500];

class Board {
public:
    vector<vector<int> > board;
    vector<pair<int, int> > pos;
    int maxDepth;
    int minWidth;
    int maxWidth;
    Board(int n) {
        maxDepth = 0;
        minWidth = 1500;
        maxWidth = 0;
        pos.resize(n+10);
        for (int i = 0; i < 1500; i++) {
            vector<int> tmp(1500);
            board.push_back(tmp);
        }
        pair<int, int> position = make_pair(750, 750);
        int direction = 0;
        for (int cur = 1; cur <= n; cur++) {
            maxDepth = max(maxDepth, position.second);
            maxWidth = max(maxWidth, position.first);
            minWidth = min(minWidth, position.first);
            board[position.second][position.first] = cur;
            pos[cur] = position;
            int left = direction+1;
            left %= 4;
            if (board[position.second+dy[left]][position.first+dx[left]] == 0) {
                direction = left;
            }
            position.first += dx[direction];
            position.second += dy[direction];
        }
    }
};

void initPrime() {
    for (int i = 2; i < MAXM; i++) isPrime[i] = true;
    for (int i = 2; i*i < MAXM; i++) {
        if (isPrime[i]) {
            for (int j = 2; j * i < MAXM; j++) {
                isPrime[i*j] = false;
            }
        }
    }
}

int main(void) {
    int n, m;
    initPrime();
    while (cin >> n >> m) {
        if (n == 0 && m == 0) break;
        Board board(n);
//        for (int i = 745; i < 755; i++) {
//            for (int j = 745; j < 755; j++) {
//                cout << board.board[i][j] << "\t";
//            }
//            cout << endl;
//        }
//        cout << board.maxDepth << endl;
        for (int i = 0; i < 1500; i++) {
            for (int j = 0; j < 1500; j++) {
                dp[i][j] = -1;
                last[i][j] = -1;
            }
        }
        auto start = board.pos[m];
        if (isPrime[m]) dp[start.second][start.first] = 1, last[start.second][start.first] = m;
        else dp[start.second][start.first] = 0;
        for (int i = start.second; i <= board.maxDepth; i++) {
            for (int j = board.minWidth; j <= board.maxWidth; j++) {
                if (dp[i][j] == -1) continue;
                for (int k = -1; k <= 1; k++) {
                    pair<int, int> next = make_pair(j+k, i+1);
                    if (next.first < board.minWidth || next.second > board.maxWidth || board.board[next.second][next.first] > n) continue;
                    if (isPrime[board.board[next.second][next.first]]) {
                        if (dp[next.second][next.first] <= dp[i][j] + 1) {
                            dp[next.second][next.first] = dp[i][j] + 1;
                            last[next.second][next.first] = board.board[next.second][next.first];
                        }
                    } else {
                        if (dp[next.second][next.first] <= dp[i][j]) {
                            dp[next.second][next.first] = dp[i][j];
                            last[next.second][next.first] = last[i][j];
                        }
                    }
                }
            }
        }
//        for (int i = 745; i < 755; i++) {
//            for (int j = 745; j < 755; j++) {
//                cout << dp[i][j] << "\t";
//            }
//            cout << endl;
//        }
//        for (int i = 745; i < 755; i++) {
//            for (int j = 745; j < 755; j++) {
//                cout << last[i][j] << "\t";
//            }
//            cout << endl;
//        }
        pair<int, int> ans;
        for (int i = board.minWidth; i <= board.maxWidth; i++) {
            ans = max(make_pair(dp[board.maxDepth][i], last[board.maxDepth][i]), ans);
        }
        cout << ans.first << " " << ans.second << endl;
    }
    return 0;
}

Measured memory_bytes: 36388