import sys
 
def main():
    input = sys.stdin.readline
    N = int(input())
    S = input().rstrip()
    tree = SegmentTree(initial_values=S, f=lambda x,y:x|y, converter=lambda c: 1 << (ord(c)-ord('a')))
    Q = int(input())
    update = tree.update
    query = tree.query
    for _ in range(Q):
        t, a, b = input().rstrip().split()
        if t == '1': update(int(a)-1, b)
        else: print(bin(query(int(a)-1, int(b))).count('1'))    

class SegmentTree:
    def __init__(self, n=None, f=max, zero_factory=int, converter=lambda x:x, initial_values=None):
        assert(n or initial_values)
        self.__f, self.__z, self.__c = f, zero_factory, converter
        size = n if n else len(initial_values)
        self.__n = 1 << ((size - 1).bit_length())
        d = [zero_factory() for _ in range(2 * self.__n + 1)]
        self.__dat = d
        if initial_values:
            for i, v in enumerate(initial_values): d[self.__n + i] = converter(v)
            for i in range(self.__n - 1, 0, -1): d[i] = f(d[i<<1], d[i<<1|1])

    def update(self, index, value):
        i, v, d, f = index + self.__n, self.__c(value), self.__dat, self.__f
        if d[i] == v: return
        d[i] = v
        while i:
            i = i >> 1
            d[i] = f(d[i<<1], d[i<<1|1])

    def query(self, from_inclusive, to_exclusive):
        ans = self.__z()
        if to_exclusive <= from_inclusive: return ans
        l, r, d, f = from_inclusive + self.__n, to_exclusive + self.__n, self.__dat, self.__f
        while l < r:
            if l & 1: ans, l = f(ans, d[l]), l+1
            if r & 1: ans, r = f(ans, d[r-1]), r-1
            l, r = l >> 1, r >> 1
        return ans

