import sys
import numpy as np

def numba_compile(numba_config):
    import os, sys
    if sys.argv[-1] == "ONLINE_JUDGE":
        from numba import njit
        from numba.pycc import CC
        cc = CC("my_module")
        for func, signature in numba_config:
            globals()[func.__name__] = njit(signature)(func)
            cc.export(func.__name__, signature)(func)
        cc.compile()
        exit()
    elif os.name == "posix":
        exec(f"from my_module import {','.join(func.__name__ for func, _ in numba_config)}")
        for func, _ in numba_config:
            globals()[func.__name__] = vars()[func.__name__]
    else:
        from numba import njit
        for func, signature in numba_config:
            globals()[func.__name__] = njit(signature, cache=True)(func)
        print("compiled!", file=sys.stderr)


# >>> binary indexed tree >>>
# 必要な要素数+1 の長さの ndarray の 1 要素目以降を使う
def bitify(arr):
    for i in range(1, len(arr)-1):
        arr[i + (i & -i)] += arr[i]
def bit_sum(bit, i):  # [bit_sum, "i8(i8[:],i8)"],
    # (0, i]
    res = 0
    while i:
        res += bit[i]
        i -= i & -i
    return res
def bit_add(bit, i, val):  # [bit_add, "void(i8[:],i8,i8)"],
    n = len(bit)
    while i < n:
        bit[i] += val
        i += i & -i
# <<< binary indexed tree <<<

numba_compile([
    [bitify, "void(i8[:])"],
    [bit_sum, "i8(i8[:],i8)"],
    [bit_add, "void(i8[:],i8,i8)"],
])


def main():
    N = int(sys.stdin.buffer.readline())
    S = np.frombuffer(sys.stdin.buffer.readline()[:-1], dtype=np.uint8).astype(np.int64) - 97
    Q = int(sys.stdin.buffer.readline())
    bits = np.zeros((26, (1<<19)+1), dtype=np.int64)
    bits[S, np.arange(1, N+1)] = 1
    for i in range(26):
        bitify(bits[i])
    Ans = []
    for t, i, c in zip(*[iter(sys.stdin.buffer.read().split())]*3):
        if t == b"1":
            i = int(i)
            c = ord(c)-97
            c_old = S[i-1]
            S[i-1] = c
            bit_add(bits[c_old], i, -1)
            bit_add(bits[c], i, 1)
        else:
            l, r = int(i), int(c)
            ans = 0
            for bit in bits:
                ans += bool(bit_sum(bit, r)-bit_sum(bit, l-1))
            Ans.append(ans)
    print("\n".join(map(str, Ans)))

main() import sys sys import numpy as np numpy def numba_compile(numba_config):
    import os, sys
    if sys.argv[-1] == "ONLINE_JUDGE":
        from numba import njit
        from numba.pycc import CC
        cc = CC("my_module")
        for func, signature in numba_config:
            globals()[func.__name__] = njit(signature)(func)
            cc.export(func.__name__, signature)(func)
        cc.compile()
        exit()
    elif os.name == "posix":
        exec(f"from my_module import {','.join(func.__name__ for func, _ in numba_config)}")
        for func, _ in numba_config:
            globals()[func.__name__] = vars()[func.__name__]
    else:
        from numba import njit
        for func, signature in numba_config:
            globals()[func.__name__] = njit(signature, cache=True)(func)
        print("compiled!", file=sys.stderr)


# >>> binary indexed tree >>>
# 必要な要素数+1 の長さの ndarray の 1 要素目以降を使う numba_compile import os, sys os sys if sys.argv[-1] == "ONLINE_JUDGE":
        from numba import njit
        from numba.pycc import CC
        cc = CC("my_module")
        for func, signature in numba_config:
            globals()[func.__name__] = njit(signature)(func)
            cc.export(func.__name__, signature)(func)
        cc.compile()
        exit()
    elif os.name == "posix":
        exec(f"from my_module import {','.join(func.__name__ for func, _ in numba_config)}")
        for func, _ in numba_config:
            globals()[func.__name__] = vars()[func.__name__]
    else:
        from numba import njit
        for func, signature in numba_config:
            globals()[func.__name__] = njit(signature, cache=True)(func)
        print("compiled!", file=sys.stderr)


