Source: https://www.cs.upc.edu/~gavalda/pa2/6_OOP2.pdf