# https://atcoder.jp/contests/abc157/tasks/abc157_e
# セグメント木
# 各文字をビットに対応させる(セグ木を26本持っても良い)
import sys
read = sys.stdin.readline
from functools import reduce


def read_a_int():
    return int(read())


class SqrtDecomposedList:
    def __init__(self, ls, segfunc, identity_element):
        from math import sqrt, ceil
        from copy import copy
        self.f = segfunc  # queryのfunction
        self.ide = identity_element
        self.n = len(ls)
        self.ls = copy(ls)
        self.b = ceil(sqrt(self.n))
        self.bucket = [self.ide] * (self.b + 1)
        self._build()

    def _build(self):
        for d in range(self.b):
            self.bucket[d] = reduce(
                self.f, self.ls[(d * self.b):((d + 1) * self.b)], self.ide)
        # for i, v in enumerate(self.ls):
        #     self.bucket[i // self.b] = \
        #         self.f(v, self.bucket[i // self.b])

    def __getitem__(self, idx):
        return self.ls[idx]

    def update(self, i, x):
        '''i番目の要素をxに更新する O(√n)'''
        self.ls[i] = x
        s = i // self.b * self.b
        t = s + self.b
        # print(i, self.b, i // self.b, s, t)
        self.bucket[i // self.b] = reduce(self.f,
                                          self.ls[s:t], self.ide)

    def query(self, l, r):
        '''半開区間[l,r)で指定すること O(√n)'''
        if r - l < 2 * self.b:
            return reduce(self.f, self.ls[l:r])
        l_bucket = (l - 1) // self.b + 1
        r_bucket = r // self.b  # 半開区間なのでこれでいい
        ret = reduce(self.f, self.bucket[l_bucket:r_bucket], self.ide)
        ret = self.f(
            reduce(self.f, self.ls[l:(l_bucket * self.b)], self.ide),
            ret)
        ret = self.f(
            reduce(self.f, self.ls[(r_bucket * self.b):r], self.ide),
            ret)
        return ret


def segfunc(x, y):
    # 処理したい内容
    return x | y


def moji_to_bit(a):
    return 1 << (ord(a) - ord('a'))


def bit_to_sum(n):
    return sum([(n >> i) & 1 for i in range(n.bit_length())])


N = read_a_int()
S = read()[:-1]
S_bit = [moji_to_bit(s) for s in S]

# build segment tree
st = SqrtDecomposedList(S_bit, segfunc, 0)

