//http://poj.org/problem?id=2689
#include <bitset>
#include <iostream>
#include <vector>
#include <algorithm>
#include <cmath>
using namespace std;
typedef unsigned int uint;
/*
原理:
1) 2的倍数都是合数(2除外)
2) 给定一个N, N*i(i>1)都是合数
算法:
1) 假设所有数都是素数
2) 2的倍数为合数
3) 设3<=N<=sqrt(U)+1且N为奇数,则N * i(i>1)的倍数为合数
*/
bool* GetPrimeNumbers(uint L, uint U,bool Cands[])
{
const uint N = U-L +1;
memset(Cands,1,N);
for(uint i = L%2==0?0:1;i<N;i+=2)
{
Cands[i] = false;
}
uint end = sqrt((double)U)+1;
for(uint i = 3;i<end;i+=2)
{
if(i>=L&&Cands[i-L]==false) //i是合数,不需要继续筛选
continue;
uint j = L/i*i;
if(j<L)
{
j+=i;
}
if(j==i)
j+=i;
for(j = j-L;j<N;j+=i)
{
Cands[j] = false;
}
}
if(L==2)
Cands[0] = true;
return Cands;
}
bool GetMinMax(bool * Cands,const uint N,int &C1,int &C2, int&D1,int &D2)
{
C1 = C2 = D1 =D2 = -1;
int pre = 0;
int min = 0;
int max = 0;
for(uint i =0;i<N;++i)
{
if(Cands[i]==true)
{
if(C1 == -1)
{
C1 = D1 = i;
}
else if(C2 == -1)
{
C2 =D2 = i;
min = max = C2 -C1;
}
else
{
if(i-pre<min)
{
C1 = pre;
C2 = i;
min = C2-C1;
}
else if(i- pre > max)
{
D1 = pre;
D2 = i;
max = D2 -D1;
}
}
pre =i;
}
}
return min != 0;
}
bool GetMinMax(uint L,uint U,int &C1,int &C2, int&D1,int &D2)
{
if(L<2)
L=2;
static uint const SIZE = 10000002;
static bool Cands[SIZE];
const uint N = U-L +1;
GetPrimeNumbers(L,U,Cands);
if(GetMinMax(Cands,N,C1,C2,D1,D2))
{
C1+=L;
C2+=L;
D1+=L;
D2+=L;
return true;
}
return false;
}
int main()
{
uint L,U;
while(cin>>L>>U)
{
int C1,C2,D1,D2;
if(GetMinMax(L,U,C1,C2,D1,D2))
{
printf("%d,%d are closest, %d,%d are most distant.\n",C1,C2,D1,D2);
}
else
{
printf("There are no adjacent primes.\n");
}
}
return 0;
}