note: use binary tree instead