#include <stdio.h>
#include <math.h>
#include <stdlib.h>
#include <string.h>

struct cave {
    int i;
    int j;
    int Kakomonn;
};

#define max(x,y) ( x>y?x:y )

int isPrime(int x){

    int i;

    if(x < 2 || x == 4) return 0;

    if(x == 2 || x == 3 || x == 5) return 1;

    else if((x>5 && ((x-1)%6==0 || ((x+1)%6==0))))
    {
        for(i=3;i<=sqrt(x);++i)
        {
            if(x%i==0) return 0;
        }
        return 1;
    }
    return 0;
}

int main()
{

    struct cave *cave; // 洞穴の番号と座標を格納する構造体

    cave = (struct cave*)malloc(sizeof(struct cave) * 1000001);

    int value[1000][1000];
    int map[1000][1000];
    int maxi;
//    int maxi[1000][1000];
//    memset(maxi, 0, sizeof(maxi));

    int tail, top;
    int i, j, k, limit, flag, cnt;

    // 石窟寺院建設工事
    k = 1000000;
    i = 0;
    j = 0;
    limit = 1000;
    flag = 0;
    cnt = 0;
    while(k > 0)
    {
        // 教典を素数洞穴に置く
        if(isPrime(k)){
            cave[k].Kakomonn = 1;
        }else{
            cave[k].Kakomonn = 0;
        }

        if(flag == 0) //右へ
        {
            map[i][j] = k;
            cave[k].i = i;
            cave[k].j = j;
//            maxi[i][j] = max(maxi[i][j], i);
            j++;

            cnt++;
            if(cnt == limit - 1)
            {
                flag = 1; // 方向を変える
                cnt = 0;
            }
        }
        else if(flag == 1) //下へ
        {
            map[i][j] = k;
            cave[k].i = i;
            cave[k].j = j;
//            maxi[i][j] = max(maxi[i][j], i);
            i++;

            cnt++;
            if(cnt == limit - 1)
            {
                flag = 2;
                cnt = 0;
            }
        }
        else if(flag == 2) //左へ
        {
            map[i][j] = k;
            cave[k].i = i;
            cave[k].j = j;
//            maxi[i][j] = max(maxi[i][j], i);
            j--;

            cnt++;
            if(cnt == limit - 1)
            {
                flag = 3;
                cnt = 0;
            }
        }
        else if(flag == 3) //上へ
        {
            map[i][j] = k;
            cave[k].i = i;
            cave[k].j = j;
//            maxi[i][j] = max(maxi[i][j], i);

            cnt++;
            if(cnt == limit - 1) // 内側のサークルへ
            {
                flag = 0;
                cnt = 0;
                limit -= 2;

                j++;
                k--;
                continue;
            }

            i--;
        }

        k--;
    }

    while(scanf("%d %d", &tail, &top) == 2 && tail && top)
    {
        memset(value, 0, sizeof(value));
//        memset(maxi, 0, sizeof(maxi));

        int l, r, Max_value = 0, Max_prime = 0, flag = 0;
        int k;

        l = cave[top].j;
        r = cave[top].j;

        maxi = cave[top].i;
        for(k = 1;k <= tail;++k)
        {
            maxi = max(maxi, cave[k].i);
        }

        for(i = cave[top].i; i <= maxi; ++i)
        {
            for(j = l; j <= r; ++j)
            {
                if(map[i][j] > tail)
                {
                    flag = 1;
                    break;
                }

                if(i-1 >= 0 && j-1 >= 0)
                {
                    value[i][j] = max(value[i][j], value[i-1][j-1]);
                }
                if(i-1 >= 0 && j+1 <= 999)
                {
                    value[i][j] = max(value[i][j], value[i-1][j+1]);
                }
                if(i-1 >= 0)
                {
                    value[i][j] = max(value[i][j], value[i-1][j]);
                }

                if(cave[ map[i][j] ].Kakomonn == 1)
                {
                    value[i][j]++;

                    if(value[i][j] > Max_value)
                    {
                        Max_value = value[i][j];

                        Max_prime = map[i][j];
                    }
                    else if(value[i][j] == Max_value)
                    {
                        if(map[i][j] > Max_prime)
                        {
                            Max_prime = map[i][j];
                        }
                    }
                }
            }

            if(flag) break;

            if(l - 1 > 0 && map[i+1][l-1] <= tail)
            {
                l -= 1;
            }
            else if(l - 1 > 0 && map[i+1][l] > tail)
            {
                l += 1;
            }

            if(r + 1 < 999 && map[i+1][r+1] <= tail){
                r += 1;
            }
        }

        printf("%d %d\n", Max_value, Max_prime);
//        printf("%d %d %d %d\n", t[m[l].i][m[l].j], m[l].i, m[l].j, m[l].Kakomonn);

    }

    free(cave);
    return 0;
}


Measured memory_bytes: 21044