#define _USE_MATH_DEFINES
#include <iostream>
#include <fstream>
#include <sstream>
#include <string>
#include <cstring>
#include <vector>
#include <set>
#include <map>
#include <unordered_map>
#include <queue>
#include <deque>
#include <stack>
#include <algorithm>
#include <bitset>
#include <cmath>
#include <cstdlib>
#include <ctime>
#include <numeric>
#include <functional>
#include <cctype>
#include <list>
#include <limits>
#include <cassert>
//#include <boost/multiprecision/cpp_int.hpp>



using namespace std;
using Int = long long;
//using namespace boost::multiprecision;

const double EPS = 1e-10;
long long const MOD = 1000000007;

long long mod_pow(long long x, long long n) {
    long long res = 1;
    for(int i = 0;i < 60; i++){
        if(n >> i & 1) res = res * x % MOD;
        x = x * x % MOD;
    }
    return res;
}

template<typename T>
T gcd(T a, T b) {
    return b != 0 ? gcd(b, a % b) : a;
}

template<typename T>
T lcm(T a, T b) {
    return a * b / gcd(a, b);
}

void fastInput() {
    cin.tie(0);
    ios::sync_with_stdio(false);
}

vector<int> erat(int n) {
    vector<int> primes(n);
    for (int i = 2; i < n; ++i) primes[i] = i;
    for (int i = 2; i*i < n; ++i)
        if (primes[i])
            for (int j = i*i; j < n; j+=i) primes[j] = 0;
    // 素数のみをvectorに格納する場合は以下の行を追加 (0 である要素を全削除)
    // primes.erase(remove(primes.begin(), primes.end(), 0), primes.end());
    return primes;
}

pair<int, int> makeField(vector<vector<int>> &field, int M, int N) {
    pair<int, int> ret = {1000, 1000};
    field[1000][1000] = 1;
    int cnt = 2;
    int dx[] = {0, 1, 0, -1};
    int dy[] = {1, 0, -1, 0};
    int crtX = 1001;
    int crtY = 1000;
    int crtDir = 1;
    while (cnt <= M) {
        field[crtX][crtY] = cnt;
        if (cnt == N) ret = {crtX, crtY};
        if (field[crtX + dx[(crtDir - 1 + 4) % 4]][crtY + dy[(crtDir - 1 + 4) % 4]] == 0) {
            crtDir = (crtDir - 1 + 4) % 4;
        }
        crtX += dx[crtDir];
        crtY += dy[crtDir];
        cnt++;
    }
    return ret;
}

vector<vector<int>> v;

int backTrack(int crtX, int crtY, vector<vector<int>> &field, vector<vector<int>> &dp, vector<int> &primes) {
    if (v[crtX][crtY] == 1) return 0;
    v[crtX][crtY] = 1;
    int ret = 0;
    int cnt = 0;
    if (primes[field[crtX][crtY]]) cnt = 1;
    if (dp[crtX][crtY] == 1 && dp[crtX-1][crtY-1] == 0 && dp[crtX][crtY-1] == 0 && dp[crtX+1][crtY-1] == 0) return field[crtX][crtY];

    if (dp[crtX][crtY] - cnt == dp[crtX-1][crtY-1]) ret = max(ret, backTrack(crtX-1, crtY-1, field, dp, primes));
    if (dp[crtX][crtY] - cnt == dp[crtX][crtY-1]) ret = max(ret, backTrack(crtX, crtY-1, field, dp, primes));
    if (dp[crtX][crtY] - cnt == dp[crtX+1][crtY-1]) ret = max(ret, backTrack(crtX+1, crtY-1, field, dp, primes));
    return ret;
    
}

int dfs(int crtX, int crtY, vector<vector<int>> &field, vector<vector<int>> &dp, vector<int> &primes) {
    if (dp[crtX][crtY] != -1) return dp[crtX][crtY];
    if (field[crtX][crtY] == 0) return dp[crtX][crtY] = 0;
    int ret = 0;
    if (primes[field[crtX][crtY]]) ret += 1;
    int ma = 0;
    ma = max(ma, dfs(crtX-1, crtY-1, field, dp, primes));
    ma = max(ma, dfs(crtX, crtY-1, field, dp, primes));
    ma = max(ma, dfs(crtX+1, crtY-1, field, dp, primes));
    ret += ma;
    dp[crtX][crtY] = max(dp[crtX][crtY], ret);
    return dp[crtX][crtY];
}

pair<int, int> solve(int M, int N) {
    vector<vector<int>> field(2000, vector<int>(2000));
    vector<vector<int>> dp(2000, vector<int>(2000, -1));
    v = vector<vector<int>> (2000, vector<int>(2000));
    // center = {1000, 1000};

    pair<int, int> start = makeField(field, M, N);
    vector<int> primes = erat(M+1);
    pair<int, int> ret = {0, 0};
    ret.first = dfs(start.first, start.second, field, dp, primes);
    ret.second = backTrack(start.first, start.second, field, dp, primes);
    return ret;
}

int main(void) {
    int M, N;
    vector<pair<int, int>> ans;
    while (1) {
        cin >> M >> N;
        if (!M && !N) break;
        ans.push_back(solve(M, N));
    }
    for (auto &i : ans) {
        cout << i.first << " " << i.second << endl;
    }
}


Measured memory_bytes: 65852