#!/usr/bin/env python3

import sys, math, itertools, collections, bisect

input = lambda: sys.stdin.buffer.readline().rstrip().decode('utf-8')

inf = float('inf') ;mod = 10**9+7

mans = inf ;ans = 0 ;count = 0 ;pro = 1



class SegmentTree:

  __slots__ = ['ide','n','seg','segfunc']



  def __init__(self,size,func,element):

    self.segfunc = func

    self.ide = element

    # self.size = sizeを超える最小の2冪の数

    self.n = 2 ** (n-1).bit_length()

    # 全てのnodeの数は(2*n-1)個

    # 上にn-1個,最下段にn個

    self.seg = [self.ide] * (2*self.n-1)



  def apply(self,array):

    arraysize = len(array)

    # 配列埋め込み

    for i in range(arraysize):

      self.seg[self.n-1+i] = array[i]

    # 上にあげる

    for i in range(self.n-2,-1,-1):

      self.seg[i] = self.segfunc(self.seg[2*i+1],self.seg[2*i+2])



  def update(self,k,x):

    k += self.n -1

    self.seg[k] = x

    while k:

      k = (k-1)//2

      self.seg[k] = self.segfunc(self.seg[2*k+1],self.seg[2*k+2])



  def query(self,l,r):

    # 半開区間[l,r)

    l += self.n-1; r += self.n-1

    vl = vr = self.ide

    while l < r:

      if l & 1 == 0:

        vl = self.segfunc(vl,self.seg[l])

        l += 1

      if r & 1 == 0:

        vr = self.segfunc(vr,self.seg[r-1])

      l = (l-1)//2; r = (r-1)//2

    return self.segfunc(vl,vr)



  def query2(self, p, q):

      if q <= p:

          return self.ide

      p += self.n - 1

      q += self.n - 2

      res = self.ide

      while q - p > 1:

          if p & 1 == 0:

              res = self.segfunc(res, self.seg[p])

          if q & 1 == 1:

              res = self.segfunc(res, self.seg[q])

              q -= 1

          p = p // 2

          q = (q - 1) // 2 

      if p == q:

          res = self.segfunc(res, self.seg[p])

      else:

          res = self.segfunc(self.segfunc(res, self.seg[p]), self.seg[q])

      return res

    



def segor(a,b):

  return a|b



n = int(eval(input()))

st = SegmentTree(n,segor,0)

S = eval(input())

data = [0] * n

for i,si in enumerate(S):

  k = ord(si)-ord("a")

  data[i] = 1 << k

st.apply(data)

Q = int(eval(input()))

for _ in range(Q):

  typo,a,b = input().split()

  if typo == "1":

    st.update(int(a)-1,1 << (ord(b)-ord("a")))

  if typo == "2":

    print((bin((st.query2(int(a)-1,int(b))))[2:].count("1")))

  

#!/usr/bin/env python3

import sys, math, itertools, collections, bisect

input = lambda: sys.stdin.buffer.readline().rstrip().decode('utf-8')

inf = float('inf') ;mod = 10**9+7

mans = inf ;ans = 0 ;count = 0 ;pro = 1



