static getRings(graph, experimental = false) {
    let adjacencyMatrix = graph.getComponentsAdjacencyMatrix();

    if (adjacencyMatrix.length === 0) {
      return null;
    }

    let connectedComponents = Graph.getConnectedComponents(adjacencyMatrix);
    let rings = Array();

    for (var i = 0; i < connectedComponents.length; i++) {
      let connectedComponent = connectedComponents[i];
      let ccAdjacencyMatrix = graph.getSubgraphAdjacencyMatrix([...connectedComponent]);
      let arrBondCount = new Uint16Array(ccAdjacencyMatrix.length);
      let arrRingCount = new Uint16Array(ccAdjacencyMatrix.length);

      for (var j = 0; j < ccAdjacencyMatrix.length; j++) {
        arrRingCount[j] = 0;
        arrBondCount[j] = 0;

        for (var k = 0; k < ccAdjacencyMatrix[j].length; k++) {
          arrBondCount[j] += ccAdjacencyMatrix[j][k];
        }
      } // Get the edge number and the theoretical number of rings in SSSR


      let nEdges = 0;

      for (var j = 0; j < ccAdjacencyMatrix.length; j++) {
        for (var k = j + 1; k < ccAdjacencyMatrix.length; k++) {
          nEdges += ccAdjacencyMatrix[j][k];
        }
      }

      let nSssr = nEdges - ccAdjacencyMatrix.length + 1; // console.log(nEdges, ccAdjacencyMatrix.length, nSssr);
      // console.log(SSSR.getEdgeList(ccAdjacencyMatrix));
      // console.log(ccAdjacencyMatrix);
      // If all vertices have 3 incident edges, calculate with different formula (see Euler)

      let allThree = true;

      for (var j = 0; j < arrBondCount.length; j++) {
        if (arrBondCount[j] !== 3) {
          allThree = false;
        }
      }

      if (allThree) {
        nSssr = 2.0 + nEdges - ccAdjacencyMatrix.length;
      } // All vertices are part of one ring if theres only one ring.


      if (nSssr === 1) {
        rings.push([...connectedComponent]);
        continue;
      }

      if (experimental) {
        nSssr = 999;
      }

      let {
        d,
        pe,
        pe_prime
      } = SSSR.getPathIncludedDistanceMatrices(ccAdjacencyMatrix);
      let c = SSSR.getRingCandidates(d, pe, pe_prime);
      let sssr = SSSR.getSSSR(c, d, ccAdjacencyMatrix, pe, pe_prime, arrBondCount, arrRingCount, nSssr);

      for (var j = 0; j < sssr.length; j++) {
        let ring = Array(sssr[j].size);
        let index = 0;

        for (let val of sssr[j]) {
          // Get the original id of the vertex back
          ring[index++] = connectedComponent[val];
        }

        rings.push(ring);
      }
    } // So, for some reason, this would return three rings for C1CCCC2CC1CCCC2, which is wrong
    // As I don't have time to fix this properly, it will stay in. I'm sorry next person who works
    // on it. At that point it might be best to reimplement the whole SSSR thing...


    return rings;
  }
Returns an array containing arrays, each representing a ring from the smallest set of smallest rings in the graph.

@param {Graph} graph A Graph object.
@param {Boolean} [experimental=false] Whether or not to use experimental SSSR.
@returns {Array[]} An array containing arrays, each representing a ring from the smallest set of smallest rings in the group.