#include <iostream>
#include <vector>
#include <chrono>
#include <ctime>
#include <cmath>
#define LOG2(X) ((unsigned) (8*sizeof (unsigned long long) - __builtin_clzll((X)) - 1))
using namespace std;
typedef uint64_t ntype;
////////////////////////////////////////////////////////////////////////////////
struct Task_my
{ ntype result;
Task_my(ntype from, ntype to)
{ for(ntype i = from; i <= to; i += 2)
{ if(is_simple(i)) result = i;
}
}
bool is_simple(ntype n)
{ for(ntype i = 3; i < sqrt(n); i += 2)
{ if(n%i == 0) return false;
}
return true;
}
};
////////////////////////////////////////////////////////////////////////////////
struct Task_ferma
{ ntype result;
Task_ferma(ntype from, ntype to)
{ for(ntype i = from; i <= to; i += 2)
{ if(ferma(i)) result = i;
}
}
bool ferma(ntype x)
{ if(x == 2) return true;
srand(time(NULL));
ntype k = LOG2(x) + 2;
for(ntype i = 0; i<k; i++)
{ ntype a = (rand() % (x - 2)) + 2;
if (gcd(a, x) != 1) return false;
if( pows(a, x-1, x) != 1) return false;
}
return true;
}
ntype gcd(ntype a, ntype b)
{ if(b==0) return a;
return gcd(b, a%b);
}
ntype pows(ntype a, ntype b, ntype m)
{ if(b==0)
return 1;
if(b%2==0)
{ ntype t = pows(a, b/2, m);
return mul(t , t, m) % m;
}
return ( mul(pows(a, b-1, m) , a, m)) % m;
}
ntype mul(ntype a, ntype b, ntype m)
{ if(b==1)
return a;
if(b%2==0)
{ ntype t = mul(a, b/2, m);
return (2 * t) % m;
}
return (mul(a, b-1, m) + a) % m;
}
};
int main() {
ntype min_number = 4000000000001ull;
ntype max_number = 4000000010000ull;
ntype cur_number = 1;
ntype result = 1;
using time = std::chrono::duration<double, std::milli>;
////////////////////////////////////////////////////////////////////////////
auto s3 = std::chrono::high_resolution_clock::now();
Task_ferma task3(min_number, max_number);
auto t3 = std::chrono::high_resolution_clock::now() - s3;
cout << "ferma:" << task3.result <<
" time: " << time(t3).count() << "ms\n";
////////////////////////////////////////////////////////////////////////////
auto s2 = std::chrono::high_resolution_clock::now();
Task_my task2(min_number, max_number);
auto t2 = std::chrono::high_resolution_clock::now() - s2;
cout << "my: " << task2.result <<
" time: " << time(t2).count() << "ms\n";
return 0;
}