#include <iostream>
#include <algorithm>
#include <vector>
#include <map>
#include <set>
#include <functional>
#include <queue>
#include <stack>
#include <string>
#include <utility>
#include <cstring>
#include <cmath>
#include <cstdio>
#include <cassert>
#include <cinttypes>

#define fi first
#define se second

using namespace std;

typedef int64_t i64;
typedef uint64_t u64;

const i64 INF = 1e18 + 10;

typedef pair<int, int> P;
inline P operator+(const P& p1, const P& p2) {
  return P(p1.first + p2.first, p1.second + p2.second);
}

int cave[1101][1101];

void MakeCave(int n) {
  memset(cave, 0, sizeof(cave));

  int y = 501;
  int x = 501;

  int dy[4] = { 1, 0, -1, 0 };
  int dx[4] = { 0, 1, 0, -1 };

  int dir = 0;
  for (int i = 1; i <= n; i++) {
    cave[y][x] = i;

    int ny = y + dy[(dir + 1) % 4];
    int nx = x + dx[(dir + 1) % 4];
    if (ny < 0 || ny >= 1100 || nx < 0 || nx >= 1100 || cave[ny][nx] == 0) {
      y = ny;
      x = nx;
      dir = (dir + 1) % 4;
    } else {
      y = y + dy[dir];
      x = x + dx[dir];
    }
  }
}

bool IsPrime(int num) {
  static bool is_prime[1000001];

  static bool init = false;

  if (!init) {
    fill(is_prime, is_prime + 1000001, true);
    init = true;
    is_prime[0] = false;
    is_prime[1] = false;
    for (int i = 2; i * i < 1000001; i++) {
      if (is_prime[i]) {
        for (int j = 2; i * j < 1000001; j++) {
          is_prime[i * j] = false;
        }
      }
    }
  }

  return is_prime[num];
}

P Solve(int n, int m) {
  int start_y = -1;
  int start_x = -1;

  for (int i = 0; start_x == -1 && i < 1101; i++) {
    for (int j = 0; start_x == -1 && j < 1101; j++) {
      if (cave[i][j] == m) {
        start_y = i;
        start_x = j;
      }
    }
  }

  struct Search {
    int y, x;
    int prime;
    int count;
    Search(): y(-1), x(-1), prime(0), count(0) { }
    Search(int y, int x, int prime, int count):
      y(y), x(x), prime(prime), count(count) { }
  };

  int dy[3] = {  1, 1, 1 };
  int dx[3] = { -1, 0, 1 };

  static bool checked[1101][1101];
  static Search memo[1101][1101];
  memset(checked, false, sizeof(checked));

  function<Search(int, int)> dfs = [&](int y, int x) {
    if (checked[y][x]) {
      return memo[y][x];
    }

    if (cave[y][x] == 0) {
      return Search(y, x, 0, 0);
    }

    Search s(y, x, 0, 0);
    if (IsPrime(cave[y][x])) {
      s.count++;
      s.prime = cave[y][x];
    }

    int count = 0;
    int prime = s.prime;
    for (int i = 0; i < 3; i++) {
      int ny = y + dy[i];
      int nx = x + dx[i];

      Search t = dfs(ny, nx);
      if (t.count > count) {
        count = t.count;
        prime = t.prime;
      } else if (t.count == count) {
        if (prime < t.prime) {
          prime = t.prime;
        }
      }
    }

    s.count += count;
    s.prime = prime;

    checked[y][x] = true;
    memo[y][x] = s;

    return s;
  };

  Search ans = dfs(start_y, start_x);

  return P(ans.count, ans.prime);
}

int main() {
  while (true) {
    int n, m;
    cin >> n >> m;
    if (n + m == 0) {
      break;
    }
    MakeCave(n);
    P ans = Solve(n, m);
    cout << ans.first << " " << ans.second << endl;
  }

  return 0;
}

Measured memory_bytes: 28892