def reachable(stepFunction, start, destinations):
    """ Determines the subset of destinations that can be reached from a set of starting positions,
    while using stepFunction (which produces a list of neighbor states) to navigate. 
    Uses breadth-first search. """
    if len(start) == 0:
        return {}
    
    # dict with distances to destinations
    res = {}
    for s in start:
        if s in destinations:
            res[s] = 0
            start.remove(s)
    
    # do one step
    new = set()
    for s in start:
        new.update(stepFunction(s))
    for s in new.copy():
        if s in destinations:
            res[s] = 1
            new.remove(s)
    
    # recursively do the rest
    deeper = reachable(stepFunction, new, destinations)
    
    # adjust distances
    for k, val in deeper.items():
        res[k] = val + 1
    return res