code: private void search(int v, BitSet prev, BitSet curr) {
  
          state[v] = curr; // set the state before we visit v
          curr = copy(curr); // include v in our current state (state[v] is unmodified)
          curr.set(v);
          visited.or(curr); // mark v as visited (or being visited)
  
          // for each neighbor w of v
          for (int w : g[v]) {
  
              // if w is in our prev state we have a cycle of size >3.
              // we don't check out current state as this will always
              // include w - they are adjacent
              if (prev.get(w)) {
                  numCycles++;
                  // we have a cycle, xor the state when we last visited 'w'
                  // with our current state. this set is all the vertices
                  // we visited since then
                  add(xor(state[w], curr));
              }
  
              // check w hasn't been visited or isn't being visited further up the stack.
              // this mainly stops us re-visiting the vertex we came from
              else if (!visited.get(w)) {
                  // recursively call for the neighbor 'w'
                  search(w, state[v], curr);
              }
          }
  
      }
docs: Perform a depth first search from the vertex <i>v</i>.
  
  @param v    vertex to search from
  @param prev the state before we vistaed our parent (previous state)
  @param curr the current state (including our parent)