#単位元を設定
ide = 0

class SegmentTree:
	def __init__(self,n):
        #セグ木の頂点はindex == 1から。index == 0は無視すること。
        #つまり、STtable[0]は無視。頂点はSTtable[1]。
		self.n = n
		tmp = 0
		while True:
			if 2 ** tmp >= self.n:
				break
			tmp += 1
		self.STtable = [ide] * (2*2**tmp)
		self.STtable_size = len(self.STtable)

	def update(self,i,a):
        #更新のためのインデックスの指定は0_indexedで。
		a_bit = 1 << ord(a)-97
		i += self.STtable_size//2
		self.STtable[i] = a_bit
		while i > 0:
			i //= 2
			self.STtable[i] = self.STtable[i*2] | self.STtable[i*2+1]

	def find(self,a,b,k=1,l=0,r=None):
        #kは頂点番号。初期値は1にすること。
		#[a,b)の最小を返す。
		#[l,r)からです。
        #初期値のrは、self.STtable_size//2にすると、ちょうど要素数と同じ値になって[l,r)のrになる。
        #問題に適するように範囲を指定するように注意。大体[l,r]で指定されている。
		if r == None:
			r = self.STtable_size//2        
		if a >= r or b <= l:
			return ide
		elif a <= l and b >= r:
			return self.STtable[k]
		else:
			mid = (l+r)//2
			if b <= mid:
				return self.find(a,b,2*k,l,mid)
			elif a >= mid:
				return self.find(a,b,2*k+1,mid,r)
			else:
				v1 = self.find(a,mid,2*k,l,mid)
				v2 = self.find(mid,b,2*k+1,mid,r)
			return v1 | v2

N = int(input())
solve = SegmentTree(N)
S = input()
for i in range(N):
	solve.update(i,S[i])
Q = int(input())
ans = []
for _ in range(Q):
	a,b,c = map(str, input().split())
	if a == '1':
		solve.update(int(b)-1,c)
	else:
		tmp = solve.find(int(b)-1,int(c))
		cnt = 0
		for i in range(26):
			if tmp >> i & 1 == 1:
				cnt += 1
		ans.append(cnt)

