#include <iostream>
#include <vector>

using namespace std;

class range {
private:
  struct Iterator {
    int val;
    int operator*() {return val;}
    bool operator!=(Iterator& itr) {return val < itr.val;}
    void operator++() {++val;}
  };
  Iterator i, n;
public:
  range(int n) : i({0}), n({n}) {}
  range(int i, int n) : i({i}), n({n}) {}
  Iterator& begin() {return i;}
  Iterator& end() {return n;}
};

template<class T> inline T at(const vector<T> &v, int i) {return v[(i % (int)v.size() + v.size()) % v.size()];}

template<class T> inline bool is_max(T &a, const T &b) {return a < b ? a = b, true : false;}
template<class T> inline bool is_min(T &a, const T &b) {return a > b ? a = b, true : false;}

int maze[2000][2000];
const int dx[] = {1, 0, -1, 0};
const int dy[] = {0, -1, 0, 1};
pair<int, int> dp[2000][2000];

#include <algorithm>

class Prime {
private:
  vector<long long> divisor;
  
  vector<long long> _factor(long long n) {
    if (n == 1) return vector<long long>();
    if (n < (long long)divisor.size()) {
      if (divisor[n] == 0) {
        return vector<long long>(1, n);
      } else {
        vector<long long> ans = _factor(n / divisor[n]);
        ans.emplace_back(divisor[n]);
        return ans;
      }
    }
    for (int i = divisor.size(); i <= n / i; ++i) if (n % i == 0) {
      vector<long long> ans = _factor(n / i);
      ans.emplace_back(i);
      return ans;
    }
    return vector<long long>(1, n);
  }
  
public:
  Prime() {divisor = vector<long long>(2, 1);}
  
  Prime(long long n) {
    divisor = vector<long long>(n, 0);
    divisor[0] = divisor[1] = 1;
    for (long long i = 2; i <= n / i; ++i) if (divisor[i] == 0) {
      for (long long j = i * i; j < n; j += i) divisor[j] = i;
    }
  }
  
  bool is_prime(long long n) {
    if (n < (long long)divisor.size()) return divisor[n] == 0;
    for (long long i = divisor.size(); i <= n / i; ++i) if (n % i == 0) return false;
    return true;
  }
  
  vector<long long> factor(long long n) {
    if (n == 1) return vector<long long>(1, 1);
    vector<long long> ans = _factor(n);
    sort(ans.begin(), ans.end());
    return ans;
  }
  
  vector<long long> get_divisors(long long n) {
    vector<long long> ans;
    for (long long i = 1; i * i <= n; ++i) if (n % i == 0) {
      ans.emplace_back(i);
      if (i * i != n) ans.emplace_back(n / i);
    }
    sort(ans.begin(), ans.end());
    return ans;
  }
};

int main() {
  int y = 1000, x = 1000;
  int t = 1, s = 2, ss = 1, d = 0;
  for (int i : range(1, 1000001)) {
    maze[y][x] = t++;
    if (ss == 0) {
      ss = ++s / 2;
      d = (d + 1) % 4;
    }
    y += dy[d];
    x += dx[d];
    --ss;
  }
  Prime prime;
  while (true) {
    int m, n;
    cin >> m >> n;
    if (m == 0 && n == 0) break;
    for (int i : range(2000)) for (int j : range(2000)) dp[i][j] = make_pair(-1, 0);
    for (int i : range(2000)) for (int j : range(2000)) if (maze[i][j] == n) dp[i][j] = make_pair(0, 0);
    for (int i : range(1999)) for (int j : range(1, 1999)) if (dp[i][j].first != -1) {
      if (maze[i][j] <= m && prime.is_prime(maze[i][j])) {
        is_max(dp[i + 1][j + 1], make_pair(dp[i][j].first + 1, maze[i][j]));
        is_max(dp[i + 1][j    ], make_pair(dp[i][j].first + 1, maze[i][j]));
        is_max(dp[i + 1][j - 1], make_pair(dp[i][j].first + 1, maze[i][j]));
      } else {
        is_max(dp[i + 1][j + 1], dp[i][j]);
        is_max(dp[i + 1][j    ], dp[i][j]);
        is_max(dp[i + 1][j - 1], dp[i][j]);
      }
    }
    pair<int, int> res = make_pair(0, 0);
    for (int i : range(2000)) is_max(res, dp[1999][i]);
    cout << res.first << " " << res.second << endl;
  }
}

Measured memory_bytes: 46244