class SegmentTree:
    def __init__(self, lst, op, e):
        self.n = len(lst)
        self.N = 1 << ((self.n - 1).bit_length())
        self.op = op # operation
        self.e = e # identity element
        self.v = self._build(lst) # self.v is set to be 1-indexed for simplicity
        
    def _build(self, lst):
        # construction of a tree
        # total 2 * self.N elements (tree[0] is not used)
        tree = [self.e] * (self.N) + lst + [self.e] * (self.N - self.n)
        for i in range(self.N - 1, 0, -1): tree[i] = self.op(tree[i << 1], tree[(i << 1)|1])
        return tree
    
    def __getitem__(self, i):
        return self.v[i + self.N]
    
    # update a_i to be x 
    def update(self, i, x):
        v, op = self.v, self.op
        i += self.N
        v[i] = x
        while i > 0:
            i >>= 1 # move to parent
            v[i] = op(v[i << 1], v[(i << 1)|1])
    
    # returns answer for the query interval [l, r)
    def fold(self, l, r):
        N, e, v, op = self.N, self.e, self.v, self.op
        left = l + N; right = r + N
        L = R = e
        while left < right:
            if left & 1: # self.v[left] is the right child
                L = op(L, v[left])
                left += 1
            if right & 1: # self.v[right-1] is the left child
                right -= 1
                R = op(v[right], R)
            left >>= 1; right >>= 1
        return op(L, R)

def wa(set1, set2):
    return set1 | set2

n = int(input())
s = input()
lst = []
for i in range(n):
    lst.append(set([s[i]]))

st = SegmentTree(lst, wa, set([]))

ans = []
q = int(input())
for i in range(q):
    que = input()
    if que[0] == '1':
        kind, i, c = que.split()
        i = int(i) - 1
        st.update(i, set([c]))
    else:
        kind, l, r = map(int, que.split())
        l -= 1
        ans.append(len(st.fold(l, r)))

