def bfs(graph, source, target):
    """
    Breadth first search on the graph.

    :param graph: A graph which supports the methods edges_from(v) and edges_to(v)
    :param source: Source vertex
    :param target: Target vertex
    :return: Whether target was reachable from source
    """

    assert source < len(graph) and target < len(graph)

    curr = [source]
    opened = [source]

    while len(curr) > 0:
        v = curr.pop(0)

        if v == target:
            return True
        else:
            for x in graph.edges_from(v):
                if x not in opened:
                    curr.append(x)
                    opened.append(x)

    return False