class SegmentTree:

  __slots__ = ['ide','n','seg','segfunc']



  def __init__(self,size,func,element):

    self.segfunc = func

    self.ide = element

    # self.size = sizeを超える最小の2冪の数

    self.n = 2 ** (n-1).bit_length()

    # 全てのnodeの数は(2*n-1)個

    # 上にn-1個,最下段にn個

    self.seg = [self.ide] * (2*self.n-1)



  def apply(self,array):

    arraysize = len(array)

    # 配列埋め込み

    for i in range(arraysize):

      self.seg[self.n-1+i] = array[i]

    # 上にあげる

    for i in range(self.n-2,-1,-1):

      self.seg[i] = self.segfunc(self.seg[2*i+1],self.seg[2*i+2])



  def update(self,k,x):

    k += self.n -1

    self.seg[k] = x

    while k:

      k = (k-1)//2

      self.seg[k] = self.segfunc(self.seg[2*k+1],self.seg[2*k+2])



  def query(self,l,r):

    # 半開区間[l,r)

    l += self.n-1; r += self.n-1

    vl = vr = self.ide

    while l < r:

      if l & 1 == 0:

        vl = self.segfunc(vl,self.seg[l])

        l += 1

      if r & 1 == 0:

        vr = self.segfunc(vr,self.seg[r-1])

      l = (l-1)//2; r = (r-1)//2

    return self.segfunc(vl,vr)



  def query1(self,l,r):

    # 半開区間[l,r)

    l += self.n-1; r += self.n-1

    res = self.ide

    while l < r:

      if l & 1 == 0:

        res = self.segfunc(res,self.seg[l])

        l += 1

      if r & 1 == 0:

        res = self.segfunc(res,self.seg[r-1])

      l = (l-1)//2; r = (r-1)//2

    return res



  def query2(self, p, q):

      if q <= p:

          return self.ide

      p += self.n - 1

      q += self.n - 2

      res = self.ide

      while q - p > 1:

          if p & 1 == 0:

              res = self.segfunc(res, self.seg[p])

          if q & 1 == 1:

              res = self.segfunc(res, self.seg[q])

              q -= 1

          p = p // 2

          q = (q - 1) // 2 

      if p == q:

          res = self.segfunc(res, self.seg[p])

      else:

          res = self.segfunc(self.segfunc(res, self.seg[p]), self.seg[q])

      return res

    



def segor(a,b):

  return a|b



n = int(eval(input()))

st = SegmentTree(n,segor,0)

S = eval(input())

data = [0] * n

for i,si in enumerate(S):

  k = ord(si)-ord("a")

  data[i] = 1 << k

st.apply(data)

Q = int(eval(input()))

for _ in range(Q):

  typo,a,b = input().split()

  if typo == "1":

    st.update(int(a)-1,1 << (ord(b)-ord("a")))

  if typo == "2":

    print((bin((st.query1(int(a)-1,int(b))))[2:].count("1")))

  

#!/usr/bin/env python3
import sys, math, itertools, collections, bisect

input = lambda: sys.stdin.buffer.readline().rstrip().decode("utf-8")
inf = float("inf")
mod = 10**9 + 7
mans = inf
ans = 0
count = 0
pro = 1


class SegmentTree:
    __slots__ = ["ide", "n", "seg", "segfunc"]

    def __init__(self, size, func, element):
        self.segfunc = func
        self.ide = element
        # self.size = sizeを超える最小の2冪の数
        self.n = 2 ** (n - 1).bit_length()
        # 全てのnodeの数は(2*n-1)個
        # 上にn-1個,最下段にn個
        self.seg = [self.ide] * (2 * self.n - 1)

    def apply(self, array):
        arraysize = len(array)
        # 配列埋め込み
        for i in range(arraysize):
            self.seg[self.n - 1 + i] = array[i]
        # 上にあげる
        for i in range(self.n - 2, -1, -1):
            self.seg[i] = self.segfunc(self.seg[2 * i + 1], self.seg[2 * i + 2])

    def update(self, k, x):
        k += self.n - 1
        self.seg[k] = x
        while k:
            k = (k - 1) // 2
            self.seg[k] = self.segfunc(self.seg[2 * k + 1], self.seg[2 * k + 2])

    def query(self, l, r):
        # 半開区間[l,r)
        l += self.n - 1
        r += self.n - 1
        vl = vr = self.ide
        while l < r:
            if l & 1 == 0:
                vl = self.segfunc(vl, self.seg[l])
                l += 1
            if r & 1 == 0:
                vr = self.segfunc(vr, self.seg[r - 1])
            l = (l - 1) // 2
            r = (r - 1) // 2
        return self.segfunc(vl, vr)

    def query2(self, p, q):
        if q <= p:
            return self.ide
        p += self.n - 1
        q += self.n - 2
        res = self.ide
        while q - p > 1:
            if p & 1 == 0:
                res = self.segfunc(res, self.seg[p])
            if q & 1 == 1:
                res = self.segfunc(res, self.seg[q])
                q -= 1
            p = p // 2
            q = (q - 1) // 2
        if p == q:
            res = self.segfunc(res, self.seg[p])
        else:
            res = self.segfunc(self.segfunc(res, self.seg[p]), self.seg[q])
        return res


def segor(a, b):
    return a | b


n = int(eval(input()))
st = SegmentTree(n, segor, 0)
S = eval(input())
data = [0] * n
for i, si in enumerate(S):
    k = ord(si) - ord("a")
    data[i] = 1 << k
