#include <bits/stdc++.h>

class Solve {
private:
	using vi = std::vector<int>;
	using vvi = std::vector<vi>;

	using vb = std::vector<bool>;
	using vvb = std::vector<vb>;
public:
	bool is_last_query{};
	Solve()
	{
		int m, n;
		scanf("%d%d", &m, &n);
		if (m == 0)
		{
			is_last_query = true;
			return;
		}
		vvi number(1100, vi(1100, -1));
		int place[2]{550, 550}, begin[2]{550, 550};
		int dir[4][2]{{1, 0}, {0, -1}, {-1, 0}, {0, 1}}, now_dir{};
		number[place[0]][place[1]] = 1;
		place[0] += dir[now_dir][0];
		place[1] += dir[now_dir][1];
		for (int i{2}; i <= m; i++)
		{
			if (i == n)
			{
				begin[0] = place[0];
				begin[1] = place[1];
			}
			number[place[0]][place[1]] = i;
			if (number[place[0] + dir[(now_dir + 1) % 4][0]][place[1] + dir[(now_dir + 1) % 4][1]] < 0)
				now_dir = (now_dir + 1) % 4;
			place[0] += dir[now_dir][0];
			place[1] += dir[now_dir][1];
		}

		vb isPrime(m + 1, true);
		isPrime[1] = false;
		for (int i{2}; i <= m; i++)
		{
			if (!isPrime[i]) continue;
			for (int j{2 * i}; j <= m; j += i)
				isPrime[j] = false;
		}

		vvb visited(1100, vb(1100));

		std::queue<std::pair<int, int>> que;
		que.push({begin[0], begin[1]});

		vvi maxTable(1100, vi(1100, 0));
		std::pair<int, int> max;
		while (!que.empty())
		{
			auto now{que.front()};
			que.pop();
			if (visited[now.first][now.second] || number[now.first][now.second] < 0) continue;
			visited[now.first][now.second] = true;
			auto& now_max{maxTable[now.first][now.second]};
			for (int i{now.first - 1}; i <= now.first + 1; i++)
				now_max = std::max(now_max, maxTable[i][now.second - 1]);
			if (isPrime[number[now.first][now.second]])
			{
				now_max++;
				max = std::max(max, {now_max, number[now.first][now.second]});
			}
			for (int i{now.first - 1}; i <= now.first + 1; i++)
				que.push({i, now.second + 1});
		}
		printf("%d %d\n", max.first, max.second);
	}
};

int main()
{
	while (!Solve().is_last_query);

	return 0;
}
