def exact_div(p, d, allow_divzero=False):
    """Find and return an integer n such that p == n * d

    If no such integer exists, this function raises ValueError.

    Both operands must be integers.

    If the second operand is zero, this function will raise ZeroDivisionError
    unless allow_divzero is true (default: False).
    """

    if not isinstance(p, int) or not isinstance(d, int):
        raise TypeError("unsupported operand type(s): %r and %r" % (type(p).__name__, type(d).__name__))

    if d == 0 and allow_divzero:
        n = 0
        if p != n * d:
            raise ValueError("No solution could be found")
    else:
        (n, r) = divmod(p, d)
        if r != 0:
            raise ValueError("No solution could be found")

    assert p == n * d
    return n