st.apply(data)
Q = int(eval(input()))
for _ in range(Q):
    typo, a, b = input().split()
    if typo == "1":
        st.update(int(a) - 1, 1 << (ord(b) - ord("a")))
    if typo == "2":
        print((bin((st.query2(int(a) - 1, int(b))))[2:].count("1")))

#!/usr/bin/env python3
import sys, math, itertools, collections, bisect

input = lambda: sys.stdin.buffer.readline().rstrip().decode("utf-8")
inf = float("inf")
mod = 10**9 + 7
mans = inf
ans = 0
count = 0
pro = 1


class SegmentTree:
    __slots__ = ["ide", "n", "seg", "segfunc"]

    def __init__(self, size, func, element):
        self.segfunc = func
        self.ide = element
        # self.size = sizeを超える最小の2冪の数
        self.n = 2 ** (n - 1).bit_length()
        # 全てのnodeの数は(2*n-1)個
        # 上にn-1個,最下段にn個
        self.seg = [self.ide] * (2 * self.n - 1)

    def apply(self, array):
        arraysize = len(array)
        # 配列埋め込み
        for i in range(arraysize):
            self.seg[self.n - 1 + i] = array[i]
        # 上にあげる
        for i in range(self.n - 2, -1, -1):
            self.seg[i] = self.segfunc(self.seg[2 * i + 1], self.seg[2 * i + 2])

    def update(self, k, x):
        k += self.n - 1
        self.seg[k] = x
        while k:
            k = (k - 1) // 2
            self.seg[k] = self.segfunc(self.seg[2 * k + 1], self.seg[2 * k + 2])

    def query(self, l, r):
        # 半開区間[l,r)
        l += self.n - 1
        r += self.n - 1
        vl = vr = self.ide
        while l < r:
            if l & 1 == 0:
                vl = self.segfunc(vl, self.seg[l])
                l += 1
            if r & 1 == 0:
                vr = self.segfunc(vr, self.seg[r - 1])
            l = (l - 1) // 2
            r = (r - 1) // 2
        return self.segfunc(vl, vr)

    def query1(self, l, r):
        # 半開区間[l,r)
        l += self.n - 1
        r += self.n - 1
        res = self.ide
        while l < r:
            if l & 1 == 0:
                res = self.segfunc(res, self.seg[l])
                l += 1
            if r & 1 == 0:
                res = self.segfunc(res, self.seg[r - 1])
            l = (l - 1) // 2
            r = (r - 1) // 2
        return res

    def query2(self, p, q):
        if q <= p:
            return self.ide
        p += self.n - 1
        q += self.n - 2
        res = self.ide
        while q - p > 1:
            if p & 1 == 0:
                res = self.segfunc(res, self.seg[p])
            if q & 1 == 1:
                res = self.segfunc(res, self.seg[q])
                q -= 1
            p = p // 2
            q = (q - 1) // 2
        if p == q:
            res = self.segfunc(res, self.seg[p])
        else:
            res = self.segfunc(self.segfunc(res, self.seg[p]), self.seg[q])
        return res


def segor(a, b):
    return a | b


n = int(eval(input()))
st = SegmentTree(n, segor, 0)
S = eval(input())
data = [0] * n
for i, si in enumerate(S):
    k = ord(si) - ord("a")
    data[i] = 1 << k
st.apply(data)
Q = int(eval(input()))
for _ in range(Q):
    typo, a, b = input().split()
    if typo == "1":
        st.update(int(a) - 1, 1 << (ord(b) - ord("a")))
    if typo == "2":
        print((bin((st.query1(int(a) - 1, int(b))))[2:].count("1")))

+    def query1(self, l, r): +        # 半開区間[l,r) +        l += self.n - 1 +        r += self.n - 1 +        res = self.ide +        while l < r: +            if l & 1 == 0: +                res = self.segfunc(res, self.seg[l]) +                l += 1 +            if r & 1 == 0: +                res = self.segfunc(res, self.seg[r - 1]) +            l = (l - 1) // 2 +            r = (r - 1) // 2 +        return res + -        print((bin((st.query2(int(a) - 1, int(b))))[2:].count("1"))) +        print((bin((st.query1(int(a) - 1, int(b))))[2:].count("1")))