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 C++14 (GCC 5.4.1) (judge verdict: Accepted)

#include <algorithm>
#include <cmath>
#include <complex>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <vector>
#include <functional>
#include <cstring>
#include <regex>
#include <random>
#include <cassert>
using namespace std;

#define rep(i, n) for (int i = 0; i < (int)(n); i++)
#define repr(i, s, n) for (int i = (s); i < (int)(n); i++)
#define revrep(i, n) for (int i = (n) - 1; i >= 0; i--)
#define revrepr(i, s, n) for (int i = (n) - 1; i >= s; i--)
#define debug(x) cerr << #x << ": " << x << "\n"

using ll = long long;
using P = pair<int, int>;

const long long MOD = 1e9+7;

template<class T> inline bool chmax(T& a, T b) { if (a < b) { a = b; return 1; } return 0; }
template<class T> inline bool chmin(T& a, T b) { if (a > b) { a = b; return 1; } return 0; }

template<class T>
istream& operator >>(istream &is, vector<T> &v) {
    for (int i = 0; i < (int)v.size(); i++) cin >> v.at(i);
    return is;
}

template<class T>
void print(const vector<T> &v, const string &delimiter) { rep(i, v.size()) cout << (0 < i ? delimiter : "") << v.at(i); cout << endl; }

template<class T>
void print(const vector<vector<T>> &vv, const string &delimiter) { for (const auto &v: vv) print(v, delimiter); }

template<class T>
struct Bit {
    vector<T> bit[2];
    int N;

    Bit() {}
    Bit(int n): N(n) { for (int i = 0; i < 2; i++) bit[i].assign(n + 1, 0); }

    //[1, n]
    void init(int n) {
        for (int i = 0; i < 2; i++) bit[i].assign(n + 1, 0);
        N = n;
    }

    T sub_sum(int p, int i) {
        T s = 0;
        while (0 < i) {
            s += bit[p].at(i);
            i -= i & -i;
        }
        return s;
    }
    // 1-indexed
    T sum(int i) { return sub_sum(0, i) + sub_sum(1, i) * i; }
    // [a, b]
    T sum(int a, int b) { return sum(b) - sum(a - 1); }

    void sub_add(int p, int i, T v) {
        while (i <= N) {
            bit[p].at(i) += v;
            i += i & -i;
        }
    }
    //[a, b] 1-indexed
    void add(int a, int b, T v) {
        sub_add(0, a, -v * (a - 1));
        sub_add(1, a, v);
        sub_add(0, b + 1, v * b);
        sub_add(1, b + 1, -v);
    }
};

int main() {
    int n;
    string s;
    cin >> n >> s;

    vector<Bit<int>> bits(26);
    rep(i, 26) bits.at(i).init(n + 1);

    rep(i, n) {
        int c = s.at(i) - 'a';
        bits.at(c).add(i + 1, i + 1, 1);
    }

    int q;
    cin >> q;
    rep(_q, q) {
        int query;
        cin >> query;
        if (query == 1) {
            int idx;
            char c;
            cin >> idx >> c;

            int ci = c - 'a';
            int prev_ci = s.at(idx - 1) - 'a';

            bits.at(prev_ci).add(idx, idx, -1);
            bits.at(ci).add(idx, idx, 1);
            s.at(idx - 1) = c;
        }
        else {
            int l, r;
            cin >> l >> r;

            int cnt = 0;
            rep(i, 26) cnt += min(1, bits.at(i).sum(l, r));
            cout << cnt << endl;
        }
    }
}