if __name__ == '__main__':
    main() import sys sys def main():
    input = sys.stdin.readline
    N = int(input())
    S = input().rstrip()
    tree = SegmentTree(initial_values=S, f=lambda x,y:x|y, converter=lambda c: 1 << (ord(c)-ord('a')))
    Q = int(input())
    update = tree.update
    query = tree.query
    for _ in range(Q):
        t, a, b = input().rstrip().split()
        if t == '1': update(int(a)-1, b)
        else: print(bin(query(int(a)-1, int(b))).count('1'))     main input = sys.stdin.readline input sys.stdin.readline sys.stdin sys stdin readline N = int(input()) N int(input()) int input() input S = input().rstrip() S input().rstrip() ().rstrip () input rstrip tree = SegmentTree(initial_values=S, f=lambda x,y:x|y, converter=lambda c: 1 << (ord(c)-ord('a'))) tree SegmentTree(initial_values=S, f=lambda x,y:x|y, converter=lambda c: 1 << (ord(c)-ord('a'))) SegmentTree initial_values=S initial_values S f=lambda x,y:x|y f lambda x,y:x|y x|y x y x y converter=lambda c: 1 << (ord(c)-ord('a')) converter lambda c: 1 << (ord(c)-ord('a')) 1 << (ord(c)-ord('a')) 1 ord(c)-ord('a') ord(c) ord c ord('a') ord 'a' c Q = int(input()) Q int(input()) int input() input update = tree.update update tree.update tree update query = tree.query query tree.query tree query for _ in range(Q):
        t, a, b = input().rstrip().split()
        if t == '1': update(int(a)-1, b)
        else: print(bin(query(int(a)-1, int(b))).count('1'))     _ range(Q) range Q t, a, b = input().rstrip().split() t input().rstrip().split() ().rstrip().split ().rstrip() ().rstrip () input rstrip split a b if t == '1': update(int(a)-1, b)
        else: print(bin(query(int(a)-1, int(b))).count('1'))     t == '1' t '1' class SegmentTree:
    def __init__(self, n=None, f=max, zero_factory=int, converter=lambda x:x, initial_values=None):
        assert(n or initial_values)
        self.__f, self.__z, self.__c = f, zero_factory, converter
        size = n if n else len(initial_values)
        self.__n = 1 << ((size - 1).bit_length())
        d = [zero_factory() for _ in range(2 * self.__n + 1)]
        self.__dat = d
        if initial_values:
            for i, v in enumerate(initial_values): d[self.__n + i] = converter(v)
            for i in range(self.__n - 1, 0, -1): d[i] = f(d[i<<1], d[i<<1|1])

    def update(self, index, value):
        i, v, d, f = index + self.__n, self.__c(value), self.__dat, self.__f
        if d[i] == v: return
        d[i] = v
        while i:
            i = i >> 1
            d[i] = f(d[i<<1], d[i<<1|1])

    def query(self, from_inclusive, to_exclusive):
        ans = self.__z()
        if to_exclusive <= from_inclusive: return ans
        l, r, d, f = from_inclusive + self.__n, to_exclusive + self.__n, self.__dat, self.__f
        while l < r:
            if l & 1: ans, l = f(ans, d[l]), l+1
            if r & 1: ans, r = f(ans, d[r-1]), r-1
            l, r = l >> 1, r >> 1
        return ans SegmentTree def __init__(self, n=None, f=max, zero_factory=int, converter=lambda x:x, initial_values=None):
        assert(n or initial_values)
        self.__f, self.__z, self.__c = f, zero_factory, converter
        size = n if n else len(initial_values)
        self.__n = 1 << ((size - 1).bit_length())
        d = [zero_factory() for _ in range(2 * self.__n + 1)]
        self.__dat = d
        if initial_values:
            for i, v in enumerate(initial_values): d[self.__n + i] = converter(v)
            for i in range(self.__n - 1, 0, -1): d[i] = f(d[i<<1], d[i<<1|1])

     __init__ assert(n or initial_values) n or initial_values n initial_values self.__f, self.__z, self.__c = f, zero_factory, converter self.__f self __f f self.__z self __z zero_factory self.__c self __c converter size = n if n else len(initial_values) size n if n else len(initial_values) n n len(initial_values) len initial_values self.__n = 1 << ((size - 1).bit_length()) self.__n self __n 1 << ((size - 1).bit_length()) 1 (size - 1).bit_length() size - 1).bit_length size - 1 size 1 bit_length zero_factory() for _ in range(2 * self.__n + 1) for _ in range(2 * self.__n + 1) _ range(2 * self.__n + 1) range 2 * self.__n + 1 2 * self.__n 2 self.__n self __n 1 for _ in range(2 * self.__n + 1) zero_factory() zero_factory d = [zero_factory() for _ in range(2 * self.__n + 1)] d [zero_factory() for _ in range(2 * self.__n + 1)] self.__dat = d self.__dat self __dat d if initial_values:
            for i, v in enumerate(initial_values): d[self.__n + i] = converter(v)
            for i in range(self.__n - 1, 0, -1): d[i] = f(d[i<<1], d[i<<1|1])

     initial_values for i, v in enumerate(initial_values): d[self.__n + i] = converter(v)
             i v enumerate(initial_values) enumerate initial_values for i in range(self.__n - 1, 0, -1): d[i] = f(d[i<<1], d[i<<1|1])

     i range(self.__n - 1, 0, -1) range self.__n - 1 self.__n self __n 1 0 -1 self self n=None n None f=max f max zero_factory=int zero_factory int converter=lambda x:x converter lambda x:x x x initial_values=None initial_values None def update(self, index, value):
        i, v, d, f = index + self.__n, self.__c(value), self.__dat, self.__f
        if d[i] == v: return
        d[i] = v
        while i:
            i = i >> 1
            d[i] = f(d[i<<1], d[i<<1|1])

     update i, v, d, f = index + self.__n, self.__c(value), self.__dat, self.__f i index + self.__n index self.__n self __n v self.__c(value) self.__c self __c value d self.__dat self __dat f self.__f self __f if d[i] == v: return
         d[i] == v d[i] d i v d[i] = v d[i] d i v while i:
            i = i >> 1
            d[i] = f(d[i<<1], d[i<<1|1])

     i i = i >> 1 i i >> 1 i 1 d[i] = f(d[i<<1], d[i<<1|1]) d[i] d i f(d[i<<1], d[i<<1|1]) f d[i<<1] d i<<1 i 1 d[i<<1|1] d i<<1|1 i<<1 i 1 1 self self index index value value def query(self, from_inclusive, to_exclusive):
        ans = self.__z()
        if to_exclusive <= from_inclusive: return ans
        l, r, d, f = from_inclusive + self.__n, to_exclusive + self.__n, self.__dat, self.__f
        while l < r:
            if l & 1: ans, l = f(ans, d[l]), l+1
            if r & 1: ans, r = f(ans, d[r-1]), r-1
            l, r = l >> 1, r >> 1
        return ans query ans = self.__z() ans self.__z() self.__z self __z if to_exclusive <= from_inclusive: return ans
         to_exclusive <= from_inclusive to_exclusive from_inclusive l, r, d, f = from_inclusive + self.__n, to_exclusive + self.__n, self.__dat, self.__f l from_inclusive + self.__n from_inclusive self.__n self __n r to_exclusive + self.__n to_exclusive self.__n self __n d self.__dat self __dat f self.__f self __f while l < r:
            if l & 1: ans, l = f(ans, d[l]), l+1
            if r & 1: ans, r = f(ans, d[r-1]), r-1
            l, r = l >> 1, r >> 1
         l < r l r if l & 1: ans, l = f(ans, d[l]), l+1
             l & 1 l 1 if r & 1: ans, r = f(ans, d[r-1]), r-1
             r & 1 r 1 l, r = l >> 1, r >> 1 l l >> 1 l 1 r r >> 1 r 1 return ans ans self self from_inclusive from_inclusive to_exclusive to_exclusive if __name__ == '__main__':
    main() __name__ == '__main__' __name__ '__main__' main() main def main():
    input = sys.stdin.readline
    N = int(input())
    S = input().rstrip()
    tree = SegmentTree(initial_values=S, f=lambda x,y:x|y, converter=lambda c: 1 << (ord(c)-ord('a')))
    Q = int(input())
    update = tree.update
    query = tree.query
    for _ in range(Q):
        t, a, b = input().rstrip().split()
        if t == '1': update(int(a)-1, b)
        else: print(bin(query(int(a)-1, int(b))).count('1'))     def main():
    input = sys.stdin.readline
    N = int(input())
    S = input().rstrip()
    tree = SegmentTree(initial_values=S, f=lambda x,y:x|y, converter=lambda c: 1 << (ord(c)-ord('a')))
    Q = int(input())
    update = tree.update
    query = tree.query
    for _ in range(Q):
        t, a, b = input().rstrip().split()
        if t == '1': update(int(a)-1, b)
        else: print(bin(query(int(a)-1, int(b))).count('1'))     main class SegmentTree:
    def __init__(self, n=None, f=max, zero_factory=int, converter=lambda x:x, initial_values=None):
        assert(n or initial_values)
        self.__f, self.__z, self.__c = f, zero_factory, converter
        size = n if n else len(initial_values)
        self.__n = 1 << ((size - 1).bit_length())
        d = [zero_factory() for _ in range(2 * self.__n + 1)]
        self.__dat = d
        if initial_values:
            for i, v in enumerate(initial_values): d[self.__n + i] = converter(v)
            for i in range(self.__n - 1, 0, -1): d[i] = f(d[i<<1], d[i<<1|1])

    def update(self, index, value):
        i, v, d, f = index + self.__n, self.__c(value), self.__dat, self.__f
        if d[i] == v: return
        d[i] = v
        while i:
            i = i >> 1
            d[i] = f(d[i<<1], d[i<<1|1])

    def query(self, from_inclusive, to_exclusive):
        ans = self.__z()
        if to_exclusive <= from_inclusive: return ans
        l, r, d, f = from_inclusive + self.__n, to_exclusive + self.__n, self.__dat, self.__f
        while l < r:
            if l & 1: ans, l = f(ans, d[l]), l+1
            if r & 1: ans, r = f(ans, d[r-1]), r-1
            l, r = l >> 1, r >> 1
        return ans class SegmentTree:
    def __init__(self, n=None, f=max, zero_factory=int, converter=lambda x:x, initial_values=None):
        assert(n or initial_values)
        self.__f, self.__z, self.__c = f, zero_factory, converter
        size = n if n else len(initial_values)
        self.__n = 1 << ((size - 1).bit_length())
        d = [zero_factory() for _ in range(2 * self.__n + 1)]
        self.__dat = d
        if initial_values:
            for i, v in enumerate(initial_values): d[self.__n + i] = converter(v)
            for i in range(self.__n - 1, 0, -1): d[i] = f(d[i<<1], d[i<<1|1])

    def update(self, index, value):
        i, v, d, f = index + self.__n, self.__c(value), self.__dat, self.__f
        if d[i] == v: return
        d[i] = v
        while i:
            i = i >> 1
            d[i] = f(d[i<<1], d[i<<1|1])

    def query(self, from_inclusive, to_exclusive):
        ans = self.__z()
        if to_exclusive <= from_inclusive: return ans
        l, r, d, f = from_inclusive + self.__n, to_exclusive + self.__n, self.__dat, self.__f
        while l < r:
            if l & 1: ans, l = f(ans, d[l]), l+1
            if r & 1: ans, r = f(ans, d[r-1]), r-1
            l, r = l >> 1, r >> 1
        return ans SegmentTree