# >>> binary indexed tree >>>
# 必要な要素数+1 の長さの ndarray の 1 要素目以降を使う sys.argv[-1] == "ONLINE_JUDGE" sys.argv[-1] sys.argv sys argv -1 "ONLINE_JUDGE" from numba import njit from numba.pycc import CC cc = CC("my_module") cc CC("my_module") CC "my_module" for func, signature in numba_config:
            globals()[func.__name__] = njit(signature)(func)
            cc.export(func.__name__, signature)(func)
         func signature numba_config globals()[func.__name__] = njit(signature)(func) globals()[func.__name__] () globals func.__name__ func __name__ njit(signature)(func) (signature) njit signature func cc.export(func.__name__, signature)(func) cc.export(func.__name__, signature) cc.export cc export func.__name__ func __name__ signature func cc.compile() cc.compile cc compile exit() exit elif os.name == "posix":
        exec(f"from my_module import {','.join(func.__name__ for func, _ in numba_config)}")
        for func, _ in numba_config:
            globals()[func.__name__] = vars()[func.__name__]
     os.name == "posix" os.name os name "posix" exec(f"from my_module import {','.join(func.__name__ for func, _ in numba_config)}") exec f"from my_module import {','.join(func.__name__ for func, _ in numba_config)}" for func, _ in numba_config:
            globals()[func.__name__] = vars()[func.__name__]
     func _ numba_config globals()[func.__name__] = vars()[func.__name__] globals()[func.__name__] () globals func.__name__ func __name__ vars()[func.__name__] () vars func.__name__ func __name__ from numba import njit for func, signature in numba_config:
            globals()[func.__name__] = njit(signature, cache=True)(func)
         func signature numba_config globals()[func.__name__] = njit(signature, cache=True)(func) globals()[func.__name__] () globals func.__name__ func __name__ njit(signature, cache=True)(func) (signature, cache=True) njit signature cache=True cache True func print("compiled!", file=sys.stderr) print "compiled!" file=sys.stderr file sys.stderr sys stderr numba_config numba_config def bitify(arr):
    for i in range(1, len(arr)-1):
        arr[i + (i & -i)] += arr[i] bitify for i in range(1, len(arr)-1):
        arr[i + (i & -i)] += arr[i] i range(1, len(arr)-1) range 1 len(arr)-1 len(arr) len arr 1 arr[i + (i & -i)] += arr[i] arr[i + (i & -i)] arr i + (i & -i) i i & -i i -i i arr[i] arr i arr arr def bit_sum(bit, i):  # [bit_sum, "i8(i8[:],i8)"],
    # (0, i]
    res = 0
    while i:
        res += bit[i]
        i -= i & -i
    return res bit_sum res = 0 res 0 while i:
        res += bit[i]
        i -= i & -i
     i res += bit[i] res bit[i] bit i i -= i & -i i i & -i i -i i return res res bit bit i i def bit_add(bit, i, val):  # [bit_add, "void(i8[:],i8,i8)"],
    n = len(bit)
    while i < n:
        bit[i] += val
        i += i & -i
# <<< binary indexed tree <<< bit_add n = len(bit) n len(bit) len bit while i < n:
        bit[i] += val
        i += i & -i
