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: Accepted)

class SegTree
  attr_reader :size, :e, :f
  attr_accessor :seg

  def self.create(a=[],e,f)
    n = 1
    n *= 2 while n < a.size
    this = new(n,e,f)
    a.size.times do |i|
      this.seg[i+n] = a[i]
    end
    (n-1).downto(1) do |i|
      this.seg[i] = f[ this.seg[i*2],this.seg[i*2+1] ]
    end
    this
  end

  def initialize(n=2**32,e,f)
    @size = n
    @e = e
    @f = f
    @seg = Array.new(size*2, e)
  end

  def [](i)
    i += size
    seg[i]
  end

  def []=(i,x)
    i += size
    seg[i] = x
  end

  def update(i,x)
    i += size
    seg[i] = x
    _update(i)
  end
  
  def _update(i)
    while i > 1
      i /= 2
      seg[i] = f[ seg[i*2], seg[i*2+1] ]
    end
  end

  def swap(i,j)
    i += size
    j += size
    seg[j][0],seg[i][0] = seg[i][0],seg[j][0]
    _update(i)
    _update(j)
  end

  def query(a,b)
    ans = e
    a += size; b += size
    while a < b
      (ans = f[ ans, seg[a] ]; a += 1) if a.odd?
      (b -= 1; ans = f[ ans, seg[b] ]) if b.odd?
      a /= 2; b /= 2
    end
    ans
  end

  def inspect
    # { size: size, seg: seg }.to_s
    puts "size: #{size}"
    seg.each.with_index do |a,i|
      printf("%02d: %s\n", i, a.to_s(2))
    end
  end
end

# SegTree.new(N,E,F) := 要素数N、単位元E、演算Fで初期化、ただしNは2の冪
# SegTree.create(A,E,F) := モノイドA、単位元E、演算Fで初期化で初期化
# update(i,x) := A[i]をxに更新
# query(a,b) := 半開区間[a,b)でのA[i]の演算結果
#
# 単位元を追加してモノイドにする例（gcd）
# E = -1
# F = -> x,y { x == E ? y : y == E ? x : x.gcd(y) }
# T = SegTree.create(a,E,F)

E = 0
F = -> x,y { x | y }
CONV = -> c { 1 << (c.ord - 97)} # "a".ord == 97

n = gets.to_i
a = gets.chomp.chars.map{ |v| CONV[v] }
m = gets.to_i

T = SegTree.create(a,E,F)

m.times do |j|
  x,y,z = gets.chomp.split
  if x == "1"
    i = y.to_i - 1
    c = CONV[z]
    T.update(i,c)
  else
    l = y.to_i - 1
    r = z.to_i
    a = T.query(l,r)
    ans = a.to_s(2).count("1")
    puts ans
  end
end