#include <bits/stdc++.h>
using namespace std;
#pragma region macros_and_aliases
#define rep(i, n) for(long long i = 0; i < (n); i++)
#define rrep(i, n) for(long long i = (n)-1; i > -1; i--)
#define Rep(i, m, n) for(long long i = (m); i < (n); i++)
#define rRep(i, m, n) for(long long i = (n)-1; i >= (m); i--)
#define REP(i, m, n, p) for(long long i = m; i < n; i += p)
#define foa(s, v) for(auto &s : v)
#define all(v) (v).begin(), (v).end()
#define rall(v) (v).rbegin(), (v).rend()
#define pq priority_queue
#define bcnt(n) __builtin_popcountll(n)
#define endk endl
#define ednl endl
#define enld endl
using ll = long long;
using ld = long double;
using vll = vector<ll>;
using vvll = vector<vll>;
using vvvll = vector<vvll>;
using vb = vector<bool>;
using mll = map<long long, long long>;
using pll = pair<long long, long long>;
using qll = queue<long long>;
using sll = set<long long>;
using vpll = vector<pair<long long, long long>>;
template <class T = ll>
using V = vector<T>;
template <class T = ll>
using VV = V<V<T>>;
template <class T = ll>
using VVV = V<V<V<T>>>;
//昇順pq(小さい方から取り出す)
template <class T = ll>
using pqup = priority_queue<T, vector<T>, greater<T>>;
//降順pq(大きい方から取り出す)
template <class T = ll>
using pqdn = priority_queue<T>;
#define debug(var)              \
	std::cout << #var << " : "; \
	view(var)
template <typename T>
void view(T e) {
	std::cout << e << std::endl;
}
template <typename T>
void view(const std::vector<T> &v) {
	for(const auto &e : v) {
		std::cout << e << " ";
	}
	std::cout << std::endl;
}
template <typename T>
void view(const std::vector<std::vector<T>> &vv) {
	for(const auto &v : vv) {
		view(v);
	}
}
template <typename T1, typename T2>
ostream &operator<<(ostream &os, const pair<T1, T2> &p) {
	os << p.first << " " << p.second;
	return os;
}
template <typename T1, typename T2>
istream &operator>>(istream &is, pair<T1, T2> &p) {
	is >> p.first >> p.second;
	return is;
}
#pragma endregion

#pragma region constants

long long const limLL = 9223372036854775807;  // POW(2,63)-1 ~ 9.22e18
long long const dekai = 3e16;
const long double pi = acos(-1);
int dx[4] = {1, 0, -1, 0};
int dy[4] = {0, 1, 0, -1};
int ddx[8] = {-1, -1, -1, 0, 0, 1, 1, 1};
int ddy[8] = {-1, 0, 1, -1, 1, -1, 0, 1};

const int mod = 1000000007;
// const int mod = 998244353;
#pragma endregion
template <class T>
void vout(vector<T> &v, bool tate = 0) {
	if(v.size() > 0) {
		for(auto it = v.begin(); it < v.end(); it++) {
			cout << *it;
			if(it != v.end() - 1) {
				if(tate)
					cout << endl;
				else
					cout << " ";
			}
		}
	}
	cout << endl;
}

template <class T = long long>
struct ST {	 //非再帰抽象化セグ木
	long long n;
	vector<T> seg;
	T unit;
	function<T(T, T)> operation;
	ST(long long _n, function<T(T, T)> _operation, T _unit = 0) : n(_n), seg(n * 2, 0), operation(_operation), unit(_unit) {}
	void update(long long i, T x) {
		i += n;
		seg[i] = x;
		i >>= 1;
		while(i > 0) {
			seg[i] = operation(seg[(i << 1)], seg[(i << 1) | 1]);
			i >>= 1;
		}
	}
	T take(long long lef, long long rig) {
		T a = unit, b = unit;
		lef += n;
		rig += n;
		while(lef < rig) {
			if(lef & 1) a = operation(a, seg[lef]);
			if(rig & 1) b = operation(seg[rig - 1], b);
			(lef += 1) >>= 1;
			rig >>= 1;
		}
		return operation(a, b);
	}
};

int main() {
	ios::sync_with_stdio(false);
	cin.tie(nullptr);
	// cout << fixed << setprecision(15);

	ll n;
	cin >> n;
	string s;
	cin >> s;
	long long q;
	cin >> q;
	vector<long long> ans;
	ST<> st(
		n, [](ll a, ll b) { return a | b; }, 0);
	rep(i, n) { st.update(i, (1LL << (s[i] - 'a'))); }
	for(long long i = 0; i < q; i++) {
		ll t;
		cin >> t;
		if(t == 1) {
			ll id;
			char c;
			cin >> id >> c;
			id--;
			ll k = (1LL << (c - 'a'));
			st.update(id, k);
		} else {
			ll l, r;
			cin >> l >> r;
			l--;
			ll k = st.take(l, r);
			ans.push_back(bcnt(k));
		}
	}
	for(long long i = 0; i < (ans.size()); i++) {
		cout << ans[i] << endl;
	}
}

Measured memory_bytes: 11868