#include <iostream>
#include <string>
#include <algorithm>
#include <cmath>
#include <functional>
#include <vector>
#include <queue>
#include <deque>
#include <map>
#include <set>
#include <cassert>
#define InfL 1000000000
#define InfLL 1000000000000000000LL
#define nmax_def 110000
#define mod 1000000007
#define rep(i,n) for(int (i)=0;(i)<(n);(i)++)
#define rrep(i,n) for(int (i)=(n-1);(i)>=(0);(i)--)
using namespace std;
typedef long long ll;
typedef double db;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
typedef vector<int> vi;
typedef vector<ll> vl;
typedef vector<bool> vb;
typedef vector<db> vd;

class SegmentTree {
public:
    int listnum;
    int listnum_pow2 = 1;
    vl node_val;

    void SegmentTree_ini(vl node_val_ini); // 初期化 (ノード更新あり)
    void update(int x, ll val_update); // 1要素の代入 (ノード更新あり)
    ll val_x(int x); // 値の取得
    ll getmin(int search_L, int search_R); // 最小値の取得
    void add(int search_L, int search_R, ll val_add); // 足す (ノード更新あり)
    ll getsum(int search_L, int search_R); // 区間和

private:
    ll getmin_sbrt(int search_L, int search_R, int nodetmp, int L, int R);
    void add_sbrt(int search_L, int search_R, ll val_add, int nodetmp, int L, int R);
    ll getsum_sbrt(int search_L, int search_R, int nodetmp, int L, int R);

};

void SegmentTree::SegmentTree_ini(vl node_val_ini) { // 初期化 (ノード更新あり)
    listnum = node_val_ini.size();
    listnum_pow2 = 1;
    while (listnum_pow2 < listnum)
        listnum_pow2 *= 2;
    for (int i = listnum; i < listnum_pow2; i++) {
        node_val_ini.push_back(0); // 和
    }

    node_val.resize(2 * listnum_pow2 - 1);

    for (int i = 0; i < listnum_pow2; i++)
        node_val[i + listnum_pow2 - 1] = node_val_ini[i];
    for (int i = listnum_pow2 - 2; i >= 0; i--) {
        node_val[i] = node_val[i * 2 + 1] + node_val[i * 2 + 2]; // 和
    }
}

void SegmentTree::update(int x, ll val_update) { // 1要素の代入 (ノード更新あり)
    int nodetmp = x + listnum_pow2 - 1;
    node_val[nodetmp] = val_update;
    while (nodetmp > 0) {
        nodetmp = (nodetmp - 1) / 2;
        node_val[nodetmp] = node_val[2 * nodetmp + 1] + node_val[2 * nodetmp + 2]; // 和
    }
    return;
}

ll SegmentTree::val_x(int x) { // 値の取得
    int nodetmp = x + listnum_pow2 - 1;
    ll ans = node_val[nodetmp];
    return ans;
}

ll SegmentTree::getmin_sbrt(int search_L, int search_R, int nodetmp, int L, int R) { // 最小値の取得
    if (R <= search_L || search_R <= L)
        return InfL;
    if (search_L <= L && R <= search_R)
        return node_val[nodetmp];

    int M = (L + R) / 2;
    int nodenew_L = 2 * nodetmp + 1;
    ll node_val_min_L = getmin_sbrt(search_L, search_R, nodenew_L, L, M);
    int nodenew_R = 2 * nodetmp + 2;
    ll node_val_min_R = getmin_sbrt(search_L, search_R, nodenew_R, M, R);
    ll node_val_min = min(node_val_min_L, node_val_min_R);
    return node_val_min;
}

ll SegmentTree::getmin(int search_L, int search_R) { // 最小値の取得
    ll ans = getmin_sbrt(search_L, search_R, 0, 0, listnum_pow2);
    return ans;
}

ll SegmentTree::getsum_sbrt(int search_L, int search_R, int nodetmp, int L, int R) { // 区間和
    if (search_R <= L || R <= search_L)
        return 0;
    if (search_L <= L && R <= search_R)
        return node_val[nodetmp];

    int M = (L + R) / 2;
    int nodenew_L = 2 * nodetmp + 1;
    ll node_val_min_L = getsum_sbrt(search_L, search_R, nodenew_L, L, M);
    int nodenew_R = 2 * nodetmp + 2;
    ll node_val_min_R = getsum_sbrt(search_L, search_R, nodenew_R, M, R);
    ll node_val_min = node_val_min_L + node_val_min_R;
    return node_val_min;
}

ll SegmentTree::getsum(int search_L, int search_R) { // 区間和
    ll ans = getsum_sbrt(search_L, search_R, 0, 0, listnum_pow2);
    return ans;
}

int main() {
    int N;
    cin >> N;
    vector<vl> a(26);
    rep(i, 26)
        a[i].resize(N, 0);
    vector<SegmentTree> Tree(26);
    string S;
    cin >> S;
    rep(i, N) {
        int ctmp = S[i] - 'a';
        a[ctmp][i] = 1;
    }
    rep(i, 26)
        Tree[i].SegmentTree_ini(a[i]);
    int Q;
    cin >> Q;
    rep(t, Q) {
        int type;
        cin >> type;
        if (type == 1) {
            int i;
            char c;
            cin >> i >> c;
            int ctmp = c - 'a';
            int cold = S[i - 1] - 'a';
            Tree[cold].update(i - 1, 0);
            Tree[ctmp].update(i - 1, 1);
            S[i - 1] = c;
        }
        else {
            int l, r;
            cin >> l >> r;
            int ans = 0;
            rep(i, 26) {
                int anstmp = Tree[i].getsum(l - 1, r);
                anstmp = min(1, anstmp);
                ans += anstmp;
            }
            cout << ans << endl;
        }
    }
    return 0;
}

Measured memory_bytes: 327240