# ----- BIT -----
class Bit:
    """ used for only int(>=0) 
        1-indexed (ignore 0-index)
    """
    def __init__(self, n):
        self.size = n
        self.tree = [0] * (n + 1)
        self.depth = n.bit_length()
 
    def sum(self, i):
        s = 0
        while i > 0:
            s += self.tree[i]
            i -= i & -i
        return s
 
    def add(self, i, x):
        while i <= self.size:
            self.tree[i] += x
            i += i & -i

    def lower_bound(self, x):
        """ 累積和がx以上になる最小のindexと、その直前までの累積和 """
        sum_ = 0
        pos = 0
        for i in range(self.depth, -1, -1):
            k = pos + (1 << i)
            if k <= self.size and sum_ + self.tree[k] < x:
                sum_ += self.tree[k]
                pos += 1 << i
        return pos + 1, sum_

    def get_less_than_x_cnt(self, x):
        """ 累積和がx未満 の個数 """
        lb_pos, lb_sum = self.lower_bound(x)
        return lb_pos-1

    def get_less_than_and_x_cnt(self, x):
        """ 累積和がx以下 の個数 """
        lb_pos, lb_sum = self.lower_bound(x+1)
        return lb_pos-1
    
    def get_more_than_x_cnt(self, x):
        """ 累積和がxより大きい 個数 """
        return self.size - self.get_less_than_and_x_cnt(x)


def main():
    n = int(input())
    s = list(input())
    q = int(input())
    alps = 'abcdefghijklmnopqrstuvwxyz'

    
    alp_d = {chr(ord('a') + i): Bit(n) for i in range(26)}
    for i,si in enumerate(s):
        alp_d[si].add(i+1,1) 

    ansl = []
    for i in range(q):
        com,a,b = map(str, input().split())
        if com == '1':
            i,c = int(a),b
            si = s[i-1]
            alp_d[si].add(i, -1)
            alp_d[c].add(i, 1)
            s[i-1] = c
        else:
            l,r = int(a),int(b)
            ans = 0
            for alp in alps:
                cnt = alp_d[alp].sum(r) - alp_d[alp].sum(l-1)
                if cnt > 0:
                    ans+=1
            ansl.append(ans)

    for a in ansl:
        print(a)


