/* package whatever; // don't place package name! */
import java.util.*;
import java.lang.*;
import java.io.*;
/* Name of the class has to be "Main" only if the class is public. */
class Ideone
{
{
Scanner sc
= new Scanner
(System.
in); sc.nextInt();
sc.nextLine();
int q = sc.nextInt();
int[][] queries = new int[q][3];
for(int i=0; i<q; i++){
queries[i][0] = sc.nextInt();
queries[i][1] = sc.nextInt();
queries[i][2] = sc.nextInt();
}
System.
out.
println(findDistinctCharacters
(data, queries
)); }
private static List
<Integer
> findDistinctCharacters
(String data,
int[][]queries
){ List<Integer> ans = new ArrayList<>();
StringBuilder s = new StringBuilder(data);
for(int[] query: queries){
if(query[0] ==1){
char rep = (char) ('a' + query[2] - 1);
s.setCharAt(query[1]-1, rep);
}
if(query[0]==2){
int distinct = countDistinct(s, query[1], query[2]);
ans.add(distinct);
}
}
return ans;
}
private static int countDistinct(StringBuilder s, int l, int r){
HashSet<Character> set = new HashSet<>();
l=l-1;
r= r-1;
while(l<s.length() && l<=r){
// char curr = s.charAt(l++);
// if(!set.contains(curr)){
// distinct++;
// set.add(curr);
// }
set.add(s.charAt(l++));
}
return set.size();
}
}
LyogcGFja2FnZSB3aGF0ZXZlcjsgLy8gZG9uJ3QgcGxhY2UgcGFja2FnZSBuYW1lISAqLwoKaW1wb3J0IGphdmEudXRpbC4qOwppbXBvcnQgamF2YS5sYW5nLio7CmltcG9ydCBqYXZhLmlvLio7CgovKiBOYW1lIG9mIHRoZSBjbGFzcyBoYXMgdG8gYmUgIk1haW4iIG9ubHkgaWYgdGhlIGNsYXNzIGlzIHB1YmxpYy4gKi8KY2xhc3MgSWRlb25lCnsKICAgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluIChTdHJpbmdbXSBhcmdzKSB0aHJvd3MgamF2YS5sYW5nLkV4Y2VwdGlvbgogICAgewogICAgICAgICAgICBTY2FubmVyIHNjID0gbmV3IFNjYW5uZXIoU3lzdGVtLmluKTsKICAgICAgICAgICAgc2MubmV4dEludCgpOwogICAgICAgICAgICBzYy5uZXh0TGluZSgpOwogICAgICAgICAgICBTdHJpbmcgZGF0YSA9IHNjLm5leHRMaW5lKCk7CiAgICAgICAgICAgIGludCBxID0gc2MubmV4dEludCgpOwogICAgICAgICAgICBpbnRbXVtdIHF1ZXJpZXMgPSBuZXcgaW50W3FdWzNdOwogICAgICAgICAgICBmb3IoaW50IGk9MDsgaTxxOyBpKyspewogICAgICAgICAgICAgICAgcXVlcmllc1tpXVswXSA9IHNjLm5leHRJbnQoKTsKICAgICAgICAgICAgICAgIHF1ZXJpZXNbaV1bMV0gPSBzYy5uZXh0SW50KCk7CiAgICAgICAgICAgICAgICBxdWVyaWVzW2ldWzJdID0gc2MubmV4dEludCgpOwogICAgICAgICAgICB9CgogICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oZmluZERpc3RpbmN0Q2hhcmFjdGVycyhkYXRhLCBxdWVyaWVzKSk7CiAgICB9CiAgICBwcml2YXRlIHN0YXRpYyBMaXN0PEludGVnZXI+IGZpbmREaXN0aW5jdENoYXJhY3RlcnMoU3RyaW5nIGRhdGEsIGludFtdW11xdWVyaWVzKXsKICAgICAgICBMaXN0PEludGVnZXI+IGFucyA9IG5ldyBBcnJheUxpc3Q8PigpOwogICAgICAgIFN0cmluZ0J1aWxkZXIgcyA9IG5ldyBTdHJpbmdCdWlsZGVyKGRhdGEpOwogICAgICAgIGZvcihpbnRbXSBxdWVyeTogcXVlcmllcyl7CiAgICAgICAgICAgIGlmKHF1ZXJ5WzBdID09MSl7CiAgICAgICAgICAgICAgICBjaGFyIHJlcCA9IChjaGFyKSAoJ2EnICsgcXVlcnlbMl0gLSAxKTsKICAgICAgICAgICAgICAgIHMuc2V0Q2hhckF0KHF1ZXJ5WzFdLTEsIHJlcCk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYocXVlcnlbMF09PTIpewogICAgICAgICAgICAgICAgaW50IGRpc3RpbmN0ID0gY291bnREaXN0aW5jdChzLCBxdWVyeVsxXSwgcXVlcnlbMl0pOwogICAgICAgICAgICAgICAgYW5zLmFkZChkaXN0aW5jdCk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgcmV0dXJuIGFuczsKICAgIH0KICAgIHByaXZhdGUgc3RhdGljIGludCBjb3VudERpc3RpbmN0KFN0cmluZ0J1aWxkZXIgcywgaW50IGwsIGludCByKXsKICAgICAgICBIYXNoU2V0PENoYXJhY3Rlcj4gc2V0ID0gbmV3IEhhc2hTZXQ8PigpOwogICAgICAgIGw9bC0xOwogICAgICAgIHI9IHItMTsKICAgICAgICB3aGlsZShsPHMubGVuZ3RoKCkgJiYgbDw9cil7CiAgICAgICAgICAgIC8vIGNoYXIgY3VyciA9IHMuY2hhckF0KGwrKyk7CiAgICAgICAgICAgIC8vIGlmKCFzZXQuY29udGFpbnMoY3VycikpewogICAgICAgICAgICAvLyAgICAgZGlzdGluY3QrKzsKICAgICAgICAgICAgLy8gICAgIHNldC5hZGQoY3Vycik7CiAgICAgICAgICAgIC8vIH0KICAgICAgICAgICAgc2V0LmFkZChzLmNoYXJBdChsKyspKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHNldC5zaXplKCk7CiAgICB9Cn0=