from sympy import Range


def is_composite(a: int, d: int, n: int, s: int) -> bool:
    if pow(a, d, n) == 1:
        return False
    for i in Range(s):
        if pow(a, 2 ** i * d, n) == n - 1:
            return False
    # n  is definitely composite
    return True


def is_prime(number: int, rounds: int = 128) -> int:
    if number in primes:
        return True
    if any((number % p) == 0 for p in primes) or number in (0, 1):
        return False
    d, s = number - 1, 0
    while not d % 2:
        d, s = d >> 1, s + 1
    if number < 1373653:
        return not any(is_composite(a, d, number, s) for a in (2, 3))
    if number < 25326001:
        return not any(is_composite(a, d, number, s) for a in (2, 3, 5))
    if number < 118670087467:
        if number == 3215031751:
            return False
        return not any(is_composite(a, d, number, s) for a in (2, 3, 5, 7))
    if number < 2152302898747:
        return not any(is_composite(a, d, number, s) for a in (2, 3, 5, 7, 11))
    if number < 3474749660383:
        return not any(is_composite(a, d, number, s) for a in (2, 3, 5, 7, 11, 13))
    if number < 341550071728321:
        return not any(
            is_composite(a, d, number, s) for a in (2, 3, 5, 7, 11, 13, 17)
            )
    # otherwise
    return not any(is_composite(a, d, number, s) for a in primes[:rounds])


primes = [2, 3]
primes += [x for x in range(5, 1000, 2) if is_prime(x)]


def main() -> None:
    number = int(input("Enter the number to check for primality: "))
    if is_prime(number):
        print("The number", number, "is prime.")
    else:
        print("The number", number, "is composite.")


if __name__ == "__main__":
    main()
