more sensible algorithm, runs in ~2 seconds