#include "fmpz.h"
#include "fmpz_mod.h"
static const unsigned char _eight_primes[8] = {2, 5, 7, 11, 13, 17, 19, 23};
static const unsigned char _smooth_prime_lut[][8] =
{
{0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02},
{0x04, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00},
{0x04, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00},
{0x03, 0x00, 0x03, 0x00, 0x00, 0x01, 0x00, 0x00},
{0x02, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02},
{0x04, 0x02, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00},
{0x01, 0x03, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00},
{0x01, 0x00, 0x00, 0x00, 0x03, 0x01, 0x00, 0x00},
{0x06, 0x02, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x04, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00},
{0x06, 0x00, 0x00, 0x02, 0x00, 0x00, 0x01, 0x00},
{0x05, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00},
{0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02},
{0x02, 0x00, 0x00, 0x00, 0x03, 0x00, 0x01, 0x00},
{0x07, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00},
{0x03, 0x00, 0x01, 0x00, 0x00, 0x03, 0x00, 0x00},
{0x03, 0x03, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00},
{0x03, 0x03, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00},
{0x04, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x02},
{0x02, 0x00, 0x00, 0x00, 0x00, 0x02, 0x02, 0x00},
{0x02, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x03},
{0x06, 0x02, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00},
{0x02, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x02},
{0x03, 0x00, 0x00, 0x00, 0x00, 0x03, 0x01, 0x00},
{0x06, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02},
{0x05, 0x00, 0x01, 0x00, 0x00, 0x03, 0x00, 0x00},
{0x01, 0x00, 0x00, 0x02, 0x00, 0x03, 0x00, 0x00},
{0x05, 0x00, 0x00, 0x00, 0x03, 0x01, 0x00, 0x00},
{0x04, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00},
{0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03},
{0x08, 0x00, 0x02, 0x00, 0x02, 0x00, 0x00, 0x00},
{0x03, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03},
{0x04, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x02},
{0x04, 0x04, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00},
{0x03, 0x00, 0x00, 0x03, 0x00, 0x02, 0x00, 0x00},
{0x04, 0x00, 0x00, 0x02, 0x03, 0x00, 0x00, 0x00},
{0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04},
{0x07, 0x00, 0x00, 0x00, 0x03, 0x01, 0x00, 0x00},
{0x05, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x03},
{0x08, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x02},
{0x06, 0x00, 0x02, 0x00, 0x03, 0x00, 0x00, 0x00},
{0x04, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00},
{0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00},
{0x08, 0x00, 0x00, 0x00, 0x03, 0x00, 0x01, 0x00},
{0x07, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x03},
{0x08, 0x00, 0x00, 0x00, 0x02, 0x02, 0x00, 0x00},
{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05},
{0x02, 0x00, 0x00, 0x04, 0x00, 0x02, 0x00, 0x00},
{0x06, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02},
{0x01, 0x00, 0x00, 0x00, 0x03, 0x03, 0x00, 0x00},
{0x08, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x02},
{0x08, 0x00, 0x03, 0x00, 0x00, 0x02, 0x00, 0x00},
{0x07, 0x00, 0x02, 0x00, 0x00, 0x03, 0x00, 0x00},
{0x02, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x02},
{0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x03},
{0x07, 0x03, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00},
{0x04, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00},
{0x06, 0x00, 0x00, 0x00, 0x03, 0x02, 0x00, 0x00},
{0x01, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x03},
{0x02, 0x00, 0x00, 0x00, 0x03, 0x00, 0x03, 0x00},
{0x02, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x02},
{0x06, 0x00, 0x00, 0x00, 0x01, 0x04, 0x00, 0x00},
{0x04, 0x00, 0x03, 0x04, 0x00, 0x00, 0x00, 0x00},
{0x06, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x02},
{0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x04, 0x00},
{0x07, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x02},
{0x05, 0x00, 0x04, 0x03, 0x00, 0x00, 0x00, 0x00},
{0x07, 0x00, 0x00, 0x00, 0x02, 0x03, 0x00, 0x00},
{0x04, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04},
{0x08, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00},
{0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x02, 0x00},
{0x03, 0x05, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00},
{0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x04},
{0x06, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x04},
{0x03, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x03},
{0x04, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03},
{0x06, 0x00, 0x02, 0x00, 0x00, 0x04, 0x00, 0x00},
{0x01, 0x00, 0x00, 0x00, 0x04, 0x03, 0x00, 0x00},
{0x05, 0x00, 0x00, 0x03, 0x00, 0x00, 0x03, 0x00},
{0x08, 0x00, 0x00, 0x00, 0x02, 0x00, 0x03, 0x00},
{0x03, 0x00, 0x00, 0x03, 0x04, 0x00, 0x00, 0x00},
{0x02, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x04},
{0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x04},
{0x07, 0x00, 0x00, 0x03, 0x03, 0x00, 0x00, 0x00},
{0x04, 0x00, 0x00, 0x00, 0x00, 0x04, 0x02, 0x00},
{0x04, 0x00, 0x04, 0x04, 0x00, 0x00, 0x00, 0x00},
{0x06, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x02},
{0x07, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x04},
{0x04, 0x00, 0x03, 0x00, 0x00, 0x00, 0x04, 0x00},
{0x05, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x03},
{0x06, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x04},
{0x09, 0x00, 0x00, 0x00, 0x00, 0x03, 0x02, 0x00},
{0x06, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x02},
{0x09, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x03},
{0x05, 0x00, 0x00, 0x00, 0x00, 0x01, 0x05, 0x00},
{0x03, 0x00, 0x00, 0x02, 0x00, 0x05, 0x00, 0x00},
{0x06, 0x00, 0x00, 0x00, 0x02, 0x00, 0x04, 0x00},
{0x05, 0x00, 0x00, 0x05, 0x00, 0x02, 0x00, 0x00},
{0x08, 0x00, 0x05, 0x00, 0x00, 0x00, 0x02, 0x00},
{0x09, 0x04, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00},
{0x09, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04},
{0x06, 0x00, 0x00, 0x04, 0x03, 0x00, 0x00, 0x00},
{0x03, 0x05, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00},
{0x05, 0x00, 0x00, 0x04, 0x00, 0x03, 0x00, 0x00},
{0x07, 0x05, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00},
{0x03, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x03},
{0x06, 0x00, 0x03, 0x00, 0x00, 0x00, 0x04, 0x00},
{0x03, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x04},
{0x04, 0x00, 0x04, 0x00, 0x00, 0x04, 0x00, 0x00},
{0x07, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x03},
{0x08, 0x00, 0x00, 0x00, 0x03, 0x00, 0x03, 0x00},
{0x08, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03},
{0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x02},
{0x04, 0x00, 0x04, 0x00, 0x00, 0x00, 0x04, 0x00},
{0x05, 0x00, 0x00, 0x03, 0x00, 0x00, 0x04, 0x00},
{0x06, 0x00, 0x00, 0x04, 0x00, 0x00, 0x03, 0x00},
{0x05, 0x03, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00},
{0x06, 0x03, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00},
{0x08, 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00},
{0x07, 0x00, 0x00, 0x03, 0x00, 0x04, 0x00, 0x00},
{0x04, 0x00, 0x00, 0x04, 0x00, 0x04, 0x00, 0x00},
{0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x02},
{0x0b, 0x00, 0x00, 0x00, 0x03, 0x03, 0x00, 0x00},
{0x03, 0x00, 0x00, 0x00, 0x03, 0x05, 0x00, 0x00},
{0x06, 0x00, 0x00, 0x00, 0x00, 0x04, 0x03, 0x00},
{0x04, 0x00, 0x00, 0x00, 0x04, 0x04, 0x00, 0x00},
{0x0a, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x02},
{0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x04, 0x00},
{0x0b, 0x00, 0x00, 0x00, 0x00, 0x03, 0x03, 0x00},
{0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x02},
{0x06, 0x00, 0x00, 0x03, 0x00, 0x05, 0x00, 0x00},
{0x07, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x03},
{0x05, 0x00, 0x00, 0x05, 0x04, 0x00, 0x00, 0x00},
{0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06},
{0x05, 0x00, 0x00, 0x00, 0x02, 0x03, 0x03, 0x00},
{0x08, 0x00, 0x00, 0x00, 0x00, 0x02, 0x05, 0x00},
{0x04, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x02},
{0x02, 0x00, 0x00, 0x00, 0x04, 0x00, 0x05, 0x00},
{0x03, 0x00, 0x00, 0x04, 0x00, 0x03, 0x00, 0x02},
{0x08, 0x00, 0x00, 0x04, 0x00, 0x04, 0x00, 0x00},
{0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x05},
{0x06, 0x00, 0x04, 0x00, 0x00, 0x00, 0x05, 0x00},
{0x05, 0x00, 0x00, 0x00, 0x00, 0x03, 0x03, 0x02},
{0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x04},
{0x0b, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x04},
{0x04, 0x00, 0x00, 0x00, 0x05, 0x00, 0x04, 0x00},
{0x09, 0x00, 0x00, 0x00, 0x05, 0x03, 0x00, 0x00},
{0x08, 0x05, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00},
{0x0c, 0x00, 0x00, 0x00, 0x03, 0x00, 0x04, 0x00},
{0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x04},
{0x06, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x05},
{0x08, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x05},
{0x04, 0x00, 0x00, 0x00, 0x00, 0x06, 0x03, 0x00},
{0x07, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x03},
{0x06, 0x00, 0x00, 0x00, 0x05, 0x00, 0x04, 0x00},
{0x03, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x04},
{0x0c, 0x00, 0x00, 0x04, 0x00, 0x04, 0x00, 0x00},
{0x02, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x04},
{0x05, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x06},
{0x06, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x04},
{0x09, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x05},
{0x0e, 0x00, 0x00, 0x00, 0x00, 0x04, 0x03, 0x00},
{0x08, 0x00, 0x00, 0x03, 0x00, 0x03, 0x03, 0x00},
{0x09, 0x00, 0x05, 0x00, 0x00, 0x05, 0x00, 0x00},
{0x02, 0x00, 0x00, 0x00, 0x00, 0x06, 0x04, 0x00},
{0x06, 0x00, 0x00, 0x00, 0x00, 0x04, 0x05, 0x00},
{0x03, 0x00, 0x00, 0x00, 0x03, 0x04, 0x00, 0x03},
{0x0c, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04},
{0x0d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x05},
{0x07, 0x00, 0x00, 0x00, 0x03, 0x00, 0x03, 0x03},
{0x03, 0x00, 0x00, 0x00, 0x03, 0x03, 0x00, 0x04},
{0x07, 0x00, 0x00, 0x00, 0x07, 0x03, 0x00, 0x00},
{0x09, 0x00, 0x00, 0x02, 0x00, 0x03, 0x04, 0x00},
{0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x02, 0x05},
{0x06, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x04},
{0x0c, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x02},
{0x08, 0x00, 0x00, 0x06, 0x00, 0x00, 0x04, 0x00},
{0x06, 0x04, 0x00, 0x03, 0x00, 0x05, 0x00, 0x00},
{0x06, 0x00, 0x00, 0x00, 0x03, 0x04, 0x03, 0x00},
{0x09, 0x00, 0x00, 0x02, 0x00, 0x03, 0x00, 0x04},
{0x0c, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x04},
{0x07, 0x00, 0x00, 0x00, 0x04, 0x03, 0x03, 0x00},
{0x09, 0x00, 0x00, 0x00, 0x02, 0x00, 0x04, 0x03},
{0x05, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x04},
{0x0c, 0x00, 0x00, 0x00, 0x05, 0x00, 0x04, 0x00},
{0x0a, 0x00, 0x00, 0x00, 0x00, 0x04, 0x05, 0x00},
{0x08, 0x00, 0x00, 0x00, 0x05, 0x00, 0x05, 0x00},
{0x08, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x05},
{0x06, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x06},
{0x07, 0x00, 0x00, 0x06, 0x00, 0x05, 0x00, 0x00},
{0x05, 0x00, 0x00, 0x03, 0x04, 0x00, 0x00, 0x04},
{0x05, 0x00, 0x00, 0x04, 0x00, 0x05, 0x00, 0x02},
{0x0b, 0x00, 0x00, 0x00, 0x03, 0x00, 0x03, 0x03},
{0x07, 0x00, 0x00, 0x00, 0x03, 0x03, 0x00, 0x04},
{0x09, 0x00, 0x00, 0x03, 0x00, 0x04, 0x03, 0x00},
{0x0a, 0x00, 0x00, 0x04, 0x00, 0x02, 0x04, 0x00},
{0x06, 0x00, 0x00, 0x00, 0x00, 0x02, 0x04, 0x04},
{0x05, 0x00, 0x00, 0x00, 0x04, 0x05, 0x00, 0x02},
{0x0d, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x05},
{0x08, 0x00, 0x00, 0x00, 0x00, 0x04, 0x06, 0x00},
{0x0b, 0x00, 0x00, 0x00, 0x05, 0x05, 0x00, 0x00},
{0x04, 0x00, 0x03, 0x00, 0x00, 0x04, 0x05, 0x00},
{0x0a, 0x00, 0x00, 0x04, 0x00, 0x02, 0x00, 0x04},
{0x04, 0x00, 0x00, 0x06, 0x00, 0x00, 0x06, 0x00},
{0x08, 0x00, 0x00, 0x00, 0x07, 0x04, 0x00, 0x00},
{0x0d, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x05},
{0x09, 0x00, 0x00, 0x05, 0x00, 0x06, 0x00, 0x00},
{0x08, 0x00, 0x00, 0x04, 0x03, 0x00, 0x00, 0x04},
{0x09, 0x00, 0x00, 0x00, 0x06, 0x05, 0x00, 0x00},
{0x07, 0x00, 0x00, 0x00, 0x04, 0x04, 0x00, 0x03},
{0x07, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x05},
{0x0d, 0x00, 0x00, 0x00, 0x05, 0x05, 0x00, 0x00},
{0x0a, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x06},
{0x0a, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x07},
{0x0a, 0x00, 0x04, 0x00, 0x00, 0x00, 0x03, 0x04},
{0x06, 0x00, 0x00, 0x00, 0x03, 0x00, 0x04, 0x04},
{0x09, 0x00, 0x00, 0x04, 0x00, 0x05, 0x00, 0x02},
{0x04, 0x00, 0x00, 0x00, 0x04, 0x06, 0x00, 0x02},
{0x05, 0x00, 0x03, 0x00, 0x00, 0x04, 0x00, 0x05},
{0x0a, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x04},
{0x02, 0x00, 0x00, 0x00, 0x00, 0x05, 0x04, 0x03},
{0x0a, 0x00, 0x00, 0x00, 0x05, 0x06, 0x00, 0x00},
{0x0e, 0x00, 0x00, 0x00, 0x04, 0x06, 0x00, 0x00},
{0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x07},
{0x0f, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x04},
{0x08, 0x00, 0x04, 0x00, 0x00, 0x04, 0x00, 0x04},
{0x0e, 0x00, 0x00, 0x00, 0x05, 0x00, 0x05, 0x00},
{0x0a, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x04},
{0x03, 0x00, 0x00, 0x04, 0x00, 0x05, 0x04, 0x00},
{0x08, 0x00, 0x04, 0x00, 0x00, 0x00, 0x04, 0x04},
{0x06, 0x06, 0x00, 0x00, 0x00, 0x04, 0x00, 0x04},
{0x07, 0x00, 0x03, 0x00, 0x00, 0x04, 0x00, 0x05},
{0x04, 0x00, 0x00, 0x04, 0x05, 0x00, 0x00, 0x04},
{0x0d, 0x00, 0x00, 0x00, 0x00, 0x05, 0x05, 0x00},
{0x05, 0x03, 0x00, 0x00, 0x00, 0x05, 0x00, 0x05},
{0x09, 0x00, 0x04, 0x00, 0x00, 0x00, 0x05, 0x03},
{0x05, 0x00, 0x00, 0x00, 0x00, 0x05, 0x07, 0x00},
{0x07, 0x00, 0x00, 0x00, 0x04, 0x03, 0x05, 0x00},
{0x0b, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x06},
{0x09, 0x00, 0x00, 0x00, 0x03, 0x00, 0x03, 0x05},
{0x0d, 0x00, 0x00, 0x00, 0x06, 0x05, 0x00, 0x00},
{0x0a, 0x00, 0x03, 0x00, 0x00, 0x04, 0x05, 0x00},
{0x09, 0x00, 0x00, 0x05, 0x00, 0x00, 0x07, 0x00},
{0x04, 0x00, 0x00, 0x00, 0x04, 0x06, 0x03, 0x00},
{0x06, 0x05, 0x00, 0x00, 0x00, 0x05, 0x00, 0x04},
{0x05, 0x00, 0x00, 0x00, 0x00, 0x05, 0x03, 0x04},
{0x06, 0x00, 0x00, 0x00, 0x03, 0x00, 0x05, 0x04},
{0x08, 0x00, 0x00, 0x03, 0x00, 0x05, 0x00, 0x04},
{0x08, 0x06, 0x00, 0x00, 0x00, 0x00, 0x04, 0x04},
{0x04, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x06},
{0x05, 0x00, 0x00, 0x05, 0x00, 0x03, 0x00, 0x05},
{0x0b, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x03},
{0x08, 0x00, 0x00, 0x00, 0x00, 0x08, 0x04, 0x00},
{0x04, 0x00, 0x00, 0x00, 0x03, 0x06, 0x00, 0x04},
{0x07, 0x00, 0x00, 0x00, 0x00, 0x06, 0x03, 0x03},
{0x0b, 0x00, 0x00, 0x00, 0x00, 0x04, 0x04, 0x03},
{0x05, 0x00, 0x05, 0x00, 0x00, 0x04, 0x00, 0x05},
{0x0a, 0x00, 0x05, 0x00, 0x00, 0x05, 0x00, 0x03},
{0x07, 0x00, 0x00, 0x04, 0x00, 0x05, 0x04, 0x00},
{0x06, 0x00, 0x00, 0x00, 0x04, 0x04, 0x05, 0x00},
{0x03, 0x00, 0x00, 0x00, 0x00, 0x04, 0x06, 0x03},
{0x08, 0x00, 0x00, 0x04, 0x05, 0x00, 0x00, 0x04},
{0x0a, 0x00, 0x00, 0x04, 0x00, 0x03, 0x00, 0x05},
{0x0c, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x05},
{0x0b, 0x00, 0x00, 0x05, 0x00, 0x00, 0x03, 0x04},
{0x09, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x07},
{0x08, 0x05, 0x00, 0x00, 0x00, 0x00, 0x04, 0x05},
{0x06, 0x00, 0x00, 0x00, 0x05, 0x03, 0x00, 0x05},
{0x02, 0x00, 0x00, 0x00, 0x04, 0x06, 0x00, 0x04},
{0x0b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x07},
{0x08, 0x00, 0x00, 0x00, 0x05, 0x04, 0x04, 0x00},
{0x05, 0x00, 0x00, 0x05, 0x00, 0x04, 0x05, 0x00},
{0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x04},
{0x04, 0x00, 0x00, 0x00, 0x00, 0x03, 0x05, 0x05},
{0x06, 0x00, 0x00, 0x00, 0x08, 0x06, 0x00, 0x00},
{0x04, 0x00, 0x00, 0x06, 0x05, 0x00, 0x04, 0x00},
{0x09, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x06},
{0x03, 0x00, 0x00, 0x00, 0x05, 0x04, 0x00, 0x05},
{0x0a, 0x00, 0x04, 0x00, 0x00, 0x00, 0x05, 0x04},
{0x04, 0x00, 0x00, 0x05, 0x00, 0x00, 0x04, 0x05},
{0x09, 0x00, 0x00, 0x04, 0x00, 0x06, 0x00, 0x03},
{0x09, 0x00, 0x06, 0x00, 0x04, 0x05, 0x00, 0x00},
{0x09, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x05},
{0x0a, 0x00, 0x06, 0x00, 0x00, 0x04, 0x00, 0x04},
{0x0a, 0x00, 0x00, 0x04, 0x00, 0x04, 0x05, 0x00},
{0x0a, 0x00, 0x03, 0x00, 0x00, 0x05, 0x00, 0x05},
{0x04, 0x00, 0x00, 0x03, 0x00, 0x06, 0x00, 0x05},
{0x05, 0x00, 0x00, 0x00, 0x05, 0x06, 0x00, 0x03},
{0x04, 0x00, 0x00, 0x00, 0x04, 0x05, 0x00, 0x05},
{0x0c, 0x00, 0x00, 0x00, 0x04, 0x00, 0x04, 0x04},
{0x08, 0x00, 0x07, 0x00, 0x00, 0x04, 0x00, 0x04},
{0x0a, 0x00, 0x00, 0x05, 0x00, 0x00, 0x05, 0x03},
{0x03, 0x00, 0x00, 0x00, 0x00, 0x06, 0x05, 0x03},
{0x09, 0x00, 0x00, 0x04, 0x00, 0x00, 0x04, 0x05},
{0x0b, 0x00, 0x05, 0x00, 0x00, 0x05, 0x04, 0x00},
{0x07, 0x00, 0x00, 0x00, 0x00, 0x05, 0x04, 0x04},
{0x08, 0x00, 0x00, 0x05, 0x04, 0x00, 0x00, 0x05},
{0x0a, 0x00, 0x00, 0x00, 0x05, 0x04, 0x00, 0x04},
{0x07, 0x00, 0x00, 0x06, 0x04, 0x05, 0x00, 0x00},
{0x07, 0x00, 0x03, 0x00, 0x00, 0x05, 0x00, 0x06},
{0x07, 0x00, 0x00, 0x03, 0x05, 0x00, 0x00, 0x06},
{0x0a, 0x00, 0x00, 0x05, 0x06, 0x00, 0x00, 0x03},
{0x0b, 0x00, 0x05, 0x00, 0x00, 0x06, 0x00, 0x03},
{0x02, 0x00, 0x00, 0x05, 0x00, 0x00, 0x05, 0x05},
{0x0a, 0x00, 0x00, 0x04, 0x04, 0x06, 0x00, 0x00},
{0x05, 0x00, 0x07, 0x00, 0x00, 0x05, 0x00, 0x04},
{0x0a, 0x00, 0x05, 0x00, 0x04, 0x06, 0x00, 0x00},
{0x05, 0x00, 0x04, 0x00, 0x00, 0x05, 0x00, 0x06},
{0x08, 0x00, 0x00, 0x05, 0x00, 0x05, 0x00, 0x04},
{0x08, 0x00, 0x00, 0x06, 0x00, 0x00, 0x04, 0x04},
{0x0d, 0x00, 0x00, 0x08, 0x06, 0x08, 0x00, 0x07},
{0x03, 0x00, 0x00, 0x00, 0x07, 0x08, 0x08, 0x07},
{0x0e, 0x00, 0x00, 0x00, 0x05, 0x07, 0x06, 0x09},
{0x08, 0x07, 0x00, 0x00, 0x00, 0x08, 0x07, 0x09},
{0x08, 0x00, 0x00, 0x00, 0x09, 0x06, 0x06, 0x08},
{0x14, 0x00, 0x00, 0x00, 0x00, 0x07, 0x09, 0x09},
{0x09, 0x00, 0x00, 0x07, 0x00, 0x08, 0x06, 0x08},
{0x0b, 0x00, 0x00, 0x08, 0x09, 0x07, 0x00, 0x06},
{0x0c, 0x00, 0x00, 0x00, 0x07, 0x06, 0x09, 0x06},
{0x0e, 0x00, 0x00, 0x08, 0x00, 0x06, 0x06, 0x08},
{0x0a, 0x00, 0x00, 0x07, 0x00, 0x09, 0x07, 0x06},
{0x0e, 0x00, 0x00, 0x07, 0x00, 0x07, 0x08, 0x06},
{0x17, 0x00, 0x00, 0x00, 0x0d, 0x0b, 0x07, 0x0a},
{0x1c, 0x00, 0x00, 0x00, 0x07, 0x0b, 0x0a, 0x0b},
{0x17, 0x00, 0x00, 0x00, 0x07, 0x0b, 0x08, 0x0e},
{0x1c, 0x00, 0x00, 0x0a, 0x00, 0x0a, 0x0a, 0x0a},
{0x1a, 0x00, 0x00, 0x00, 0x0b, 0x07, 0x0d, 0x09},
{0x18, 0x00, 0x00, 0x09, 0x0a, 0x06, 0x08, 0x09},
{0x18, 0x00, 0x00, 0x0a, 0x0a, 0x0c, 0x0b, 0x00},
{0x1b, 0x00, 0x00, 0x0d, 0x00, 0x0a, 0x0a, 0x08},
{0x18, 0x00, 0x00, 0x00, 0x09, 0x08, 0x09, 0x0e},
{0x19, 0x00, 0x00, 0x09, 0x0a, 0x08, 0x07, 0x08},
{0x1a, 0x00, 0x00, 0x07, 0x00, 0x0a, 0x0c, 0x0b},
{0x17, 0x00, 0x00, 0x0d, 0x00, 0x0b, 0x09, 0x09},
};
static const slong num_entries = sizeof(_smooth_prime_lut)/sizeof(const unsigned char [8]);
static void _get_lut_entry(fmpz_t p, slong i)
{
slong j;
fmpz_one(p);
for (j = 0; j < 8; j++)
{
fmpz_t t;
fmpz_init_set_ui(t, _eight_primes[j]);
fmpz_pow_ui(t, t, _smooth_prime_lut[i][j]);
fmpz_mul(p, p, t);
fmpz_clear(t);
}
fmpz_add_ui(p, p, 1);
}
int fmpz_next_smooth_prime(fmpz_t a, const fmpz_t b)
{
int success;
slong lo, mid, hi;
fmpz_t lo_p, mid_p, hi_p;
fmpz_init(lo_p);
fmpz_init(mid_p);
fmpz_init(hi_p);
FLINT_ASSERT(num_entries > 1);
lo = 0;
hi = num_entries - 1;
_get_lut_entry(lo_p, lo);
_get_lut_entry(hi_p, hi);
if (fmpz_cmp(b, lo_p) < 0)
{
fmpz_swap(a, lo_p);
success = 1;
goto cleanup;
}
if (fmpz_cmp(hi_p, b) <= 0)
{
fmpz_zero(a);
success = 0;
goto cleanup;
}
while (hi - lo > 4)
{
mid = lo + (hi - lo)/2;
_get_lut_entry(mid_p, mid);
if (fmpz_cmp(b, mid_p) < 0)
{
hi = mid;
fmpz_swap(hi_p, mid_p);
}
else
{
lo = mid;
fmpz_swap(lo_p, mid_p);
}
}
for (; lo <= hi; lo++)
{
_get_lut_entry(lo_p, lo);
if (fmpz_cmp(lo_p, b) > 0)
{
fmpz_swap(a, lo_p);
success = 1;
goto cleanup;
}
}
success = 0;
fmpz_zero(a);
cleanup:
fmpz_clear(lo_p);
fmpz_clear(mid_p);
fmpz_clear(hi_p);
return success;
}