def getN():
    return int(input())
def getNM():
    return map(int, input().split())
def getList():
    return list(map(int, input().split()))
def getArray(intn):
    return [int(input()) for i in range(intn)]
def input():
    return sys.stdin.readline().rstrip()
def rand_N(ran1, ran2):
    return random.randint(ran1, ran2)
def rand_List(ran1, ran2, rantime):
    return [random.randint(ran1, ran2) for i in range(rantime)]
def rand_ints_nodup(ran1, ran2, rantime):
  ns = []
  while len(ns) < rantime:
    n = random.randint(ran1, ran2)
    if not n in ns:
      ns.append(n)
  return sorted(ns)

def rand_query(ran1, ran2, rantime):
  r_query = []
  while len(r_query) < rantime:
    n_q = rand_ints_nodup(ran1, ran2, 2)
    if not n_q in r_query:
      r_query.append(n_q)
  return sorted(r_query)

from collections import defaultdict, deque, Counter
from sys import exit
from decimal import *
import heapq
import math
from fractions import gcd
import random
import string
import copy
from itertools import combinations, permutations, product
from operator import mul
from functools import reduce
from bisect import bisect_left, bisect_right

import sys
sys.setrecursionlimit(1000000000)
mod = 10 ** 9 + 7


#############
# Main Code #
#############

#####segfunc#####
def segfunc(x, y):
    return x * y
#################

#####ide_ele#####
ide_ele = 1
#################

class SegTree:
    """
    init(init_val, ide_ele): 配列init_valで初期化 O(N)
    update(k, x): k番目の値をxに更新 O(logN)
    query(l, r): 区間[l, r)をsegfuncしたものを返す O(logN)
    """
    def __init__(self, init_val, segfunc, ide_ele):
        """
        init_val: 配列の初期値
        segfunc: 区間にしたい操作
        ide_ele: 単位元
        n: 要素数
        num: n以上の最小の2のべき乗
        tree: セグメント木(1-index)
        """
        n = len(init_val)
        self.segfunc = segfunc
        self.ide_ele = ide_ele
        self.num = 1 << (n - 1).bit_length()
        self.tree = [ide_ele] * 2 * self.num
        # 配列の値を葉にセット
        for i in range(n):
            self.tree[self.num + i] = init_val[i]
        # 構築していく
        for i in range(self.num - 1, 0, -1):
            self.tree[i] = self.segfunc(self.tree[2 * i], self.tree[2 * i + 1])

    def update(self, k, x):
        """
        k番目の値をxに更新
        k: index(0-index)
        x: update value
        """
        k += self.num
        self.tree[k] = x
        while k > 1:
            self.tree[k >> 1] = self.segfunc(self.tree[k], self.tree[k ^ 1])
            k >>= 1

    def query(self, l, r):
        """
        [l, r)のsegfuncしたものを得る
        l: index(0-index)
        r: index(0-index)
        """
        res = self.ide_ele

        l += self.num
        r += self.num
        while l < r:
            if l & 1:
                res = self.segfunc(res, self.tree[l])
                l += 1
            if r & 1:
                res = self.segfunc(res, self.tree[r - 1])
            l >>= 1
            r >>= 1
        return res

N = getN()
s = input()
Q = getN()
query = [input().split() for i in range(Q)]

S = []
for i in s:
    # 面倒なので文字を数値化
	S.append(ord(i) - ord("a"))

seg = [SegTree([1] * N, segfunc, ide_ele) for _ in range(26)]

# 入力
for i in range(N):
	seg[S[i]].update(i, 0)