import sys
 
def main():
    input = sys.stdin.readline
    N = int(input())
    S = input().rstrip()
    tree = SegmentTree(initial_values=S, f=lambda x,y:x|y, converter=lambda c: 1 << (ord(c)-ord('a')))
    Q = int(input())
    update = tree.update
    query = tree.query
    for _ in range(Q):
        t, a, b = input().rstrip().split()
        if t == '1': update(int(a)-1, b)
        else: print(bin(query(int(a)-1, int(b))).count('1'))    

class SegmentTree:
    def __init__(self, n=None, f=max, zero_factory=int, converter=lambda x:x, initial_values=None):
        assert(n or initial_values)
        self.__f, self.__z, self.__c = f, zero_factory, converter
        size = n if n else len(initial_values)
        self.__n = 1 << ((size - 1).bit_length())
        d = [zero_factory() for _ in range(2 * self.__n + 1)]
        self.__dat = d
        if initial_values:
            for i, v in enumerate(initial_values): d[self.__n + i] = converter(v)
            for i in range(self.__n - 1, 0, -1): d[i] = f(d[i<<1], d[i<<1|1])

    def update(self, index, value):
        i, v, d, f = index + self.__n, self.__c(value), self.__dat, self.__f
        if d[i] == v: return
        d[i] = v
        while i:
            i = i >> 1
            d[i] = f(d[i<<1], d[i<<1|1])

    def query(self, from_inclusive, to_exclusive):
        ans = self.__z()
        if to_exclusive <= from_inclusive: return ans
        l, r, d, f = from_inclusive + self.__n, to_exclusive + self.__n, self.__dat, self.__f
        while l < r:
            if l & 1: ans, l = f(ans, d[l]), l+1
            if r & 1: ans, r = f(ans, d[r-1]), r-1
            l, r = l >> 1, r >> 1
        return ans

if __name__ == '__main__':
    main()
