from typing import List
from typing import Tuple


def char_span_to_token_span(spans: List[Tuple[int, int]],
                            char_start: int, char_end: int) -> Tuple[int, int]:
    """ Map a character span to the minimal containing token span.
    Args:
        spans: a list of end-exclusive character spans for each token
        char_start: starting character offset
        char_end: ending character offset (exclusive)
    Returns:
        (start, end) token indices, end-exclusive
    """
    # first span ending after target start
    tok_s = min(i for i, s in enumerate(spans) if s[1] >= char_start)
    # last span starting before target end
    tok_e = max(i for i, s in enumerate(spans) if s[0] <= char_end)
    return (tok_s, tok_e + 1)