for i in range(Q):
	a, b, c = query[i]
	if int(a) == 1:
        # 何番目
		b = int(b) - 1
        # もともと１番目にあったものを1（消滅）させる
		seg[S[b]].update(b, 1)
		t = ord(c) - ord("a")
		seg[t].update(b, 0)
		S[b] = t

	else:
		b = int(b) - 1
		c = int(c)
		cnt = 0
		for se in seg:
            # 1 * 1 * 0 * 1 *...
            # 区間内に一つでも0があれば0
			if se.query(b, c) == 0:
				cnt += 1
		print(cnt) def getN():
    return int(input()) getN return int(input()) int(input()) int input() input def getNM():
    return map(int, input().split()) getNM return map(int, input().split()) map(int, input().split()) map int input().split() ().split () input split def getList():
    return list(map(int, input().split())) getList return list(map(int, input().split())) list(map(int, input().split())) list map(int, input().split()) map int input().split() ().split () input split def getArray(intn):
    return [int(input()) for i in range(intn)] getArray int(input()) for i in range(intn) for i in range(intn) i range(intn) range intn for i in range(intn) int(input()) int input() input return [int(input()) for i in range(intn)] [int(input()) for i in range(intn)] intn intn def input():
    return sys.stdin.readline().rstrip() input return sys.stdin.readline().rstrip() sys.stdin.readline().rstrip() sys.stdin.readline().rstrip sys.stdin.readline() sys.stdin.readline sys.stdin sys stdin readline rstrip def rand_N(ran1, ran2):
    return random.randint(ran1, ran2) rand_N return random.randint(ran1, ran2) random.randint(ran1, ran2) random.randint random randint ran1 ran2 ran1 ran1 ran2 ran2 def rand_List(ran1, ran2, rantime):
    return [random.randint(ran1, ran2) for i in range(rantime)] rand_List random.randint(ran1, ran2) for i in range(rantime) for i in range(rantime) i range(rantime) range rantime for i in range(rantime) random.randint(ran1, ran2) random.randint random randint ran1 ran2 return [random.randint(ran1, ran2) for i in range(rantime)] [random.randint(ran1, ran2) for i in range(rantime)] ran1 ran1 ran2 ran2 rantime rantime def rand_ints_nodup(ran1, ran2, rantime):
  ns = []
  while len(ns) < rantime:
    n = random.randint(ran1, ran2)
    if not n in ns:
      ns.append(n)
  return sorted(ns) rand_ints_nodup ns = [] ns [] while len(ns) < rantime:
    n = random.randint(ran1, ran2)
    if not n in ns:
      ns.append(n)
   len(ns) < rantime len(ns) len ns rantime n = random.randint(ran1, ran2) n random.randint(ran1, ran2) random.randint random randint ran1 ran2 if not n in ns:
      ns.append(n)
   not n in ns n in ns n ns ns.append(n) ns.append ns append n return sorted(ns) sorted(ns) sorted ns ran1 ran1 ran2 ran2 rantime rantime def rand_query(ran1, ran2, rantime):
  r_query = []
  while len(r_query) < rantime:
    n_q = rand_ints_nodup(ran1, ran2, 2)
    if not n_q in r_query:
      r_query.append(n_q)
  return sorted(r_query) rand_query r_query = [] r_query [] while len(r_query) < rantime:
    n_q = rand_ints_nodup(ran1, ran2, 2)
    if not n_q in r_query:
      r_query.append(n_q)
   len(r_query) < rantime len(r_query) len r_query rantime n_q = rand_ints_nodup(ran1, ran2, 2) n_q rand_ints_nodup(ran1, ran2, 2) rand_ints_nodup ran1 ran2 2 if not n_q in r_query:
      r_query.append(n_q)
   not n_q in r_query n_q in r_query n_q r_query r_query.append(n_q) r_query.append r_query append n_q return sorted(r_query) sorted(r_query) sorted r_query ran1 ran1 ran2 ran2 rantime rantime from collections import defaultdict, deque, Counter from sys import exit from decimal import * import heapq heapq import math math from fractions import gcd import random random import string string import copy copy from itertools import combinations, permutations, product from operator import mul from functools import reduce from bisect import bisect_left, bisect_right import sys sys sys.setrecursionlimit(1000000000) sys.setrecursionlimit sys setrecursionlimit 1000000000 mod = 10 ** 9 + 7 mod 10 ** 9 + 7 10 ** 9 10 9 7 def segfunc(x, y):
    return x * y
#################

