def bezout(a, b):
    """ bezout function finds a particular integer solution
    (u, v) to the diophantine equation a.u + b.v = gcd(a, b)
    Returns (u, v, gcd(a, b))
    Usage: bezout(5, 8) -> (-3, 2, 1)   
    
    Implements extended Euclide's algorithm.

    :type a:    int 
    :type b:    int (a and b not both 0)

    :return:  (u, v, gcd(a,b))
    :rtype:   int x3

    :Example:

    >>> bezout(0, 0)
    Traceback (most recent call last):
    ...
    ValueError: a and b shall not be both 0

    >>> bezout(7.8, 9)
    Traceback (most recent call last):
    ...
    ValueError: a and b shall be integers
    
    >>> bezout(120, 23); bezout(-120, 23); bezout(-120, -23); bezout(120, -23)
    (-9, 47, 1)
    (9, 47, 1)
    (9, -47, 1)
    (-9, -47, 1)
    >>> bezout(1, 10); bezout(1, -10); bezout(10, 1); bezout(-10, 1)
    (1, 0, 1)
    (1, 0, 1)
    (0, 1, 1)
    (0, 1, 1)
    >>> bezout(-1, 10); bezout(-1, -10); bezout(10, -1); bezout(-10, -1)
    (-1, 0, 1)
    (-1, 0, 1)
    (0, -1, 1)
    (0, -1, 1)
    >>> bezout(0, 10); bezout(0, -10); bezout(-10, 0); bezout(10, 0)
    (0, 1, 10)
    (0, -1, 10)
    (-1, 0, 10)
    (1, 0, 10)
    >>> bezout(1, 0); bezout(-1, 0)
    (1, 0, 1)
    (-1, 0, 1)
    >>> bezout(1, 1); bezout(-1, 1); bezout(1, -1); bezout(-1, -1)
    (0, 1, 1)
    (0, 1, 1)
    (0, -1, 1)
    (0, -1, 1)
    >>> def test_bezout(a, b):
    ...     u, v, g = bezout(a, b)
    ...     return a*u+b*v==g and g==gcd(a, b)
    >>> all(test_bezout(a, b)     for a in range(-1000, 2000, 99) for b in range(-1000, 1000, 51))
    True
    """
    if a == 0 and b == 0:
        raise ValueError('a and b shall not be both 0')
    if not type(a) is type(b) is int:
        raise ValueError('a and b shall be integers')
    sign_a = 1
    if a < 0:
        a = -a
        sign_a = -1
    sign_b = 1
    if b < 0:
        b = -b
        sign_b = -1
    if a == 0:
        return 0, sign_b, b
    if b == 0:
        return sign_a, 0, a
    u1, v1 = 1, 0
    u2, v2 = 0, 1
    while True:
        q, r = divmod(a, b)
        if r == 0:
            return sign_a * u2, sign_b * v2, b
        u1, v1, u2, v2 = u2, v2, u1 - q * u2, v1 - q * v2
        a, b = b, r
