recursively traverse