#####ide_ele##### segfunc return x * y x * y x y x x y y ide_ele = 1 ide_ele 1 class SegTree:
    """
    init(init_val, ide_ele): 配列init_valで初期化 O(N)
    update(k, x): k番目の値をxに更新 O(logN)
    query(l, r): 区間[l, r)をsegfuncしたものを返す O(logN)
    """
    def __init__(self, init_val, segfunc, ide_ele):
        """
        init_val: 配列の初期値
        segfunc: 区間にしたい操作
        ide_ele: 単位元
        n: 要素数
        num: n以上の最小の2のべき乗
        tree: セグメント木(1-index)
        """
        n = len(init_val)
        self.segfunc = segfunc
        self.ide_ele = ide_ele
        self.num = 1 << (n - 1).bit_length()
        self.tree = [ide_ele] * 2 * self.num
        # 配列の値を葉にセット
        for i in range(n):
            self.tree[self.num + i] = init_val[i]
        # 構築していく
        for i in range(self.num - 1, 0, -1):
            self.tree[i] = self.segfunc(self.tree[2 * i], self.tree[2 * i + 1])

    def update(self, k, x):
        """
        k番目の値をxに更新
        k: index(0-index)
        x: update value
        """
        k += self.num
        self.tree[k] = x
        while k > 1:
            self.tree[k >> 1] = self.segfunc(self.tree[k], self.tree[k ^ 1])
            k >>= 1

    def query(self, l, r):
        """
        [l, r)のsegfuncしたものを得る
        l: index(0-index)
        r: index(0-index)
        """
        res = self.ide_ele

        l += self.num
        r += self.num
        while l < r:
            if l & 1:
                res = self.segfunc(res, self.tree[l])
                l += 1
            if r & 1:
                res = self.segfunc(res, self.tree[r - 1])
            l >>= 1
            r >>= 1
        return res SegTree """
    init(init_val, ide_ele): 配列init_valで初期化 O(N)
    update(k, x): k番目の値をxに更新 O(logN)
    query(l, r): 区間[l, r)をsegfuncしたものを返す O(logN)
    """ def __init__(self, init_val, segfunc, ide_ele):
        """
        init_val: 配列の初期値
        segfunc: 区間にしたい操作
        ide_ele: 単位元
        n: 要素数
        num: n以上の最小の2のべき乗
        tree: セグメント木(1-index)
        """
        n = len(init_val)
        self.segfunc = segfunc
        self.ide_ele = ide_ele
        self.num = 1 << (n - 1).bit_length()
        self.tree = [ide_ele] * 2 * self.num
        # 配列の値を葉にセット
        for i in range(n):
            self.tree[self.num + i] = init_val[i]
        # 構築していく
        for i in range(self.num - 1, 0, -1):
            self.tree[i] = self.segfunc(self.tree[2 * i], self.tree[2 * i + 1])

     __init__ """
        init_val: 配列の初期値
        segfunc: 区間にしたい操作
        ide_ele: 単位元
        n: 要素数
        num: n以上の最小の2のべき乗
        tree: セグメント木(1-index)
        """ n = len(init_val) n len(init_val) len init_val self.segfunc = segfunc self.segfunc self segfunc segfunc self.ide_ele = ide_ele self.ide_ele self ide_ele ide_ele self.num = 1 << (n - 1).bit_length() self.num self num 1 << (n - 1).bit_length() 1 (n - 1).bit_length() n - 1).bit_length n - 1 n 1 bit_length self.tree = [ide_ele] * 2 * self.num self.tree self tree [ide_ele] * 2 * self.num [ide_ele] * 2 [ide_ele] ide_ele 2 self.num self num for i in range(n):
            self.tree[self.num + i] = init_val[i]
        # 構築していく
         i range(n) range n self.tree[self.num + i] = init_val[i] self.tree[self.num + i] self.tree self tree self.num + i self.num self num i init_val[i] init_val i for i in range(self.num - 1, 0, -1):
            self.tree[i] = self.segfunc(self.tree[2 * i], self.tree[2 * i + 1])

     i range(self.num - 1, 0, -1) range self.num - 1 self.num self num 1 0 -1 self.tree[i] = self.segfunc(self.tree[2 * i], self.tree[2 * i + 1]) self.tree[i] self.tree self tree i self.segfunc(self.tree[2 * i], self.tree[2 * i + 1]) self.segfunc self segfunc self.tree[2 * i] self.tree self tree 2 * i 2 i self.tree[2 * i + 1] self.tree self tree 2 * i + 1 2 * i 2 i 1 self self init_val init_val segfunc segfunc ide_ele ide_ele def update(self, k, x):
        """
        k番目の値をxに更新
        k: index(0-index)
        x: update value
        """
        k += self.num
        self.tree[k] = x
        while k > 1:
            self.tree[k >> 1] = self.segfunc(self.tree[k], self.tree[k ^ 1])
            k >>= 1

     update """
        k番目の値をxに更新
        k: index(0-index)
        x: update value
        """ k += self.num k self.num self num self.tree[k] = x self.tree[k] self.tree self tree k x while k > 1:
            self.tree[k >> 1] = self.segfunc(self.tree[k], self.tree[k ^ 1])
            k >>= 1

     k > 1 k 1 self.tree[k >> 1] = self.segfunc(self.tree[k], self.tree[k ^ 1]) self.tree[k >> 1] self.tree self tree k >> 1 k 1 self.segfunc(self.tree[k], self.tree[k ^ 1]) self.segfunc self segfunc self.tree[k] self.tree self tree k self.tree[k ^ 1] self.tree self tree k ^ 1 k 1 k >>= 1 k 1 self self k k x x def query(self, l, r):
        """
        [l, r)のsegfuncしたものを得る
        l: index(0-index)
        r: index(0-index)
        """
        res = self.ide_ele

        l += self.num
        r += self.num
        while l < r:
            if l & 1:
                res = self.segfunc(res, self.tree[l])
                l += 1
            if r & 1:
                res = self.segfunc(res, self.tree[r - 1])
            l >>= 1
            r >>= 1
        return res query """
        [l, r)のsegfuncしたものを得る
        l: index(0-index)
        r: index(0-index)
        """ res = self.ide_ele res self.ide_ele self ide_ele l += self.num l self.num self num r += self.num r self.num self num while l < r:
            if l & 1:
                res = self.segfunc(res, self.tree[l])
                l += 1
            if r & 1:
                res = self.segfunc(res, self.tree[r - 1])
            l >>= 1
            r >>= 1
         l < r l r if l & 1:
                res = self.segfunc(res, self.tree[l])
                l += 1
             l & 1 l 1 res = self.segfunc(res, self.tree[l]) res self.segfunc(res, self.tree[l]) self.segfunc self segfunc res self.tree[l] self.tree self tree l l += 1 l 1 if r & 1:
                res = self.segfunc(res, self.tree[r - 1])
             r & 1 r 1 res = self.segfunc(res, self.tree[r - 1]) res self.segfunc(res, self.tree[r - 1]) self.segfunc self segfunc res self.tree[r - 1] self.tree self tree r - 1 r 1 l >>= 1 l 1 r >>= 1 r 1 return res res self self l l r r N = getN() N getN() getN s = input() s input() input Q = getN() Q getN() getN input().split() for i in range(Q) for i in range(Q) i range(Q) range Q for i in range(Q) input().split() ().split () input split query = [input().split() for i in range(Q)] query [input().split() for i in range(Q)] S = [] S [] for i in s:
    # 面倒なので文字を数値化
	S.append(ord(i) - ord("a")) i s S.append(ord(i) - ord("a")) S.append S append ord(i) - ord("a") ord(i) ord i ord("a") ord "a" SegTree([1] * N, segfunc, ide_ele) for _ in range(26) for _ in range(26) _ range(26) range 26 for _ in range(26) SegTree([1] * N, segfunc, ide_ele) SegTree [1] * N [1] 1 N segfunc ide_ele seg = [SegTree([1] * N, segfunc, ide_ele) for _ in range(26)] seg [SegTree([1] * N, segfunc, ide_ele) for _ in range(26)] for i in range(N):
	seg[S[i]].update(i, 0) i range(N) range N seg[S[i]].update(i, 0) [S[i]].update [S[i]] seg S[i] S i update i 0 for i in range(Q):
	a, b, c = query[i]
	if int(a) == 1:
        # 何番目
		b = int(b) - 1
        # もともと１番目にあったものを1（消滅）させる
		seg[S[b]].update(b, 1)
		t = ord(c) - ord("a")
		seg[t].update(b, 0)
		S[b] = t

	else:
		b = int(b) - 1
		c = int(c)
		cnt = 0
		for se in seg:
            # 1 * 1 * 0 * 1 *...
            # 区間内に一つでも0があれば0
			if se.query(b, c) == 0:
				cnt += 1
		print(cnt) i range(Q) range Q a, b, c = query[i] a query[i] query i b c if int(a) == 1:
        # 何番目
		b = int(b) - 1
        # もともと１番目にあったものを1（消滅）させる
		seg[S[b]].update(b, 1)
		t = ord(c) - ord("a")
		seg[t].update(b, 0)
		S[b] = t

	else:
		b = int(b) - 1
		c = int(c)
		cnt = 0
		for se in seg:
            # 1 * 1 * 0 * 1 *...
            # 区間内に一つでも0があれば0
			if se.query(b, c) == 0:
				cnt += 1
		print(cnt) int(a) == 1 int(a) int a 1 b = int(b) - 1 b int(b) - 1 int(b) int b 1 seg[S[b]].update(b, 1) [S[b]].update [S[b]] seg S[b] S b update b 1 t = ord(c) - ord("a") t ord(c) - ord("a") ord(c) ord c ord("a") ord "a" seg[t].update(b, 0) [t].update [t] seg t update b 0 S[b] = t S[b] S b t b = int(b) - 1 b int(b) - 1 int(b) int b 1 c = int(c) c int(c) int c cnt = 0 cnt 0 for se in seg:
            # 1 * 1 * 0 * 1 *...
            # 区間内に一つでも0があれば0
			if se.query(b, c) == 0:
				cnt += 1
		 se seg if se.query(b, c) == 0:
				cnt += 1
		 se.query(b, c) == 0 se.query(b, c) se.query se query b c 0 cnt += 1 cnt 1 print(cnt) print cnt def getNM():
    return map(int, input().split()) def getNM():
    return map(int, input().split()) getNM def getArray(intn):
    return [int(input()) for i in range(intn)] def getArray(intn):
    return [int(input()) for i in range(intn)] getArray mod = 10 ** 9 + 7 10 ** 9 + 7 mod def rand_List(ran1, ran2, rantime):
    return [random.randint(ran1, ran2) for i in range(rantime)] def rand_List(ran1, ran2, rantime):
    return [random.randint(ran1, ran2) for i in range(rantime)] rand_List N = getN() getN() N c = int(c) int(c) c def getList():
    return list(map(int, input().split())) def getList():
    return list(map(int, input().split())) getList ide_ele = 1 1 ide_ele t = ord(c) - ord("a") ord(c) - ord("a") t a, b, c = query[i] query[i] a S = [] [] S seg = [SegTree([1] * N, segfunc, ide_ele) for _ in range(26)] [SegTree([1] * N, segfunc, ide_ele) for _ in range(26)] seg b, c = query[i] query[i] b def getN():
    return int(input()) def getN():
    return int(input()) getN def input():
    return sys.stdin.readline().rstrip() def input():
    return sys.stdin.readline().rstrip() input def rand_query(ran1, ran2, rantime):
  r_query = []
  while len(r_query) < rantime:
    n_q = rand_ints_nodup(ran1, ran2, 2)
    if not n_q in r_query:
      r_query.append(n_q)
  return sorted(r_query) def rand_query(ran1, ran2, rantime):
  r_query = []
  while len(r_query) < rantime:
    n_q = rand_ints_nodup(ran1, ran2, 2)
    if not n_q in r_query:
      r_query.append(n_q)
  return sorted(r_query) rand_query class SegTree:
    """
    init(init_val, ide_ele): 配列init_valで初期化 O(N)
    update(k, x): k番目の値をxに更新 O(logN)
    query(l, r): 区間[l, r)をsegfuncしたものを返す O(logN)
    """
    def __init__(self, init_val, segfunc, ide_ele):
        """
        init_val: 配列の初期値
        segfunc: 区間にしたい操作
        ide_ele: 単位元
        n: 要素数
        num: n以上の最小の2のべき乗
        tree: セグメント木(1-index)
        """
        n = len(init_val)
        self.segfunc = segfunc
        self.ide_ele = ide_ele
        self.num = 1 << (n - 1).bit_length()
        self.tree = [ide_ele] * 2 * self.num
        # 配列の値を葉にセット
        for i in range(n):
            self.tree[self.num + i] = init_val[i]
        # 構築していく
        for i in range(self.num - 1, 0, -1):
            self.tree[i] = self.segfunc(self.tree[2 * i], self.tree[2 * i + 1])

    def update(self, k, x):
        """
        k番目の値をxに更新
        k: index(0-index)
        x: update value
        """
        k += self.num
        self.tree[k] = x
        while k > 1:
            self.tree[k >> 1] = self.segfunc(self.tree[k], self.tree[k ^ 1])
            k >>= 1

    def query(self, l, r):
        """
        [l, r)のsegfuncしたものを得る
        l: index(0-index)
        r: index(0-index)
        """
        res = self.ide_ele

        l += self.num
        r += self.num
        while l < r:
            if l & 1:
                res = self.segfunc(res, self.tree[l])
                l += 1
            if r & 1:
                res = self.segfunc(res, self.tree[r - 1])
            l >>= 1
            r >>= 1
        return res class SegTree:
    """
    init(init_val, ide_ele): 配列init_valで初期化 O(N)
    update(k, x): k番目の値をxに更新 O(logN)
    query(l, r): 区間[l, r)をsegfuncしたものを返す O(logN)
    """
    def __init__(self, init_val, segfunc, ide_ele):
        """
        init_val: 配列の初期値
        segfunc: 区間にしたい操作
        ide_ele: 単位元
        n: 要素数
        num: n以上の最小の2のべき乗
        tree: セグメント木(1-index)
        """
        n = len(init_val)
        self.segfunc = segfunc
        self.ide_ele = ide_ele
        self.num = 1 << (n - 1).bit_length()
        self.tree = [ide_ele] * 2 * self.num
        # 配列の値を葉にセット
        for i in range(n):
            self.tree[self.num + i] = init_val[i]
        # 構築していく
        for i in range(self.num - 1, 0, -1):
            self.tree[i] = self.segfunc(self.tree[2 * i], self.tree[2 * i + 1])

    def update(self, k, x):
        """
        k番目の値をxに更新
        k: index(0-index)
        x: update value
        """
        k += self.num
        self.tree[k] = x
        while k > 1:
            self.tree[k >> 1] = self.segfunc(self.tree[k], self.tree[k ^ 1])
            k >>= 1

    def query(self, l, r):
        """
        [l, r)のsegfuncしたものを得る
        l: index(0-index)
        r: index(0-index)
        """
        res = self.ide_ele

        l += self.num
        r += self.num
        while l < r:
            if l & 1:
                res = self.segfunc(res, self.tree[l])
                l += 1
            if r & 1:
                res = self.segfunc(res, self.tree[r - 1])
            l >>= 1
            r >>= 1
        return res SegTree b = int(b) - 1 int(b) - 1 b query = [input().split() for i in range(Q)] [input().split() for i in range(Q)] query cnt = 0 0 cnt def rand_ints_nodup(ran1, ran2, rantime):
  ns = []
  while len(ns) < rantime:
    n = random.randint(ran1, ran2)
    if not n in ns:
      ns.append(n)
  return sorted(ns) def rand_ints_nodup(ran1, ran2, rantime):
  ns = []
  while len(ns) < rantime:
    n = random.randint(ran1, ran2)
    if not n in ns:
      ns.append(n)
  return sorted(ns) rand_ints_nodup s = input() input() s c = query[i] query[i] c Q = getN() getN() Q cnt += 1 1 cnt def segfunc(x, y):
    return x * y
