// #define STOPIT
#include<bits/stdc++.h>
#define rep(i,n,m) for(int i = (n); i <(m); i++)
#define rrep(i,n,m) for(int i = (n) - 1; i >=(m); i--)
using namespace std;
using ll = long long;

void debug_impl() { cerr << endl; }
template <typename Head, typename... Tail>
void debug_impl(Head head, Tail... tail) { cerr << " " << head; debug_impl(tail...); }
#ifndef STOPIT
    #define debug(...)\
    do {\
        cerr << boolalpha << "[" << #__VA_ARGS__ << "]:";\
        debug_impl(__VA_ARGS__);\
        cerr << std::noboolalpha;\
    } while (false)
#else
    #define debug(...) {}
#endif

template < typename Container, typename Value = typename Container::value_type, enable_if_t<!is_same< Container, string >::value, nullptr_t> = nullptr>
istream& operator>> (istream& is, Container& v)
  { for (auto & x : v) { is >> x; } return is; }

template < typename Container, typename Value = typename Container::value_type, enable_if_t<!is_same< Container, string >::value, nullptr_t> = nullptr >
ostream& operator<< (ostream& os, Container const& v) {
  os << "{";
  for (auto it = v.begin(); it != v.end(); it++)
    {os << (it != v.begin() ? "," : "") << *it;}
  return os << "}";
}

template <typename T>
struct SegmentTree
{
    using F  = function<T(T, T)>;
    int n;
    F f;
    T unit;
    vector<T> data;
    SegmentTree(){};
    SegmentTree(F f, T unit):f(f), unit(unit){}
    void init(int n_)
    {
        n = 1;
        while (n < n_) n <<= 1; 
        data.assign(n << 1, unit);
    }

    void build(const vector<T> &v)
    {
        init(v.size());
        for(int i=0; i<v.size(); ++i) data[n+i] = v[i];
        for(int i=n-1; i>0; --i) data[i] = f(data[2*i], data[2*i+1]);
    }

    void update(int k, T x)
    {
        data[k+=n] = x;
        while (k >>= 1)
            data[k] = f(data[2 * k], data[2 * k + 1]);
    }

    T query(int a, int b)
    {
        T vl, vr;
        vl = vr = unit;
        for (int l = a+n, r = b+n; l < r; l >>= 1, r >>= 1)
        {
            if (l&1) vl = f(vl, data[l++]);
            if (r&1) vr = f(vr, data[--r]);
        }
        return f(vl, vr);
    }
};


// example
// auto f=[&](int a,int b){return max(a,b);};
// SegmentTree<int> sgtree(f, 0);
// sgtree.build(values); 

int main()
{
    int N, Q;
    string S;
    cin >> N >> S >> Q;

    // initialize segment tree
    auto f = [](int a, int b){return a|b;};
    SegmentTree<int> sgtree(f, 0);
    sgtree.init(N);

    // build initial　segment tree
    rep(i, 0, S.size())
    {
        int num = S[i]-'a';
        int bit = 1<<num;
        sgtree.update(i, bit);
    }
    
    rep(i, 0, Q)
    {
        // read input
        int order;
        cin >> order;
        if (order == 1)
        {
            // read input
            int i;
            char c;
            cin >> i >> c;

            // update
            int num = c - 'a';
            sgtree.update(i-1, 1<<num);
        }
        else
        {
            // read input
            int l, r;
            cin >> l >> r;

            // count 
            int state = sgtree.query(l-1, r);
            // debug(state);
            printf("%d\n", (int)__builtin_popcount(state));
        }
    }
    return 0;
}


Measured memory_bytes: 4996