// Contest: AtCoder Beginner Contest 157 (https://atcoder.jp/contests/abc157)
// Problem: E: Simple String Queries (https://atcoder.jp/contests/abc157/tasks/abc157_e)


// region {{{ boilerplate
#include <algorithm>
#include <array>
#include <bitset>
#include <cassert>
#include <cmath>
#include <chrono>
#include <cstdint>
#include <deque>
#include <exception>
#include <forward_list>
#include <functional>
#include <initializer_list>
#include <iomanip>
#include <iostream>
#include <iterator>
#include <limits>
#include <list>
#include <map>
#include <memory>
#include <numeric>
#include <queue>
#include <random>
#include <set>
#include <stack>
#include <string>
#include <tuple>
#include <type_traits>
#include <unordered_map>
#include <unordered_set>
#include <utility>
#include <vector>

#if __cplusplus >= 201703L
#   include <optional>
#   include <string_view>
#   include <variant>
#endif

using namespace std;

#if __cplusplus >= 201703L
#   define all(a)      begin(a),end(a)
#   define sz(x)       ((int)size(x))
#else
#   define all(a)      (a).begin(),(a).end()
#   define sz(x)       ((int)(x).size())
#endif

#define rep(a, b)      for(int a = 0; a < (b); ++a)
#define reps(a, b, c)  for(int a = (b); a < (c); ++a)
#define trav(a, b)     for(auto& a : b)

using ll = long long;
using ld = long double;
using u64 = uint64_t;
using u32 = uint32_t;

using pi = pair<int, int>;
using pl = pair<ll, ll>;
using vi = vector<int>;
using vl = vector<ll>;
using vvi = vector<vi>;
using vpi = vector<pi>;

#if __cplusplus >= 201703L
#   define MAYBE_UNUSED [[maybe_unused]]
#else
#   define MAYBE_UNUSED
#endif

MAYBE_UNUSED static constexpr int INF = (int)1e9 + 5;
MAYBE_UNUSED static constexpr ll INFL = (ll)1e18 + 5;
MAYBE_UNUSED static mt19937 rng((u32)chrono::duration_cast<chrono::nanoseconds>(chrono::high_resolution_clock::now().time_since_epoch()).count());
//endregion }}}

struct Fenwick {
    using T = int;
    static const T NEUTRAL;
    static T combine(const T& a, const T& b) { return a + b; }
    static T inv(const T& a, const T& b) { return a - b; }

    vector<T> d;

    explicit Fenwick(int n) : d(n, NEUTRAL) {}

    void update(int i, T val) {
        for (; i < sz(d); i |= i + 1)
            d[i] = combine(d[i], val);
    }

    T query(int i) const { // [0, i)
        T r = NEUTRAL;
        for (; i > 0; i &= i - 1)
            r = combine(r, d[i - 1]);
        return r;
    }

    T query(int l, int r) { // [l, r)
        return inv(query(r), query(l));
    }
};

const int Fenwick::NEUTRAL = 0;

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);

    int n; cin >> n;
    vector<Fenwick> f(26, Fenwick(n));
    string s; cin >> s;
    rep(i, n)
        f[s[i]-'a'].update(i, 1);

    int q; cin >> q;
    while (q--) {
        int t; cin >> t;
        if (t == 1) {
            int i; char c; cin >> i >> c; --i;
            f[s[i]-'a'].update(i, -1);
            f[c-'a'].update(i, 1);
            s[i]=c;
        } else {
            int l, r; cin >> l >> r, --l;
            int res = 0;
            rep(i, 26)
                res += f[i].query(l, r) > 0;
            cout << res << '\n';
        }
    }

    return 0;
}

Measured memory_bytes: 53120