4th edit.

improve the efficiency a lot.