import sys
def main():
    input = sys.stdin.readline
    N = int(input())
    S = input().rstrip()
    S = [conv(c) for c in S]
    segtree = SegmentTree(initial_values=S, f=lambda x,y:x|y)

    Q = int(input())
    for _ in range(Q):
        t, a, b = input().rstrip().split()
        if t == '1':
            a = int(a) - 1
            segtree.set_val(a, conv(b))
        else:
            a, b = int(a) - 1, int(b)
            q = segtree.query(a, b)
            print(popcount(q))

def conv(c): return 1 << (ord(c) - ord('a'))
def popcount(x):
    x = (x & 0x5555555555555555) + (x >> 1 & 0x5555555555555555)
    x = (x & 0x3333333333333333) + (x >> 2 & 0x3333333333333333)
    x = x + (x >> 4) & 0x0f0f0f0f0f0f0f0f
    x += x >> 8
    x += x >> 16
    x += x >> 32
    return x & 0x7f

class SegmentTree:
    def __init__(self, n=None, f=max, identity_factory=int, initial_values=None):
        assert(n or initial_values)
        size = n if n else len(initial_values)
        d = [identity_factory() for _ in range(2 * size + 1)]
        self.__n, self.__d, self.__f, self.__e = size, d, f, identity_factory
        if initial_values:
            for i, v in enumerate(initial_values): d[size + i] = v
            for i in range(size - 1, 0, -1): d[i] = f(d[i<<1], d[i<<1|1])

    def get_val(self, index):
        return self.__d[index + self.__n]

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

    def modify(self, index, value):
        self.set_val(index, self.__f(self.__d[index + self.__n], value))

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

    def bisect_left(self, func):
        '''func()がFalseになるもっとも左のindexを探す
        '''
        i, n, f, d, v = 1, self.__n, self.__f, self.__d, self.__e()
        while i < n:
            if func(f(v, d[i<<1])): v, i = f(v, d[i<<1]), i<<1|1
            else: i = i<<1
        return i - n