Q = read_a_int()
for q in range(Q):
    com, a, b = read().split()
    if int(com) == 1:
        i, c = int(a) - 1, b
        st.update(i, moji_to_bit(c))
    else:
        l, r = int(a) - 1, int(b)
        print(bit_to_sum(st.query(l, r))) import sys sys read = sys.stdin.readline read sys.stdin.readline sys.stdin sys stdin readline from functools import reduce def read_a_int():
    return int(read()) read_a_int return int(read()) int(read()) int read() read class SqrtDecomposedList:
    def __init__(self, ls, segfunc, identity_element):
        from math import sqrt, ceil
        from copy import copy
        self.f = segfunc  # queryのfunction
        self.ide = identity_element
        self.n = len(ls)
        self.ls = copy(ls)
        self.b = ceil(sqrt(self.n))
        self.bucket = [self.ide] * (self.b + 1)
        self._build()

    def _build(self):
        for d in range(self.b):
            self.bucket[d] = reduce(
                self.f, self.ls[(d * self.b):((d + 1) * self.b)], self.ide)
        # for i, v in enumerate(self.ls):
        #     self.bucket[i // self.b] = \
        #         self.f(v, self.bucket[i // self.b])

    def __getitem__(self, idx):
        return self.ls[idx]

    def update(self, i, x):
        '''i番目の要素をxに更新する O(√n)'''
        self.ls[i] = x
        s = i // self.b * self.b
        t = s + self.b
        # print(i, self.b, i // self.b, s, t)
        self.bucket[i // self.b] = reduce(self.f,
                                          self.ls[s:t], self.ide)

    def query(self, l, r):
        '''半開区間[l,r)で指定すること O(√n)'''
        if r - l < 2 * self.b:
            return reduce(self.f, self.ls[l:r])
        l_bucket = (l - 1) // self.b + 1
        r_bucket = r // self.b  # 半開区間なのでこれでいい
        ret = reduce(self.f, self.bucket[l_bucket:r_bucket], self.ide)
        ret = self.f(
            reduce(self.f, self.ls[l:(l_bucket * self.b)], self.ide),
            ret)
        ret = self.f(
            reduce(self.f, self.ls[(r_bucket * self.b):r], self.ide),
            ret)
        return ret SqrtDecomposedList def __init__(self, ls, segfunc, identity_element):
        from math import sqrt, ceil
        from copy import copy
        self.f = segfunc  # queryのfunction
        self.ide = identity_element
        self.n = len(ls)
        self.ls = copy(ls)
        self.b = ceil(sqrt(self.n))
        self.bucket = [self.ide] * (self.b + 1)
        self._build()

     __init__ from math import sqrt, ceil from copy import copy self.f = segfunc self.f self f segfunc self.ide = identity_element self.ide self ide identity_element self.n = len(ls) self.n self n len(ls) len ls self.ls = copy(ls) self.ls self ls copy(ls) copy ls self.b = ceil(sqrt(self.n)) self.b self b ceil(sqrt(self.n)) ceil sqrt(self.n) sqrt self.n self n self.bucket = [self.ide] * (self.b + 1) self.bucket self bucket [self.ide] * (self.b + 1) [self.ide] self.ide self ide self.b + 1 self.b self b 1 self._build() self._build self _build self self ls ls segfunc segfunc identity_element identity_element def _build(self):
        for d in range(self.b):
            self.bucket[d] = reduce(
                self.f, self.ls[(d * self.b):((d + 1) * self.b)], self.ide)
        # for i, v in enumerate(self.ls):
        #     self.bucket[i // self.b] = \
        #         self.f(v, self.bucket[i // self.b])

     _build for d in range(self.b):
            self.bucket[d] = reduce(
                self.f, self.ls[(d * self.b):((d + 1) * self.b)], self.ide)
        # for i, v in enumerate(self.ls):
        #     self.bucket[i // self.b] = \
        #         self.f(v, self.bucket[i // self.b])

     d range(self.b) range self.b self b self.bucket[d] = reduce(
                self.f, self.ls[(d * self.b):((d + 1) * self.b)], self.ide) self.bucket[d] self.bucket self bucket d reduce(
                self.f, self.ls[(d * self.b):((d + 1) * self.b)], self.ide) reduce self.f self f self.ls[(d * self.b):((d + 1) * self.b)] self.ls self ls (d * self.b):((d + 1) * self.b) d * self.b d self.b self b (d + 1) * self.b d + 1 d 1 self.b self b self.ide self ide self self def __getitem__(self, idx):
        return self.ls[idx]

     __getitem__ return self.ls[idx] self.ls[idx] self.ls self ls idx self self idx idx def update(self, i, x):
        '''i番目の要素をxに更新する O(√n)'''
        self.ls[i] = x
        s = i // self.b * self.b
        t = s + self.b
        # print(i, self.b, i // self.b, s, t)
        self.bucket[i // self.b] = reduce(self.f,
                                          self.ls[s:t], self.ide)

     update '''i番目の要素をxに更新する O(√n)''' self.ls[i] = x self.ls[i] self.ls self ls i x s = i // self.b * self.b s i // self.b * self.b i // self.b i self.b self b self.b self b t = s + self.b t s + self.b s self.b self b self.bucket[i // self.b] = reduce(self.f,
                                          self.ls[s:t], self.ide) self.bucket[i // self.b] self.bucket self bucket i // self.b i self.b self b reduce(self.f,
                                          self.ls[s:t], self.ide) reduce self.f self f self.ls[s:t] self.ls self ls s:t s t self.ide self ide self self i i x x def query(self, l, r):
        '''半開区間[l,r)で指定すること O(√n)'''
        if r - l < 2 * self.b:
            return reduce(self.f, self.ls[l:r])
        l_bucket = (l - 1) // self.b + 1
        r_bucket = r // self.b  # 半開区間なのでこれでいい
        ret = reduce(self.f, self.bucket[l_bucket:r_bucket], self.ide)
        ret = self.f(
            reduce(self.f, self.ls[l:(l_bucket * self.b)], self.ide),
            ret)
        ret = self.f(
            reduce(self.f, self.ls[(r_bucket * self.b):r], self.ide),
            ret)
        return ret query '''半開区間[l,r)で指定すること O(√n)''' if r - l < 2 * self.b:
            return reduce(self.f, self.ls[l:r])
         r - l < 2 * self.b r - l r l 2 * self.b 2 self.b self b return reduce(self.f, self.ls[l:r]) reduce(self.f, self.ls[l:r]) reduce self.f self f self.ls[l:r] self.ls self ls l:r l r l_bucket = (l - 1) // self.b + 1 l_bucket (l - 1) // self.b + 1 (l - 1) // self.b l - 1 l 1 self.b self b 1 r_bucket = r // self.b r_bucket r // self.b r self.b self b ret = reduce(self.f, self.bucket[l_bucket:r_bucket], self.ide) ret reduce(self.f, self.bucket[l_bucket:r_bucket], self.ide) reduce self.f self f self.bucket[l_bucket:r_bucket] self.bucket self bucket l_bucket:r_bucket l_bucket r_bucket self.ide self ide ret = self.f(
            reduce(self.f, self.ls[l:(l_bucket * self.b)], self.ide),
            ret) ret self.f(
            reduce(self.f, self.ls[l:(l_bucket * self.b)], self.ide),
            ret) self.f self f reduce(self.f, self.ls[l:(l_bucket * self.b)], self.ide) reduce self.f self f self.ls[l:(l_bucket * self.b)] self.ls self ls l:(l_bucket * self.b) l l_bucket * self.b l_bucket self.b self b self.ide self ide ret ret = self.f(
            reduce(self.f, self.ls[(r_bucket * self.b):r], self.ide),
            ret) ret self.f(
            reduce(self.f, self.ls[(r_bucket * self.b):r], self.ide),
            ret) self.f self f reduce(self.f, self.ls[(r_bucket * self.b):r], self.ide) reduce self.f self f self.ls[(r_bucket * self.b):r] self.ls self ls (r_bucket * self.b):r r_bucket * self.b r_bucket self.b self b r self.ide self ide ret return ret ret self self l l r r def segfunc(x, y):
    # 処理したい内容
    return x | y segfunc return x | y x | y x y x x y y def moji_to_bit(a):
    return 1 << (ord(a) - ord('a')) moji_to_bit return 1 << (ord(a) - ord('a')) 1 << (ord(a) - ord('a')) 1 ord(a) - ord('a') ord(a) ord a ord('a') ord 'a' a a def bit_to_sum(n):
    return sum([(n >> i) & 1 for i in range(n.bit_length())]) bit_to_sum (n >> i) & 1 for i in range(n.bit_length()) for i in range(n.bit_length()) i range(n.bit_length()) range n.bit_length() n.bit_length n bit_length for i in range(n.bit_length()) (n >> i) & 1 n >> i n i 1 return sum([(n >> i) & 1 for i in range(n.bit_length())]) sum([(n >> i) & 1 for i in range(n.bit_length())]) sum [(n >> i) & 1 for i in range(n.bit_length())] n n N = read_a_int() N read_a_int() read_a_int S = read()[:-1] S read()[:-1] () read :-1 -1 moji_to_bit(s) for s in S for s in S s S for s in S moji_to_bit(s) moji_to_bit s S_bit = [moji_to_bit(s) for s in S] S_bit [moji_to_bit(s) for s in S] st = SqrtDecomposedList(S_bit, segfunc, 0) st SqrtDecomposedList(S_bit, segfunc, 0) SqrtDecomposedList S_bit segfunc 0 Q = read_a_int() Q read_a_int() read_a_int for q in range(Q):
    com, a, b = read().split()
    if int(com) == 1:
        i, c = int(a) - 1, b
        st.update(i, moji_to_bit(c))
    else:
        l, r = int(a) - 1, int(b)
        print(bit_to_sum(st.query(l, r))) q range(Q) range Q com, a, b = read().split() com read().split() ().split () read split a b if int(com) == 1:
        i, c = int(a) - 1, b
        st.update(i, moji_to_bit(c))
    else:
        l, r = int(a) - 1, int(b)
        print(bit_to_sum(st.query(l, r))) int(com) == 1 int(com) int com 1 i, c = int(a) - 1, b i int(a) - 1 int(a) int a 1 c b st.update(i, moji_to_bit(c)) st.update st update i moji_to_bit(c) moji_to_bit c l, r = int(a) - 1, int(b) l int(a) - 1 int(a) int a 1 r int(b) int b print(bit_to_sum(st.query(l, r))) print bit_to_sum(st.query(l, r)) bit_to_sum st.query(l, r) st.query st query l r l, r = int(a) - 1, int(b) int(a) - 1 l read = sys.stdin.readline sys.stdin.readline read N = read_a_int() read_a_int() N c = int(a) - 1, b b c a, b = read().split() read().split() a class SqrtDecomposedList:
    def __init__(self, ls, segfunc, identity_element):
        from math import sqrt, ceil
        from copy import copy
        self.f = segfunc  # queryのfunction
        self.ide = identity_element
        self.n = len(ls)
        self.ls = copy(ls)
        self.b = ceil(sqrt(self.n))
        self.bucket = [self.ide] * (self.b + 1)
        self._build()

    def _build(self):
        for d in range(self.b):
            self.bucket[d] = reduce(
                self.f, self.ls[(d * self.b):((d + 1) * self.b)], self.ide)
        # for i, v in enumerate(self.ls):
        #     self.bucket[i // self.b] = \
        #         self.f(v, self.bucket[i // self.b])

    def __getitem__(self, idx):
        return self.ls[idx]

    def update(self, i, x):
        '''i番目の要素をxに更新する O(√n)'''
        self.ls[i] = x
        s = i // self.b * self.b
        t = s + self.b
        # print(i, self.b, i // self.b, s, t)
        self.bucket[i // self.b] = reduce(self.f,
                                          self.ls[s:t], self.ide)

    def query(self, l, r):
        '''半開区間[l,r)で指定すること O(√n)'''
        if r - l < 2 * self.b:
            return reduce(self.f, self.ls[l:r])
        l_bucket = (l - 1) // self.b + 1
        r_bucket = r // self.b  # 半開区間なのでこれでいい
        ret = reduce(self.f, self.bucket[l_bucket:r_bucket], self.ide)
        ret = self.f(
            reduce(self.f, self.ls[l:(l_bucket * self.b)], self.ide),
            ret)
        ret = self.f(
            reduce(self.f, self.ls[(r_bucket * self.b):r], self.ide),
            ret)
        return ret class SqrtDecomposedList:
    def __init__(self, ls, segfunc, identity_element):
        from math import sqrt, ceil
        from copy import copy
        self.f = segfunc  # queryのfunction
        self.ide = identity_element
        self.n = len(ls)
        self.ls = copy(ls)
        self.b = ceil(sqrt(self.n))
        self.bucket = [self.ide] * (self.b + 1)
        self._build()

    def _build(self):
        for d in range(self.b):
            self.bucket[d] = reduce(
                self.f, self.ls[(d * self.b):((d + 1) * self.b)], self.ide)
        # for i, v in enumerate(self.ls):
        #     self.bucket[i // self.b] = \
        #         self.f(v, self.bucket[i // self.b])

    def __getitem__(self, idx):
        return self.ls[idx]

    def update(self, i, x):
        '''i番目の要素をxに更新する O(√n)'''
        self.ls[i] = x
        s = i // self.b * self.b
        t = s + self.b
        # print(i, self.b, i // self.b, s, t)
        self.bucket[i // self.b] = reduce(self.f,
                                          self.ls[s:t], self.ide)

    def query(self, l, r):
        '''半開区間[l,r)で指定すること O(√n)'''
        if r - l < 2 * self.b:
            return reduce(self.f, self.ls[l:r])
        l_bucket = (l - 1) // self.b + 1
        r_bucket = r // self.b  # 半開区間なのでこれでいい
        ret = reduce(self.f, self.bucket[l_bucket:r_bucket], self.ide)
        ret = self.f(
            reduce(self.f, self.ls[l:(l_bucket * self.b)], self.ide),
            ret)
        ret = self.f(
            reduce(self.f, self.ls[(r_bucket * self.b):r], self.ide),
            ret)
        return ret SqrtDecomposedList st = SqrtDecomposedList(S_bit, segfunc, 0) SqrtDecomposedList(S_bit, segfunc, 0) st def read_a_int():
    return int(read()) def read_a_int():
    return int(read()) read_a_int def bit_to_sum(n):
    return sum([(n >> i) & 1 for i in range(n.bit_length())]) def bit_to_sum(n):
    return sum([(n >> i) & 1 for i in range(n.bit_length())]) bit_to_sum Q = read_a_int() read_a_int() Q def segfunc(x, y):
    # 処理したい内容
    return x | y def segfunc(x, y):
    # 処理したい内容
    return x | y segfunc r = int(a) - 1, int(b) int(b) r S_bit = [moji_to_bit(s) for s in S] [moji_to_bit(s) for s in S] S_bit b = read().split() read().split() b i, c = int(a) - 1, b int(a) - 1 i def moji_to_bit(a):
    return 1 << (ord(a) - ord('a')) def moji_to_bit(a):
    return 1 << (ord(a) - ord('a')) moji_to_bit S = read()[:-1] read()[:-1] S com, a, b = read().split() read().split() com