#################

#####ide_ele##### def segfunc(x, y):
    return x * y
#################

#####ide_ele##### segfunc def rand_N(ran1, ran2):
    return random.randint(ran1, ran2) def rand_N(ran1, ran2):
    return random.randint(ran1, ran2) rand_N b = int(b) - 1 int(b) - 1 b
def getN():
    return int(input())
def getNM():
    return map(int, input().split())
def getList():
    return list(map(int, input().split()))
def getArray(intn):
    return [int(input()) for i in range(intn)]
def input():
    return sys.stdin.readline().rstrip()
def rand_N(ran1, ran2):
    return random.randint(ran1, ran2)
def rand_List(ran1, ran2, rantime):
    return [random.randint(ran1, ran2) for i in range(rantime)]
def rand_ints_nodup(ran1, ran2, rantime):
  ns = []
  while len(ns) < rantime:
    n = random.randint(ran1, ran2)
    if not n in ns:
      ns.append(n)
  return sorted(ns)

def rand_query(ran1, ran2, rantime):
  r_query = []
  while len(r_query) < rantime:
    n_q = rand_ints_nodup(ran1, ran2, 2)
    if not n_q in r_query:
      r_query.append(n_q)
  return sorted(r_query)

from collections import defaultdict, deque, Counter
from sys import exit
from decimal import *
import heapq
import math
from fractions import gcd
import random
import string
import copy
from itertools import combinations, permutations, product
from operator import mul
from functools import reduce
from bisect import bisect_left, bisect_right

