package main

import (
	"bufio"
	"fmt"
	"os"
	"strconv"
)

var sc = bufio.NewScanner(os.Stdin)

func Scanner() string {
	sc.Scan()
	return sc.Text()
}

func intScanner() int {
	n, _ := strconv.Atoi(Scanner())
	return n
}

func floatScanner() float64 {
	n, _ := strconv.ParseFloat(Scanner(), 64)
	return n
}
func stringToInt(s string) int {
	n, _ := strconv.Atoi(s)
	return n
}
func stringSliceScanner(n int) []string {
	a := make([]string, n)
	for i := 0; i < n; i++ {
		a[i] = Scanner()
	}
	return a
}
func intSliceScanner(n int) []int {
	a := make([]int, n)
	for i := 0; i < n; i++ {
		a[i] = intScanner()
	}
	return a
}
func larger(a, b int) int {
	if a < b {
		return b
	} else {
		return a
	}
}
func smaller(a, b int) int {
	if a > b {
		return b
	} else {
		return a
	}
}
func max(a []int) int {
	x := a[0]
	for i := 0; i < len(a); i++ {
		if x < a[i] {
			x = a[i]
		}
	}
	return x
}
func min(a []int) int {
	x := a[0]
	for i := 0; i < len(a); i++ {
		if x > a[i] {
			x = a[i]
		}
	}
	return x
}
func abs(x int) int {
	if x < 0 {
		x = -x
	}
	return x
}

var mod int
var t float64

func main() {
	mod = 1000000007
	buf := make([]byte, 0)
	sc.Buffer(buf, mod)
	sc.Split(bufio.ScanWords)
	n := intScanner()
	s := Scanner()
	q := intScanner()
	trees := make([]*SegmentTree, 26)
	for i := 0; i < 26; i++ {
		trees[i] = InitSegmentTree(make([]int, n), mod)
	}
	runes := make([]int, n)
	for i, r := range s {
		trees[int(r)-97].UpdateAt(i, -1)
		runes[i] = int(r) - 97
	}
	for j := 0; j < q; j++ {
		f := intScanner()
		if f == 1 {
			i, c := intScanner()-1, Scanner()
			bef := runes[i]
			trees[bef].UpdateAt(i, 0)
			runes[i] = int([]rune(c)[0]) - 97
			trees[runes[i]].UpdateAt(i, -1)
		} else {
			l, r := intScanner()-1, intScanner()
			count := 0
			for i := 0; i < 26; i++ {
				if trees[i].GetRange(l, r) == -1 {
					count++
				}
			}
			fmt.Println(count)
		}
	}
}

type SegmentTree struct {
	offset int
	data   []int
	inf    int
}

func InitSegmentTree(a []int, inf int) *SegmentTree {
	n := len(a)
	size := 1
	for size < n {
		size *= 2
	}
	data := make([]int, size*2)
	for j, i := 0, size-1; i < size+n-1; i++ {
		data[i] = a[j]
		j++
	}
	for i := size + n - 1; i < size*2; i++ {
		data[i] = inf
	}
	for i := size - 2; i >= 0; i-- {
		if data[i*2+1] < data[i*2+2] {
			data[i] = data[i*2+1]
		} else {
			data[i] = data[i*2+2]
		}
	}
	return &SegmentTree{
		offset: size,
		data:   data,
		inf:    inf,
	}
}
func (tree *SegmentTree) GetRange(from, to int) int {
	return tree.getRange(from, to, 0, 0, tree.offset)
}
func (tree *SegmentTree) getRange(from, to, index, left, right int) int {
	if to <= left || right <= from {
		return tree.inf
	}
	if from <= left && right <= to {
		return tree.data[index]
	}
	med := (left + right) / 2
	lvalue := tree.getRange(from, to, index*2+1, left, med)
	rvalue := tree.getRange(from, to, index*2+2, med, right)
	if lvalue < rvalue {
		return lvalue
	}
	return rvalue
}
func (tree *SegmentTree) UpdateAt(index, value int) {
	idx := tree.offset - 1 + index
	tree.data[idx] = value
	for idx >= 1 {
		parent := (idx - 1) / 2
		left := parent*2 + 1
		right := parent*2 + 2
		if tree.data[left] < tree.data[right] {
			tree.data[parent] = tree.data[left]
		} else {
			tree.data[parent] = tree.data[right]
		}
		idx = parent
	}
}


Measured memory_bytes: 252164