# <<< binary indexed tree <<< i < n i n bit[i] += val bit[i] bit i val i += i & -i i i & -i i -i i bit bit i i val val numba_compile([
    [bitify, "void(i8[:])"],
    [bit_sum, "i8(i8[:],i8)"],
    [bit_add, "void(i8[:],i8,i8)"],
]) numba_compile [
    [bitify, "void(i8[:])"],
    [bit_sum, "i8(i8[:],i8)"],
    [bit_add, "void(i8[:],i8,i8)"],
] [bitify, "void(i8[:])"] bitify "void(i8[:])" [bit_sum, "i8(i8[:],i8)"] bit_sum "i8(i8[:],i8)" [bit_add, "void(i8[:],i8,i8)"] bit_add "void(i8[:],i8,i8)" def main():
    N = int(sys.stdin.buffer.readline())
    S = np.frombuffer(sys.stdin.buffer.readline()[:-1], dtype=np.uint8).astype(np.int64) - 97
    Q = int(sys.stdin.buffer.readline())
    bits = np.zeros((26, (1<<19)+1), dtype=np.int64)
    bits[S, np.arange(1, N+1)] = 1
    for i in range(26):
        bitify(bits[i])
    Ans = []
    for t, i, c in zip(*[iter(sys.stdin.buffer.read().split())]*3):
        if t == b"1":
            i = int(i)
            c = ord(c)-97
            c_old = S[i-1]
            S[i-1] = c
            bit_add(bits[c_old], i, -1)
            bit_add(bits[c], i, 1)
        else:
            l, r = int(i), int(c)
            ans = 0
            for bit in bits:
                ans += bool(bit_sum(bit, r)-bit_sum(bit, l-1))
            Ans.append(ans)
    print("\n".join(map(str, Ans))) main N = int(sys.stdin.buffer.readline()) N int(sys.stdin.buffer.readline()) int sys.stdin.buffer.readline() sys.stdin.buffer.readline sys.stdin.buffer sys.stdin sys stdin buffer readline S = np.frombuffer(sys.stdin.buffer.readline()[:-1], dtype=np.uint8).astype(np.int64) - 97 S np.frombuffer(sys.stdin.buffer.readline()[:-1], dtype=np.uint8).astype(np.int64) - 97 np.frombuffer(sys.stdin.buffer.readline()[:-1], dtype=np.uint8).astype(np.int64) np.frombuffer(sys.stdin.buffer.readline()[:-1], dtype=np.uint8).astype np.frombuffer(sys.stdin.buffer.readline()[:-1], dtype=np.uint8) np.frombuffer np frombuffer sys.stdin.buffer.readline()[:-1] sys.stdin.buffer.readline() sys.stdin.buffer.readline sys.stdin.buffer sys.stdin sys stdin buffer readline :-1 -1 dtype=np.uint8 dtype np.uint8 np uint8 astype np.int64 np int64 97 Q = int(sys.stdin.buffer.readline()) Q int(sys.stdin.buffer.readline()) int sys.stdin.buffer.readline() sys.stdin.buffer.readline sys.stdin.buffer sys.stdin sys stdin buffer readline bits = np.zeros((26, (1<<19)+1), dtype=np.int64) bits np.zeros((26, (1<<19)+1), dtype=np.int64) np.zeros np zeros (26, (1<<19)+1) 26 (1<<19)+1 1<<19 1 19 1 dtype=np.int64 dtype np.int64 np int64 bits[S, np.arange(1, N+1)] = 1 bits[S, np.arange(1, N+1)] bits S 1 for i in range(26):
        bitify(bits[i])
     i range(26) range 26 bitify(bits[i]) bitify bits[i] bits i Ans = [] Ans [] for t, i, c in zip(*[iter(sys.stdin.buffer.read().split())]*3):
        if t == b"1":
            i = int(i)
            c = ord(c)-97
            c_old = S[i-1]
            S[i-1] = c
            bit_add(bits[c_old], i, -1)
            bit_add(bits[c], i, 1)
        else:
            l, r = int(i), int(c)
            ans = 0
            for bit in bits:
                ans += bool(bit_sum(bit, r)-bit_sum(bit, l-1))
            Ans.append(ans)
     t i c zip(*[iter(sys.stdin.buffer.read().split())]*3) zip *[iter(sys.stdin.buffer.read().split())]*3 [iter(sys.stdin.buffer.read().split())]*3 [iter(sys.stdin.buffer.read().split())] iter(sys.stdin.buffer.read().split()) iter sys.stdin.buffer.read().split() sys.stdin.buffer.read().split sys.stdin.buffer.read() sys.stdin.buffer.read sys.stdin.buffer sys.stdin sys stdin buffer read split 3 if t == b"1":
            i = int(i)
            c = ord(c)-97
            c_old = S[i-1]
            S[i-1] = c
            bit_add(bits[c_old], i, -1)
            bit_add(bits[c], i, 1)
        else:
            l, r = int(i), int(c)
            ans = 0
            for bit in bits:
                ans += bool(bit_sum(bit, r)-bit_sum(bit, l-1))
            Ans.append(ans)
     t == b"1" t b"1" i = int(i) i int(i) int i c = ord(c)-97 c ord(c)-97 ord(c) ord c 97 c_old = S[i-1] c_old S[i-1] S i-1 i 1 S[i-1] = c S[i-1] S i-1 i 1 c bit_add(bits[c_old], i, -1) bit_add bits[c_old] bits c_old i -1 bit_add(bits[c], i, 1) bit_add bits[c] bits c i 1 l, r = int(i), int(c) l int(i) int i r int(c) int c ans = 0 ans 0 for bit in bits:
                ans += bool(bit_sum(bit, r)-bit_sum(bit, l-1))
             bit bits ans += bool(bit_sum(bit, r)-bit_sum(bit, l-1)) ans bool(bit_sum(bit, r)-bit_sum(bit, l-1)) bool bit_sum(bit, r)-bit_sum(bit, l-1) bit_sum(bit, r) bit_sum bit r bit_sum(bit, l-1) bit_sum bit l-1 l 1 Ans.append(ans) Ans.append Ans append ans print("\n".join(map(str, Ans))) print "\n".join(map(str, Ans)) "\n".join "\n" join map(str, Ans) map str Ans main() main def bitify(arr):
    for i in range(1, len(arr)-1):
        arr[i + (i & -i)] += arr[i] def bitify(arr):
    for i in range(1, len(arr)-1):
        arr[i + (i & -i)] += arr[i] bitify def main():
    N = int(sys.stdin.buffer.readline())
    S = np.frombuffer(sys.stdin.buffer.readline()[:-1], dtype=np.uint8).astype(np.int64) - 97
    Q = int(sys.stdin.buffer.readline())
    bits = np.zeros((26, (1<<19)+1), dtype=np.int64)
    bits[S, np.arange(1, N+1)] = 1
    for i in range(26):
        bitify(bits[i])
    Ans = []
    for t, i, c in zip(*[iter(sys.stdin.buffer.read().split())]*3):
        if t == b"1":
            i = int(i)
            c = ord(c)-97
            c_old = S[i-1]
            S[i-1] = c
            bit_add(bits[c_old], i, -1)
            bit_add(bits[c], i, 1)
        else:
            l, r = int(i), int(c)
            ans = 0
            for bit in bits:
                ans += bool(bit_sum(bit, r)-bit_sum(bit, l-1))
            Ans.append(ans)
    print("\n".join(map(str, Ans))) def main():
    N = int(sys.stdin.buffer.readline())
    S = np.frombuffer(sys.stdin.buffer.readline()[:-1], dtype=np.uint8).astype(np.int64) - 97
    Q = int(sys.stdin.buffer.readline())
    bits = np.zeros((26, (1<<19)+1), dtype=np.int64)
    bits[S, np.arange(1, N+1)] = 1
    for i in range(26):
        bitify(bits[i])
    Ans = []
    for t, i, c in zip(*[iter(sys.stdin.buffer.read().split())]*3):
        if t == b"1":
            i = int(i)
            c = ord(c)-97
            c_old = S[i-1]
            S[i-1] = c
            bit_add(bits[c_old], i, -1)
            bit_add(bits[c], i, 1)
        else:
            l, r = int(i), int(c)
            ans = 0
            for bit in bits:
                ans += bool(bit_sum(bit, r)-bit_sum(bit, l-1))
            Ans.append(ans)
    print("\n".join(map(str, Ans))) main def numba_compile(numba_config):
    import os, sys
    if sys.argv[-1] == "ONLINE_JUDGE":
        from numba import njit
        from numba.pycc import CC
        cc = CC("my_module")
        for func, signature in numba_config:
            globals()[func.__name__] = njit(signature)(func)
            cc.export(func.__name__, signature)(func)
        cc.compile()
        exit()
    elif os.name == "posix":
        exec(f"from my_module import {','.join(func.__name__ for func, _ in numba_config)}")
        for func, _ in numba_config:
            globals()[func.__name__] = vars()[func.__name__]
    else:
        from numba import njit
        for func, signature in numba_config:
            globals()[func.__name__] = njit(signature, cache=True)(func)
        print("compiled!", file=sys.stderr)


