//#define _GLIBCXX_DEBUG
#include "bits/stdc++.h"

using namespace std;

//------------------------------- Type Names -------------------------------//

using i64 = int_fast64_t;

using seika = string;
//{akari : 1D, yukari : 2D, maki : 3D} vector
template <class kizuna>
using akari = vector<kizuna>;
template <class yuzuki>
using yukari = akari<akari<yuzuki>>;
template <class tsurumaki>
using maki = akari<yukari<tsurumaki>>;
//{akane : ascending order, aoi : decending order} priority queue
template <class kotonoha>
using akane = priority_queue<kotonoha, akari<kotonoha>, greater<kotonoha>>;
template <class kotonoha>
using aoi = priority_queue<kotonoha>;

//------------------------------- Libraries ---------------------------------//

template <class T>
class SegmentTree
{
private:
    int n;
    const T unit = 0;
    vector<T> node;

public:
    SegmentTree(int n_)
    {
        this->n = 1;
        while (this->n < n_)
        {
            this->n *= 2;
        }
        this->node.resize(2 * n - 1, this->unit);
    }

    SegmentTree(vector<T> v)
    {
        int n_ = v.size();
        this->n = 1;
        while (this->n < n_)
        {
            this->n *= 2;
        }
        node.resize(2 * this->n - 1, this->unit);
        for (int i = 0; i < this->n; i++)
        {
            this->node[this->n - 1 + i] = v[i];
        }
        for (int i = this->n - 2; i >= 0; i--)
        {
            this->node[i] = this->node[i * 2 + 1] | this->node[i * 2 + 2];
        }
    }

    void update(int idx, T val)
    {
        idx += this->n - 1;
        this->node[idx] = val;
        while (idx)
        {
            idx = (idx - 1) / 2;
            this->node[idx] = this->node[2 * idx + 1] | this->node[2 * idx + 2];
        }
    }

    T get(int a, int b, int now = 0, int l = 0, int r = -1)
    {
        if (r < 0)
        {
            r = this->n;
        }
        if (r <= a || b <= l)
        {
            return this->unit;
        }
        if (a <= l && r <= b)
        {
            return this->node[now];
        }
        T lVal = get(a, b, 2 * now + 1, l, (l + r) / 2);
        T rVal = get(a, b, 2 * now + 2, (l + r) / 2, r);
        return (lVal | rVal);
    }
};

//------------------------------- Dubug Functions ---------------------------//

inline void print()
{
    cout << endl;
}
template <typename First, typename... Rest>
void print(const First &first, const Rest &... rest)
{
    cout << first << ' ';
    print(rest...);
}

//------------------------------- Solver ------------------------------------//

void solve()
{
    int n;
    seika s;
    int q;
    cin >> n >> s >> q;
    akari<int> v(n);
    for (int i = 0; i < n; i++)
    {
        v[i] = 1 << (s[i] - 'a');
    }
    SegmentTree<int> seg(v);
    while (q--)
    {
        int x;
        cin >> x;
        if (x == 1)
        {
            int y;
            char z;
            cin >> y >> z;
            seg.update(y - 1, 1 << (z - 'a'));
        }
        else
        {
            int y, z;
            cin >> y >> z;
            cout << __builtin_popcount(seg.get(y - 1, z)) << endl;
        }
    }
}

int main()
{
    solve();
    return 0;
}


Measured memory_bytes: 8836