Notice in the sieve code: when marking multiples of p, we start at p². Why not start at 2p?
Because all smaller multiples have already been marked. For example, when p = 5, the multiple 2×5 = 10 was already crossed out when we processed p = 2.
Starting at p² saves work and does not miss any composites.