def insert(
        self,
        index: int,
        moment_or_operation_tree: cirq.OP_TREE,
        strategy: cirq.InsertStrategy = InsertStrategy.EARLIEST,
    ) -> int:
        """Inserts operations into the circuit.

        Operations are inserted into the moment specified by the index and
        'InsertStrategy'.
        Moments within the operation tree are inserted intact.

        Args:
            index: The index to insert all the operations at.
            moment_or_operation_tree: The moment or operation tree to insert.
            strategy: How to pick/create the moment to put operations into.

        Returns:
            The insertion index that will place operations just after the
            operations that were inserted by this method.

        Raises:
            ValueError: Bad insertion strategy.
        """
        # limit index to 0..len(self._moments), also deal with indices smaller 0
        k = max(min(index if index >= 0 else len(self._moments) + index, len(self._moments)), 0)
        if strategy != InsertStrategy.EARLIEST or k != len(self._moments):
            self._placement_cache = None
        mops = list(ops.flatten_to_ops_or_moments(moment_or_operation_tree))
        if self._placement_cache:
            batches = [mops]  # Any grouping would work here; this just happens to be the fastest.
        elif strategy is InsertStrategy.NEW:
            batches = [[mop] for mop in mops]  # Each op goes into its own moment.
        else:
            batches = list(_group_into_moment_compatible(mops))
        for batch in batches:
            # Insert a moment if inline/earliest and _any_ op in the batch requires it.
            if (
                not self._placement_cache
                and not isinstance(batch[0], Moment)
                and strategy in (InsertStrategy.INLINE, InsertStrategy.EARLIEST)
                and not all(
                    (strategy is InsertStrategy.EARLIEST and self._can_add_op_at(k, op))
                    or (k > 0 and self._can_add_op_at(k - 1, op))
                    for op in cast(list[cirq.Operation], batch)
                )
            ):
                self._moments.insert(k, Moment())
                if strategy is InsertStrategy.INLINE:
                    k += 1
            max_p = 0
            for moment_or_op in batch:
                # Determine Placement
                if self._placement_cache:
                    p = self._placement_cache.append(moment_or_op)
                elif isinstance(moment_or_op, Moment):
                    p = k
                elif strategy in (InsertStrategy.NEW, InsertStrategy.NEW_THEN_INLINE):
                    self._moments.insert(k, Moment())
                    p = k
                elif strategy is InsertStrategy.INLINE:
                    p = k - 1
                else:  # InsertStrategy.EARLIEST:
                    p = self.earliest_available_moment(moment_or_op, end_moment_index=k)
                # Place
                if isinstance(moment_or_op, Moment):
                    self._moments.insert(p, moment_or_op)
                elif p == len(self._moments):
                    self._moments.append(Moment(moment_or_op))
                else:
                    self._moments[p] = self._moments[p].with_operation(moment_or_op)
                # Iterate
                max_p = max(p, max_p)
                if strategy is InsertStrategy.NEW_THEN_INLINE:
                    strategy = InsertStrategy.INLINE
                    k += 1
            k = max(k, max_p + 1)
        self._mutated(preserve_placement_cache=True)
        return k
Inserts operations into the circuit.

        Operations are inserted into the moment specified by the index and
        'InsertStrategy'.
        Moments within the operation tree are inserted intact.

        Args:
            index: The index to insert all the operations at.
            moment_or_operation_tree: The moment or operation tree to insert.
            strategy: How to pick/create the moment to put operations into.

        Returns:
            The insertion index that will place operations just after the
            operations that were inserted by this method.

        Raises:
            ValueError: Bad insertion strategy.
        
cirq-core/cirq/circuits/circuit.py