Basic depth-first search