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.7.1) (judge verdict: Time Limit Exceeded)

require 'set'

class Hash
  def push(key, value)
    self[key] = [] if self[key] == nil
    self[key].push(value)
  end
end

class Array
  def lower_bound(value)
    left = -1;
    right = self.length;
    while left + 1 < right
      mid = left + (right - left) / 2;
      if self[mid] >= value
        right = mid
      else
        left = mid
      end
    end
    right
  end

  def unique
    res = [self.first]
    each_cons(2) do |a, b|
      if a != b
        res.push(b)
      end
    end
    res
  end
end

def get_ints
  gets.split.map(&:to_i)
end

def get_ints_minus_one
  get_ints.map { |x| x - 1 }
end

def get_int
  gets.chomp.to_i
end

# N = get_int
# S = gets.chomp
# Q = get_int
# queries = []
# Q.times do |i|
#   queries[i] = gets.chomp.split
#   queries[i][0] = queries[i][0].to_i
#   queries[i][1] = queries[i][1].to_i
# end
#
# words = Hash.new { |h, k| h[k] = [] }
#
# S.split('').each.with_index do |w, index|
#   index += 1
#   words[w].push(index)
# end
#
# words.each do |k, v|
#   v.sort!
# end
#
# queries.each do |q|
#   if q[0] == 1
#     w, _ = words.find { |k, v| v.bsearch { |x| x >= q[1] } == q[1] }
#     index = words[w].bsearch_index { |x| x >= q[1] }
#     words[w].delete_at(index)
#     words[q[2]].push(q[1])
#     words[q[2]].sort!
#     # words[w].delete(q[1])
#     # words[q[2]].add(q[1])
#   else
#     puts words.count { |k, v|
#       youso = v.bsearch { |x| x >= q[1] }
#       !youso.nil? && youso <= q[2].to_i
#     }
#   end
# end

# 添字は1から
class Bit
  UNITY_SUM = 0

  attr_accessor :dat

  # [1, n)
  def initialize(n)
    @dat = []
    (n+1).times do |i|
      dat[i] = UNITY_SUM
    end
  end

  # a is 1-indexed
  # a番目の要素にxを足す
  def add(a, x)
    i = a
    while i < dat.length
      dat[i] += x
      i += i & -i
    end
  end

  # [1, a), a is 1-indexed
  def sum(a)
    res = UNITY_SUM
    i = a
    while i > 0
      res += dat[i]
      i -= i & -i
    end
    res
  end

  # [a, b), a and b are 1-indexed
  def sum_section(a, b)
    sum(b-1) - sum(a-1)
  end

  # k番目の数を取得する
  # 各値の数を数え上げる場合のみ有効なメソッド
  # add(x, 1) と add(x, -1) しかしないとき
  def get_kth_when_counting(k)
    k -= 1
    high = dat.length
    low = 0

    while high - low > 1
      mid = low + (high - low) / 2

      if sum(mid) > k
        high = mid
      else
        low = mid
      end
    end
    high
  end
end

N = get_int
S = gets.chomp
Q = get_int
queries = []
Q.times do |i|
  queries[i] = gets.chomp.split
  queries[i][0] = queries[i][0].to_i
  queries[i][1] = queries[i][1].to_i
end

hash = {}
[*'a'..'z'].each do |w|
  hash[w] = Bit.new(N)
end

S.split('').each.with_index do |s, index|
  index += 1
  hash[s].add(index, 1)
end

queries.each do |q|
  if q[0] == 1
    word, _ = hash.find { |_, v| v.sum_section(q[1], q[1]+1) > 0 }
    hash[word].add(q[1], -1)
    hash[q[2]].add(q[1], 1)
  else
    puts hash.values.count { |bit|
      bit.sum_section(q[1], q[2].to_i+1) > 0
    }
  end
end