<gh_stars>0
# Cryptomath Module
# https://www.nostarch.com/crackingcodes/ (BSD Licensed)
import collections
from itertools import chain
from typing import Optional, List, Set, Dict, Counter


def gcd(a: int, b: int) -> int:
    """ Return the GCD of a and b using Euclid's algorithm.

    :param a: First integer.
    :param b: Second integer.
    :return: The Greatest Common Divisor between two given numbers.
    """
    while a != 0:
        a, b = b % a, a
    return b


def find_mod_inverse(a: int, m: int) -> Optional[int]:
    """ Return the modular inverse of a % m

    Modular inverse is the number x such that a*x % m = 1.

    :param a: First integer.
    :param m: Second integer.
    :return:  Module inverse integer.
    """
    if gcd(a, m) != 1:
        return None  # No mod inverse if a & m aren't relatively prime.
    else:
        # Calculate using the extended Euclidean algorithm:
        u1, u2, u3 = 1, 0, a
        v1, v2, v3 = 0, 1, m
        while v3 != 0:
            q = u3 // v3  # Note that // is the integer division operator.
            v1, v2, v3, u1, u2, u3 = (u1 - q * v1), (u2 - q * v2), (u3 - q * v3), v1, v2, v3
        result = u1 % m
        return result


def find_factors(number: int) -> List[int]:
    """ Get math factors for this number.

    Number 1 is not returned as factor, because is evident.

    :param number: Number to get factors from.
    :return: A list with found factors.
    """
    factors = []
    for candidate in range(2, number+1):
        if number % candidate == 0:
            factors.append(candidate)
    return factors


def count_factors(*factor_lists: List[int]) -> Counter[int]:
    """ Get a sequence of lists of factors and return a counter of how many factors there are.

    :param factor_lists: A variable length sequence of list. Every list has factors for a number:
    :return: A counter of factors
    """
    factors = collections.Counter(chain(*factor_lists))
    return factors

# Cryptomath Module
# https://www.nostarch.com/crackingcodes/ (BSD Licensed)
import collections
from itertools import chain
from typing import Optional, List, Set, Dict, Counter


def gcd(a: int, b: int) -> int:
    """ Return the GCD of a and b using Euclid's algorithm.

    :param a: First integer.
    :param b: Second integer.
    :return: The Greatest Common Divisor between two given numbers.
    """
    while a != 0:
        a, b = b % a, a
    return b


def find_mod_inverse(a: int, m: int) -> Optional[int]:
    """ Return the modular inverse of a % m

    Modular inverse is the number x such that a*x % m = 1.

    :param a: First integer.
    :param m: Second integer.
    :return:  Module inverse integer.
    """
    if gcd(a, m) != 1:
        return None  # No mod inverse if a & m aren't relatively prime.
    else:
        # Calculate using the extended Euclidean algorithm:
        u1, u2, u3 = 1, 0, a
        v1, v2, v3 = 0, 1, m
        while v3 != 0:
            q = u3 // v3  # Note that // is the integer division operator.
            v1, v2, v3, u1, u2, u3 = (u1 - q * v1), (u2 - q * v2), (u3 - q * v3), v1, v2, v3
        result = u1 % m
        return result


def find_factors(number: int) -> List[int]:
    """ Get math factors for this number.

    Number 1 is not returned as factor, because is evident.

    :param number: Number to get factors from.
    :return: A list with found factors.
    """
    factors = []
    for candidate in range(2, number+1):
        if number % candidate == 0:
            factors.append(candidate)
    return factors


def count_factors(*factor_lists: List[int]) -> Counter[int]:
    """ Get a sequence of lists of factors and return a counter of how many factors there are.

    :param factor_lists: A variable length sequence of list. Every list has factors for a number:
    :return: A counter of factors
    """
    factors = collections.Counter(chain(*factor_lists))
    return factors
# Cryptomath Module # https://www.nostarch.com/crackingcodes/ (BSD Licensed) Return the GCD of a and b using Euclid's algorithm.      :param a: First integer.     :param b: Second integer.     :return: The Greatest Common Divisor between two given numbers. Return the modular inverse of a % m      Modular inverse is the number x such that a*x % m = 1.      :param a: First integer.     :param m: Second integer.     :return:  Module inverse integer. # No mod inverse if a & m aren't relatively prime. # Calculate using the extended Euclidean algorithm: # Note that // is the integer division operator. Get math factors for this number.      Number 1 is not returned as factor, because is evident.      :param number: Number to get factors from.     :return: A list with found factors. Get a sequence of lists of factors and return a counter of how many factors there are.      :param factor_lists: A variable length sequence of list. Every list has factors for a number:     :return: A counter of factors