for i in ans:
    print(i) class SegmentTree:
    def __init__(self, lst, op, e):
        self.n = len(lst)
        self.N = 1 << ((self.n - 1).bit_length())
        self.op = op # operation
        self.e = e # identity element
        self.v = self._build(lst) # self.v is set to be 1-indexed for simplicity
        
    def _build(self, lst):
        # construction of a tree
        # total 2 * self.N elements (tree[0] is not used)
        tree = [self.e] * (self.N) + lst + [self.e] * (self.N - self.n)
        for i in range(self.N - 1, 0, -1): tree[i] = self.op(tree[i << 1], tree[(i << 1)|1])
        return tree
    
    def __getitem__(self, i):
        return self.v[i + self.N]
    
    # update a_i to be x 
    def update(self, i, x):
        v, op = self.v, self.op
        i += self.N
        v[i] = x
        while i > 0:
            i >>= 1 # move to parent
            v[i] = op(v[i << 1], v[(i << 1)|1])
    
    # returns answer for the query interval [l, r)
    def fold(self, l, r):
        N, e, v, op = self.N, self.e, self.v, self.op
        left = l + N; right = r + N
        L = R = e
        while left < right:
            if left & 1: # self.v[left] is the right child
                L = op(L, v[left])
                left += 1
            if right & 1: # self.v[right-1] is the left child
                right -= 1
                R = op(v[right], R)
            left >>= 1; right >>= 1
        return op(L, R) SegmentTree def __init__(self, lst, op, e):
        self.n = len(lst)
        self.N = 1 << ((self.n - 1).bit_length())
        self.op = op # operation
        self.e = e # identity element
        self.v = self._build(lst) # self.v is set to be 1-indexed for simplicity
        
     __init__ self.n = len(lst) self.n self n len(lst) len lst self.N = 1 << ((self.n - 1).bit_length()) self.N self N 1 << ((self.n - 1).bit_length()) 1 (self.n - 1).bit_length() self.n - 1).bit_length self.n - 1 self.n self n 1 bit_length self.op = op self.op self op op self.e = e self.e self e e self.v = self._build(lst) self.v self v self._build(lst) self._build self _build lst self self lst lst op op e e def _build(self, lst):
        # construction of a tree
        # total 2 * self.N elements (tree[0] is not used)
        tree = [self.e] * (self.N) + lst + [self.e] * (self.N - self.n)
        for i in range(self.N - 1, 0, -1): tree[i] = self.op(tree[i << 1], tree[(i << 1)|1])
        return tree
    
     _build tree = [self.e] * (self.N) + lst + [self.e] * (self.N - self.n) tree [self.e] * (self.N) + lst + [self.e] * (self.N - self.n) [self.e] * (self.N) + lst [self.e] * (self.N) [self.e] self.e self e self.N self N lst [self.e] * (self.N - self.n) [self.e] self.e self e self.N - self.n self.N self N self.n self n for i in range(self.N - 1, 0, -1): tree[i] = self.op(tree[i << 1], tree[(i << 1)|1])
         i range(self.N - 1, 0, -1) range self.N - 1 self.N self N 1 0 -1 return tree tree self self lst lst def __getitem__(self, i):
        return self.v[i + self.N]
    
    # update a_i to be x 
     __getitem__ return self.v[i + self.N] self.v[i + self.N] self.v self v i + self.N i self.N self N self self i i def update(self, i, x):
        v, op = self.v, self.op
        i += self.N
        v[i] = x
        while i > 0:
            i >>= 1 # move to parent
            v[i] = op(v[i << 1], v[(i << 1)|1])
    
    # returns answer for the query interval [l, r)
     update v, op = self.v, self.op v self.v self v op self.op self op i += self.N i self.N self N v[i] = x v[i] v i x while i > 0:
            i >>= 1 # move to parent
            v[i] = op(v[i << 1], v[(i << 1)|1])
    
    # returns answer for the query interval [l, r)
     i > 0 i 0 i >>= 1 i 1 v[i] = op(v[i << 1], v[(i << 1)|1]) v[i] v i op(v[i << 1], v[(i << 1)|1]) op v[i << 1] v i << 1 i 1 v[(i << 1)|1] v (i << 1)|1 i << 1 i 1 1 self self i i x x def fold(self, l, r):
        N, e, v, op = self.N, self.e, self.v, self.op
        left = l + N; right = r + N
        L = R = e
        while left < right:
            if left & 1: # self.v[left] is the right child
                L = op(L, v[left])
                left += 1
            if right & 1: # self.v[right-1] is the left child
                right -= 1
                R = op(v[right], R)
            left >>= 1; right >>= 1
        return op(L, R) fold N, e, v, op = self.N, self.e, self.v, self.op N self.N self N e self.e self e v self.v self v op self.op self op left = l + N left l + N l N right = r + N right r + N r N L = R = e L e = R = e R e while left < right:
            if left & 1: # self.v[left] is the right child
                L = op(L, v[left])
                left += 1
            if right & 1: # self.v[right-1] is the left child
                right -= 1
                R = op(v[right], R)
            left >>= 1; right >>= 1
         left < right left right if left & 1: # self.v[left] is the right child
                L = op(L, v[left])
                left += 1
             left & 1 left 1 L = op(L, v[left]) L op(L, v[left]) op L v[left] v left left += 1 left 1 if right & 1: # self.v[right-1] is the left child
                right -= 1
                R = op(v[right], R)
             right & 1 right 1 right -= 1 right 1 R = op(v[right], R) R op(v[right], R) op v[right] v right R left >>= 1 left 1 right >>= 1 right 1 return op(L, R) op(L, R) op L R self self l l r r def wa(set1, set2):
    return set1 | set2 wa return set1 | set2 set1 | set2 set1 set2 set1 set1 set2 set2 n = int(input()) n int(input()) int input() input s = input() s input() input lst = [] lst [] for i in range(n):
    lst.append(set([s[i]])) i range(n) range n lst.append(set([s[i]])) lst.append lst append set([s[i]]) set [s[i]] s[i] s i st = SegmentTree(lst, wa, set([])) st SegmentTree(lst, wa, set([])) SegmentTree lst wa set([]) set [] ans = [] ans [] q = int(input()) q int(input()) int input() input for i in range(q):
    que = input()
    if que[0] == '1':
        kind, i, c = que.split()
        i = int(i) - 1
        st.update(i, set([c]))
    else:
        kind, l, r = map(int, que.split())
        l -= 1
        ans.append(len(st.fold(l, r))) i range(q) range q que = input() que input() input if que[0] == '1':
        kind, i, c = que.split()
        i = int(i) - 1
        st.update(i, set([c]))
    else:
        kind, l, r = map(int, que.split())
        l -= 1
        ans.append(len(st.fold(l, r))) que[0] == '1' que[0] que 0 '1' kind, i, c = que.split() kind que.split() que.split que split i c i = int(i) - 1 i int(i) - 1 int(i) int i 1 st.update(i, set([c])) st.update st update i set([c]) set [c] c kind, l, r = map(int, que.split()) kind map(int, que.split()) map int que.split() que.split que split l r l -= 1 l 1 ans.append(len(st.fold(l, r))) ans.append ans append len(st.fold(l, r)) len st.fold(l, r) st.fold st fold l r for i in ans:
    print(i) i ans print(i) print i ans = [] [] ans que = input() input() que kind, i, c = que.split() que.split() kind i, c = que.split() que.split() i r = map(int, que.split()) map(int, que.split()) r lst = [] [] lst l -= 1 1 l st = SegmentTree(lst, wa, set([])) SegmentTree(lst, wa, set([])) st kind, l, r = map(int, que.split()) map(int, que.split()) kind n = int(input()) int(input()) n q = int(input()) int(input()) q class SegmentTree:
    def __init__(self, lst, op, e):
        self.n = len(lst)
        self.N = 1 << ((self.n - 1).bit_length())
        self.op = op # operation
        self.e = e # identity element
        self.v = self._build(lst) # self.v is set to be 1-indexed for simplicity
        
    def _build(self, lst):
        # construction of a tree
        # total 2 * self.N elements (tree[0] is not used)
        tree = [self.e] * (self.N) + lst + [self.e] * (self.N - self.n)
        for i in range(self.N - 1, 0, -1): tree[i] = self.op(tree[i << 1], tree[(i << 1)|1])
        return tree
    
    def __getitem__(self, i):
        return self.v[i + self.N]
    
    # update a_i to be x 
    def update(self, i, x):
        v, op = self.v, self.op
        i += self.N
        v[i] = x
        while i > 0:
            i >>= 1 # move to parent
            v[i] = op(v[i << 1], v[(i << 1)|1])
    
    # returns answer for the query interval [l, r)
    def fold(self, l, r):
        N, e, v, op = self.N, self.e, self.v, self.op
        left = l + N; right = r + N
        L = R = e
        while left < right:
            if left & 1: # self.v[left] is the right child
                L = op(L, v[left])
                left += 1
            if right & 1: # self.v[right-1] is the left child
                right -= 1
                R = op(v[right], R)
            left >>= 1; right >>= 1
        return op(L, R) class SegmentTree:
    def __init__(self, lst, op, e):
        self.n = len(lst)
        self.N = 1 << ((self.n - 1).bit_length())
        self.op = op # operation
        self.e = e # identity element
        self.v = self._build(lst) # self.v is set to be 1-indexed for simplicity
        
    def _build(self, lst):
        # construction of a tree
        # total 2 * self.N elements (tree[0] is not used)
        tree = [self.e] * (self.N) + lst + [self.e] * (self.N - self.n)
        for i in range(self.N - 1, 0, -1): tree[i] = self.op(tree[i << 1], tree[(i << 1)|1])
        return tree
    
    def __getitem__(self, i):
        return self.v[i + self.N]
    
    # update a_i to be x 
    def update(self, i, x):
        v, op = self.v, self.op
        i += self.N
        v[i] = x
        while i > 0:
            i >>= 1 # move to parent
            v[i] = op(v[i << 1], v[(i << 1)|1])
    
    # returns answer for the query interval [l, r)
    def fold(self, l, r):
        N, e, v, op = self.N, self.e, self.v, self.op
        left = l + N; right = r + N
        L = R = e
        while left < right:
            if left & 1: # self.v[left] is the right child
                L = op(L, v[left])
                left += 1
            if right & 1: # self.v[right-1] is the left child
                right -= 1
                R = op(v[right], R)
            left >>= 1; right >>= 1
        return op(L, R) SegmentTree c = que.split() que.split() c s = input() input() s i = int(i) - 1 int(i) - 1 i def wa(set1, set2):
    return set1 | set2 def wa(set1, set2):
    return set1 | set2 wa l, r = map(int, que.split()) map(int, que.split()) l
