class SegmentTree():

    """一点更新、区間取得クエリをそれぞれO(logN)で答えるデータ構造を構築する

    update: i番目をvalに変更する

    get_min: 区間[begin, end)の最小値を求める

    """

    def __init__(self, n):

        self.n = n

        self.INF = 0

        self.size = 1

        while self.size < n:

            self.size *= 2

        self.node = [self.INF] * (2*self.size - 1)



    def update(self, i, val):

        i += (self.size - 1)

        self.node[i] = val

        while i > 0:

            i = (i - 1) // 2

            self.node[i] = self.node[2*i + 1] | self.node[2*i + 2]



    def get_min(self, begin, end):

        begin += (self.size - 1)

        end += (self.size - 1)

        s = 0

        while begin < end:

            if (end - 1) & 1:

                end -= 1

                s = s | self.node[end]

            if (begin - 1) & 1:

                s = s | self.node[begin]

                begin += 1

            begin = (begin - 1) // 2

            end = (end - 1) // 2

        return s



import sys

input = sys.stdin.readline





n = int(eval(input()))

s = eval(input())

q = int(eval(input()))

query = [list(input().split()) for i in range(q)] 



alph = "abcdefghijklmnopqrstuvwxyz"

to_int = {char: i for i, char in enumerate(alph)}

st = SegmentTree(n)



for i, char in enumerate(s[0:n]):

    st.update(i, 1 << to_int[char]) 



for num, l, r in query:

    if num == "1":

        st.update(int(l) - 1, 1 << to_int[r]) 

    else:

        tmp = st.get_min(int(l) - 1, int(r))

        print((bin(tmp).count("1")))
class SegmentTree():

    """一点更新、区間取得クエリをそれぞれO(logN)で答えるデータ構造を構築する。

    built(array)   := arrayを初期値とするセグメント木を構築する O(N)。

    update(i, val) := i番目の要素をvalに変更する。

    get_val(l, r)  := 区間[l, r)に対する二項演算の畳み込みの結果を返す。

    """



    def __init__(self, n, op, e):

        """要素数、二項演算、単位元を引数として渡す

        例) 区間最小値 SegmentTree(n, min, 10 ** 18)

            区間和     SegmentTree(n, lambda a, b : a + b, 0)

        """

        self.n = n

        self.op = op

        self.e = e

        self.size = 2 ** ((n - 1).bit_length())

        self.node = [self.e] * (2 * self.size)



    def built(self, array):

        """arrayを初期値とするセグメント木を構築する"""

        for i in range(self.n):

            self.node[self.size + i] = array[i]

        for i in range(self.size - 1, 0, -1):

            self.node[i] = self.op(self.node[i << 1], self.node[(i << 1) + 1])



    def update(self, i, val):

        """i番目の要素をvalに変更する"""

        i += self.size

        self.node[i] = val

        while i > 1:

            i >>= 1

            self.node[i] = self.op(self.node[i << 1], self.node[(i << 1) + 1])



    def get_val(self, l, r):

        """[l, r)の畳み込みの結果を返す"""

        l, r = l + self.size, r + self.size

        res = self.e

        while l < r:

            if l & 1:

                res = self.op(self.node[l], res)

                l += 1

            if r & 1:

                r -= 1

                res = self.op(self.node[r], res)

            l, r = l >> 1, r >> 1

        return res



import sys

input = sys.stdin.readline





n = int(eval(input()))

s = eval(input())

q = int(eval(input()))

query = [list(input().split()) for i in range(q)] 

 

alph = "abcdefghijklmnopqrstuvwxyz"

to_int = {char: i for i, char in enumerate(alph)}

st = SegmentTree(n, lambda a, b : a | b, 0)

 

init = [0] * n

for i, char in enumerate(s[0:n]):

    init[i] = 1 << to_int[char]

st.built(init)



for num, l, r in query:

    if num == "1":

        st.update(int(l) - 1, 1 << to_int[r]) 

    else:

        tmp = st.get_val(int(l) - 1, int(r))

        print((bin(tmp).count("1")))
class SegmentTree:
    """一点更新、区間取得クエリをそれぞれO(logN)で答えるデータ構造を構築する
    update: i番目をvalに変更する
    get_min: 区間[begin, end)の最小値を求める
    """

    def __init__(self, n):
        self.n = n
        self.INF = 0
        self.size = 1
        while self.size < n:
            self.size *= 2
        self.node = [self.INF] * (2 * self.size - 1)

    def update(self, i, val):
        i += self.size - 1
        self.node[i] = val
        while i > 0:
            i = (i - 1) // 2
            self.node[i] = self.node[2 * i + 1] | self.node[2 * i + 2]

    def get_min(self, begin, end):
        begin += self.size - 1
        end += self.size - 1
        s = 0
        while begin < end:
            if (end - 1) & 1:
                end -= 1
                s = s | self.node[end]
            if (begin - 1) & 1:
                s = s | self.node[begin]
                begin += 1
            begin = (begin - 1) // 2
            end = (end - 1) // 2
        return s


import sys

input = sys.stdin.readline
n = int(eval(input()))
s = eval(input())
q = int(eval(input()))
query = [list(input().split()) for i in range(q)]
alph = "abcdefghijklmnopqrstuvwxyz"
to_int = {char: i for i, char in enumerate(alph)}
st = SegmentTree(n)
for i, char in enumerate(s[0:n]):
    st.update(i, 1 << to_int[char])
