
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())
    ql = []
    for _ in range(q): 
        num,a,b = map(str, input().split())
        ql.append((num,a,b))
    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)

    for query in ql:
        a,b,c = query
        if a == '1':
            b = int(b)
            before = s[b-1]
            alp_d[before].add(b, -1)
            alp_d[c].add(b,1)
            s[b-1] = c
        else:
            l,r = int(b),int(c)
            cnt = 0
            for v in alp_d.values():
                if v.sum(r)-v.sum(l-1) > 0:
                    cnt += 1
            print(cnt) 


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())
    ql = []
    for _ in range(q): 
        num,a,b = map(str, input().split())
        ql.append((num,a,b))
    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)

    for query in ql:
        a,b,c = query
        if a == '1':
            b = int(b)
            before = s[b-1]
            alp_d[before].add(b, -1)
            alp_d[c].add(b,1)
            s[b-1] = c
        else:
            l,r = int(b),int(c)
            cnt = 0
            for v in alp_d.values():
                if v.sum(r)-v.sum(l-1) > 0:
                    cnt += 1
            print(cnt)  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 ql = [] ql [] for _ in range(q): 
        num,a,b = map(str, input().split())
        ql.append((num,a,b))
     _ range(q) range q num,a,b = map(str, input().split()) num map(str, input().split()) map str input().split() ().split () input split a b ql.append((num,a,b)) ql.append ql append (num,a,b) num a b 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 for query in ql:
        a,b,c = query
        if a == '1':
            b = int(b)
            before = s[b-1]
            alp_d[before].add(b, -1)
            alp_d[c].add(b,1)
            s[b-1] = c
        else:
            l,r = int(b),int(c)
            cnt = 0
            for v in alp_d.values():
                if v.sum(r)-v.sum(l-1) > 0:
                    cnt += 1
            print(cnt)  query ql a,b,c = query a query b c if a == '1':
            b = int(b)
            before = s[b-1]
            alp_d[before].add(b, -1)
            alp_d[c].add(b,1)
            s[b-1] = c
        else:
            l,r = int(b),int(c)
            cnt = 0
            for v in alp_d.values():
                if v.sum(r)-v.sum(l-1) > 0:
                    cnt += 1
            print(cnt)  a == '1' a '1' b = int(b) b int(b) int b before = s[b-1] before s[b-1] s b-1 b 1 alp_d[before].add(b, -1) [before].add [before] alp_d before add b -1 alp_d[c].add(b,1) [c].add [c] alp_d c add b 1 s[b-1] = c s[b-1] s b-1 b 1 c l,r = int(b),int(c) l int(b) int b r int(c) int c cnt = 0 cnt 0 for v in alp_d.values():
                if v.sum(r)-v.sum(l-1) > 0:
                    cnt += 1
             v alp_d.values() alp_d.values alp_d values if v.sum(r)-v.sum(l-1) > 0:
                    cnt += 1
             v.sum(r)-v.sum(l-1) > 0 v.sum(r)-v.sum(l-1) v.sum(r) v.sum v sum r v.sum(l-1) v.sum v sum l-1 l 1 0 cnt += 1 cnt 1 print(cnt) print cnt if __name__ == "__main__":
    main() __name__ == "__main__" __name__ "__main__" 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) 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 def main():
    n = int(input())
    s = list(input())
    q = int(input())
    ql = []
    for _ in range(q): 
        num,a,b = map(str, input().split())
        ql.append((num,a,b))
    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)

    for query in ql:
        a,b,c = query
        if a == '1':
            b = int(b)
            before = s[b-1]
            alp_d[before].add(b, -1)
            alp_d[c].add(b,1)
            s[b-1] = c
        else:
            l,r = int(b),int(c)
            cnt = 0
            for v in alp_d.values():
                if v.sum(r)-v.sum(l-1) > 0:
                    cnt += 1
            print(cnt)  def main():
    n = int(input())
    s = list(input())
    q = int(input())
    ql = []
    for _ in range(q): 
        num,a,b = map(str, input().split())
        ql.append((num,a,b))
    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)

    for query in ql:
        a,b,c = query
        if a == '1':
            b = int(b)
            before = s[b-1]
            alp_d[before].add(b, -1)
            alp_d[c].add(b,1)
            s[b-1] = c
        else:
            l,r = int(b),int(c)
            cnt = 0
            for v in alp_d.values():
                if v.sum(r)-v.sum(l-1) > 0:
                    cnt += 1
            print(cnt)  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)


def main():
    n = int(input())
    s = list(input())
    q = int(input())
    ql = []
    for _ in range(q): 
        num,a,b = map(str, input().split())
        ql.append((num,a,b))
    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)

    for query in ql:
        a,b,c = query
        if a == '1':
            b = int(b)
            before = s[b-1]
            alp_d[before].add(b, -1)
            alp_d[c].add(b,1)
            s[b-1] = c
        else:
            l,r = int(b),int(c)
            cnt = 0
            for v in alp_d.values():
                if v.sum(r)-v.sum(l-1) > 0:
                    cnt += 1
            print(cnt) 


if __name__ == "__main__":
    main()