#coding:utf-8
import sys,os
sys.setrecursionlimit(10**6)
write = sys.stdout.write
dbg = (lambda *something: print(*something)) if 'TERM_PROGRAM' in os.environ else lambda *x: 0
from collections import Counter, deque
from random import random
class Node:
        def __init__(self,value:int=-1):
            self.left = None
            self.right = None
            self.value = value
            self.priority = random()
            # self.count_partial = 1
            # self.sum_partial = value
class Treap:
    
    #Node [left, right, key, value, priority]
    def __init__(self):
        self.root = None

    # def update(self, node):
    #     if node.left is None:
    #         left_count = 0
    #         left_sum = 0
    #     else:
    #         left_count = node.left.count_partial
    #         left_sum = node.left.sum_partial
    #     if node.right is None:
    #         right_count = 0
    #         right_sum = 0
    #     else:
    #         right_count = node.right.count_partial
    #         right_sum = node.right.sum_partial

    #     node.count_partial = left_count + right_count + 1
    #     node.sum_partial = left_sum + right_sum + node.value
    #     return node

    def merge(self, left_tree, right_tree):
        if left_tree is None or right_tree is None:
            return left_tree if right_tree is None else right_tree

        # priority
        if left_tree[4] > right_tree[4]:
            left_tree[1] = self.merge(left_tree[1], right_tree)
            # return self.update(left)
            return left_tree
        else:
            right_tree[0] = self.merge(left_tree,right_tree[0])
            # return self.update(right)
            return right_tree


    # def node_size(self, node:Node):
    #     return 0 if node is None else node.count_partial
    
    # def node_key(self, node:None):
    #     return -1 if node is None else node.key

    #指定された場所のノードは右の木に含まれる

    # def split(self, node:Node, key:int, level=0):
    #     if node is None:
    #         return (None,None)

    #     if key <= self.node_size(node.left):
    #         left,right = self.split(node.left, key,level+1)
    #         node.left = right
    #         return left, self.update(node)
    #     else:
    #         left,right = self.split(node.right, key - self.node_size(node.left) - 1,level+1)
    #         node.right = left
    #         return self.update(node),right 
    def split(self, node:None, value):
        if node is None:
            return None,None

        if value <= node[3]:
            left_tree,right_tree = self.split(node[0], value)
            node[0] = right_tree
            return left_tree, node
        else:
            left_tree,right_tree = self.split(node[1], value)
            node[1] = left_tree
            return node, right_tree

    
    def insert(self, key:int,value:int =-1):
        value = value if value > 0 else key
        left_tree, right_tree = self.split(self.root, key)
        new_node = [None,None,key,value,random()]
        self.root = self.merge(self.merge(left_tree,new_node),right_tree)
    
    def erase(self, pos:int):
        middle_tree,right_tree = self.split(self.root, pos+1)
        left_tree,middle_tree = self.split(middle_tree, pos)
        self.root = self.merge(left_tree,right_tree)

        

    def printTree(self, node=None, level=0):
        node = self.root if node is None else node
        if node is None:
            print('level=',level,'root is None')
            return
        else:
            print('level=',level,'v=',node.value,'c=',node.count_partial, 'p=',node.priority)
        if node.left is not None:
            self.printTree(node.left,level+1)
        
        if node.right is not None:
            self.printTree(node.right,level+1)
        
    

    # def search(self, pos):
    #     #return self.search_recursively(pos,self.root)
    #     v = self.root
    #     while v:
    #         left_count = self.node_size(v.left)
    #         if pos < left_count:
    #             v = v.left
    #         elif pos == left_count:
    #             return v.value
    #         else:
    #             v = v.right
    #             pos -= left_count + 1
    #     return -1

    def search2(self, value):
        v = self.root
        upper = 10**18
        while v:
            if value == v[3]:
                return value

            elif value < v[3]:
                upper = v[3]
                v = v[0]
            else:
                v = v[1]
        return upper

    # def search_recursively(self, pos, node):
    #     if node is None:
    #         return -1
    #     num_left = 0 if node.left is None else node.left.count_partial
    #     if num_left + 1 == pos:
    #         return node.value
    #     if pos <= num_left:
    #         return self.search_recursively(pos, node.left)
    #     else:
    #         return self.search_recursively(pos - num_left - 1, node.right)
        


    
                










def main(given=sys.stdin.readline):
    input = lambda: given().rstrip()
    LMIIS = lambda: list(map(int,input().split()))
    II = lambda: int(input())
    XLMIIS = lambda x: [LMIIS() for _ in range(x)]
    YN = lambda c : print('Yes') if c else print('No')
    MOD = 10**9+7

    N = II()
    S = list(map(lambda c: ord(c) - ord('a'), list(input())))



    trees = []
    for i in range(26):
        trees.append(Treap())
    

    for i,c in enumerate(S):
        trees[c].insert(i)
    
    Q = int(input())
    out = []
    for _ in range(Q):
        q1,q2,q3 = input().split()
        if int(q1) == 1:
            iq = int(q2)-1
            before = S[iq]
            after = ord(q3)-ord('a')
            S[iq] = after
            trees[before].erase(iq)
            trees[after].insert(iq)

        else:
            l,r = int(q2)-1,int(q3)-1
            count = 0
            for i in range(26):
                if trees[i].search2(l) <= r:
                    count += 1
            out.append(count)
    print('\n'.join(map(str,out)))


