import sys
input = sys.stdin.readline

class SegmentTree():
    def segfunc(self, x, y):
        return max(x, y)
        
    def __init__(self, ide_ele, n, l, target):
        # n以上の最小の2のべき乗、一番下の段はここからスタートになる
        self.ide_ele = ide_ele
        self.num =2**(n-1).bit_length()
        self.tree = [ide_ele]*self.num*2
        # 一番下の段
        for i in range(n):
            if l[i] == target:
                self.tree[i+self.num-1] = 1
        # 
        for i in range(self.num-2, -1, -1):
            self.tree[i] = self.segfunc(self.tree[2*i+1], self.tree[2*i+2])
    
    def update(self, k, add):
        k += self.num-1
        if add:
            self.tree[k] = 1
        else:
            self.tree[k] = 0
        while k:
            k = (k-1)//2
            self.tree[k] = self.segfunc(self.tree[k*2+1], self.tree[k*2+2])
    
    def query(self, p, q):
        if q<=p:
            return self.ide_ele

        # [p, q)
        p += self.num - 1
        q += self.num - 2
        res = self.ide_ele
        while q-p>1: # まだ隣同士の節点ではないなら
            # &で偶奇判定->中途半端な位置にいるなら寄せる
            if p&1 == 0: #左なのに右端
                res = self.segfunc(res, self.tree[p])
            if q&1 == 1: #右なのに左端
                res = self.segfunc(res, self.tree[q])
                q -= 1
            p = p//2
            q = (q-1)//2
        if p==q:
            res = self.segfunc(res, self.tree[p])
        else:
            res = self.segfunc(self.segfunc(res, self.tree[p]), self.tree[q])
        return res

    # 閉区間になってる
    def rec_query(self, p, q, k, l, r):
        #q -= 1 [)の場合
        #print(p, q, k, l, r)
        if r < p or q < l: # out of range
            return self.ide_ele
        if p <= l and r <= q:
            return self.tree[k]
        else:
            vl = self.rec_query(p, q, k*2+1, l, (l+r)//2)
            vr = self.rec_query(p, q, k*2+2, (l+r)//2+1, r)
        #print(vl, vr)
        return self.segfunc(vl, vr)



N = int(input())
S = input()
Q = int(input())

result = ""

d = {}
for i in range(26):
    d[chr(ord("a")+i)] = SegmentTree(0, N, S, chr(ord("a")+i))

S = list(S)

for q in range(Q):
    case, p, q = (i for i in input().split())
    #print(case, p, q)
    p = int(p)-1
    case = int(case)
    if case==1:
        #print(p)
        d[S[p]].update(p, False)
        d[q].update(p, True)
        S[p] = q
    else:
        ans = 0
        for c in range(26):
            #print(d[chr(ord("a")+c)].tree)
            ans += d[chr(ord("a")+c)].query(p, int(q))
        result += str(ans)+"\n"

#print(S)
print(result[:-1]) import sys sys input = sys.stdin.readline input sys.stdin.readline sys.stdin sys stdin readline class SegmentTree():
    def segfunc(self, x, y):
        return max(x, y)
        
    def __init__(self, ide_ele, n, l, target):
        # n以上の最小の2のべき乗、一番下の段はここからスタートになる
        self.ide_ele = ide_ele
        self.num =2**(n-1).bit_length()
        self.tree = [ide_ele]*self.num*2
        # 一番下の段
        for i in range(n):
            if l[i] == target:
                self.tree[i+self.num-1] = 1
        # 
        for i in range(self.num-2, -1, -1):
            self.tree[i] = self.segfunc(self.tree[2*i+1], self.tree[2*i+2])
    
    def update(self, k, add):
        k += self.num-1
        if add:
            self.tree[k] = 1
        else:
            self.tree[k] = 0
        while k:
            k = (k-1)//2
            self.tree[k] = self.segfunc(self.tree[k*2+1], self.tree[k*2+2])
    
    def query(self, p, q):
        if q<=p:
            return self.ide_ele

        # [p, q)
        p += self.num - 1
        q += self.num - 2
        res = self.ide_ele
        while q-p>1: # まだ隣同士の節点ではないなら
            # &で偶奇判定->中途半端な位置にいるなら寄せる
            if p&1 == 0: #左なのに右端
                res = self.segfunc(res, self.tree[p])
            if q&1 == 1: #右なのに左端
                res = self.segfunc(res, self.tree[q])
                q -= 1
            p = p//2
            q = (q-1)//2
        if p==q:
            res = self.segfunc(res, self.tree[p])
        else:
            res = self.segfunc(self.segfunc(res, self.tree[p]), self.tree[q])
        return res

    # 閉区間になってる
    def rec_query(self, p, q, k, l, r):
        #q -= 1 [)の場合
        #print(p, q, k, l, r)
        if r < p or q < l: # out of range
            return self.ide_ele
        if p <= l and r <= q:
            return self.tree[k]
        else:
            vl = self.rec_query(p, q, k*2+1, l, (l+r)//2)
            vr = self.rec_query(p, q, k*2+2, (l+r)//2+1, r)
        #print(vl, vr)
        return self.segfunc(vl, vr) SegmentTree def segfunc(self, x, y):
        return max(x, y)
        
     segfunc return max(x, y) max(x, y) max x y self self x x y y def __init__(self, ide_ele, n, l, target):
        # n以上の最小の2のべき乗、一番下の段はここからスタートになる
        self.ide_ele = ide_ele
        self.num =2**(n-1).bit_length()
        self.tree = [ide_ele]*self.num*2
        # 一番下の段
        for i in range(n):
            if l[i] == target:
                self.tree[i+self.num-1] = 1
        # 
        for i in range(self.num-2, -1, -1):
            self.tree[i] = self.segfunc(self.tree[2*i+1], self.tree[2*i+2])
    
     __init__ self.ide_ele = ide_ele self.ide_ele self ide_ele ide_ele self.num =2**(n-1).bit_length() self.num self num 2**(n-1).bit_length() 2 (n-1).bit_length() n-1).bit_length n-1 n 1 bit_length self.tree = [ide_ele]*self.num*2 self.tree self tree [ide_ele]*self.num*2 [ide_ele]*self.num [ide_ele] ide_ele self.num self num 2 for i in range(n):
            if l[i] == target:
                self.tree[i+self.num-1] = 1
        # 
         i range(n) range n if l[i] == target:
                self.tree[i+self.num-1] = 1
        # 
         l[i] == target l[i] l i target self.tree[i+self.num-1] = 1 self.tree[i+self.num-1] self.tree self tree i+self.num-1 i+self.num i self.num self num 1 1 for i in range(self.num-2, -1, -1):
            self.tree[i] = self.segfunc(self.tree[2*i+1], self.tree[2*i+2])
    
     i range(self.num-2, -1, -1) range self.num-2 self.num self num 2 -1 -1 self.tree[i] = self.segfunc(self.tree[2*i+1], self.tree[2*i+2]) self.tree[i] self.tree self tree i self.segfunc(self.tree[2*i+1], self.tree[2*i+2]) self.segfunc self segfunc self.tree[2*i+1] self.tree self tree 2*i+1 2*i 2 i 1 self.tree[2*i+2] self.tree self tree 2*i+2 2*i 2 i 2 self self ide_ele ide_ele n n l l target target def update(self, k, add):
        k += self.num-1
        if add:
            self.tree[k] = 1
        else:
            self.tree[k] = 0
        while k:
            k = (k-1)//2
            self.tree[k] = self.segfunc(self.tree[k*2+1], self.tree[k*2+2])
    
     update k += self.num-1 k self.num-1 self.num self num 1 if add:
            self.tree[k] = 1
        else:
            self.tree[k] = 0
         add self.tree[k] = 1 self.tree[k] self.tree self tree k 1 self.tree[k] = 0 self.tree[k] self.tree self tree k 0 while k:
            k = (k-1)//2
            self.tree[k] = self.segfunc(self.tree[k*2+1], self.tree[k*2+2])
    
     k k = (k-1)//2 k (k-1)//2 k-1 k 1 2 self.tree[k] = self.segfunc(self.tree[k*2+1], self.tree[k*2+2]) self.tree[k] self.tree self tree k self.segfunc(self.tree[k*2+1], self.tree[k*2+2]) self.segfunc self segfunc self.tree[k*2+1] self.tree self tree k*2+1 k*2 k 2 1 self.tree[k*2+2] self.tree self tree k*2+2 k*2 k 2 2 self self k k add add def query(self, p, q):
        if q<=p:
            return self.ide_ele

        # [p, q)
        p += self.num - 1
        q += self.num - 2
        res = self.ide_ele
        while q-p>1: # まだ隣同士の節点ではないなら
            # &で偶奇判定->中途半端な位置にいるなら寄せる
            if p&1 == 0: #左なのに右端
                res = self.segfunc(res, self.tree[p])
            if q&1 == 1: #右なのに左端
                res = self.segfunc(res, self.tree[q])
                q -= 1
            p = p//2
            q = (q-1)//2
        if p==q:
            res = self.segfunc(res, self.tree[p])
        else:
            res = self.segfunc(self.segfunc(res, self.tree[p]), self.tree[q])
        return res

    # 閉区間になってる
     query if q<=p:
            return self.ide_ele

        # [p, q)
         q<=p q p return self.ide_ele self.ide_ele self ide_ele p += self.num - 1 p self.num - 1 self.num self num 1 q += self.num - 2 q self.num - 2 self.num self num 2 res = self.ide_ele res self.ide_ele self ide_ele while q-p>1: # まだ隣同士の節点ではないなら
            # &で偶奇判定->中途半端な位置にいるなら寄せる
            if p&1 == 0: #左なのに右端
                res = self.segfunc(res, self.tree[p])
            if q&1 == 1: #右なのに左端
                res = self.segfunc(res, self.tree[q])
                q -= 1
            p = p//2
            q = (q-1)//2
         q-p>1 q-p q p 1 if p&1 == 0: #左なのに右端
                res = self.segfunc(res, self.tree[p])
             p&1 == 0 p&1 p 1 0 res = self.segfunc(res, self.tree[p]) res self.segfunc(res, self.tree[p]) self.segfunc self segfunc res self.tree[p] self.tree self tree p if q&1 == 1: #右なのに左端
                res = self.segfunc(res, self.tree[q])
                q -= 1
             q&1 == 1 q&1 q 1 1 res = self.segfunc(res, self.tree[q]) res self.segfunc(res, self.tree[q]) self.segfunc self segfunc res self.tree[q] self.tree self tree q q -= 1 q 1 p = p//2 p p//2 p 2 q = (q-1)//2 q (q-1)//2 q-1 q 1 2 if p==q:
            res = self.segfunc(res, self.tree[p])
        else:
            res = self.segfunc(self.segfunc(res, self.tree[p]), self.tree[q])
         p==q p q res = self.segfunc(res, self.tree[p]) res self.segfunc(res, self.tree[p]) self.segfunc self segfunc res self.tree[p] self.tree self tree p res = self.segfunc(self.segfunc(res, self.tree[p]), self.tree[q]) res self.segfunc(self.segfunc(res, self.tree[p]), self.tree[q]) self.segfunc self segfunc self.segfunc(res, self.tree[p]) self.segfunc self segfunc res self.tree[p] self.tree self tree p self.tree[q] self.tree self tree q return res res self self p p q q def rec_query(self, p, q, k, l, r):
        #q -= 1 [)の場合
        #print(p, q, k, l, r)
        if r < p or q < l: # out of range
            return self.ide_ele
        if p <= l and r <= q:
            return self.tree[k]
        else:
            vl = self.rec_query(p, q, k*2+1, l, (l+r)//2)
            vr = self.rec_query(p, q, k*2+2, (l+r)//2+1, r)
        #print(vl, vr)
        return self.segfunc(vl, vr) rec_query if r < p or q < l: # out of range
            return self.ide_ele
         r < p or q < l r < p r p q < l q l return self.ide_ele self.ide_ele self ide_ele if p <= l and r <= q:
            return self.tree[k]
        else:
            vl = self.rec_query(p, q, k*2+1, l, (l+r)//2)
            vr = self.rec_query(p, q, k*2+2, (l+r)//2+1, r)
        #print(vl, vr)
         p <= l and r <= q p <= l p l r <= q r q return self.tree[k] self.tree[k] self.tree self tree k vl = self.rec_query(p, q, k*2+1, l, (l+r)//2) vl self.rec_query(p, q, k*2+1, l, (l+r)//2) self.rec_query self rec_query p q k*2+1 k*2 k 2 1 l (l+r)//2 l+r l r 2 vr = self.rec_query(p, q, k*2+2, (l+r)//2+1, r) vr self.rec_query(p, q, k*2+2, (l+r)//2+1, r) self.rec_query self rec_query p q k*2+2 k*2 k 2 2 (l+r)//2+1 (l+r)//2 l+r l r 2 1 r return self.segfunc(vl, vr) self.segfunc(vl, vr) self.segfunc self segfunc vl vr self self p p q q k k l l r r N = int(input()) N int(input()) int input() input S = input() S input() input Q = int(input()) Q int(input()) int input() input result = "" result "" d = {} d {} for i in range(26):
    d[chr(ord("a")+i)] = SegmentTree(0, N, S, chr(ord("a")+i)) i range(26) range 26 d[chr(ord("a")+i)] = SegmentTree(0, N, S, chr(ord("a")+i)) d[chr(ord("a")+i)] d chr(ord("a")+i) chr ord("a")+i ord("a") ord "a" i SegmentTree(0, N, S, chr(ord("a")+i)) SegmentTree 0 N S chr(ord("a")+i) chr ord("a")+i ord("a") ord "a" i S = list(S) S list(S) list S for q in range(Q):
    case, p, q = (i for i in input().split())
    #print(case, p, q)
    p = int(p)-1
    case = int(case)
    if case==1:
        #print(p)
        d[S[p]].update(p, False)
        d[q].update(p, True)
        S[p] = q
    else:
        ans = 0
        for c in range(26):
            #print(d[chr(ord("a")+c)].tree)
            ans += d[chr(ord("a")+c)].query(p, int(q))
        result += str(ans)+"\n"

#print(S) q range(Q) range Q i for i in input().split() for i in input().split() i input().split() ().split () input split for i in input().split() i case, p, q = (i for i in input().split()) case (i for i in input().split()) p q p = int(p)-1 p int(p)-1 int(p) int p 1 case = int(case) case int(case) int case if case==1:
        #print(p)
        d[S[p]].update(p, False)
        d[q].update(p, True)
        S[p] = q
    else:
        ans = 0
        for c in range(26):
            #print(d[chr(ord("a")+c)].tree)
            ans += d[chr(ord("a")+c)].query(p, int(q))
        result += str(ans)+"\n"

#print(S) case==1 case 1 d[S[p]].update(p, False) [S[p]].update [S[p]] d S[p] S p update p False d[q].update(p, True) [q].update [q] d q update p True S[p] = q S[p] S p q ans = 0 ans 0 for c in range(26):
            #print(d[chr(ord("a")+c)].tree)
            ans += d[chr(ord("a")+c)].query(p, int(q))
         c range(26) range 26 ans += d[chr(ord("a")+c)].query(p, int(q)) ans d[chr(ord("a")+c)].query(p, int(q)) [chr(ord("a")+c)].query [chr(ord("a")+c)] d chr(ord("a")+c) chr ord("a")+c ord("a") ord "a" c query p int(q) int q result += str(ans)+"\n" result str(ans)+"\n" str(ans) str ans "\n" print(result[:-1]) print result[:-1] result :-1 -1 N = int(input()) int(input()) N input = sys.stdin.readline sys.stdin.readline input result += str(ans)+"\n" str(ans)+"\n" result S = input() input() S case, p, q = (i for i in input().split()) (i for i in input().split()) case Q = int(input()) int(input()) Q S = list(S) list(S) S q = (i for i in input().split()) (i for i in input().split()) q result = "" "" result p = int(p)-1 int(p)-1 p class SegmentTree():
    def segfunc(self, x, y):
        return max(x, y)
        
    def __init__(self, ide_ele, n, l, target):
        # n以上の最小の2のべき乗、一番下の段はここからスタートになる
        self.ide_ele = ide_ele
        self.num =2**(n-1).bit_length()
        self.tree = [ide_ele]*self.num*2
        # 一番下の段
        for i in range(n):
            if l[i] == target:
                self.tree[i+self.num-1] = 1
        # 
        for i in range(self.num-2, -1, -1):
            self.tree[i] = self.segfunc(self.tree[2*i+1], self.tree[2*i+2])
    
    def update(self, k, add):
        k += self.num-1
        if add:
            self.tree[k] = 1
        else:
            self.tree[k] = 0
        while k:
            k = (k-1)//2
            self.tree[k] = self.segfunc(self.tree[k*2+1], self.tree[k*2+2])
    
    def query(self, p, q):
        if q<=p:
            return self.ide_ele

        # [p, q)
        p += self.num - 1
        q += self.num - 2
        res = self.ide_ele
        while q-p>1: # まだ隣同士の節点ではないなら
            # &で偶奇判定->中途半端な位置にいるなら寄せる
            if p&1 == 0: #左なのに右端
                res = self.segfunc(res, self.tree[p])
            if q&1 == 1: #右なのに左端
                res = self.segfunc(res, self.tree[q])
                q -= 1
            p = p//2
            q = (q-1)//2
        if p==q:
            res = self.segfunc(res, self.tree[p])
        else:
            res = self.segfunc(self.segfunc(res, self.tree[p]), self.tree[q])
        return res

    # 閉区間になってる
    def rec_query(self, p, q, k, l, r):
        #q -= 1 [)の場合
        #print(p, q, k, l, r)
        if r < p or q < l: # out of range
            return self.ide_ele
        if p <= l and r <= q:
            return self.tree[k]
        else:
            vl = self.rec_query(p, q, k*2+1, l, (l+r)//2)
            vr = self.rec_query(p, q, k*2+2, (l+r)//2+1, r)
        #print(vl, vr)
        return self.segfunc(vl, vr) class SegmentTree():
    def segfunc(self, x, y):
        return max(x, y)
        
    def __init__(self, ide_ele, n, l, target):
        # n以上の最小の2のべき乗、一番下の段はここからスタートになる
        self.ide_ele = ide_ele
        self.num =2**(n-1).bit_length()
        self.tree = [ide_ele]*self.num*2
        # 一番下の段
        for i in range(n):
            if l[i] == target:
                self.tree[i+self.num-1] = 1
        # 
        for i in range(self.num-2, -1, -1):
            self.tree[i] = self.segfunc(self.tree[2*i+1], self.tree[2*i+2])
    
    def update(self, k, add):
        k += self.num-1
        if add:
            self.tree[k] = 1
        else:
            self.tree[k] = 0
        while k:
            k = (k-1)//2
            self.tree[k] = self.segfunc(self.tree[k*2+1], self.tree[k*2+2])
    
    def query(self, p, q):
        if q<=p:
            return self.ide_ele

        # [p, q)
        p += self.num - 1
        q += self.num - 2
        res = self.ide_ele
        while q-p>1: # まだ隣同士の節点ではないなら
            # &で偶奇判定->中途半端な位置にいるなら寄せる
            if p&1 == 0: #左なのに右端
                res = self.segfunc(res, self.tree[p])
            if q&1 == 1: #右なのに左端
                res = self.segfunc(res, self.tree[q])
                q -= 1
            p = p//2
            q = (q-1)//2
        if p==q:
            res = self.segfunc(res, self.tree[p])
        else:
            res = self.segfunc(self.segfunc(res, self.tree[p]), self.tree[q])
        return res

    # 閉区間になってる
    def rec_query(self, p, q, k, l, r):
        #q -= 1 [)の場合
        #print(p, q, k, l, r)
        if r < p or q < l: # out of range
            return self.ide_ele
        if p <= l and r <= q:
            return self.tree[k]
        else:
            vl = self.rec_query(p, q, k*2+1, l, (l+r)//2)
            vr = self.rec_query(p, q, k*2+2, (l+r)//2+1, r)
        #print(vl, vr)
        return self.segfunc(vl, vr) SegmentTree ans = 0 0 ans p, q = (i for i in input().split()) (i for i in input().split()) p d = {} {} d ans += d[chr(ord("a")+c)].query(p, int(q)) d[chr(ord("a")+c)].query(p, int(q)) ans case = int(case) int(case) case
import sys
input = sys.stdin.readline

class SegmentTree():
    def segfunc(self, x, y):
        return max(x, y)
        
    def __init__(self, ide_ele, n, l, target):
        # n以上の最小の2のべき乗、一番下の段はここからスタートになる
        self.ide_ele = ide_ele
        self.num =2**(n-1).bit_length()
        self.tree = [ide_ele]*self.num*2
        # 一番下の段
        for i in range(n):
            if l[i] == target:
                self.tree[i+self.num-1] = 1
        # 
        for i in range(self.num-2, -1, -1):
            self.tree[i] = self.segfunc(self.tree[2*i+1], self.tree[2*i+2])
    
    def update(self, k, add):
        k += self.num-1
        if add:
            self.tree[k] = 1
        else:
            self.tree[k] = 0
        while k:
            k = (k-1)//2
            self.tree[k] = self.segfunc(self.tree[k*2+1], self.tree[k*2+2])
    
    def query(self, p, q):
        if q<=p:
            return self.ide_ele

        # [p, q)
        p += self.num - 1
        q += self.num - 2
        res = self.ide_ele
        while q-p>1: # まだ隣同士の節点ではないなら
            # &で偶奇判定->中途半端な位置にいるなら寄せる
            if p&1 == 0: #左なのに右端
                res = self.segfunc(res, self.tree[p])
            if q&1 == 1: #右なのに左端
                res = self.segfunc(res, self.tree[q])
                q -= 1
            p = p//2
            q = (q-1)//2
        if p==q:
            res = self.segfunc(res, self.tree[p])
        else:
            res = self.segfunc(self.segfunc(res, self.tree[p]), self.tree[q])
        return res

    # 閉区間になってる
    def rec_query(self, p, q, k, l, r):
        #q -= 1 [)の場合
        #print(p, q, k, l, r)
        if r < p or q < l: # out of range
            return self.ide_ele
        if p <= l and r <= q:
            return self.tree[k]
        else:
            vl = self.rec_query(p, q, k*2+1, l, (l+r)//2)
            vr = self.rec_query(p, q, k*2+2, (l+r)//2+1, r)
        #print(vl, vr)
        return self.segfunc(vl, vr)



N = int(input())
S = input()
Q = int(input())

result = ""

d = {}
for i in range(26):
    d[chr(ord("a")+i)] = SegmentTree(0, N, S, chr(ord("a")+i))

S = list(S)

for q in range(Q):
    case, p, q = (i for i in input().split())
    #print(case, p, q)
    p = int(p)-1
    case = int(case)
    if case==1:
        #print(p)
        d[S[p]].update(p, False)
        d[q].update(p, True)
        S[p] = q
    else:
        ans = 0
        for c in range(26):
            #print(d[chr(ord("a")+c)].tree)
            ans += d[chr(ord("a")+c)].query(p, int(q))
        result += str(ans)+"\n"

#print(S)
print(result[:-1])
