Whenever we have a cycle in our graph, we can direct the edges along the cycle. After such a change, the reachability will be the same as in the undirected case. More generally, whenever we have a non-trivial biconnected component, we can direct its edges to make a strongly connected component in the directed graph. (Note that we don't actually have to do that in our code.) Find all biconnected components and contract each of them to a vertex. You will be left with a tree. In this tree, we have up to 20 pairs (s[i],t[i]) for which we want to guarantee connectivity. Imagine a graph with one vertex for each (s[i],t[i]) pair. In this graph, connect two vertices by an edge iff the corresponding requests cannot be both satisfied (i.e., if they both contain the same edge of the tree and want to use it in opposite direction). The answer is the size of the maximum independent set in that graph. As there are at most 20 vertices, we can find that using brute force.