if __name__ == '__main__':
    main() import sys,os sys os sys.setrecursionlimit(10**6) sys.setrecursionlimit sys setrecursionlimit 10**6 10 6 write = sys.stdout.write write sys.stdout.write sys.stdout sys stdout write dbg = (lambda *something: print(*something)) if 'TERM_PROGRAM' in os.environ else lambda *x: 0 dbg (lambda *something: print(*something)) if 'TERM_PROGRAM' in os.environ else lambda *x: 0 'TERM_PROGRAM' in os.environ 'TERM_PROGRAM' os.environ os environ lambda *something: print(*something) print(*something) print *something something *something lambda *x: 0 0 *x from collections import Counter, deque from random import random class Node:
        def __init__(self,value:int=-1):
            self.left = None
            self.right = None
            self.value = value
            self.priority = random()
            # self.count_partial = 1
            # self.sum_partial = value Node def __init__(self,value:int=-1):
            self.left = None
            self.right = None
            self.value = value
            self.priority = random()
            # self.count_partial = 1
            # self.sum_partial = value __init__ self.left = None self.left self left None self.right = None self.right self right None self.value = value self.value self value value self.priority = random() self.priority self priority random() random self self value:int=-1 value -1 class Treap:
    
    #Node [left, right, key, value, priority]
    def __init__(self):
        self.root = None

    # def update(self, node):
    #     if node.left is None:
    #         left_count = 0
    #         left_sum = 0
    #     else:
    #         left_count = node.left.count_partial
    #         left_sum = node.left.sum_partial
    #     if node.right is None:
    #         right_count = 0
    #         right_sum = 0
    #     else:
    #         right_count = node.right.count_partial
    #         right_sum = node.right.sum_partial

    #     node.count_partial = left_count + right_count + 1
    #     node.sum_partial = left_sum + right_sum + node.value
    #     return node

    def merge(self, left_tree, right_tree):
        if left_tree is None or right_tree is None:
            return left_tree if right_tree is None else right_tree

        # priority
        if left_tree[4] > right_tree[4]:
            left_tree[1] = self.merge(left_tree[1], right_tree)
            # return self.update(left)
            return left_tree
        else:
            right_tree[0] = self.merge(left_tree,right_tree[0])
            # return self.update(right)
            return right_tree


    # def node_size(self, node:Node):
    #     return 0 if node is None else node.count_partial
    
    # def node_key(self, node:None):
    #     return -1 if node is None else node.key

    #指定された場所のノードは右の木に含まれる

    # def split(self, node:Node, key:int, level=0):
    #     if node is None:
    #         return (None,None)

    #     if key <= self.node_size(node.left):
    #         left,right = self.split(node.left, key,level+1)
    #         node.left = right
    #         return left, self.update(node)
    #     else:
    #         left,right = self.split(node.right, key - self.node_size(node.left) - 1,level+1)
    #         node.right = left
    #         return self.update(node),right 
    def split(self, node:None, value):
        if node is None:
            return None,None

        if value <= node[3]:
            left_tree,right_tree = self.split(node[0], value)
            node[0] = right_tree
            return left_tree, node
        else:
            left_tree,right_tree = self.split(node[1], value)
            node[1] = left_tree
            return node, right_tree

    
    def insert(self, key:int,value:int =-1):
        value = value if value > 0 else key
        left_tree, right_tree = self.split(self.root, key)
        new_node = [None,None,key,value,random()]
        self.root = self.merge(self.merge(left_tree,new_node),right_tree)
    
    def erase(self, pos:int):
        middle_tree,right_tree = self.split(self.root, pos+1)
        left_tree,middle_tree = self.split(middle_tree, pos)
        self.root = self.merge(left_tree,right_tree)

        

    def printTree(self, node=None, level=0):
        node = self.root if node is None else node
        if node is None:
            print('level=',level,'root is None')
            return
        else:
            print('level=',level,'v=',node.value,'c=',node.count_partial, 'p=',node.priority)
        if node.left is not None:
            self.printTree(node.left,level+1)
        
        if node.right is not None:
            self.printTree(node.right,level+1)
        
    

    # def search(self, pos):
    #     #return self.search_recursively(pos,self.root)
    #     v = self.root
    #     while v:
    #         left_count = self.node_size(v.left)
    #         if pos < left_count:
    #             v = v.left
    #         elif pos == left_count:
    #             return v.value
    #         else:
    #             v = v.right
    #             pos -= left_count + 1
    #     return -1

    def search2(self, value):
        v = self.root
        upper = 10**18
        while v:
            if value == v[3]:
                return value

            elif value < v[3]:
                upper = v[3]
                v = v[0]
            else:
                v = v[1]
        return upper

    # def search_recursively(self, pos, node):
    #     if node is None:
    #         return -1
    #     num_left = 0 if node.left is None else node.left.count_partial
    #     if num_left + 1 == pos:
    #         return node.value
    #     if pos <= num_left:
    #         return self.search_recursively(pos, node.left)
    #     else:
    #         return self.search_recursively(pos - num_left - 1, node.right)
        


    
                 Treap def __init__(self):
        self.root = None

    # def update(self, node):
    #     if node.left is None:
    #         left_count = 0
    #         left_sum = 0
    #     else:
    #         left_count = node.left.count_partial
    #         left_sum = node.left.sum_partial
    #     if node.right is None:
    #         right_count = 0
    #         right_sum = 0
    #     else:
    #         right_count = node.right.count_partial
    #         right_sum = node.right.sum_partial

    #     node.count_partial = left_count + right_count + 1
    #     node.sum_partial = left_sum + right_sum + node.value
    #     return node

     __init__ self.root = None self.root self root None self self def merge(self, left_tree, right_tree):
        if left_tree is None or right_tree is None:
            return left_tree if right_tree is None else right_tree

        # priority
        if left_tree[4] > right_tree[4]:
            left_tree[1] = self.merge(left_tree[1], right_tree)
            # return self.update(left)
            return left_tree
        else:
            right_tree[0] = self.merge(left_tree,right_tree[0])
            # return self.update(right)
            return right_tree


    # def node_size(self, node:Node):
    #     return 0 if node is None else node.count_partial
    
    # def node_key(self, node:None):
    #     return -1 if node is None else node.key

    #指定された場所のノードは右の木に含まれる

    # def split(self, node:Node, key:int, level=0):
    #     if node is None:
    #         return (None,None)

    #     if key <= self.node_size(node.left):
    #         left,right = self.split(node.left, key,level+1)
    #         node.left = right
    #         return left, self.update(node)
    #     else:
    #         left,right = self.split(node.right, key - self.node_size(node.left) - 1,level+1)
    #         node.right = left
    #         return self.update(node),right 
     merge if left_tree is None or right_tree is None:
            return left_tree if right_tree is None else right_tree

        # priority
         left_tree is None or right_tree is None left_tree is None left_tree None right_tree is None right_tree None return left_tree if right_tree is None else right_tree left_tree if right_tree is None else right_tree right_tree is None right_tree None left_tree right_tree if left_tree[4] > right_tree[4]:
            left_tree[1] = self.merge(left_tree[1], right_tree)
            # return self.update(left)
            return left_tree
        else:
            right_tree[0] = self.merge(left_tree,right_tree[0])
            # return self.update(right)
            return right_tree


    # def node_size(self, node:Node):
    #     return 0 if node is None else node.count_partial
    
    # def node_key(self, node:None):
    #     return -1 if node is None else node.key

    #指定された場所のノードは右の木に含まれる

    # def split(self, node:Node, key:int, level=0):
    #     if node is None:
    #         return (None,None)

    #     if key <= self.node_size(node.left):
    #         left,right = self.split(node.left, key,level+1)
    #         node.left = right
    #         return left, self.update(node)
    #     else:
    #         left,right = self.split(node.right, key - self.node_size(node.left) - 1,level+1)
    #         node.right = left
    #         return self.update(node),right 
     left_tree[4] > right_tree[4] left_tree[4] left_tree 4 right_tree[4] right_tree 4 left_tree[1] = self.merge(left_tree[1], right_tree) left_tree[1] left_tree 1 self.merge(left_tree[1], right_tree) self.merge self merge left_tree[1] left_tree 1 right_tree return left_tree left_tree right_tree[0] = self.merge(left_tree,right_tree[0]) right_tree[0] right_tree 0 self.merge(left_tree,right_tree[0]) self.merge self merge left_tree right_tree[0] right_tree 0 return right_tree right_tree self self left_tree left_tree right_tree right_tree def split(self, node:None, value):
        if node is None:
            return None,None

        if value <= node[3]:
            left_tree,right_tree = self.split(node[0], value)
            node[0] = right_tree
            return left_tree, node
        else:
            left_tree,right_tree = self.split(node[1], value)
            node[1] = left_tree
            return node, right_tree

    
     split if node is None:
            return None,None

         node is None node None return None,None return None,None None None if value <= node[3]:
            left_tree,right_tree = self.split(node[0], value)
            node[0] = right_tree
            return left_tree, node
        else:
            left_tree,right_tree = self.split(node[1], value)
            node[1] = left_tree
            return node, right_tree

    
     value <= node[3] value node[3] node 3 left_tree,right_tree = self.split(node[0], value) left_tree self.split(node[0], value) self.split self split node[0] node 0 value right_tree node[0] = right_tree node[0] node 0 right_tree return left_tree, node return left_tree, node left_tree node left_tree,right_tree = self.split(node[1], value) left_tree self.split(node[1], value) self.split self split node[1] node 1 value right_tree node[1] = left_tree node[1] node 1 left_tree return node, right_tree return node, right_tree node right_tree self self node:None node value value def insert(self, key:int,value:int =-1):
        value = value if value > 0 else key
        left_tree, right_tree = self.split(self.root, key)
        new_node = [None,None,key,value,random()]
        self.root = self.merge(self.merge(left_tree,new_node),right_tree)
    
     insert value = value if value > 0 else key value value if value > 0 else key value > 0 value 0 value key left_tree, right_tree = self.split(self.root, key) left_tree self.split(self.root, key) self.split self split self.root self root key right_tree new_node = [None,None,key,value,random()] new_node [None,None,key,value,random()] None None key value random() random self.root = self.merge(self.merge(left_tree,new_node),right_tree) self.root self root self.merge(self.merge(left_tree,new_node),right_tree) self.merge self merge self.merge(left_tree,new_node) self.merge self merge left_tree new_node right_tree self self key:int key value:int =-1 value -1 def erase(self, pos:int):
        middle_tree,right_tree = self.split(self.root, pos+1)
        left_tree,middle_tree = self.split(middle_tree, pos)
        self.root = self.merge(left_tree,right_tree)

        

     erase middle_tree,right_tree = self.split(self.root, pos+1) middle_tree self.split(self.root, pos+1) self.split self split self.root self root pos+1 pos 1 right_tree left_tree,middle_tree = self.split(middle_tree, pos) left_tree self.split(middle_tree, pos) self.split self split middle_tree pos middle_tree self.root = self.merge(left_tree,right_tree) self.root self root self.merge(left_tree,right_tree) self.merge self merge left_tree right_tree self self pos:int pos def printTree(self, node=None, level=0):
        node = self.root if node is None else node
        if node is None:
            print('level=',level,'root is None')
            return
        else:
            print('level=',level,'v=',node.value,'c=',node.count_partial, 'p=',node.priority)
        if node.left is not None:
            self.printTree(node.left,level+1)
        
        if node.right is not None:
            self.printTree(node.right,level+1)
        
    

    # def search(self, pos):
    #     #return self.search_recursively(pos,self.root)
    #     v = self.root
    #     while v:
    #         left_count = self.node_size(v.left)
    #         if pos < left_count:
    #             v = v.left
    #         elif pos == left_count:
    #             return v.value
    #         else:
    #             v = v.right
    #             pos -= left_count + 1
    #     return -1

     printTree node = self.root if node is None else node node self.root if node is None else node node is None node None self.root self root node if node is None:
            print('level=',level,'root is None')
            return
        else:
            print('level=',level,'v=',node.value,'c=',node.count_partial, 'p=',node.priority)
         node is None node None print('level=',level,'root is None') print 'level=' level 'root is None' return print('level=',level,'v=',node.value,'c=',node.count_partial, 'p=',node.priority) print 'level=' level 'v=' node.value node value 'c=' node.count_partial node count_partial 'p=' node.priority node priority if node.left is not None:
            self.printTree(node.left,level+1)
        
         node.left is not None node.left node left None self.printTree(node.left,level+1) self.printTree self printTree node.left node left level+1 level 1 if node.right is not None:
            self.printTree(node.right,level+1)
        
    

    # def search(self, pos):
    #     #return self.search_recursively(pos,self.root)
    #     v = self.root
    #     while v:
    #         left_count = self.node_size(v.left)
    #         if pos < left_count:
    #             v = v.left
    #         elif pos == left_count:
    #             return v.value
    #         else:
    #             v = v.right
    #             pos -= left_count + 1
    #     return -1

     node.right is not None node.right node right None self.printTree(node.right,level+1) self.printTree self printTree node.right node right level+1 level 1 self self node=None node None level=0 level 0 def search2(self, value):
        v = self.root
        upper = 10**18
        while v:
            if value == v[3]:
                return value

            elif value < v[3]:
                upper = v[3]
                v = v[0]
            else:
                v = v[1]
        return upper

    # def search_recursively(self, pos, node):
    #     if node is None:
    #         return -1
    #     num_left = 0 if node.left is None else node.left.count_partial
    #     if num_left + 1 == pos:
    #         return node.value
    #     if pos <= num_left:
    #         return self.search_recursively(pos, node.left)
    #     else:
    #         return self.search_recursively(pos - num_left - 1, node.right)
        


    
                 search2 v = self.root v self.root self root upper = 10**18 upper 10**18 10 18 while v:
            if value == v[3]:
                return value

            elif value < v[3]:
                upper = v[3]
                v = v[0]
            else:
                v = v[1]
         v if value == v[3]:
                return value

            elif value < v[3]:
                upper = v[3]
                v = v[0]
            else:
                v = v[1]
         value == v[3] value v[3] v 3 return value value elif value < v[3]:
                upper = v[3]
                v = v[0]
             value < v[3] value v[3] v 3 upper = v[3] upper v[3] v 3 v = v[0] v v[0] v 0 v = v[1] v v[1] v 1 return upper upper self self value value def main(given=sys.stdin.readline):
    input = lambda: given().rstrip()
    LMIIS = lambda: list(map(int,input().split()))
    II = lambda: int(input())
    XLMIIS = lambda x: [LMIIS() for _ in range(x)]
    YN = lambda c : print('Yes') if c else print('No')
    MOD = 10**9+7

    N = II()
    S = list(map(lambda c: ord(c) - ord('a'), list(input())))



    trees = []
    for i in range(26):
        trees.append(Treap())
    

    for i,c in enumerate(S):
        trees[c].insert(i)
    
    Q = int(input())
    out = []
    for _ in range(Q):
        q1,q2,q3 = input().split()
        if int(q1) == 1:
            iq = int(q2)-1
            before = S[iq]
            after = ord(q3)-ord('a')
            S[iq] = after
            trees[before].erase(iq)
            trees[after].insert(iq)

        else:
            l,r = int(q2)-1,int(q3)-1
            count = 0
            for i in range(26):
                if trees[i].search2(l) <= r:
                    count += 1
            out.append(count)
    print('\n'.join(map(str,out))) main input = lambda: given().rstrip() input lambda: given().rstrip() given().rstrip() ().rstrip () given rstrip LMIIS = lambda: list(map(int,input().split())) LMIIS lambda: list(map(int,input().split())) list(map(int,input().split())) list map(int,input().split()) map int input().split() ().split () input split II = lambda: int(input()) II lambda: int(input()) int(input()) int input() input LMIIS() for _ in range(x) for _ in range(x) _ range(x) range x for _ in range(x) LMIIS() LMIIS XLMIIS = lambda x: [LMIIS() for _ in range(x)] XLMIIS lambda x: [LMIIS() for _ in range(x)] [LMIIS() for _ in range(x)] x YN = lambda c : print('Yes') if c else print('No') YN lambda c : print('Yes') if c else print('No') print('Yes') if c else print('No') c print('Yes') print 'Yes' print('No') print 'No' c MOD = 10**9+7 MOD 10**9+7 10**9 10 9 7 N = II() N II() II S = list(map(lambda c: ord(c) - ord('a'), list(input()))) S list(map(lambda c: ord(c) - ord('a'), list(input()))) list map(lambda c: ord(c) - ord('a'), list(input())) map lambda c: ord(c) - ord('a') ord(c) - ord('a') ord(c) ord c ord('a') ord 'a' c list(input()) list input() input trees = [] trees [] for i in range(26):
        trees.append(Treap())
    

     i range(26) range 26 trees.append(Treap()) trees.append trees append Treap() Treap for i,c in enumerate(S):
        trees[c].insert(i)
    
     i c enumerate(S) enumerate S trees[c].insert(i) [c].insert [c] trees c insert i Q = int(input()) Q int(input()) int input() input out = [] out [] for _ in range(Q):
        q1,q2,q3 = input().split()
        if int(q1) == 1:
            iq = int(q2)-1
            before = S[iq]
            after = ord(q3)-ord('a')
            S[iq] = after
            trees[before].erase(iq)
            trees[after].insert(iq)

        else:
            l,r = int(q2)-1,int(q3)-1
            count = 0
            for i in range(26):
                if trees[i].search2(l) <= r:
                    count += 1
            out.append(count)
     _ range(Q) range Q q1,q2,q3 = input().split() q1 input().split() ().split () input split q2 q3 if int(q1) == 1:
            iq = int(q2)-1
            before = S[iq]
            after = ord(q3)-ord('a')
            S[iq] = after
            trees[before].erase(iq)
            trees[after].insert(iq)

        else:
            l,r = int(q2)-1,int(q3)-1
            count = 0
            for i in range(26):
                if trees[i].search2(l) <= r:
                    count += 1
            out.append(count)
     int(q1) == 1 int(q1) int q1 1 iq = int(q2)-1 iq int(q2)-1 int(q2) int q2 1 before = S[iq] before S[iq] S iq after = ord(q3)-ord('a') after ord(q3)-ord('a') ord(q3) ord q3 ord('a') ord 'a' S[iq] = after S[iq] S iq after trees[before].erase(iq) [before].erase [before] trees before erase iq trees[after].insert(iq) [after].insert [after] trees after insert iq l,r = int(q2)-1,int(q3)-1 l int(q2)-1 int(q2) int q2 1 r int(q3)-1 int(q3) int q3 1 count = 0 count 0 for i in range(26):
                if trees[i].search2(l) <= r:
                    count += 1
             i range(26) range 26 if trees[i].search2(l) <= r:
                    count += 1
             trees[i].search2(l) <= r trees[i].search2(l) [i].search2 [i] trees i search2 l r count += 1 count 1 out.append(count) out.append out append count print('\n'.join(map(str,out))) print '\n'.join(map(str,out)) '\n'.join '\n' join map(str,out) map str out given=sys.stdin.readline given sys.stdin.readline sys.stdin sys stdin readline if __name__ == '__main__':
    main() __name__ == '__main__' __name__ '__main__' main() main write = sys.stdout.write sys.stdout.write write class Treap:
    
    #Node [left, right, key, value, priority]
    def __init__(self):
        self.root = None

    # def update(self, node):
    #     if node.left is None:
    #         left_count = 0
    #         left_sum = 0
    #     else:
    #         left_count = node.left.count_partial
    #         left_sum = node.left.sum_partial
    #     if node.right is None:
    #         right_count = 0
    #         right_sum = 0
    #     else:
    #         right_count = node.right.count_partial
    #         right_sum = node.right.sum_partial

    #     node.count_partial = left_count + right_count + 1
    #     node.sum_partial = left_sum + right_sum + node.value
    #     return node

    def merge(self, left_tree, right_tree):
        if left_tree is None or right_tree is None:
            return left_tree if right_tree is None else right_tree

        # priority
        if left_tree[4] > right_tree[4]:
            left_tree[1] = self.merge(left_tree[1], right_tree)
            # return self.update(left)
            return left_tree
        else:
            right_tree[0] = self.merge(left_tree,right_tree[0])
            # return self.update(right)
            return right_tree


    # def node_size(self, node:Node):
    #     return 0 if node is None else node.count_partial
    
    # def node_key(self, node:None):
    #     return -1 if node is None else node.key

    #指定された場所のノードは右の木に含まれる

    # def split(self, node:Node, key:int, level=0):
    #     if node is None:
    #         return (None,None)

    #     if key <= self.node_size(node.left):
    #         left,right = self.split(node.left, key,level+1)
    #         node.left = right
    #         return left, self.update(node)
    #     else:
    #         left,right = self.split(node.right, key - self.node_size(node.left) - 1,level+1)
    #         node.right = left
    #         return self.update(node),right 
    def split(self, node:None, value):
        if node is None:
            return None,None

        if value <= node[3]:
            left_tree,right_tree = self.split(node[0], value)
            node[0] = right_tree
            return left_tree, node
        else:
            left_tree,right_tree = self.split(node[1], value)
            node[1] = left_tree
            return node, right_tree

    
    def insert(self, key:int,value:int =-1):
        value = value if value > 0 else key
        left_tree, right_tree = self.split(self.root, key)
        new_node = [None,None,key,value,random()]
        self.root = self.merge(self.merge(left_tree,new_node),right_tree)
    
    def erase(self, pos:int):
        middle_tree,right_tree = self.split(self.root, pos+1)
        left_tree,middle_tree = self.split(middle_tree, pos)
        self.root = self.merge(left_tree,right_tree)

        

    def printTree(self, node=None, level=0):
        node = self.root if node is None else node
        if node is None:
            print('level=',level,'root is None')
            return
        else:
            print('level=',level,'v=',node.value,'c=',node.count_partial, 'p=',node.priority)
        if node.left is not None:
            self.printTree(node.left,level+1)
        
        if node.right is not None:
            self.printTree(node.right,level+1)
        
    

    # def search(self, pos):
    #     #return self.search_recursively(pos,self.root)
    #     v = self.root
    #     while v:
    #         left_count = self.node_size(v.left)
    #         if pos < left_count:
    #             v = v.left
    #         elif pos == left_count:
    #             return v.value
    #         else:
    #             v = v.right
    #             pos -= left_count + 1
    #     return -1

    def search2(self, value):
        v = self.root
        upper = 10**18
        while v:
            if value == v[3]:
                return value

            elif value < v[3]:
                upper = v[3]
                v = v[0]
            else:
                v = v[1]
        return upper

    # def search_recursively(self, pos, node):
    #     if node is None:
    #         return -1
    #     num_left = 0 if node.left is None else node.left.count_partial
    #     if num_left + 1 == pos:
    #         return node.value
    #     if pos <= num_left:
    #         return self.search_recursively(pos, node.left)
    #     else:
    #         return self.search_recursively(pos - num_left - 1, node.right)
        


    
                 class Treap:
    
    #Node [left, right, key, value, priority]
    def __init__(self):
        self.root = None

    # def update(self, node):
    #     if node.left is None:
    #         left_count = 0
    #         left_sum = 0
    #     else:
    #         left_count = node.left.count_partial
    #         left_sum = node.left.sum_partial
    #     if node.right is None:
    #         right_count = 0
    #         right_sum = 0
    #     else:
    #         right_count = node.right.count_partial
    #         right_sum = node.right.sum_partial

    #     node.count_partial = left_count + right_count + 1
    #     node.sum_partial = left_sum + right_sum + node.value
    #     return node

    def merge(self, left_tree, right_tree):
        if left_tree is None or right_tree is None:
            return left_tree if right_tree is None else right_tree

        # priority
        if left_tree[4] > right_tree[4]:
            left_tree[1] = self.merge(left_tree[1], right_tree)
            # return self.update(left)
            return left_tree
        else:
            right_tree[0] = self.merge(left_tree,right_tree[0])
            # return self.update(right)
            return right_tree


    # def node_size(self, node:Node):
    #     return 0 if node is None else node.count_partial
    
    # def node_key(self, node:None):
    #     return -1 if node is None else node.key

    #指定された場所のノードは右の木に含まれる

    # def split(self, node:Node, key:int, level=0):
    #     if node is None:
    #         return (None,None)

    #     if key <= self.node_size(node.left):
    #         left,right = self.split(node.left, key,level+1)
    #         node.left = right
    #         return left, self.update(node)
    #     else:
    #         left,right = self.split(node.right, key - self.node_size(node.left) - 1,level+1)
    #         node.right = left
    #         return self.update(node),right 
    def split(self, node:None, value):
        if node is None:
            return None,None

        if value <= node[3]:
            left_tree,right_tree = self.split(node[0], value)
            node[0] = right_tree
            return left_tree, node
        else:
            left_tree,right_tree = self.split(node[1], value)
            node[1] = left_tree
            return node, right_tree

    
    def insert(self, key:int,value:int =-1):
        value = value if value > 0 else key
        left_tree, right_tree = self.split(self.root, key)
        new_node = [None,None,key,value,random()]
        self.root = self.merge(self.merge(left_tree,new_node),right_tree)
    
    def erase(self, pos:int):
        middle_tree,right_tree = self.split(self.root, pos+1)
        left_tree,middle_tree = self.split(middle_tree, pos)
        self.root = self.merge(left_tree,right_tree)

        

    def printTree(self, node=None, level=0):
        node = self.root if node is None else node
        if node is None:
            print('level=',level,'root is None')
            return
        else:
            print('level=',level,'v=',node.value,'c=',node.count_partial, 'p=',node.priority)
        if node.left is not None:
            self.printTree(node.left,level+1)
        
        if node.right is not None:
            self.printTree(node.right,level+1)
        
    

    # def search(self, pos):
    #     #return self.search_recursively(pos,self.root)
    #     v = self.root
    #     while v:
    #         left_count = self.node_size(v.left)
    #         if pos < left_count:
    #             v = v.left
    #         elif pos == left_count:
    #             return v.value
    #         else:
    #             v = v.right
    #             pos -= left_count + 1
    #     return -1

    def search2(self, value):
        v = self.root
        upper = 10**18
        while v:
            if value == v[3]:
                return value

            elif value < v[3]:
                upper = v[3]
                v = v[0]
            else:
                v = v[1]
        return upper

    # def search_recursively(self, pos, node):
    #     if node is None:
    #         return -1
    #     num_left = 0 if node.left is None else node.left.count_partial
    #     if num_left + 1 == pos:
    #         return node.value
    #     if pos <= num_left:
    #         return self.search_recursively(pos, node.left)
    #     else:
    #         return self.search_recursively(pos - num_left - 1, node.right)
        


    
                 Treap dbg = (lambda *something: print(*something)) if 'TERM_PROGRAM' in os.environ else lambda *x: 0 (lambda *something: print(*something)) if 'TERM_PROGRAM' in os.environ else lambda *x: 0 dbg def main(given=sys.stdin.readline):
    input = lambda: given().rstrip()
    LMIIS = lambda: list(map(int,input().split()))
    II = lambda: int(input())
    XLMIIS = lambda x: [LMIIS() for _ in range(x)]
    YN = lambda c : print('Yes') if c else print('No')
    MOD = 10**9+7

    N = II()
    S = list(map(lambda c: ord(c) - ord('a'), list(input())))



    trees = []
    for i in range(26):
        trees.append(Treap())
    

    for i,c in enumerate(S):
        trees[c].insert(i)
    
    Q = int(input())
    out = []
    for _ in range(Q):
        q1,q2,q3 = input().split()
        if int(q1) == 1:
            iq = int(q2)-1
            before = S[iq]
            after = ord(q3)-ord('a')
            S[iq] = after
            trees[before].erase(iq)
            trees[after].insert(iq)

        else:
            l,r = int(q2)-1,int(q3)-1
            count = 0
            for i in range(26):
                if trees[i].search2(l) <= r:
                    count += 1
            out.append(count)
    print('\n'.join(map(str,out))) def main(given=sys.stdin.readline):
    input = lambda: given().rstrip()
    LMIIS = lambda: list(map(int,input().split()))
    II = lambda: int(input())
    XLMIIS = lambda x: [LMIIS() for _ in range(x)]
    YN = lambda c : print('Yes') if c else print('No')
    MOD = 10**9+7

    N = II()
    S = list(map(lambda c: ord(c) - ord('a'), list(input())))



    trees = []
    for i in range(26):
        trees.append(Treap())
    

    for i,c in enumerate(S):
        trees[c].insert(i)
    
    Q = int(input())
    out = []
    for _ in range(Q):
        q1,q2,q3 = input().split()
        if int(q1) == 1:
            iq = int(q2)-1
            before = S[iq]
            after = ord(q3)-ord('a')
            S[iq] = after
            trees[before].erase(iq)
            trees[after].insert(iq)

        else:
            l,r = int(q2)-1,int(q3)-1
            count = 0
            for i in range(26):
                if trees[i].search2(l) <= r:
                    count += 1
            out.append(count)
    print('\n'.join(map(str,out))) main class Node:
        def __init__(self,value:int=-1):
            self.left = None
            self.right = None
            self.value = value
            self.priority = random()
            # self.count_partial = 1
            # self.sum_partial = value class Node:
        def __init__(self,value:int=-1):
            self.left = None
            self.right = None
            self.value = value
            self.priority = random()
            # self.count_partial = 1
            # self.sum_partial = value Node
