refer to others' solution, reimplement it