import sys
def input(): return sys.stdin.readline().rstrip()

# ライブラリ参照https://atcoder.jp/contests/practice2/submissions/16580070
class SegmentTree:

    __slots__ = ["func", "e", "original_size", "n", "data"]

    def __init__(self, length_or_list, func, e):
        self.func = func
        self.e = e
        if isinstance(length_or_list, int):
            self.original_size = length_or_list
            self.n = 1 << ((length_or_list - 1).bit_length())
            self.data = [self.e] * self.n
        else:
            self.original_size = len(length_or_list)
            self.n = 1 << ((self.original_size - 1).bit_length())
            self.data = [self.e] * self.n + length_or_list + \
                [self.e] * (self.n - self.original_size)
            for i in range(self.n-1, 0, -1):
                self.data[i] = self.func(self.data[2*i], self.data[2*i+1])

    def replace(self, index, value):
        index += self.n
        self.data[index] = value
        index //= 2
        while index > 0:
            self.data[index] = self.func(
                self.data[2*index], self.data[2*index+1])
            index //= 2

    def folded(self, l, r):
        left_folded = self.e
        right_folded = self.e
        l += self.n
        r += self.n
        while l < r:
            if l % 2:
                left_folded = self.func(left_folded, self.data[l])
                l += 1
            if r % 2:
                r -= 1
                right_folded = self.func(self.data[r], right_folded)
            l //= 2
            r //= 2
        return self.func(left_folded, right_folded)

    def all_folded(self):
        return self.data[1]

    def __getitem__(self, index):
        return self.data[self.n + index]

    def max_right(self, l, f):
        # assert f(self.e)
        if l >= self.original_size:
            return self.original_size
        l += self.n
        left_folded = self.e
        while True:
            # l //= l & -l
            while l % 2 == 0:
                l //= 2
            if not f(self.func(left_folded, self.data[l])):
                while l < self.n:
                    l *= 2
                    if f(self.func(left_folded, self.data[l])):
                        left_folded = self.func(left_folded, self.data[l])
                        l += 1
                return l - self.n
            left_folded = self.func(left_folded, self.data[l])
            l += 1
            if l == l & -l:
                break
        return self.original_size

    # 未verify
    def min_left(self, r, f):
        # assert f(self.e)
        if r == 0:
            return 0
        r += self.n
        right_folded = self.e
        while True:
            r //= r & -r
            if not f(self.func(self.data[r], right_folded)):
                while r < self.n:
                    r = 2 * r + 1
                    if f(self.func(self.data[r], right_folded)):
                        right_folded = self.func(self.data[r], right_folded)
                        r -= 1
                return r + 1 - self.n
            if r == r & -r:
                break
        return 0


def orr(x, y):
    return x | y


def main():
    N = int(input())
    S = input()
    S = list(map(lambda c: 2**(ord(c) - ord('a')), list(S)))
    Q = int(input())
    seg = SegmentTree(S, orr, 0)
    for _ in range(Q):
        num, x, y = input().split()
        if num == '1':
            seg.replace(int(x)-1, 2**(ord(y) - ord('a')))
        else:
            bits = seg.folded(int(x)-1, int(y))
            print(sum(map(int, list(bin(bits))[2:])))


if __name__ == '__main__':
    main() import sys sys def input(): return sys.stdin.readline().rstrip()