for a in ans:
	print(a) ide = 0 ide 0 class SegmentTree:
	def __init__(self,n):
        #セグ木の頂点はindex == 1から。index == 0は無視すること。
        #つまり、STtable[0]は無視。頂点はSTtable[1]。
		self.n = n
		tmp = 0
		while True:
			if 2 ** tmp >= self.n:
				break
			tmp += 1
		self.STtable = [ide] * (2*2**tmp)
		self.STtable_size = len(self.STtable)

	def update(self,i,a):
        #更新のためのインデックスの指定は0_indexedで。
		a_bit = 1 << ord(a)-97
		i += self.STtable_size//2
		self.STtable[i] = a_bit
		while i > 0:
			i //= 2
			self.STtable[i] = self.STtable[i*2] | self.STtable[i*2+1]

	def find(self,a,b,k=1,l=0,r=None):
        #kは頂点番号。初期値は1にすること。
		#[a,b)の最小を返す。
		#[l,r)からです。
        #初期値のrは、self.STtable_size//2にすると、ちょうど要素数と同じ値になって[l,r)のrになる。
        #問題に適するように範囲を指定するように注意。大体[l,r]で指定されている。
		if r == None:
			r = self.STtable_size//2        
		if a >= r or b <= l:
			return ide
		elif a <= l and b >= r:
			return self.STtable[k]
		else:
			mid = (l+r)//2
			if b <= mid:
				return self.find(a,b,2*k,l,mid)
			elif a >= mid:
				return self.find(a,b,2*k+1,mid,r)
			else:
				v1 = self.find(a,mid,2*k,l,mid)
				v2 = self.find(mid,b,2*k+1,mid,r)
			return v1 | v2 SegmentTree def __init__(self,n):
        #セグ木の頂点はindex == 1から。index == 0は無視すること。
        #つまり、STtable[0]は無視。頂点はSTtable[1]。
		self.n = n
		tmp = 0
		while True:
			if 2 ** tmp >= self.n:
				break
			tmp += 1
		self.STtable = [ide] * (2*2**tmp)
		self.STtable_size = len(self.STtable)

	 __init__ self.n = n self.n self n n tmp = 0 tmp 0 while True:
			if 2 ** tmp >= self.n:
				break
			tmp += 1
		 True if 2 ** tmp >= self.n:
				break
			 2 ** tmp >= self.n 2 ** tmp 2 tmp self.n self n break tmp += 1 tmp 1 self.STtable = [ide] * (2*2**tmp) self.STtable self STtable [ide] * (2*2**tmp) [ide] ide 2*2**tmp 2 2**tmp 2 tmp self.STtable_size = len(self.STtable) self.STtable_size self STtable_size len(self.STtable) len self.STtable self STtable self self n n def update(self,i,a):
        #更新のためのインデックスの指定は0_indexedで。
		a_bit = 1 << ord(a)-97
		i += self.STtable_size//2
		self.STtable[i] = a_bit
		while i > 0:
			i //= 2
			self.STtable[i] = self.STtable[i*2] | self.STtable[i*2+1]

	 update a_bit = 1 << ord(a)-97 a_bit 1 << ord(a)-97 1 ord(a)-97 ord(a) ord a 97 i += self.STtable_size//2 i self.STtable_size//2 self.STtable_size self STtable_size 2 self.STtable[i] = a_bit self.STtable[i] self.STtable self STtable i a_bit while i > 0:
			i //= 2
			self.STtable[i] = self.STtable[i*2] | self.STtable[i*2+1]

	 i > 0 i 0 i //= 2 i 2 self.STtable[i] = self.STtable[i*2] | self.STtable[i*2+1] self.STtable[i] self.STtable self STtable i self.STtable[i*2] | self.STtable[i*2+1] self.STtable[i*2] self.STtable self STtable i*2 i 2 self.STtable[i*2+1] self.STtable self STtable i*2+1 i*2 i 2 1 self self i i a a def find(self,a,b,k=1,l=0,r=None):
        #kは頂点番号。初期値は1にすること。
		#[a,b)の最小を返す。
		#[l,r)からです。
        #初期値のrは、self.STtable_size//2にすると、ちょうど要素数と同じ値になって[l,r)のrになる。
        #問題に適するように範囲を指定するように注意。大体[l,r]で指定されている。
		if r == None:
			r = self.STtable_size//2        
		if a >= r or b <= l:
			return ide
		elif a <= l and b >= r:
			return self.STtable[k]
		else:
			mid = (l+r)//2
			if b <= mid:
				return self.find(a,b,2*k,l,mid)
			elif a >= mid:
				return self.find(a,b,2*k+1,mid,r)
			else:
				v1 = self.find(a,mid,2*k,l,mid)
				v2 = self.find(mid,b,2*k+1,mid,r)
			return v1 | v2 find if r == None:
			r = self.STtable_size//2        
		 r == None r None r = self.STtable_size//2 r self.STtable_size//2 self.STtable_size self STtable_size 2 if a >= r or b <= l:
			return ide
		elif a <= l and b >= r:
			return self.STtable[k]
		else:
			mid = (l+r)//2
			if b <= mid:
				return self.find(a,b,2*k,l,mid)
			elif a >= mid:
				return self.find(a,b,2*k+1,mid,r)
			else:
				v1 = self.find(a,mid,2*k,l,mid)
				v2 = self.find(mid,b,2*k+1,mid,r)
			return v1 | v2 a >= r or b <= l a >= r a r b <= l b l return ide ide elif a <= l and b >= r:
			return self.STtable[k]
		 a <= l and b >= r a <= l a l b >= r b r return self.STtable[k] self.STtable[k] self.STtable self STtable k mid = (l+r)//2 mid (l+r)//2 l+r l r 2 if b <= mid:
				return self.find(a,b,2*k,l,mid)
			elif a >= mid:
				return self.find(a,b,2*k+1,mid,r)
			else:
				v1 = self.find(a,mid,2*k,l,mid)
				v2 = self.find(mid,b,2*k+1,mid,r)
			 b <= mid b mid return self.find(a,b,2*k,l,mid) self.find(a,b,2*k,l,mid) self.find self find a b 2*k 2 k l mid elif a >= mid:
				return self.find(a,b,2*k+1,mid,r)
			 a >= mid a mid return self.find(a,b,2*k+1,mid,r) self.find(a,b,2*k+1,mid,r) self.find self find a b 2*k+1 2*k 2 k 1 mid r v1 = self.find(a,mid,2*k,l,mid) v1 self.find(a,mid,2*k,l,mid) self.find self find a mid 2*k 2 k l mid v2 = self.find(mid,b,2*k+1,mid,r) v2 self.find(mid,b,2*k+1,mid,r) self.find self find mid b 2*k+1 2*k 2 k 1 mid r return v1 | v2 v1 | v2 v1 v2 self self a a b b k=1 k 1 l=0 l 0 r=None r None N = int(input()) N int(input()) int input() input solve = SegmentTree(N) solve SegmentTree(N) SegmentTree N S = input() S input() input for i in range(N):
	solve.update(i,S[i]) i range(N) range N solve.update(i,S[i]) solve.update solve update i S[i] S i Q = int(input()) Q int(input()) int input() input ans = [] ans [] for _ in range(Q):
	a,b,c = map(str, input().split())
	if a == '1':
		solve.update(int(b)-1,c)
	else:
		tmp = solve.find(int(b)-1,int(c))
		cnt = 0
		for i in range(26):
			if tmp >> i & 1 == 1:
				cnt += 1
		ans.append(cnt) _ range(Q) range Q a,b,c = map(str, input().split()) a map(str, input().split()) map str input().split() ().split () input split b c if a == '1':
		solve.update(int(b)-1,c)
	else:
		tmp = solve.find(int(b)-1,int(c))
		cnt = 0
		for i in range(26):
			if tmp >> i & 1 == 1:
				cnt += 1
		ans.append(cnt) a == '1' a '1' solve.update(int(b)-1,c) solve.update solve update int(b)-1 int(b) int b 1 c tmp = solve.find(int(b)-1,int(c)) tmp solve.find(int(b)-1,int(c)) solve.find solve find int(b)-1 int(b) int b 1 int(c) int c cnt = 0 cnt 0 for i in range(26):
			if tmp >> i & 1 == 1:
				cnt += 1
		 i range(26) range 26 if tmp >> i & 1 == 1:
				cnt += 1
		 tmp >> i & 1 == 1 tmp >> i & 1 tmp >> i tmp i 1 1 cnt += 1 cnt 1 ans.append(cnt) ans.append ans append cnt for a in ans:
	print(a) a ans print(a) print a class SegmentTree:
	def __init__(self,n):
        #セグ木の頂点はindex == 1から。index == 0は無視すること。
        #つまり、STtable[0]は無視。頂点はSTtable[1]。
		self.n = n
		tmp = 0
		while True:
			if 2 ** tmp >= self.n:
				break
			tmp += 1
		self.STtable = [ide] * (2*2**tmp)
		self.STtable_size = len(self.STtable)

	def update(self,i,a):
        #更新のためのインデックスの指定は0_indexedで。
		a_bit = 1 << ord(a)-97
		i += self.STtable_size//2
		self.STtable[i] = a_bit
		while i > 0:
			i //= 2
			self.STtable[i] = self.STtable[i*2] | self.STtable[i*2+1]

	def find(self,a,b,k=1,l=0,r=None):
        #kは頂点番号。初期値は1にすること。
		#[a,b)の最小を返す。
		#[l,r)からです。
        #初期値のrは、self.STtable_size//2にすると、ちょうど要素数と同じ値になって[l,r)のrになる。
        #問題に適するように範囲を指定するように注意。大体[l,r]で指定されている。
		if r == None:
			r = self.STtable_size//2        
		if a >= r or b <= l:
			return ide
		elif a <= l and b >= r:
			return self.STtable[k]
		else:
			mid = (l+r)//2
			if b <= mid:
				return self.find(a,b,2*k,l,mid)
			elif a >= mid:
				return self.find(a,b,2*k+1,mid,r)
			else:
				v1 = self.find(a,mid,2*k,l,mid)
				v2 = self.find(mid,b,2*k+1,mid,r)
			return v1 | v2 class SegmentTree:
	def __init__(self,n):
        #セグ木の頂点はindex == 1から。index == 0は無視すること。
        #つまり、STtable[0]は無視。頂点はSTtable[1]。
		self.n = n
		tmp = 0
		while True:
			if 2 ** tmp >= self.n:
				break
			tmp += 1
		self.STtable = [ide] * (2*2**tmp)
		self.STtable_size = len(self.STtable)

	def update(self,i,a):
        #更新のためのインデックスの指定は0_indexedで。
		a_bit = 1 << ord(a)-97
		i += self.STtable_size//2
		self.STtable[i] = a_bit
		while i > 0:
			i //= 2
			self.STtable[i] = self.STtable[i*2] | self.STtable[i*2+1]

	def find(self,a,b,k=1,l=0,r=None):
        #kは頂点番号。初期値は1にすること。
		#[a,b)の最小を返す。
		#[l,r)からです。
        #初期値のrは、self.STtable_size//2にすると、ちょうど要素数と同じ値になって[l,r)のrになる。
        #問題に適するように範囲を指定するように注意。大体[l,r]で指定されている。
		if r == None:
			r = self.STtable_size//2        
		if a >= r or b <= l:
			return ide
		elif a <= l and b >= r:
			return self.STtable[k]
		else:
			mid = (l+r)//2
			if b <= mid:
				return self.find(a,b,2*k,l,mid)
			elif a >= mid:
				return self.find(a,b,2*k+1,mid,r)
			else:
				v1 = self.find(a,mid,2*k,l,mid)
				v2 = self.find(mid,b,2*k+1,mid,r)
			return v1 | v2 SegmentTree Q = int(input()) int(input()) Q S = input() input() S solve = SegmentTree(N) SegmentTree(N) solve ans = [] [] ans N = int(input()) int(input()) N cnt = 0 0 cnt ide = 0 0 ide tmp = solve.find(int(b)-1,int(c)) solve.find(int(b)-1,int(c)) tmp cnt += 1 1 cnt c = map(str, input().split()) map(str, input().split()) c b,c = map(str, input().split()) map(str, input().split()) b a,b,c = map(str, input().split()) map(str, input().split()) a
