def perms_canonical_labels_from(x, y, j0):
    """
    Return canonical labels for ``x``, ``y`` that starts at ``j0``.

    .. WARNING:

        The group generated by ``x`` and the elements of ``y`` should be
        transitive.

    INPUT:

    - ``x`` -- list - a permutation of `[0, ..., n]` as a list

    - ``y`` -- list of permutations of `[0, ..., n]` as a list of lists

    - ``j0`` -- an index in [0, ..., n]

    OUTPUT:

    mapping: a permutation that specify the new labels

    EXAMPLES::

        sage: from surface_dynamics.misc.constellation import perms_canonical_labels_from
        sage: perms_canonical_labels_from([0,1,2],[[1,2,0]],0)
        [0, 1, 2]
        sage: perms_canonical_labels_from([1,0,2],[[2,0,1]],0)
        [0, 1, 2]
        sage: perms_canonical_labels_from([1,0,2],[[2,0,1]],1)
        [1, 0, 2]
        sage: perms_canonical_labels_from([1,0,2],[[2,0,1]],2)
        [2, 1, 0]
    """
    n = len(x)
    k = 0
    mapping = [None] * n
    waiting = [[] for i in range(len(y))]
    while k < n:
        mapping[j0] = k
        waiting[0].append(j0)
        k += 1
        j = x[j0]
        while j != j0:
            mapping[j] = k
            waiting[0].append(j)
            k += 1
            j = x[j]
        l = 0
        while l < len(waiting):
            i = 0
            while i < len(waiting[l]):
                j1 = waiting[l][i]
                if mapping[y[l][j1]] is None:
                    break
                i += 1
            if i == len(waiting[l]):
                if l < len(waiting) - 1:
                    waiting[l + 1].extend(waiting[l])
                waiting[l] = []
                l += 1
                i = 0
            else:
                j0 = y[l][j1]
                if l < len(waiting) - 1:
                    waiting[l + 1].extend(waiting[l][:i + 1])
                del waiting[l][:i + 1]
                break
    return mapping