# https://atcoder.jp/contests/abc157/tasks/abc157_e
# セグメント木
# 各文字をビットに対応させる(セグ木を26本持っても良い)
import sys
read = sys.stdin.readline
from functools import reduce


def read_a_int():
    return int(read())


class SqrtDecomposedList:
    def __init__(self, ls, segfunc, identity_element):
        from math import sqrt, ceil
        from copy import copy
        self.f = segfunc  # queryのfunction
        self.ide = identity_element
        self.n = len(ls)
        self.ls = copy(ls)
        self.b = ceil(sqrt(self.n))
        self.bucket = [self.ide] * (self.b + 1)
        self._build()

    def _build(self):
        for d in range(self.b):
            self.bucket[d] = reduce(
                self.f, self.ls[(d * self.b):((d + 1) * self.b)], self.ide)
        # for i, v in enumerate(self.ls):
        #     self.bucket[i // self.b] = \
        #         self.f(v, self.bucket[i // self.b])

    def __getitem__(self, idx):
        return self.ls[idx]

    def update(self, i, x):
        '''i番目の要素をxに更新する O(√n)'''
        self.ls[i] = x
        s = i // self.b * self.b
        t = s + self.b
        # print(i, self.b, i // self.b, s, t)
        self.bucket[i // self.b] = reduce(self.f,
                                          self.ls[s:t], self.ide)

    def query(self, l, r):
        '''半開区間[l,r)で指定すること O(√n)'''
        if r - l < 2 * self.b:
            return reduce(self.f, self.ls[l:r])
        l_bucket = (l - 1) // self.b + 1
        r_bucket = r // self.b  # 半開区間なのでこれでいい
        ret = reduce(self.f, self.bucket[l_bucket:r_bucket], self.ide)
        ret = self.f(
            reduce(self.f, self.ls[l:(l_bucket * self.b)], self.ide),
            ret)
        ret = self.f(
            reduce(self.f, self.ls[(r_bucket * self.b):r], self.ide),
            ret)
        return ret


def segfunc(x, y):
    # 処理したい内容
    return x | y


def moji_to_bit(a):
    return 1 << (ord(a) - ord('a'))


def bit_to_sum(n):
    return sum([(n >> i) & 1 for i in range(n.bit_length())])


N = read_a_int()
S = read()[:-1]
S_bit = [moji_to_bit(s) for s in S]

# build segment tree
st = SqrtDecomposedList(S_bit, segfunc, 0)

Q = read_a_int()
for q in range(Q):
    com, a, b = read().split()
    if int(com) == 1:
        i, c = int(a) - 1, b
        st.update(i, moji_to_bit(c))
    else:
        l, r = int(a) - 1, int(b)
        print(bit_to_sum(st.query(l, r)))