#単位元を設定
ide = 0

class SegmentTree:
	def __init__(self,n):
        #セグ木の頂点はindex == 1から。index == 0は無視すること。
        #つまり、STtable[0]は無視。頂点はSTtable[1]。
		self.n = n
		tmp = 0
		while True:
			if 2 ** tmp >= self.n:
				break
			tmp += 1
		self.STtable = [ide] * (2*2**tmp)
		self.STtable_size = len(self.STtable)

	def update(self,i,a):
        #更新のためのインデックスの指定は0_indexedで。
		a_bit = 1 << ord(a)-97
		i += self.STtable_size//2
		self.STtable[i] = a_bit
		while i > 0:
			i //= 2
			self.STtable[i] = self.STtable[i*2] | self.STtable[i*2+1]

	def find(self,a,b,k=1,l=0,r=None):
        #kは頂点番号。初期値は1にすること。
		#[a,b)の最小を返す。
		#[l,r)からです。
        #初期値のrは、self.STtable_size//2にすると、ちょうど要素数と同じ値になって[l,r)のrになる。
        #問題に適するように範囲を指定するように注意。大体[l,r]で指定されている。
		if r == None:
			r = self.STtable_size//2        
		if a >= r or b <= l:
			return ide
		elif a <= l and b >= r:
			return self.STtable[k]
		else:
			mid = (l+r)//2
			if b <= mid:
				return self.find(a,b,2*k,l,mid)
			elif a >= mid:
				return self.find(a,b,2*k+1,mid,r)
			else:
				v1 = self.find(a,mid,2*k,l,mid)
				v2 = self.find(mid,b,2*k+1,mid,r)
			return v1 | v2

N = int(input())
solve = SegmentTree(N)
S = input()
for i in range(N):
	solve.update(i,S[i])
Q = int(input())
ans = []
for _ in range(Q):
	a,b,c = map(str, input().split())
	if a == '1':
		solve.update(int(b)-1,c)
	else:
		tmp = solve.find(int(b)-1,int(c))
		cnt = 0
		for i in range(26):
			if tmp >> i & 1 == 1:
				cnt += 1
		ans.append(cnt)

for a in ans:
	print(a)