# ライブラリ参照https://atcoder.jp/contests/practice2/submissions/16580070 input class SegmentTree:

    __slots__ = ["func", "e", "original_size", "n", "data"]

    def __init__(self, length_or_list, func, e):
        self.func = func
        self.e = e
        if isinstance(length_or_list, int):
            self.original_size = length_or_list
            self.n = 1 << ((length_or_list - 1).bit_length())
            self.data = [self.e] * self.n
        else:
            self.original_size = len(length_or_list)
            self.n = 1 << ((self.original_size - 1).bit_length())
            self.data = [self.e] * self.n + length_or_list + \
                [self.e] * (self.n - self.original_size)
            for i in range(self.n-1, 0, -1):
                self.data[i] = self.func(self.data[2*i], self.data[2*i+1])

    def replace(self, index, value):
        index += self.n
        self.data[index] = value
        index //= 2
        while index > 0:
            self.data[index] = self.func(
                self.data[2*index], self.data[2*index+1])
            index //= 2

    def folded(self, l, r):
        left_folded = self.e
        right_folded = self.e
        l += self.n
        r += self.n
        while l < r:
            if l % 2:
                left_folded = self.func(left_folded, self.data[l])
                l += 1
            if r % 2:
                r -= 1
                right_folded = self.func(self.data[r], right_folded)
            l //= 2
            r //= 2
        return self.func(left_folded, right_folded)

    def all_folded(self):
        return self.data[1]

    def __getitem__(self, index):
        return self.data[self.n + index]

    def max_right(self, l, f):
        # assert f(self.e)
        if l >= self.original_size:
            return self.original_size
        l += self.n
        left_folded = self.e
        while True:
            # l //= l & -l
            while l % 2 == 0:
                l //= 2
            if not f(self.func(left_folded, self.data[l])):
                while l < self.n:
                    l *= 2
                    if f(self.func(left_folded, self.data[l])):
                        left_folded = self.func(left_folded, self.data[l])
                        l += 1
                return l - self.n
            left_folded = self.func(left_folded, self.data[l])
            l += 1
            if l == l & -l:
                break
        return self.original_size

    # 未verify
    def min_left(self, r, f):
        # assert f(self.e)
        if r == 0:
            return 0
        r += self.n
        right_folded = self.e
        while True:
            r //= r & -r
            if not f(self.func(self.data[r], right_folded)):
                while r < self.n:
                    r = 2 * r + 1
                    if f(self.func(self.data[r], right_folded)):
                        right_folded = self.func(self.data[r], right_folded)
                        r -= 1
                return r + 1 - self.n
            if r == r & -r:
                break
        return 0 SegmentTree __slots__ = ["func", "e", "original_size", "n", "data"] __slots__ ["func", "e", "original_size", "n", "data"] "func" "e" "original_size" "n" "data" def __init__(self, length_or_list, func, e):
        self.func = func
        self.e = e
        if isinstance(length_or_list, int):
            self.original_size = length_or_list
            self.n = 1 << ((length_or_list - 1).bit_length())
            self.data = [self.e] * self.n
        else:
            self.original_size = len(length_or_list)
            self.n = 1 << ((self.original_size - 1).bit_length())
            self.data = [self.e] * self.n + length_or_list + \
                [self.e] * (self.n - self.original_size)
            for i in range(self.n-1, 0, -1):
                self.data[i] = self.func(self.data[2*i], self.data[2*i+1])

     __init__ self.func = func self.func self func func self.e = e self.e self e e if isinstance(length_or_list, int):
            self.original_size = length_or_list
            self.n = 1 << ((length_or_list - 1).bit_length())
            self.data = [self.e] * self.n
        else:
            self.original_size = len(length_or_list)
            self.n = 1 << ((self.original_size - 1).bit_length())
            self.data = [self.e] * self.n + length_or_list + \
                [self.e] * (self.n - self.original_size)
            for i in range(self.n-1, 0, -1):
                self.data[i] = self.func(self.data[2*i], self.data[2*i+1])

     isinstance(length_or_list, int) isinstance length_or_list int self.original_size = length_or_list self.original_size self original_size length_or_list self.n = 1 << ((length_or_list - 1).bit_length()) self.n self n 1 << ((length_or_list - 1).bit_length()) 1 (length_or_list - 1).bit_length() length_or_list - 1).bit_length length_or_list - 1 length_or_list 1 bit_length self.data = [self.e] * self.n self.data self data [self.e] * self.n [self.e] self.e self e self.n self n self.original_size = len(length_or_list) self.original_size self original_size len(length_or_list) len length_or_list self.n = 1 << ((self.original_size - 1).bit_length()) self.n self n 1 << ((self.original_size - 1).bit_length()) 1 (self.original_size - 1).bit_length() self.original_size - 1).bit_length self.original_size - 1 self.original_size self original_size 1 bit_length self.data = [self.e] * self.n + length_or_list + \
                [self.e] * (self.n - self.original_size) self.data self data [self.e] * self.n + length_or_list + \
                [self.e] * (self.n - self.original_size) [self.e] * self.n + length_or_list [self.e] * self.n [self.e] self.e self e self.n self n length_or_list [self.e] * (self.n - self.original_size) [self.e] self.e self e self.n - self.original_size self.n self n self.original_size self original_size for i in range(self.n-1, 0, -1):
                self.data[i] = self.func(self.data[2*i], self.data[2*i+1])

     i range(self.n-1, 0, -1) range self.n-1 self.n self n 1 0 -1 self.data[i] = self.func(self.data[2*i], self.data[2*i+1]) self.data[i] self.data self data i self.func(self.data[2*i], self.data[2*i+1]) self.func self func self.data[2*i] self.data self data 2*i 2 i self.data[2*i+1] self.data self data 2*i+1 2*i 2 i 1 self self length_or_list length_or_list func func e e def replace(self, index, value):
        index += self.n
        self.data[index] = value
        index //= 2
        while index > 0:
            self.data[index] = self.func(
                self.data[2*index], self.data[2*index+1])
            index //= 2

     replace index += self.n index self.n self n self.data[index] = value self.data[index] self.data self data index value index //= 2 index 2 while index > 0:
            self.data[index] = self.func(
                self.data[2*index], self.data[2*index+1])
            index //= 2

     index > 0 index 0 self.data[index] = self.func(
                self.data[2*index], self.data[2*index+1]) self.data[index] self.data self data index self.func(
                self.data[2*index], self.data[2*index+1]) self.func self func self.data[2*index] self.data self data 2*index 2 index self.data[2*index+1] self.data self data 2*index+1 2*index 2 index 1 index //= 2 index 2 self self index index value value def folded(self, l, r):
        left_folded = self.e
        right_folded = self.e
        l += self.n
        r += self.n
        while l < r:
            if l % 2:
                left_folded = self.func(left_folded, self.data[l])
                l += 1
            if r % 2:
                r -= 1
                right_folded = self.func(self.data[r], right_folded)
            l //= 2
            r //= 2
        return self.func(left_folded, right_folded)

     folded left_folded = self.e left_folded self.e self e right_folded = self.e right_folded self.e self e l += self.n l self.n self n r += self.n r self.n self n while l < r:
            if l % 2:
                left_folded = self.func(left_folded, self.data[l])
                l += 1
            if r % 2:
                r -= 1
                right_folded = self.func(self.data[r], right_folded)
            l //= 2
            r //= 2
         l < r l r if l % 2:
                left_folded = self.func(left_folded, self.data[l])
                l += 1
             l % 2 l 2 left_folded = self.func(left_folded, self.data[l]) left_folded self.func(left_folded, self.data[l]) self.func self func left_folded self.data[l] self.data self data l l += 1 l 1 if r % 2:
                r -= 1
                right_folded = self.func(self.data[r], right_folded)
             r % 2 r 2 r -= 1 r 1 right_folded = self.func(self.data[r], right_folded) right_folded self.func(self.data[r], right_folded) self.func self func self.data[r] self.data self data r right_folded l //= 2 l 2 r //= 2 r 2 return self.func(left_folded, right_folded) self.func(left_folded, right_folded) self.func self func left_folded right_folded self self l l r r def all_folded(self):
        return self.data[1]

     all_folded return self.data[1] self.data[1] self.data self data 1 self self def __getitem__(self, index):
        return self.data[self.n + index]

     __getitem__ return self.data[self.n + index] self.data[self.n + index] self.data self data self.n + index self.n self n index self self index index def max_right(self, l, f):
        # assert f(self.e)
        if l >= self.original_size:
            return self.original_size
        l += self.n
        left_folded = self.e
        while True:
            # l //= l & -l
            while l % 2 == 0:
                l //= 2
            if not f(self.func(left_folded, self.data[l])):
                while l < self.n:
                    l *= 2
                    if f(self.func(left_folded, self.data[l])):
                        left_folded = self.func(left_folded, self.data[l])
                        l += 1
                return l - self.n
            left_folded = self.func(left_folded, self.data[l])
            l += 1
            if l == l & -l:
                break
        return self.original_size

    # 未verify
     max_right if l >= self.original_size:
            return self.original_size
         l >= self.original_size l self.original_size self original_size return self.original_size self.original_size self original_size l += self.n l self.n self n left_folded = self.e left_folded self.e self e while True:
            # l //= l & -l
            while l % 2 == 0:
                l //= 2
            if not f(self.func(left_folded, self.data[l])):
                while l < self.n:
                    l *= 2
                    if f(self.func(left_folded, self.data[l])):
                        left_folded = self.func(left_folded, self.data[l])
                        l += 1
                return l - self.n
            left_folded = self.func(left_folded, self.data[l])
            l += 1
            if l == l & -l:
                break
         True while l % 2 == 0:
                l //= 2
             l % 2 == 0 l % 2 l 2 0 l //= 2 l 2 if not f(self.func(left_folded, self.data[l])):
                while l < self.n:
                    l *= 2
                    if f(self.func(left_folded, self.data[l])):
                        left_folded = self.func(left_folded, self.data[l])
                        l += 1
                return l - self.n
             not f(self.func(left_folded, self.data[l])) f(self.func(left_folded, self.data[l])) f self.func(left_folded, self.data[l]) self.func self func left_folded self.data[l] self.data self data l while l < self.n:
                    l *= 2
                    if f(self.func(left_folded, self.data[l])):
                        left_folded = self.func(left_folded, self.data[l])
                        l += 1
                 l < self.n l self.n self n l *= 2 l 2 if f(self.func(left_folded, self.data[l])):
                        left_folded = self.func(left_folded, self.data[l])
                        l += 1
                 f(self.func(left_folded, self.data[l])) f self.func(left_folded, self.data[l]) self.func self func left_folded self.data[l] self.data self data l left_folded = self.func(left_folded, self.data[l]) left_folded self.func(left_folded, self.data[l]) self.func self func left_folded self.data[l] self.data self data l l += 1 l 1 return l - self.n l - self.n l self.n self n left_folded = self.func(left_folded, self.data[l]) left_folded self.func(left_folded, self.data[l]) self.func self func left_folded self.data[l] self.data self data l l += 1 l 1 if l == l & -l:
                break
         l == l & -l l l & -l l -l l break return self.original_size self.original_size self original_size self self l l f f def min_left(self, r, f):
        # assert f(self.e)
        if r == 0:
            return 0
        r += self.n
        right_folded = self.e
        while True:
            r //= r & -r
            if not f(self.func(self.data[r], right_folded)):
                while r < self.n:
                    r = 2 * r + 1
                    if f(self.func(self.data[r], right_folded)):
                        right_folded = self.func(self.data[r], right_folded)
                        r -= 1
                return r + 1 - self.n
            if r == r & -r:
                break
        return 0 min_left if r == 0:
            return 0
         r == 0 r 0 return 0 0 r += self.n r self.n self n right_folded = self.e right_folded self.e self e while True:
            r //= r & -r
            if not f(self.func(self.data[r], right_folded)):
                while r < self.n:
                    r = 2 * r + 1
                    if f(self.func(self.data[r], right_folded)):
                        right_folded = self.func(self.data[r], right_folded)
                        r -= 1
                return r + 1 - self.n
            if r == r & -r:
                break
         True r //= r & -r r r & -r r -r r if not f(self.func(self.data[r], right_folded)):
                while r < self.n:
                    r = 2 * r + 1
                    if f(self.func(self.data[r], right_folded)):
                        right_folded = self.func(self.data[r], right_folded)
                        r -= 1
                return r + 1 - self.n
             not f(self.func(self.data[r], right_folded)) f(self.func(self.data[r], right_folded)) f self.func(self.data[r], right_folded) self.func self func self.data[r] self.data self data r right_folded while r < self.n:
                    r = 2 * r + 1
                    if f(self.func(self.data[r], right_folded)):
                        right_folded = self.func(self.data[r], right_folded)
                        r -= 1
                 r < self.n r self.n self n r = 2 * r + 1 r 2 * r + 1 2 * r 2 r 1 if f(self.func(self.data[r], right_folded)):
                        right_folded = self.func(self.data[r], right_folded)
                        r -= 1
                 f(self.func(self.data[r], right_folded)) f self.func(self.data[r], right_folded) self.func self func self.data[r] self.data self data r right_folded right_folded = self.func(self.data[r], right_folded) right_folded self.func(self.data[r], right_folded) self.func self func self.data[r] self.data self data r right_folded r -= 1 r 1 return r + 1 - self.n r + 1 - self.n r + 1 r 1 self.n self n if r == r & -r:
                break
         r == r & -r r r & -r r -r r break return 0 0 self self r r f f def orr(x, y):
    return x | y orr return x | y x | y x y x x y y def main():
    N = int(input())
    S = input()
    S = list(map(lambda c: 2**(ord(c) - ord('a')), list(S)))
    Q = int(input())
    seg = SegmentTree(S, orr, 0)
    for _ in range(Q):
        num, x, y = input().split()
        if num == '1':
            seg.replace(int(x)-1, 2**(ord(y) - ord('a')))
        else:
            bits = seg.folded(int(x)-1, int(y))
            print(sum(map(int, list(bin(bits))[2:]))) main N = int(input()) N int(input()) int input() input S = input() S input() input S = list(map(lambda c: 2**(ord(c) - ord('a')), list(S))) S list(map(lambda c: 2**(ord(c) - ord('a')), list(S))) list map(lambda c: 2**(ord(c) - ord('a')), list(S)) map lambda c: 2**(ord(c) - ord('a')) 2**(ord(c) - ord('a')) 2 ord(c) - ord('a') ord(c) ord c ord('a') ord 'a' c list(S) list S Q = int(input()) Q int(input()) int input() input seg = SegmentTree(S, orr, 0) seg SegmentTree(S, orr, 0) SegmentTree S orr 0 for _ in range(Q):
        num, x, y = input().split()
        if num == '1':
            seg.replace(int(x)-1, 2**(ord(y) - ord('a')))
        else:
            bits = seg.folded(int(x)-1, int(y))
            print(sum(map(int, list(bin(bits))[2:]))) _ range(Q) range Q num, x, y = input().split() num input().split() ().split () input split x y if num == '1':
            seg.replace(int(x)-1, 2**(ord(y) - ord('a')))
        else:
            bits = seg.folded(int(x)-1, int(y))
            print(sum(map(int, list(bin(bits))[2:]))) num == '1' num '1' seg.replace(int(x)-1, 2**(ord(y) - ord('a'))) seg.replace seg replace int(x)-1 int(x) int x 1 2**(ord(y) - ord('a')) 2 ord(y) - ord('a') ord(y) ord y ord('a') ord 'a' bits = seg.folded(int(x)-1, int(y)) bits seg.folded(int(x)-1, int(y)) seg.folded seg folded int(x)-1 int(x) int x 1 int(y) int y print(sum(map(int, list(bin(bits))[2:]))) print sum(map(int, list(bin(bits))[2:])) sum map(int, list(bin(bits))[2:]) map int list(bin(bits))[2:] (bin(bits)) list bin(bits) bin bits 2: 2 if __name__ == '__main__':
    main() __name__ == '__main__' __name__ '__main__' main() main class SegmentTree:

    __slots__ = ["func", "e", "original_size", "n", "data"]

    def __init__(self, length_or_list, func, e):
        self.func = func
        self.e = e
        if isinstance(length_or_list, int):
            self.original_size = length_or_list
            self.n = 1 << ((length_or_list - 1).bit_length())
            self.data = [self.e] * self.n
        else:
            self.original_size = len(length_or_list)
            self.n = 1 << ((self.original_size - 1).bit_length())
            self.data = [self.e] * self.n + length_or_list + \
                [self.e] * (self.n - self.original_size)
            for i in range(self.n-1, 0, -1):
                self.data[i] = self.func(self.data[2*i], self.data[2*i+1])

    def replace(self, index, value):
        index += self.n
        self.data[index] = value
        index //= 2
        while index > 0:
            self.data[index] = self.func(
                self.data[2*index], self.data[2*index+1])
            index //= 2

    def folded(self, l, r):
        left_folded = self.e
        right_folded = self.e
        l += self.n
        r += self.n
        while l < r:
            if l % 2:
                left_folded = self.func(left_folded, self.data[l])
                l += 1
            if r % 2:
                r -= 1
                right_folded = self.func(self.data[r], right_folded)
            l //= 2
            r //= 2
        return self.func(left_folded, right_folded)

    def all_folded(self):
        return self.data[1]

    def __getitem__(self, index):
        return self.data[self.n + index]

    def max_right(self, l, f):
        # assert f(self.e)
        if l >= self.original_size:
            return self.original_size
        l += self.n
        left_folded = self.e
        while True:
            # l //= l & -l
            while l % 2 == 0:
                l //= 2
            if not f(self.func(left_folded, self.data[l])):
                while l < self.n:
                    l *= 2
                    if f(self.func(left_folded, self.data[l])):
                        left_folded = self.func(left_folded, self.data[l])
                        l += 1
                return l - self.n
            left_folded = self.func(left_folded, self.data[l])
            l += 1
            if l == l & -l:
                break
        return self.original_size

    # 未verify
    def min_left(self, r, f):
        # assert f(self.e)
        if r == 0:
            return 0
        r += self.n
        right_folded = self.e
        while True:
            r //= r & -r
            if not f(self.func(self.data[r], right_folded)):
                while r < self.n:
                    r = 2 * r + 1
                    if f(self.func(self.data[r], right_folded)):
                        right_folded = self.func(self.data[r], right_folded)
                        r -= 1
                return r + 1 - self.n
            if r == r & -r:
                break
        return 0 class SegmentTree:

    __slots__ = ["func", "e", "original_size", "n", "data"]

    def __init__(self, length_or_list, func, e):
        self.func = func
        self.e = e
        if isinstance(length_or_list, int):
            self.original_size = length_or_list
            self.n = 1 << ((length_or_list - 1).bit_length())
            self.data = [self.e] * self.n
        else:
            self.original_size = len(length_or_list)
            self.n = 1 << ((self.original_size - 1).bit_length())
            self.data = [self.e] * self.n + length_or_list + \
                [self.e] * (self.n - self.original_size)
            for i in range(self.n-1, 0, -1):
                self.data[i] = self.func(self.data[2*i], self.data[2*i+1])

    def replace(self, index, value):
        index += self.n
        self.data[index] = value
        index //= 2
        while index > 0:
            self.data[index] = self.func(
                self.data[2*index], self.data[2*index+1])
            index //= 2

    def folded(self, l, r):
        left_folded = self.e
        right_folded = self.e
        l += self.n
        r += self.n
        while l < r:
            if l % 2:
                left_folded = self.func(left_folded, self.data[l])
                l += 1
            if r % 2:
                r -= 1
                right_folded = self.func(self.data[r], right_folded)
            l //= 2
            r //= 2
        return self.func(left_folded, right_folded)

    def all_folded(self):
        return self.data[1]

    def __getitem__(self, index):
        return self.data[self.n + index]

    def max_right(self, l, f):
        # assert f(self.e)
        if l >= self.original_size:
            return self.original_size
        l += self.n
        left_folded = self.e
        while True:
            # l //= l & -l
            while l % 2 == 0:
                l //= 2
            if not f(self.func(left_folded, self.data[l])):
                while l < self.n:
                    l *= 2
                    if f(self.func(left_folded, self.data[l])):
                        left_folded = self.func(left_folded, self.data[l])
                        l += 1
                return l - self.n
            left_folded = self.func(left_folded, self.data[l])
            l += 1
            if l == l & -l:
                break
        return self.original_size

    # 未verify
    def min_left(self, r, f):
        # assert f(self.e)
        if r == 0:
            return 0
        r += self.n
        right_folded = self.e
        while True:
            r //= r & -r
            if not f(self.func(self.data[r], right_folded)):
                while r < self.n:
                    r = 2 * r + 1
                    if f(self.func(self.data[r], right_folded)):
                        right_folded = self.func(self.data[r], right_folded)
                        r -= 1
                return r + 1 - self.n
            if r == r & -r:
                break
        return 0 SegmentTree def orr(x, y):
    return x | y def orr(x, y):
    return x | y orr def input(): return sys.stdin.readline().rstrip()

