/*
PROG: ariprog
LANG: C
*/

#include
<stdio.h>
#define max 62500
typedef 
struct N
{
    
int a, b;
}
N;
N M[max];
int T[max * 2];
int s[max];
int cmp(const void * a, const void *b)
{
    
if (((N*)a)->== ((N*)b)->b)
    
{
        
return ((N*)a)->- ((N*)b)->a;
    }

    
else
    
{
        
return ((N*)a)->- ((N*)b)->b;
    }


}

int Is(int a, int b, int k, int n)
{
    
int i, c = a;
    
for (i = 1; (c += b) <= s[k];)
    
{
        
if (!T[c])
        
{
            
return i;
        }

        
else
        
{
            i
++;
        }

        
if (i >= n)
        
{
            
return i;
        }

    }

    
return i;
}

int main()
{
    FILE 
* fin = fopen("ariprog.in","r");
    FILE 
* fout = fopen("ariprog.out""w");
    
int i, j, k, h, x, n, m, a, b, len, q, c;
    fscanf(fin, 
"%d%d"&n, &m);
    
//对所有的平方和打表,并用T:array[] 标记平方和的数为1,表示true 
    for (i = 0, k = 0; i <= m; i++)
    
{
        
for (j = i; j <= m; j++)
        
{
            c 
= i * i + j * j;
            
if (!T[c])
            
{
                T[c] 
= 1;
                s[k
++= c;
            }

        }

    }

    x 
= 0;
    q 
= k - n + 1;//因为最后的要保证至少存在n个数,才能构成n长的数列 
    printf("%d", k);
    
//因为等差数列有y = a + k * b(k >=0);
    
//所以对于题目要求, 最大元素是m * m * 2,令a=0,最大公比是m * m * 2 / n,加个10是随意加的,保证数据安全 
    c = m * m * 2 / n + 10;
    
for (i = 0; i < q; i++)
    
{
        a 
= s[i];
        
for (j = 1; j <= c; j++)
        
{
            b 
= j;
            len 
= Is(a, b, k - 1, n);
            
if (len >= n)
            
{
                M[x].a 
= a;
                M[x
++].b = b;
            }

        }

    }
    
    qsort(M, x, 
sizeof(N), cmp);
    
if (x == 0)
    
{
        fprintf(fout, 
"NONE\n");
    }

    
for (i = 0; i < x; i++)
    
{
        fprintf(fout, 
"%d %d\n", M[i].a, M[i].b);
    }

    system(
"pause");
    
return 0;
}