import java.io.*;
public class Main {
static class EntradaRapida {
private final byte[] datos = new byte[1 << 16];
private int pos = 0;
private int longitud = 0;
if (pos >= longitud) {
longitud = entrada.read(datos);
pos = 0;
if (longitud <= 0) return -1;
}
return datos[pos++] & 255;
}
int caracter;
do {
caracter = leer();
if (caracter == -1) return -1;
} while (caracter <= 32);
int signo = 1;
if (caracter == '-') {
signo = -1;
caracter = leer();
}
int valor = 0;
while (caracter > 32 && caracter != -1) {
valor = valor * 10 + caracter - '0';
caracter = leer();
}
return valor * signo;
}
StringBuilder resultado = new StringBuilder();
int caracter;
do {
caracter = leer();
if (caracter == -1) return null;
} while (caracter <= 32);
while (caracter > 32 && caracter != -1) {
resultado.append((char) caracter);
caracter = leer();
}
return resultado.toString();
}
int caracter;
do {
caracter = leer();
} while (caracter != -1 && caracter <= 32);
return caracter == -1 ? '\0' : (char) caracter;
}
}
static class ArbolSegmentos {
private final int inicioArbol;
private final int[] segmentos;
private final int longitud;
ArbolSegmentos(char[] letras) {
longitud = letras.length;
int capacidad = 1;
while (capacidad < longitud) {
capacidad <<= 1;
}
inicioArbol = capacidad;
segmentos = new int[inicioArbol << 1];
construir(letras);
}
private int mascara(char caracter) {
if (caracter < 'a' || caracter > 'z') {
return 0;
}
return 1 << (caracter - 'a');
}
private void construir(char[] letras) {
for (int i = 0; i < longitud; i++) {
segmentos[inicioArbol + i] = mascara(letras[i]);
}
for (int i = inicioArbol - 1; i > 0; i--) {
segmentos[i] =
segmentos[i << 1] |
segmentos[i << 1 | 1];
}
}
void actualizar(int indice, char nuevoCaracter) {
if (indice < 0 || indice >= longitud) return;
int actual = inicioArbol + indice;
segmentos[actual] = mascara(nuevoCaracter);
actual >>= 1;
while (actual > 0) {
segmentos[actual] =
segmentos[actual << 1] |
segmentos[actual << 1 | 1];
actual >>= 1;
}
}
int consultar(int inicio, int fin) {
if (inicio < 0 || fin >= longitud || inicio > fin) {
return 0;
}
inicio += inicioArbol;
fin += inicioArbol + 1;
int resultado = 0;
while (inicio < fin) {
if ((inicio & 1) != 0) {
resultado |= segmentos[inicio++];
}
if ((fin & 1) != 0) {
resultado |= segmentos[--fin];
}
inicio >>= 1;
fin >>= 1;
}
return Integer.
bitCount(resultado
); }
}
static void resolver
(EntradaRapida entrada
) throws IOException { String cadena
= entrada.
leerCadena();
if (cadena == null) return;
char[] caracteres = cadena.toCharArray();
int totalConsultas = entrada.leerEntero();
if (totalConsultas < 0) return;
ArbolSegmentos arbol = new ArbolSegmentos(caracteres);
StringBuilder salida = new StringBuilder();
for (int i = 0; i < totalConsultas; i++) {
int operacion = entrada.leerEntero();
if (operacion == -1) break;
if (operacion == 1) {
int indice = entrada.leerEntero() - 1;
char nuevoCaracter = entrada.leerLetra();
if (indice >= 0 &&
indice < caracteres.length &&
nuevoCaracter >= 'a' &&
nuevoCaracter <= 'z') {
caracteres[indice] = nuevoCaracter;
arbol.actualizar(indice, nuevoCaracter);
}
} else if (operacion == 2) {
int inicio = entrada.leerEntero() - 1;
int fin = entrada.leerEntero() - 1;
salida.append(
arbol.consultar(inicio, fin)
).append('\n');
}
}
}
resolver(new EntradaRapida());
}
}