def move_from_vertex(vertex, board_size):
    """Interpret a string representing a vertex, as specified by GTP.

    Returns a pair of coordinates (row, col) in range(0, board_size)

    Raises ValueError with an appropriate message if 'vertex' isn't a valid GTP
    vertex specification for a board of size 'board_size'.

    """
    if not 0 < board_size <= 25:
        raise ValueError("board_size out of range")
    try:
        s = vertex.lower()
    except Exception:
        raise ValueError("invalid vertex")
    if s == "pass":
        return None
    try:
        col_c = s[0]
        if (not "a" <= col_c <= "z") or col_c == "i":
            raise ValueError
        if col_c > "i":
            col = ord(col_c) - ord("b")
        else:
            col = ord(col_c) - ord("a")
        row = int(s[1:]) - 1
        if row < 0:
            raise ValueError
    except (IndexError, ValueError):
        raise ValueError("invalid vertex: '%s'" % s)
    if not (col < board_size and row < board_size):
        raise ValueError("vertex is off board: '%s'" % s)
    return row, col