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
  import numpy as np
  
  read = sys.stdin.buffer.read
  readline = sys.stdin.buffer.readline
  readlines = sys.stdin.buffer.readlines
  
  seg_unit = 0
  
  
  def seg_f(x, y):
      return x | y
  
  
  def build(seg, raw_data):
      N = len(seg) // 2
      seg[N:] = raw_data
      for i in range(N - 1, 0, -1):
          seg[i] = seg_f(seg[i << 1], seg[i << 1 | 1])
  
  
  def set_val(seg, i, x):
      N = len(seg) // 2
      i += N
      seg[i] = x
      while i > 1:
          i >>= 1
          seg[i] = seg_f(seg[i << 1], seg[i << 1 | 1])
  
  
  def fold(seg, l, r):
      vl = vr = 0
      N = len(seg) // 2
      l, r = l + N, r + N
      while l < r:
          if l & 1:
              vl = seg_f(vl, seg[l])
              l += 1
          if r & 1:
              r -= 1
              vr = seg_f(seg[r], vr)
          l, r = l >> 1, r >> 1
      return seg_f(vl, vr)
  
  
  def main(N, S, query):
      seg = np.zeros(N + N, np.int64)
      build(seg, 1 << S)
      for q in query:
          t, a, b = q.split()
          if t == b"1":
              a, b = int(a) - 1, ord(b) - ord("a")
              set_val(seg, a, 1 << b)
          else:
              a, b = int(a) - 1, int(b)
              x = fold(seg, a, b)
              print(bin(x).count("1"))
  
  
  if sys.argv[-1] == "ONLINE_JUDGE":
      import numba
      from numba.pycc import CC
  
      i8 = numba.int64
      cc = CC("my_module")
  
      def cc_export(f, signature):
          cc.export(f.__name__, signature)(f)
          return numba.njit(f)
  
      seg_f = cc_export(seg_f, (i8, i8))
      build = cc_export(build, (i8[:], i8[:]))
      set_val = cc_export(set_val, (i8[:], i8, i8))
      fold = cc_export(fold, (i8[:], i8, i8))
      cc.compile()
  
  from my_module import seg_f, build, set_val, fold
  
  N = int(readline())
  S = np.array(list(readline().rstrip()), np.int64) - ord("a")
  query = readlines()[1:]
  
  main(N, S, query)
  
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."}]