#coding:utf-8
import sys,os
sys.setrecursionlimit(10**6)
write = sys.stdout.write
dbg = (lambda *something: print(*something)) if 'TERM_PROGRAM' in os.environ else lambda *x: 0
from collections import Counter, deque
from random import random
class Node:
        def __init__(self,value:int=-1):
            self.left = None
            self.right = None
            self.value = value
            self.priority = random()
            # self.count_partial = 1
            # self.sum_partial = value
class Treap:
    
    #Node [left, right, key, value, priority]
    def __init__(self):
        self.root = None

    # def update(self, node):
    #     if node.left is None:
    #         left_count = 0
    #         left_sum = 0
    #     else:
    #         left_count = node.left.count_partial
    #         left_sum = node.left.sum_partial
    #     if node.right is None:
    #         right_count = 0
    #         right_sum = 0
    #     else:
    #         right_count = node.right.count_partial
    #         right_sum = node.right.sum_partial

    #     node.count_partial = left_count + right_count + 1
    #     node.sum_partial = left_sum + right_sum + node.value
    #     return node

    def merge(self, left_tree, right_tree):
        if left_tree is None or right_tree is None:
            return left_tree if right_tree is None else right_tree

        # priority
        if left_tree[4] > right_tree[4]:
            left_tree[1] = self.merge(left_tree[1], right_tree)
            # return self.update(left)
            return left_tree
        else:
            right_tree[0] = self.merge(left_tree,right_tree[0])
            # return self.update(right)
            return right_tree


    # def node_size(self, node:Node):
    #     return 0 if node is None else node.count_partial
    
    # def node_key(self, node:None):
    #     return -1 if node is None else node.key

    #指定された場所のノードは右の木に含まれる

    # def split(self, node:Node, key:int, level=0):
    #     if node is None:
    #         return (None,None)

    #     if key <= self.node_size(node.left):
    #         left,right = self.split(node.left, key,level+1)
    #         node.left = right
    #         return left, self.update(node)
    #     else:
    #         left,right = self.split(node.right, key - self.node_size(node.left) - 1,level+1)
    #         node.right = left
    #         return self.update(node),right 
    def split(self, node:None, value):
        if node is None:
            return None,None

        if value <= node[3]:
            left_tree,right_tree = self.split(node[0], value)
            node[0] = right_tree
            return left_tree, node
        else:
            left_tree,right_tree = self.split(node[1], value)
            node[1] = left_tree
            return node, right_tree

    
    def insert(self, key:int,value:int =-1):
        value = value if value > 0 else key
        left_tree, right_tree = self.split(self.root, key)
        new_node = [None,None,key,value,random()]
        self.root = self.merge(self.merge(left_tree,new_node),right_tree)
    
    def erase(self, pos:int):
        middle_tree,right_tree = self.split(self.root, pos+1)
        left_tree,middle_tree = self.split(middle_tree, pos)
        self.root = self.merge(left_tree,right_tree)

        

    def printTree(self, node=None, level=0):
        node = self.root if node is None else node
        if node is None:
            print('level=',level,'root is None')
            return
        else:
            print('level=',level,'v=',node.value,'c=',node.count_partial, 'p=',node.priority)
        if node.left is not None:
            self.printTree(node.left,level+1)
        
        if node.right is not None:
            self.printTree(node.right,level+1)
        
    

    # def search(self, pos):
    #     #return self.search_recursively(pos,self.root)
    #     v = self.root
    #     while v:
    #         left_count = self.node_size(v.left)
    #         if pos < left_count:
    #             v = v.left
    #         elif pos == left_count:
    #             return v.value
    #         else:
    #             v = v.right
    #             pos -= left_count + 1
    #     return -1

    def search2(self, value):
        v = self.root
        upper = 10**18
        while v:
            if value == v[3]:
                return value

            elif value < v[3]:
                upper = v[3]
                v = v[0]
            else:
                v = v[1]
        return upper

    # def search_recursively(self, pos, node):
    #     if node is None:
    #         return -1
    #     num_left = 0 if node.left is None else node.left.count_partial
    #     if num_left + 1 == pos:
    #         return node.value
    #     if pos <= num_left:
    #         return self.search_recursively(pos, node.left)
    #     else:
    #         return self.search_recursively(pos - num_left - 1, node.right)
        


    
                










def main(given=sys.stdin.readline):
    input = lambda: given().rstrip()
    LMIIS = lambda: list(map(int,input().split()))
    II = lambda: int(input())
    XLMIIS = lambda x: [LMIIS() for _ in range(x)]
    YN = lambda c : print('Yes') if c else print('No')
    MOD = 10**9+7

    N = II()
    S = list(map(lambda c: ord(c) - ord('a'), list(input())))



    trees = []
    for i in range(26):
        trees.append(Treap())
    

    for i,c in enumerate(S):
        trees[c].insert(i)
    
    Q = int(input())
    out = []
    for _ in range(Q):
        q1,q2,q3 = input().split()
        if int(q1) == 1:
            iq = int(q2)-1
            before = S[iq]
            after = ord(q3)-ord('a')
            S[iq] = after
            trees[before].erase(iq)
            trees[after].insert(iq)

        else:
            l,r = int(q2)-1,int(q3)-1
            count = 0
            for i in range(26):
                if trees[i].search2(l) <= r:
                    count += 1
            out.append(count)
    print('\n'.join(map(str,out)))


if __name__ == '__main__':
    main()