# >>> binary indexed tree >>>
# 必要な要素数+1 の長さの ndarray の 1 要素目以降を使う def numba_compile(numba_config):
    import os, sys
    if sys.argv[-1] == "ONLINE_JUDGE":
        from numba import njit
        from numba.pycc import CC
        cc = CC("my_module")
        for func, signature in numba_config:
            globals()[func.__name__] = njit(signature)(func)
            cc.export(func.__name__, signature)(func)
        cc.compile()
        exit()
    elif os.name == "posix":
        exec(f"from my_module import {','.join(func.__name__ for func, _ in numba_config)}")
        for func, _ in numba_config:
            globals()[func.__name__] = vars()[func.__name__]
    else:
        from numba import njit
        for func, signature in numba_config:
            globals()[func.__name__] = njit(signature, cache=True)(func)
        print("compiled!", file=sys.stderr)


# >>> binary indexed tree >>>
# 必要な要素数+1 の長さの ndarray の 1 要素目以降を使う numba_compile def bit_add(bit, i, val):  # [bit_add, "void(i8[:],i8,i8)"],
    n = len(bit)
    while i < n:
        bit[i] += val
        i += i & -i
# <<< binary indexed tree <<< def bit_add(bit, i, val):  # [bit_add, "void(i8[:],i8,i8)"],
    n = len(bit)
    while i < n:
        bit[i] += val
        i += i & -i