class SegmentTree:
    def __init__(self, lst, op, e):
        self.n = len(lst)
        self.N = 1 << ((self.n - 1).bit_length())
        self.op = op # operation
        self.e = e # identity element
        self.v = self._build(lst) # self.v is set to be 1-indexed for simplicity
        
    def _build(self, lst):
        # construction of a tree
        # total 2 * self.N elements (tree[0] is not used)
        tree = [self.e] * (self.N) + lst + [self.e] * (self.N - self.n)
        for i in range(self.N - 1, 0, -1): tree[i] = self.op(tree[i << 1], tree[(i << 1)|1])
        return tree
    
    def __getitem__(self, i):
        return self.v[i + self.N]
    
    # update a_i to be x 
    def update(self, i, x):
        v, op = self.v, self.op
        i += self.N
        v[i] = x
        while i > 0:
            i >>= 1 # move to parent
            v[i] = op(v[i << 1], v[(i << 1)|1])
    
    # returns answer for the query interval [l, r)
    def fold(self, l, r):
        N, e, v, op = self.N, self.e, self.v, self.op
        left = l + N; right = r + N
        L = R = e
        while left < right:
            if left & 1: # self.v[left] is the right child
                L = op(L, v[left])
                left += 1
            if right & 1: # self.v[right-1] is the left child
                right -= 1
                R = op(v[right], R)
            left >>= 1; right >>= 1
        return op(L, R)

def wa(set1, set2):
    return set1 | set2

n = int(input())
s = input()
lst = []
for i in range(n):
    lst.append(set([s[i]]))

st = SegmentTree(lst, wa, set([]))

ans = []
q = int(input())
for i in range(q):
    que = input()
    if que[0] == '1':
        kind, i, c = que.split()
        i = int(i) - 1
        st.update(i, set([c]))
    else:
        kind, l, r = map(int, que.split())
        l -= 1
        ans.append(len(st.fold(l, r)))

for i in ans:
    print(i)