if __name__ == "__main__":
    main() class Bit:
    """ used for only int(>=0) 
        1-indexed (ignore 0-index)
    """
    def __init__(self, n):
        self.size = n
        self.tree = [0] * (n + 1)
        self.depth = n.bit_length()
 
    def sum(self, i):
        s = 0
        while i > 0:
            s += self.tree[i]
            i -= i & -i
        return s
 
    def add(self, i, x):
        while i <= self.size:
            self.tree[i] += x
            i += i & -i

    def lower_bound(self, x):
        """ 累積和がx以上になる最小のindexと、その直前までの累積和 """
        sum_ = 0
        pos = 0
        for i in range(self.depth, -1, -1):
            k = pos + (1 << i)
            if k <= self.size and sum_ + self.tree[k] < x:
                sum_ += self.tree[k]
                pos += 1 << i
        return pos + 1, sum_

    def get_less_than_x_cnt(self, x):
        """ 累積和がx未満 の個数 """
        lb_pos, lb_sum = self.lower_bound(x)
        return lb_pos-1

    def get_less_than_and_x_cnt(self, x):
        """ 累積和がx以下 の個数 """
        lb_pos, lb_sum = self.lower_bound(x+1)
        return lb_pos-1
    
    def get_more_than_x_cnt(self, x):
        """ 累積和がxより大きい 個数 """
        return self.size - self.get_less_than_and_x_cnt(x) Bit """ used for only int(>=0) 
        1-indexed (ignore 0-index)
    """ def __init__(self, n):
        self.size = n
        self.tree = [0] * (n + 1)
        self.depth = n.bit_length()
 
     __init__ self.size = n self.size self size n self.tree = [0] * (n + 1) self.tree self tree [0] * (n + 1) [0] 0 n + 1 n 1 self.depth = n.bit_length() self.depth self depth n.bit_length() n.bit_length n bit_length self self n n def sum(self, i):
        s = 0
        while i > 0:
            s += self.tree[i]
            i -= i & -i
        return s
 
     sum s = 0 s 0 while i > 0:
            s += self.tree[i]
            i -= i & -i
         i > 0 i 0 s += self.tree[i] s self.tree[i] self.tree self tree i i -= i & -i i i & -i i -i i return s s self self i i def add(self, i, x):
        while i <= self.size:
            self.tree[i] += x
            i += i & -i

     add while i <= self.size:
            self.tree[i] += x
            i += i & -i

     i <= self.size i self.size self size self.tree[i] += x self.tree[i] self.tree self tree i x i += i & -i i i & -i i -i i self self i i x x def lower_bound(self, x):
        """ 累積和がx以上になる最小のindexと、その直前までの累積和 """
        sum_ = 0
        pos = 0
        for i in range(self.depth, -1, -1):
            k = pos + (1 << i)
            if k <= self.size and sum_ + self.tree[k] < x:
                sum_ += self.tree[k]
                pos += 1 << i
        return pos + 1, sum_

     lower_bound """ 累積和がx以上になる最小のindexと、その直前までの累積和 """ sum_ = 0 sum_ 0 pos = 0 pos 0 for i in range(self.depth, -1, -1):
            k = pos + (1 << i)
            if k <= self.size and sum_ + self.tree[k] < x:
                sum_ += self.tree[k]
                pos += 1 << i
         i range(self.depth, -1, -1) range self.depth self depth -1 -1 k = pos + (1 << i) k pos + (1 << i) pos 1 << i 1 i if k <= self.size and sum_ + self.tree[k] < x:
                sum_ += self.tree[k]
                pos += 1 << i
         k <= self.size and sum_ + self.tree[k] < x k <= self.size k self.size self size sum_ + self.tree[k] < x sum_ + self.tree[k] sum_ self.tree[k] self.tree self tree k x sum_ += self.tree[k] sum_ self.tree[k] self.tree self tree k pos += 1 << i pos 1 << i 1 i return pos + 1, sum_ return pos + 1, sum_ pos + 1 pos 1 sum_ self self x x def get_less_than_x_cnt(self, x):
        """ 累積和がx未満 の個数 """
        lb_pos, lb_sum = self.lower_bound(x)
        return lb_pos-1

     get_less_than_x_cnt """ 累積和がx未満 の個数 """ lb_pos, lb_sum = self.lower_bound(x) lb_pos self.lower_bound(x) self.lower_bound self lower_bound x lb_sum return lb_pos-1 lb_pos-1 lb_pos 1 self self x x def get_less_than_and_x_cnt(self, x):
        """ 累積和がx以下 の個数 """
        lb_pos, lb_sum = self.lower_bound(x+1)
        return lb_pos-1
    
     get_less_than_and_x_cnt """ 累積和がx以下 の個数 """ lb_pos, lb_sum = self.lower_bound(x+1) lb_pos self.lower_bound(x+1) self.lower_bound self lower_bound x+1 x 1 lb_sum return lb_pos-1 lb_pos-1 lb_pos 1 self self x x def get_more_than_x_cnt(self, x):
        """ 累積和がxより大きい 個数 """
        return self.size - self.get_less_than_and_x_cnt(x) get_more_than_x_cnt """ 累積和がxより大きい 個数 """ return self.size - self.get_less_than_and_x_cnt(x) self.size - self.get_less_than_and_x_cnt(x) self.size self size self.get_less_than_and_x_cnt(x) self.get_less_than_and_x_cnt self get_less_than_and_x_cnt x self self x x def main():
    n = int(input())
    s = list(input())
    q = int(input())
    alps = 'abcdefghijklmnopqrstuvwxyz'

    
    alp_d = {chr(ord('a') + i): Bit(n) for i in range(26)}
    for i,si in enumerate(s):
        alp_d[si].add(i+1,1) 

    ansl = []
    for i in range(q):
        com,a,b = map(str, input().split())
        if com == '1':
            i,c = int(a),b
            si = s[i-1]
            alp_d[si].add(i, -1)
            alp_d[c].add(i, 1)
            s[i-1] = c
        else:
            l,r = int(a),int(b)
            ans = 0
            for alp in alps:
                cnt = alp_d[alp].sum(r) - alp_d[alp].sum(l-1)
                if cnt > 0:
                    ans+=1
            ansl.append(ans)

    for a in ansl:
        print(a) main n = int(input()) n int(input()) int input() input s = list(input()) s list(input()) list input() input q = int(input()) q int(input()) int input() input alps = 'abcdefghijklmnopqrstuvwxyz' alps 'abcdefghijklmnopqrstuvwxyz' chr(ord('a') + i): Bit(n) for i in range(26) for i in range(26) i range(26) range 26 for i in range(26) chr(ord('a') + i) chr ord('a') + i ord('a') ord 'a' i Bit(n) Bit n alp_d = {chr(ord('a') + i): Bit(n) for i in range(26)} alp_d {chr(ord('a') + i): Bit(n) for i in range(26)} for i,si in enumerate(s):
        alp_d[si].add(i+1,1) 

     i si enumerate(s) enumerate s alp_d[si].add(i+1,1) [si].add [si] alp_d si add i+1 i 1 1 ansl = [] ansl [] for i in range(q):
        com,a,b = map(str, input().split())
        if com == '1':
            i,c = int(a),b
            si = s[i-1]
            alp_d[si].add(i, -1)
            alp_d[c].add(i, 1)
            s[i-1] = c
        else:
            l,r = int(a),int(b)
            ans = 0
            for alp in alps:
                cnt = alp_d[alp].sum(r) - alp_d[alp].sum(l-1)
                if cnt > 0:
                    ans+=1
            ansl.append(ans)

     i range(q) range q com,a,b = map(str, input().split()) com map(str, input().split()) map str input().split() ().split () input split a b if com == '1':
            i,c = int(a),b
            si = s[i-1]
            alp_d[si].add(i, -1)
            alp_d[c].add(i, 1)
            s[i-1] = c
        else:
            l,r = int(a),int(b)
            ans = 0
            for alp in alps:
                cnt = alp_d[alp].sum(r) - alp_d[alp].sum(l-1)
                if cnt > 0:
                    ans+=1
            ansl.append(ans)

     com == '1' com '1' i,c = int(a),b i int(a) int a c b si = s[i-1] si s[i-1] s i-1 i 1 alp_d[si].add(i, -1) [si].add [si] alp_d si add i -1 alp_d[c].add(i, 1) [c].add [c] alp_d c add i 1 s[i-1] = c s[i-1] s i-1 i 1 c l,r = int(a),int(b) l int(a) int a r int(b) int b ans = 0 ans 0 for alp in alps:
                cnt = alp_d[alp].sum(r) - alp_d[alp].sum(l-1)
                if cnt > 0:
                    ans+=1
             alp alps cnt = alp_d[alp].sum(r) - alp_d[alp].sum(l-1) cnt alp_d[alp].sum(r) - alp_d[alp].sum(l-1) alp_d[alp].sum(r) [alp].sum [alp] alp_d alp sum r alp_d[alp].sum(l-1) [alp].sum [alp] alp_d alp sum l-1 l 1 if cnt > 0:
                    ans+=1
             cnt > 0 cnt 0 ans+=1 ans 1 ansl.append(ans) ansl.append ansl append ans for a in ansl:
        print(a) a ansl print(a) print a if __name__ == "__main__":
    main() __name__ == "__main__" __name__ "__main__" main() main def main():
    n = int(input())
    s = list(input())
    q = int(input())
    alps = 'abcdefghijklmnopqrstuvwxyz'

    
    alp_d = {chr(ord('a') + i): Bit(n) for i in range(26)}
    for i,si in enumerate(s):
        alp_d[si].add(i+1,1) 

    ansl = []
    for i in range(q):
        com,a,b = map(str, input().split())
        if com == '1':
            i,c = int(a),b
            si = s[i-1]
            alp_d[si].add(i, -1)
            alp_d[c].add(i, 1)
            s[i-1] = c
        else:
            l,r = int(a),int(b)
            ans = 0
            for alp in alps:
                cnt = alp_d[alp].sum(r) - alp_d[alp].sum(l-1)
                if cnt > 0:
                    ans+=1
            ansl.append(ans)

    for a in ansl:
        print(a) def main():
    n = int(input())
    s = list(input())
    q = int(input())
    alps = 'abcdefghijklmnopqrstuvwxyz'

    
    alp_d = {chr(ord('a') + i): Bit(n) for i in range(26)}
    for i,si in enumerate(s):
        alp_d[si].add(i+1,1) 

    ansl = []
    for i in range(q):
        com,a,b = map(str, input().split())
        if com == '1':
            i,c = int(a),b
            si = s[i-1]
            alp_d[si].add(i, -1)
            alp_d[c].add(i, 1)
            s[i-1] = c
        else:
            l,r = int(a),int(b)
            ans = 0
            for alp in alps:
                cnt = alp_d[alp].sum(r) - alp_d[alp].sum(l-1)
                if cnt > 0:
                    ans+=1
            ansl.append(ans)

    for a in ansl:
        print(a) main class Bit:
    """ used for only int(>=0) 
        1-indexed (ignore 0-index)
    """
    def __init__(self, n):
        self.size = n
        self.tree = [0] * (n + 1)
        self.depth = n.bit_length()
 
    def sum(self, i):
        s = 0
        while i > 0:
            s += self.tree[i]
            i -= i & -i
        return s
 
    def add(self, i, x):
        while i <= self.size:
            self.tree[i] += x
            i += i & -i

    def lower_bound(self, x):
        """ 累積和がx以上になる最小のindexと、その直前までの累積和 """
        sum_ = 0
        pos = 0
        for i in range(self.depth, -1, -1):
            k = pos + (1 << i)
            if k <= self.size and sum_ + self.tree[k] < x:
                sum_ += self.tree[k]
                pos += 1 << i
        return pos + 1, sum_

    def get_less_than_x_cnt(self, x):
        """ 累積和がx未満 の個数 """
        lb_pos, lb_sum = self.lower_bound(x)
        return lb_pos-1

    def get_less_than_and_x_cnt(self, x):
        """ 累積和がx以下 の個数 """
        lb_pos, lb_sum = self.lower_bound(x+1)
        return lb_pos-1
    
    def get_more_than_x_cnt(self, x):
        """ 累積和がxより大きい 個数 """
        return self.size - self.get_less_than_and_x_cnt(x) class Bit:
    """ used for only int(>=0) 
        1-indexed (ignore 0-index)
    """
    def __init__(self, n):
        self.size = n
        self.tree = [0] * (n + 1)
        self.depth = n.bit_length()
 
    def sum(self, i):
        s = 0
        while i > 0:
            s += self.tree[i]
            i -= i & -i
        return s
 
    def add(self, i, x):
        while i <= self.size:
            self.tree[i] += x
            i += i & -i

    def lower_bound(self, x):
        """ 累積和がx以上になる最小のindexと、その直前までの累積和 """
        sum_ = 0
        pos = 0
        for i in range(self.depth, -1, -1):
            k = pos + (1 << i)
            if k <= self.size and sum_ + self.tree[k] < x:
                sum_ += self.tree[k]
                pos += 1 << i
        return pos + 1, sum_

    def get_less_than_x_cnt(self, x):
        """ 累積和がx未満 の個数 """
        lb_pos, lb_sum = self.lower_bound(x)
        return lb_pos-1

    def get_less_than_and_x_cnt(self, x):
        """ 累積和がx以下 の個数 """
        lb_pos, lb_sum = self.lower_bound(x+1)
        return lb_pos-1
    
    def get_more_than_x_cnt(self, x):
        """ 累積和がxより大きい 個数 """
        return self.size - self.get_less_than_and_x_cnt(x) Bit