# <<< binary indexed tree <<< bit_add def bit_sum(bit, i):  # [bit_sum, "i8(i8[:],i8)"],
    # (0, i]
    res = 0
    while i:
        res += bit[i]
        i -= i & -i
    return res def bit_sum(bit, i):  # [bit_sum, "i8(i8[:],i8)"],
    # (0, i]
    res = 0
    while i:
        res += bit[i]
        i -= i & -i
    return res bit_sum
import sys
import numpy as np

def numba_compile(numba_config):
    import os, sys
    if sys.argv[-1] == "ONLINE_JUDGE":
        from numba import njit
        from numba.pycc import CC
        cc = CC("my_module")
        for func, signature in numba_config:
            globals()[func.__name__] = njit(signature)(func)
            cc.export(func.__name__, signature)(func)
        cc.compile()
        exit()
    elif os.name == "posix":
        exec(f"from my_module import {','.join(func.__name__ for func, _ in numba_config)}")
        for func, _ in numba_config:
            globals()[func.__name__] = vars()[func.__name__]
    else:
        from numba import njit
        for func, signature in numba_config:
            globals()[func.__name__] = njit(signature, cache=True)(func)
        print("compiled!", file=sys.stderr)


# >>> binary indexed tree >>>
# 必要な要素数+1 の長さの ndarray の 1 要素目以降を使う
def bitify(arr):
    for i in range(1, len(arr)-1):
        arr[i + (i & -i)] += arr[i]
def bit_sum(bit, i):  # [bit_sum, "i8(i8[:],i8)"],
    # (0, i]
    res = 0
    while i:
        res += bit[i]
        i -= i & -i
    return res
def bit_add(bit, i, val):  # [bit_add, "void(i8[:],i8,i8)"],
    n = len(bit)
    while i < n:
        bit[i] += val
        i += i & -i
# <<< binary indexed tree <<<

numba_compile([
    [bitify, "void(i8[:])"],
    [bit_sum, "i8(i8[:],i8)"],
    [bit_add, "void(i8[:],i8,i8)"],
])


def main():
    N = int(sys.stdin.buffer.readline())
    S = np.frombuffer(sys.stdin.buffer.readline()[:-1], dtype=np.uint8).astype(np.int64) - 97
    Q = int(sys.stdin.buffer.readline())
    bits = np.zeros((26, (1<<19)+1), dtype=np.int64)
    bits[S, np.arange(1, N+1)] = 1
    for i in range(26):
        bitify(bits[i])
    Ans = []
    for t, i, c in zip(*[iter(sys.stdin.buffer.read().split())]*3):
        if t == b"1":
            i = int(i)
            c = ord(c)-97
            c_old = S[i-1]
            S[i-1] = c
            bit_add(bits[c_old], i, -1)
            bit_add(bits[c], i, 1)
        else:
            l, r = int(i), int(c)
            ans = 0
            for bit in bits:
                ans += bool(bit_sum(bit, r)-bit_sum(bit, l-1))
            Ans.append(ans)
    print("\n".join(map(str, Ans)))

main()
