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 Kotlin (1.0.0) (judge verdict: Accepted)

//package Qe
import java.util.*
import java.math.*
import java.lang.Math.*

private val readString: ()->String = {readLine()!!}
private val readInt: ()->Int = {readLine()!!.toInt()}
private val readLong: ()->Long = {readLine()!!.toLong()}
private val readIntArray: ()->IntArray = {readLine()!!.split(' ').map{it.toInt()}.toIntArray()}
private val readLongArray: ()->LongArray = {readLine()!!.split(' ').map{it.toLong()}.toLongArray()}
private val errPrintln: (String)->Unit = {msg -> System.err.println(msg)}
private val MOD = 1e9.toLong()+7
private val INF = Int.MAX_VALUE/2
private val LINF = Long.MAX_VALUE/2


fun main(args: Array<String>) {
    val N = readInt()
    val S = readString()

    val bits = Array(26){LongBIT(N)}
    for (i in 0 until N) {
        bits[S[i] - 'a'].add(i, 1)
    }

    val Q = readInt()
    var ca = S.toCharArray()
    for (q in 0 until Q) {
        val (type, a, b) = readString().split(" ")

        when (type) {
            "1" -> {
                val I = a.toInt()-1
                val C = b[0]
                if (ca[I] != C) {
                    bits[ca[I] - 'a'].add(I, -1)
                    bits[C - 'a'].add(I, 1)
                    ca[I] = C
                }
            }
            "2" -> {
                val L = a.toInt()-1; val R = b.toInt()
                var ans = 0
                for (bit in bits) {
                    if (bit.sum(L, R) > 0) ans++
                }
                println(ans)
            }
        }
    }
}


class LongBIT(val N: Int) {
    var sg = LongArray(0)
    init {
        sg = LongArray(N+1){0L}
    }
    private fun add1(I: Int, X: Long) {
        var i = I
        while(i <= N) {
            sg[i] += X
            i += i and -i
        }
    }
    private fun sum1(I: Int): Long {
        var res = 0L
        var i = I
        while (i > 0) {
            res += sg[i]
            i -= i and -i
        }
        return res
    }
    private fun sum1(i: Int, j: Int): Long {
        if (i>j) return 0L
        return sum1(j) - sum1(i-1)
    }
    fun add(I: Int, X: Long) {
        var i = I+1
        while(i <= N) {
            sg[i] += X
            i += i and -i
        }
    }
    fun sum(i: Int): Long {
        return sum1(i)
    }
    fun sum(i: Int, j: Int): Long {
        return sum1(j) - sum1(i)
    }
    operator fun get(i: Int): Long {
        return sum(i, i+1)
    }
}