# ----- BIT -----
class Bit:
    """ used for only int(>=0) 
        1-indexed (ignore 0-index)
    """
    def __init__(self, n):
        self.size = n
        self.tree = [0] * (n + 1)
        self.depth = n.bit_length()
 
    def sum(self, i):
        s = 0
        while i > 0:
            s += self.tree[i]
            i -= i & -i
        return s
 
    def add(self, i, x):
        while i <= self.size:
            self.tree[i] += x
            i += i & -i

    def lower_bound(self, x):
        """ 累積和がx以上になる最小のindexと、その直前までの累積和 """
        sum_ = 0
        pos = 0
        for i in range(self.depth, -1, -1):
            k = pos + (1 << i)
            if k <= self.size and sum_ + self.tree[k] < x:
                sum_ += self.tree[k]
                pos += 1 << i
        return pos + 1, sum_

    def get_less_than_x_cnt(self, x):
        """ 累積和がx未満 の個数 """
        lb_pos, lb_sum = self.lower_bound(x)
        return lb_pos-1

    def get_less_than_and_x_cnt(self, x):
        """ 累積和がx以下 の個数 """
        lb_pos, lb_sum = self.lower_bound(x+1)
        return lb_pos-1
    
    def get_more_than_x_cnt(self, x):
        """ 累積和がxより大きい 個数 """
        return self.size - self.get_less_than_and_x_cnt(x)


def main():
    n = int(input())
    s = list(input())
    q = int(input())
    alps = 'abcdefghijklmnopqrstuvwxyz'

    
    alp_d = {chr(ord('a') + i): Bit(n) for i in range(26)}
    for i,si in enumerate(s):
        alp_d[si].add(i+1,1) 

    ansl = []
    for i in range(q):
        com,a,b = map(str, input().split())
        if com == '1':
            i,c = int(a),b
            si = s[i-1]
            alp_d[si].add(i, -1)
            alp_d[c].add(i, 1)
            s[i-1] = c
        else:
            l,r = int(a),int(b)
            ans = 0
            for alp in alps:
                cnt = alp_d[alp].sum(r) - alp_d[alp].sum(l-1)
                if cnt > 0:
                    ans+=1
            ansl.append(ans)

    for a in ansl:
        print(a)


if __name__ == "__main__":
    main()