import sys
sys.setrecursionlimit(1000000000)
mod = 10 ** 9 + 7


#############
# Main Code #
#############

#####segfunc#####
def segfunc(x, y):
    return x * y
#################

#####ide_ele#####
ide_ele = 1
#################

class SegTree:
    """
    init(init_val, ide_ele): 配列init_valで初期化 O(N)
    update(k, x): k番目の値をxに更新 O(logN)
    query(l, r): 区間[l, r)をsegfuncしたものを返す O(logN)
    """
    def __init__(self, init_val, segfunc, ide_ele):
        """
        init_val: 配列の初期値
        segfunc: 区間にしたい操作
        ide_ele: 単位元
        n: 要素数
        num: n以上の最小の2のべき乗
        tree: セグメント木(1-index)
        """
        n = len(init_val)
        self.segfunc = segfunc
        self.ide_ele = ide_ele
        self.num = 1 << (n - 1).bit_length()
        self.tree = [ide_ele] * 2 * self.num
        # 配列の値を葉にセット
        for i in range(n):
            self.tree[self.num + i] = init_val[i]
        # 構築していく
        for i in range(self.num - 1, 0, -1):
            self.tree[i] = self.segfunc(self.tree[2 * i], self.tree[2 * i + 1])

    def update(self, k, x):
        """
        k番目の値をxに更新
        k: index(0-index)
        x: update value
        """
        k += self.num
        self.tree[k] = x
        while k > 1:
            self.tree[k >> 1] = self.segfunc(self.tree[k], self.tree[k ^ 1])
            k >>= 1

    def query(self, l, r):
        """
        [l, r)のsegfuncしたものを得る
        l: index(0-index)
        r: index(0-index)
        """
        res = self.ide_ele

        l += self.num
        r += self.num
        while l < r:
            if l & 1:
                res = self.segfunc(res, self.tree[l])
                l += 1
            if r & 1:
                res = self.segfunc(res, self.tree[r - 1])
            l >>= 1
            r >>= 1
        return res

N = getN()
s = input()
Q = getN()
query = [input().split() for i in range(Q)]

S = []
for i in s:
    # 面倒なので文字を数値化
	S.append(ord(i) - ord("a"))

seg = [SegTree([1] * N, segfunc, ide_ele) for _ in range(26)]

# 入力
for i in range(N):
	seg[S[i]].update(i, 0)

for i in range(Q):
	a, b, c = query[i]
	if int(a) == 1:
        # 何番目
		b = int(b) - 1
        # もともと１番目にあったものを1（消滅）させる
		seg[S[b]].update(b, 1)
		t = ord(c) - ord("a")
		seg[t].update(b, 0)
		S[b] = t

	else:
		b = int(b) - 1
		c = int(c)
		cnt = 0
		for se in seg:
            # 1 * 1 * 0 * 1 *...
            # 区間内に一つでも0があれば0
			if se.query(b, c) == 0:
				cnt += 1
		print(cnt)