def reachable(Adj, s, t):
    """
    Adj is adjacency list rep of graph
    Return True if edges in Adj have directed path from s to t.

    Note that this routine is one of the most-used and most time-consuming
    of this whole procedure, which is why it is passed an adjacency list 
    rep rather than a list of vertices and edges, since the adjacency list
    rep is easy to update when a new edge is committed to in RP.
    """
    # search for path
    Q = [ s ]         # vertices to expand
    R = set([s])      # reachable
    while Q:
        i = Q.pop()
        for j in Adj[i]:
            if j == t:
                return True
            if j not in R:
                R.add(j)
                Q.append(j)
    return False