faster algorithm, more functionality