for num, l, r in query:
    if num == "1":
        st.update(int(l) - 1, 1 << to_int[r])
    else:
        tmp = st.get_min(int(l) - 1, int(r))
        print((bin(tmp).count("1")))

class SegmentTree:
    """一点更新、区間取得クエリをそれぞれO(logN)で答えるデータ構造を構築する。
    built(array)   := arrayを初期値とするセグメント木を構築する O(N)。
    update(i, val) := i番目の要素をvalに変更する。
    get_val(l, r)  := 区間[l, r)に対する二項演算の畳み込みの結果を返す。
    """

    def __init__(self, n, op, e):
        """要素数、二項演算、単位元を引数として渡す
        例) 区間最小値 SegmentTree(n, min, 10 ** 18)
            区間和     SegmentTree(n, lambda a, b : a + b, 0)
        """
        self.n = n
        self.op = op
        self.e = e
        self.size = 2 ** ((n - 1).bit_length())
        self.node = [self.e] * (2 * self.size)

    def built(self, array):
        """arrayを初期値とするセグメント木を構築する"""
        for i in range(self.n):
            self.node[self.size + i] = array[i]
        for i in range(self.size - 1, 0, -1):
            self.node[i] = self.op(self.node[i << 1], self.node[(i << 1) + 1])

    def update(self, i, val):
        """i番目の要素をvalに変更する"""
        i += self.size
        self.node[i] = val
        while i > 1:
            i >>= 1
            self.node[i] = self.op(self.node[i << 1], self.node[(i << 1) + 1])

    def get_val(self, l, r):
        """[l, r)の畳み込みの結果を返す"""
        l, r = l + self.size, r + self.size
        res = self.e
        while l < r:
            if l & 1:
                res = self.op(self.node[l], res)
                l += 1
            if r & 1:
                r -= 1
                res = self.op(self.node[r], res)
            l, r = l >> 1, r >> 1
        return res


import sys

input = sys.stdin.readline
n = int(eval(input()))
s = eval(input())
q = int(eval(input()))
query = [list(input().split()) for i in range(q)]
alph = "abcdefghijklmnopqrstuvwxyz"
to_int = {char: i for i, char in enumerate(alph)}
st = SegmentTree(n, lambda a, b: a | b, 0)
init = [0] * n
for i, char in enumerate(s[0:n]):
    init[i] = 1 << to_int[char]
st.built(init)
for num, l, r in query:
    if num == "1":
        st.update(int(l) - 1, 1 << to_int[r])
    else:
        tmp = st.get_val(int(l) - 1, int(r))
        print((bin(tmp).count("1")))

-    """一点更新、区間取得クエリをそれぞれO(logN)で答えるデータ構造を構築する -    update: i番目をvalに変更する -    get_min: 区間[begin, end)の最小値を求める +    """一点更新、区間取得クエリをそれぞれO(logN)で答えるデータ構造を構築する。 +    built(array)   := arrayを初期値とするセグメント木を構築する O(N)。 +    update(i, val) := i番目の要素をvalに変更する。 +    get_val(l, r)  := 区間[l, r)に対する二項演算の畳み込みの結果を返す。 -    def __init__(self, n): +    def __init__(self, n, op, e): +        """要素数、二項演算、単位元を引数として渡す +        例) 区間最小値 SegmentTree(n, min, 10 ** 18) +            区間和     SegmentTree(n, lambda a, b : a + b, 0) +        """ -        self.INF = 0 -        self.size = 1 -        while self.size < n: -            self.size *= 2 -        self.node = [self.INF] * (2 * self.size - 1) +        self.op = op +        self.e = e +        self.size = 2 ** ((n - 1).bit_length()) +        self.node = [self.e] * (2 * self.size) + +    def built(self, array): +        """arrayを初期値とするセグメント木を構築する""" +        for i in range(self.n): +            self.node[self.size + i] = array[i] +        for i in range(self.size - 1, 0, -1): +            self.node[i] = self.op(self.node[i << 1], self.node[(i << 1) + 1]) -        i += self.size - 1 +        """i番目の要素をvalに変更する""" +        i += self.size -        while i > 0: -            i = (i - 1) // 2 -            self.node[i] = self.node[2 * i + 1] | self.node[2 * i + 2] +        while i > 1: +            i >>= 1 +            self.node[i] = self.op(self.node[i << 1], self.node[(i << 1) + 1]) -    def get_min(self, begin, end): -        begin += self.size - 1 -        end += self.size - 1 -        s = 0 -        while begin < end: -            if (end - 1) & 1: -                end -= 1 -                s = s | self.node[end] -            if (begin - 1) & 1: -                s = s | self.node[begin] -                begin += 1 -            begin = (begin - 1) // 2 -            end = (end - 1) // 2 -        return s +    def get_val(self, l, r): +        """[l, r)の畳み込みの結果を返す""" +        l, r = l + self.size, r + self.size +        res = self.e +        while l < r: +            if l & 1: +                res = self.op(self.node[l], res) +                l += 1 +            if r & 1: +                r -= 1 +                res = self.op(self.node[r], res) +            l, r = l >> 1, r >> 1 +        return res -st = SegmentTree(n) +st = SegmentTree(n, lambda a, b: a | b, 0) +init = [0] * n -    st.update(i, 1 << to_int[char]) +    init[i] = 1 << to_int[char] +st.built(init) -        tmp = st.get_min(int(l) - 1, int(r)) +        tmp = st.get_val(int(l) - 1, int(r))