def METHOD_NAME(start, end, time):
    # For a given set of ancestors, we want to group them for matching in parallel.
    # For each ancestor, any overlapping, older ancestors must be in an earlier group,
    # and any overlapping, younger ancestors in a later group. Any overlapping same-age
    # ancestors must be in the same group so they don't match to each other.
    # We do this by first merging the overlapping same-age ancestors. Then build a
    # dependency graph of the ancestors by linesweep. Then form groups by topological
    # sort. Finally, we un-merge the same-age ancestors.
    assert len(start) == len(end)
    assert len(start) == len(time)
    t = time_.time()
    (
        new_start,
        new_end,
        new_time,
        old_indexes,
        sort_indices,
    ) = merge_overlapping_ancestors(start, end, time)
    logger.info(f"Merged to {len(new_start)} ancestors in {time_.time() - t:.2f}s")
    # Build a list of events for the linesweep
    t = time_.time()
    n = len(new_time)
    # Create events arrays by copying and concatenating inputs
    event_times = np.concatenate([new_time, new_time])
    event_pos = np.concatenate([new_start, new_end])
    event_index = np.concatenate([np.arange(n), np.arange(n)])
    event_type = np.concatenate([np.ones(n, dtype=np.int8), np.zeros(n, dtype=np.int8)])
    # Sort events by position, then ends before starts
    event_sort_indices = np.lexsort((event_type, event_pos))
    event_times = event_times[event_sort_indices]
    event_index = event_index[event_sort_indices]
    event_type = event_type[event_sort_indices]
    logger.info(f"Built {len(event_times)} events in {time_.time() - t:.2f}s")
    t = time_.time()
    children_data, children_indices, incoming_edge_count = run_linesweep(
        event_times, event_index, event_type, new_time
    )
    logger.info(
        f"Linesweep generated {np.sum(incoming_edge_count)} dependencies in"
        f" {time_.time() - t:.2f}s"
    )
    t = time_.time()
    group_id = find_groups(children_data, children_indices, incoming_edge_count)
    logger.info(f"Found groups in {time_.time() - t:.2f}s")
    t = time_.time()
    # Convert the group id array to lists of ids for each group
    ancestor_grouping = {}
    for group in np.unique(group_id):
        ancestor_grouping[group] = np.where(group_id == group)[0]
    # Now un-merge the same-age ancestors, simultaneously mapping back to the original,
    # unsorted indexes
    for group in ancestor_grouping:
        ancestor_grouping[group] = sorted(
            [
                sort_indices[item]
                for i in ancestor_grouping[group]
                for item in old_indexes[i]
            ]
        )
    logger.info(f"Un-merged in {time_.time() - t:.2f}s")
    logger.info(
        f"{len(ancestor_grouping)} groups with median size "
        f"{np.median([len(ancestor_grouping[group]) for group in ancestor_grouping])}"
    )
    return ancestor_grouping