output_description: For each query of type 2, print a line containing the answer.
  
  * * *
input_description: Input is given from Standard Input in the following format:
  
      
      
      N
      S
      Q
      Query_1
      \vdots
      Query_Q
      
  
  Here, Query_i in the 4-th through (Q+3)-th lines is one of the following:
  
      
      
      1 i_q c_q
      
      
      
      2 l_q r_q
attempt: import sys
  
  input = sys.stdin.readline
  
  
  def I():
      return int(input())
  
  
  def MI():
      return map(int, input().split())
  
  
  def LI():
      return list(map(int, input().split()))
  
  
  def main():
      class Segtree:
          def __init__(self, A, ide_ele, initialize=True, segf=max):
              self.N = len(A)
              self.N0 = 2 ** (self.N - 1).bit_length()
              self.ide_ele = ide_ele
              self.segf = segf
              if initialize:
                  self.data = [ide_ele] * self.N0 + A + [ide_ele] * (self.N0 - self.N)
                  for i in range(self.N0 - 1, 0, -1):
                      self.data[i] = self.segf(self.data[2 * i], self.data[2 * i + 1])
              else:
                  self.data = [ide_ele] * (2 * self.N0)
  
          def update(self, k, x):
              k += self.N0
              self.data[k] = x
              while k > 0:
                  k = k >> 1
                  self.data[k] = self.segf(self.data[2 * k], self.data[2 * k + 1])
  
          def query(self, l, r):
              L, R = l + self.N0, r + self.N0
              s = self.ide_ele
              t = self.ide_ele
              while L < R:
                  if R & 1:
                      R -= 1
                      t = self.segf(self.data[R], t)
                  if L & 1:
                      s = self.segf(s, self.data[L])
                      L += 1
                  L >>= 1
                  R >>= 1
              return self.segf(s, t)
  
          # セグ木上で二分探索，[l,r)の範囲でcheck関数を満たす最小の値をとるところのindexを返す．
          # reverse=Trueなら最大値かな
          # ない時の返り値がNoneなことに注意
          def binsearch(self, l, r, check, reverse=False):
              L, R = l + self.N0, r + self.N0
              SL, SR = [], []
              while L < R:
                  if R & 1:
                      R -= 1
                      SR.append(R)
                  if L & 1:
                      SL.append(L)
                      L += 1
                  L >>= 1
                  R >>= 1
  
              if reverse:
                  pre = self.ide_ele
                  for idx in SR + SL[::-1]:
                      if check(self.segf(self.data[idx], pre)):
                          break
                      else:
                          pre = self.segf(self.data[idx], pre)
                  else:
                      return None
                  while idx < self.N0:
                      if check(self.segf(self.data[2 * idx + 1], pre)):
                          idx = 2 * idx + 1
                      else:
                          pre = self.segf(self.data[2 * idx + 1], pre)
                          idx = 2 * idx
                  return idx - self.N0
              else:
                  pre = self.ide_ele
                  for idx in SL + SR[::-1]:
                      if not check(self.segf(pre, self.data[idx])):
                          pre = self.segf(pre, self.data[idx])
                      else:
                          break
                  else:
                      return None
                  while idx < self.N0:
                      if check(self.segf(pre, self.data[2 * idx])):
                          idx = 2 * idx
                      else:
                          pre = self.segf(pre, self.data[2 * idx])
                          idx = 2 * idx + 1
                  return idx - self.N0
  
      N = I()
      S = input()
      Q = I()
  
      A = []
      for i in range(N):
          aaa = set(S[i])
          A.append(aaa)
  
      seg = Segtree(A, set([]), segf=lambda a, b: a | b)
  
      for _ in range(Q):
          q = input().split()
          if q[0] == "1":
              i = int(q[1]) - 1
              c = q[2]
              seg.update(i, set([c]))
          else:
              l = int(q[1])
              r = int(q[2])
              ans = seg.query(l - 1, r)
              print(len(ans))
  
  
  main()
  
problem_description: Statement
  
  You are given a string S of length N consisting of lowercase English letters.
  
  Process Q queries of the following two types:
  
    * Type 1: change the i_q-th character of S to c_q. (Do nothing if the i_q-th character is already c_q.)
    * Type 2: answer the number of different characters occurring in the substring of S between the l_q-th and r_q-th characters (inclusive).
samples: [{"input": "7\n    abcdbbd\n    6\n    2 3 6\n    1 5 z\n    2 1 1\n    1 4 a\n    1 7 d\n    2 1 7", "output": "3\n    1\n    5\n    \n\nIn the first query, `cdbb` contains three kinds of letters: `b` , `c` , and\n`d`, so we print 3.\n\nIn the second query, S is modified to `abcdzbd`.\n\nIn the third query, `a` contains one kind of letter: `a`, so we print 1.\n\nIn the fourth query, S is modified to `abcazbd`.\n\nIn the fifth query, S does not change and is still `abcazbd`.\n\nIn the sixth query, `abcazbd` contains five kinds of letters: `a`, `b`, `c`,\n`d`, and `z`, so we print 5."}]