'Find the elements of `self` that generate a finite index subgroup
and, if found, return the list of elements and the coset table of `self` by
the subgroup, otherwise return `(None, None)`'

def _finite_index_subgroup(self, s=[]):

    gen = self.most_frequent_generator()
    rels = list(self.generators)
    rels.extend(self.relators)
    if (not s):
        if (len(self.generators) == 2):
            s = ([gen] + [g for g in self.generators if (g != gen)])
        else:
            rand = self.free_group.identity
            i = 0
            while (((rand in rels) or ((rand ** (-1)) in rels) or rand.is_identity) and (i < 10)):
                rand = self.random()
                i += 1
            s = ([gen, rand] + [g for g in self.generators if (g != gen)])
    mid = ((len(s) + 1) // 2)
    half1 = s[:mid]
    half2 = s[mid:]
    m = 200
    C = None
    while ((not C) and ((m / 2) < CosetTable.coset_table_max_limit)):
        m = min(m, CosetTable.coset_table_max_limit)
        try:
            C = self.coset_enumeration(half1, max_cosets=m)
            half = half1
        except ValueError:
            pass
        if (not C):
            try:
                C = self.coset_enumeration(half2, max_cosets=m)
                half = half2
            except ValueError:
                m *= 2
                continue
    if (not C):
        return (None, None)
    C.compress()
    return (half, C)
