Problem:
Score : 500 points

Problem 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).

Constraints

N, Q, i_q, l_q, and r_q are integers.

S is a string consisting of lowercase English letters.

c_q is a lowercase English letter.

1 \leq N \leq 500000

1 \leq Q \leq 20000

|S| = N

1 \leq i_q \leq N

1 \leq l_q \leq r_q \leq N

There is at least one query of type 2 in each testcase.

Input

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

Output

For each query of type 2, print a line containing the answer.

Sample Input 1

7
abcdbbd
6
2 3 6
1 5 z
2 1 1
1 4 a
1 7 d
2 1 7

Sample Output 1

3
1
5

In the first query, cdbb contains three kinds of letters: b , c , and d, so we print 3.

In the second query, S is modified to abcdzbd.

In the third query, a contains one kind of letter: a, so we print 1.

In the fourth query, S is modified to abcazbd.

In the fifth query, S does not change and is still abcazbd.

In the sixth query, abcazbd contains five kinds of letters: a, b, c, d, and z, so we print 5.

Solution in Ruby (2.3.3) (judge verdict: Time Limit Exceeded)

# 平衡二分探索木
# http://obelisk.hatenablog.com/entry/2019/01/05/175027
# http://sekai.hateblo.jp/entry/2013/09/10/211650

class Node
  attr_accessor :value, :left, :right
  def initialize(value, left=nil, right=nil)
    @value = value
    @left = left
    @right = right
  end
end

class BinaryTree
  def initialize()
    @root = nil
  end
  
  def insert(x)
    unless @root
      @root = Node.new(x)
      return
    end
    node = @root
    while node
      if x < node.value
        if node.left
          node = node.left
        else
          node.left = Node.new(x)
          break
        end
      else
        if node.right
          node = node.right
        else
          node.right = Node.new(x)
          break
        end
      end
    end
  end
  
  def between_search(l, r)
    node = @root
    while node
      value = node.value
      if value >= l && value <= r
        return true
      elsif value < l
        node = node.right
      else
        node = node.left
      end
    end
    false
  end
  
  def delete(v)
    @root, value = del(@root, v)
    value
  end
  
  private

  def del(node, v)
    if node
      if v == node.value
        if node.left.nil?
          return node.right, v
        elsif node.right.nil?
          return node.left, v
        else
          min_node = search_min(node.right)
          node.value = min_node.value
          node.right = delete_min(node.right)
        end
      elsif v < node.value
        node.left, v = del(node.left, v)
      else
        node.right, v = del(node.right, v)
      end
    end
    return node, v
  end
  
  def delete_min(node)
    return node.right unless node.left
    node.left = delete_min(node.left)
    node
  end
  
  def search_min(node)
    while node.left
      node = node.left 
    end
    node
  end
end

=begin
N = 500000
s = N.times.map{rand(0..25)}
Qnum = 20000
q = (1).times.map{[1, rand(1..N), (97 + rand(26)).chr]}
(Qnum-1).times do
  num = rand(1..N-1000)
  q << [2, num, num + rand(0..30)]
end
query = q.shuffle
=end

N = gets.to_i
s = gets.chomp.split("").map{|str|str.ord-97}
Qnum = gets.to_i

tree = Array.new(26){ BinaryTree.new }

(0..N-1).to_a.shuffle.each do |i|
  tree[s[i]].insert(i)
end

Qnum.times do
  type, x, y = gets.split
  #type, x, y = query.shift
  type, x = type.to_i, x.to_i-1
  if type == 1
    y = y.ord-97
    next if y == s[x]
    tree[s[x]].delete(x)
    s[x] = y
    tree[s[x]].insert(x)
  else
    y = y.to_i-1
    cnt = 0
    26.times do |i|
      if tree[i].between_search(x, y)
        cnt += 1
      end
    end
    puts cnt
  end
end