# ライブラリ参照https://atcoder.jp/contests/practice2/submissions/16580070 def input(): return sys.stdin.readline().rstrip()

# ライブラリ参照https://atcoder.jp/contests/practice2/submissions/16580070 input def main():
    N = int(input())
    S = input()
    S = list(map(lambda c: 2**(ord(c) - ord('a')), list(S)))
    Q = int(input())
    seg = SegmentTree(S, orr, 0)
    for _ in range(Q):
        num, x, y = input().split()
        if num == '1':
            seg.replace(int(x)-1, 2**(ord(y) - ord('a')))
        else:
            bits = seg.folded(int(x)-1, int(y))
            print(sum(map(int, list(bin(bits))[2:]))) def main():
    N = int(input())
    S = input()
    S = list(map(lambda c: 2**(ord(c) - ord('a')), list(S)))
    Q = int(input())
    seg = SegmentTree(S, orr, 0)
    for _ in range(Q):
        num, x, y = input().split()
        if num == '1':
            seg.replace(int(x)-1, 2**(ord(y) - ord('a')))
        else:
            bits = seg.folded(int(x)-1, int(y))
            print(sum(map(int, list(bin(bits))[2:]))) main
import sys
def input(): return sys.stdin.readline().rstrip()

# ライブラリ参照https://atcoder.jp/contests/practice2/submissions/16580070
class SegmentTree:

    __slots__ = ["func", "e", "original_size", "n", "data"]

    def __init__(self, length_or_list, func, e):
        self.func = func
        self.e = e
        if isinstance(length_or_list, int):
            self.original_size = length_or_list
            self.n = 1 << ((length_or_list - 1).bit_length())
            self.data = [self.e] * self.n
        else:
            self.original_size = len(length_or_list)
            self.n = 1 << ((self.original_size - 1).bit_length())
            self.data = [self.e] * self.n + length_or_list + \
                [self.e] * (self.n - self.original_size)
            for i in range(self.n-1, 0, -1):
                self.data[i] = self.func(self.data[2*i], self.data[2*i+1])

    def replace(self, index, value):
        index += self.n
        self.data[index] = value
        index //= 2
        while index > 0:
            self.data[index] = self.func(
                self.data[2*index], self.data[2*index+1])
            index //= 2

    def folded(self, l, r):
        left_folded = self.e
        right_folded = self.e
        l += self.n
        r += self.n
        while l < r:
            if l % 2:
                left_folded = self.func(left_folded, self.data[l])
                l += 1
            if r % 2:
                r -= 1
                right_folded = self.func(self.data[r], right_folded)
            l //= 2
            r //= 2
        return self.func(left_folded, right_folded)

    def all_folded(self):
        return self.data[1]

    def __getitem__(self, index):
        return self.data[self.n + index]

    def max_right(self, l, f):
        # assert f(self.e)
        if l >= self.original_size:
            return self.original_size
        l += self.n
        left_folded = self.e
        while True:
            # l //= l & -l
            while l % 2 == 0:
                l //= 2
            if not f(self.func(left_folded, self.data[l])):
                while l < self.n:
                    l *= 2
                    if f(self.func(left_folded, self.data[l])):
                        left_folded = self.func(left_folded, self.data[l])
                        l += 1
                return l - self.n
            left_folded = self.func(left_folded, self.data[l])
            l += 1
            if l == l & -l:
                break
        return self.original_size

    # 未verify
    def min_left(self, r, f):
        # assert f(self.e)
        if r == 0:
            return 0
        r += self.n
        right_folded = self.e
        while True:
            r //= r & -r
            if not f(self.func(self.data[r], right_folded)):
                while r < self.n:
                    r = 2 * r + 1
                    if f(self.func(self.data[r], right_folded)):
                        right_folded = self.func(self.data[r], right_folded)
                        r -= 1
                return r + 1 - self.n
            if r == r & -r:
                break
        return 0


def orr(x, y):
    return x | y


def main():
    N = int(input())
    S = input()
    S = list(map(lambda c: 2**(ord(c) - ord('a')), list(S)))
    Q = int(input())
    seg = SegmentTree(S, orr, 0)
    for _ in range(Q):
        num, x, y = input().split()
        if num == '1':
            seg.replace(int(x)-1, 2**(ord(y) - ord('a')))
        else:
            bits = seg.folded(int(x)-1, int(y))
            print(sum(map(int, list(bin(bits))[2:])))


if __name__ == '__main__':
    main()