if __name__ == '__main__':
    main() import sys sys def main():
    input = sys.stdin.readline
    N = int(input())
    S = input().rstrip()
    S = [conv(c) for c in S]
    segtree = SegmentTree(initial_values=S, f=lambda x,y:x|y)

    Q = int(input())
    for _ in range(Q):
        t, a, b = input().rstrip().split()
        if t == '1':
            a = int(a) - 1
            segtree.set_val(a, conv(b))
        else:
            a, b = int(a) - 1, int(b)
            q = segtree.query(a, b)
            print(popcount(q)) 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 conv(c) for c in S for c in S c S for c in S conv(c) conv c S = [conv(c) for c in S] S [conv(c) for c in S] segtree = SegmentTree(initial_values=S, f=lambda x,y:x|y) segtree SegmentTree(initial_values=S, f=lambda x,y:x|y) 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 Q = int(input()) Q int(input()) int input() input for _ in range(Q):
        t, a, b = input().rstrip().split()
        if t == '1':
            a = int(a) - 1
            segtree.set_val(a, conv(b))
        else:
            a, b = int(a) - 1, int(b)
            q = segtree.query(a, b)
            print(popcount(q)) _ 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':
            a = int(a) - 1
            segtree.set_val(a, conv(b))
        else:
            a, b = int(a) - 1, int(b)
            q = segtree.query(a, b)
            print(popcount(q)) t == '1' t '1' a = int(a) - 1 a int(a) - 1 int(a) int a 1 segtree.set_val(a, conv(b)) segtree.set_val segtree set_val a conv(b) conv b a, b = int(a) - 1, int(b) a int(a) - 1 int(a) int a 1 b int(b) int b q = segtree.query(a, b) q segtree.query(a, b) segtree.query segtree query a b print(popcount(q)) print popcount(q) popcount q def conv(c): return 1 << (ord(c) - ord('a')) conv c c def popcount(x):
    x = (x & 0x5555555555555555) + (x >> 1 & 0x5555555555555555)
    x = (x & 0x3333333333333333) + (x >> 2 & 0x3333333333333333)
    x = x + (x >> 4) & 0x0f0f0f0f0f0f0f0f
    x += x >> 8
    x += x >> 16
    x += x >> 32
    return x & 0x7f popcount x = (x & 0x5555555555555555) + (x >> 1 & 0x5555555555555555) x (x & 0x5555555555555555) + (x >> 1 & 0x5555555555555555) x & 0x5555555555555555 x 0x5555555555555555 x >> 1 & 0x5555555555555555 x >> 1 x 1 0x5555555555555555 x = (x & 0x3333333333333333) + (x >> 2 & 0x3333333333333333) x (x & 0x3333333333333333) + (x >> 2 & 0x3333333333333333) x & 0x3333333333333333 x 0x3333333333333333 x >> 2 & 0x3333333333333333 x >> 2 x 2 0x3333333333333333 x = x + (x >> 4) & 0x0f0f0f0f0f0f0f0f x x + (x >> 4) & 0x0f0f0f0f0f0f0f0f x + (x >> 4) x x >> 4 x 4 0x0f0f0f0f0f0f0f0f x += x >> 8 x x >> 8 x 8 x += x >> 16 x x >> 16 x 16 x += x >> 32 x x >> 32 x 32 return x & 0x7f x & 0x7f x 0x7f x x class SegmentTree:
    def __init__(self, n=None, f=max, identity_factory=int, initial_values=None):
        assert(n or initial_values)
        size = n if n else len(initial_values)
        d = [identity_factory() for _ in range(2 * size + 1)]
        self.__n, self.__d, self.__f, self.__e = size, d, f, identity_factory
        if initial_values:
            for i, v in enumerate(initial_values): d[size + i] = v
            for i in range(size - 1, 0, -1): d[i] = f(d[i<<1], d[i<<1|1])

    def get_val(self, index):
        return self.__d[index + self.__n]

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

    def modify(self, index, value):
        self.set_val(index, self.__f(self.__d[index + self.__n], value))

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

    def bisect_left(self, func):
        '''func()がFalseになるもっとも左のindexを探す
        '''
        i, n, f, d, v = 1, self.__n, self.__f, self.__d, self.__e()
        while i < n:
            if func(f(v, d[i<<1])): v, i = f(v, d[i<<1]), i<<1|1
            else: i = i<<1
        return i - n SegmentTree def __init__(self, n=None, f=max, identity_factory=int, initial_values=None):
        assert(n or initial_values)
        size = n if n else len(initial_values)
        d = [identity_factory() for _ in range(2 * size + 1)]
        self.__n, self.__d, self.__f, self.__e = size, d, f, identity_factory
        if initial_values:
            for i, v in enumerate(initial_values): d[size + i] = v
            for i in range(size - 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 size = n if n else len(initial_values) size n if n else len(initial_values) n n len(initial_values) len initial_values identity_factory() for _ in range(2 * size + 1) for _ in range(2 * size + 1) _ range(2 * size + 1) range 2 * size + 1 2 * size 2 size 1 for _ in range(2 * size + 1) identity_factory() identity_factory d = [identity_factory() for _ in range(2 * size + 1)] d [identity_factory() for _ in range(2 * size + 1)] self.__n, self.__d, self.__f, self.__e = size, d, f, identity_factory self.__n self __n size self.__d self __d d self.__f self __f f self.__e self __e identity_factory if initial_values:
            for i, v in enumerate(initial_values): d[size + i] = v
            for i in range(size - 1, 0, -1): d[i] = f(d[i<<1], d[i<<1|1])

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

     i range(size - 1, 0, -1) range size - 1 size 1 0 -1 self self n=None n None f=max f max identity_factory=int identity_factory int initial_values=None initial_values None def get_val(self, index):
        return self.__d[index + self.__n]

     get_val return self.__d[index + self.__n] self.__d[index + self.__n] self.__d self __d index + self.__n index self.__n self __n self self index index def set_val(self, index, value):
        i, d, f = index + self.__n, self.__d, self.__f
        if d[i] == value: return
        d[i] = value
        while i:
            i = i >> 1
            d[i] = f(d[i<<1], d[i<<1|1])

     set_val i, d, f = index + self.__n, self.__d, self.__f i index + self.__n index self.__n self __n d self.__d self __d f self.__f self __f if d[i] == value: return
         d[i] == value d[i] d i value d[i] = value d[i] d i value 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 modify(self, index, value):
        self.set_val(index, self.__f(self.__d[index + self.__n], value))

     modify self.set_val(index, self.__f(self.__d[index + self.__n], value)) self.set_val self set_val index self.__f(self.__d[index + self.__n], value) self.__f self __f self.__d[index + self.__n] self.__d self __d index + self.__n index self.__n self __n value self self index index value value def query(self, from_inclusive, to_exclusive):
        ans = self.__e()
        if to_exclusive <= from_inclusive: return ans
        l, r, d, f = from_inclusive + self.__n, to_exclusive + self.__n, self.__d, self.__f
        while l < r:
            if l & 1: ans, l = f(ans, d[l]), l+1
            if r & 1: ans, r = f(d[r-1], ans), r-1
            l, r = l >> 1, r >> 1
        return ans

     query ans = self.__e() ans self.__e() self.__e self __e 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.__d, 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.__d self __d 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(d[r-1], ans), 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(d[r-1], ans), 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 def bisect_left(self, func):
        '''func()がFalseになるもっとも左のindexを探す
        '''
        i, n, f, d, v = 1, self.__n, self.__f, self.__d, self.__e()
        while i < n:
            if func(f(v, d[i<<1])): v, i = f(v, d[i<<1]), i<<1|1
            else: i = i<<1
        return i - n bisect_left '''func()がFalseになるもっとも左のindexを探す
        ''' i, n, f, d, v = 1, self.__n, self.__f, self.__d, self.__e() i 1 n self.__n self __n f self.__f self __f d self.__d self __d v self.__e() self.__e self __e while i < n:
            if func(f(v, d[i<<1])): v, i = f(v, d[i<<1]), i<<1|1
            else: i = i<<1
         i < n i n if func(f(v, d[i<<1])): v, i = f(v, d[i<<1]), i<<1|1
            else: i = i<<1
         func(f(v, d[i<<1])) func f(v, d[i<<1]) f v d[i<<1] d i<<1 i 1 return i - n i - n i n self self func func if __name__ == '__main__':
    main() __name__ == '__main__' __name__ '__main__' main() main class SegmentTree:
    def __init__(self, n=None, f=max, identity_factory=int, initial_values=None):
        assert(n or initial_values)
        size = n if n else len(initial_values)
        d = [identity_factory() for _ in range(2 * size + 1)]
        self.__n, self.__d, self.__f, self.__e = size, d, f, identity_factory
        if initial_values:
            for i, v in enumerate(initial_values): d[size + i] = v
            for i in range(size - 1, 0, -1): d[i] = f(d[i<<1], d[i<<1|1])

    def get_val(self, index):
        return self.__d[index + self.__n]

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

    def modify(self, index, value):
        self.set_val(index, self.__f(self.__d[index + self.__n], value))

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

    def bisect_left(self, func):
        '''func()がFalseになるもっとも左のindexを探す
        '''
        i, n, f, d, v = 1, self.__n, self.__f, self.__d, self.__e()
        while i < n:
            if func(f(v, d[i<<1])): v, i = f(v, d[i<<1]), i<<1|1
            else: i = i<<1
        return i - n class SegmentTree:
    def __init__(self, n=None, f=max, identity_factory=int, initial_values=None):
        assert(n or initial_values)
        size = n if n else len(initial_values)
        d = [identity_factory() for _ in range(2 * size + 1)]
        self.__n, self.__d, self.__f, self.__e = size, d, f, identity_factory
        if initial_values:
            for i, v in enumerate(initial_values): d[size + i] = v
            for i in range(size - 1, 0, -1): d[i] = f(d[i<<1], d[i<<1|1])

    def get_val(self, index):
        return self.__d[index + self.__n]

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

    def modify(self, index, value):
        self.set_val(index, self.__f(self.__d[index + self.__n], value))

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

    def bisect_left(self, func):
        '''func()がFalseになるもっとも左のindexを探す
        '''
        i, n, f, d, v = 1, self.__n, self.__f, self.__d, self.__e()
        while i < n:
            if func(f(v, d[i<<1])): v, i = f(v, d[i<<1]), i<<1|1
            else: i = i<<1
        return i - n SegmentTree def main():
    input = sys.stdin.readline
    N = int(input())
    S = input().rstrip()
    S = [conv(c) for c in S]
    segtree = SegmentTree(initial_values=S, f=lambda x,y:x|y)

    Q = int(input())
    for _ in range(Q):
        t, a, b = input().rstrip().split()
        if t == '1':
            a = int(a) - 1
            segtree.set_val(a, conv(b))
        else:
            a, b = int(a) - 1, int(b)
            q = segtree.query(a, b)
            print(popcount(q)) def main():
    input = sys.stdin.readline
    N = int(input())
    S = input().rstrip()
    S = [conv(c) for c in S]
    segtree = SegmentTree(initial_values=S, f=lambda x,y:x|y)

    Q = int(input())
    for _ in range(Q):
        t, a, b = input().rstrip().split()
        if t == '1':
            a = int(a) - 1
            segtree.set_val(a, conv(b))
        else:
            a, b = int(a) - 1, int(b)
            q = segtree.query(a, b)
            print(popcount(q)) main def conv(c): return 1 << (ord(c) - ord('a')) def conv(c): return 1 << (ord(c) - ord('a')) conv def popcount(x):
    x = (x & 0x5555555555555555) + (x >> 1 & 0x5555555555555555)
    x = (x & 0x3333333333333333) + (x >> 2 & 0x3333333333333333)
    x = x + (x >> 4) & 0x0f0f0f0f0f0f0f0f
    x += x >> 8
    x += x >> 16
    x += x >> 32
    return x & 0x7f def popcount(x):
    x = (x & 0x5555555555555555) + (x >> 1 & 0x5555555555555555)
    x = (x & 0x3333333333333333) + (x >> 2 & 0x3333333333333333)
    x = x + (x >> 4) & 0x0f0f0f0f0f0f0f0f
    x += x >> 8
    x += x >> 16
    x += x >> 32
    return x & 0x7f popcount
import sys
def main():
    input = sys.stdin.readline
    N = int(input())
    S = input().rstrip()
    S = [conv(c) for c in S]
    segtree = SegmentTree(initial_values=S, f=lambda x,y:x|y)

    Q = int(input())
    for _ in range(Q):
        t, a, b = input().rstrip().split()
        if t == '1':
            a = int(a) - 1
            segtree.set_val(a, conv(b))
        else:
            a, b = int(a) - 1, int(b)
            q = segtree.query(a, b)
            print(popcount(q))

def conv(c): return 1 << (ord(c) - ord('a'))
def popcount(x):
    x = (x & 0x5555555555555555) + (x >> 1 & 0x5555555555555555)
    x = (x & 0x3333333333333333) + (x >> 2 & 0x3333333333333333)
    x = x + (x >> 4) & 0x0f0f0f0f0f0f0f0f
    x += x >> 8
    x += x >> 16
    x += x >> 32
    return x & 0x7f

class SegmentTree:
    def __init__(self, n=None, f=max, identity_factory=int, initial_values=None):
        assert(n or initial_values)
        size = n if n else len(initial_values)
        d = [identity_factory() for _ in range(2 * size + 1)]
        self.__n, self.__d, self.__f, self.__e = size, d, f, identity_factory
        if initial_values:
            for i, v in enumerate(initial_values): d[size + i] = v
            for i in range(size - 1, 0, -1): d[i] = f(d[i<<1], d[i<<1|1])

    def get_val(self, index):
        return self.__d[index + self.__n]

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

    def modify(self, index, value):
        self.set_val(index, self.__f(self.__d[index + self.__n], value))

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

    def bisect_left(self, func):
        '''func()がFalseになるもっとも左のindexを探す
        '''
        i, n, f, d, v = 1, self.__n, self.__f, self.__d, self.__e()
        while i < n:
            if func(f(v, d[i<<1])): v, i = f(v, d[i<<1]), i<<1|1
            else: i = i<<1
        return i - n


if __name__ == '__main__':
    main()