Buggy python submission (verdict: Time Limit Exceeded):
class SegTree:

    def __init__(self, N, S):
        self.N = 1
        while self.N < N:
            self.N *= 2
        self.tree = [set() for i in range(2 * self.N - 1)]
        for i in range(len(S)):
            self.tree[self.N - 1 + i] = set(S[i])
        for i in range(self.N - 2, -1, -1):
            self.tree[i] = self.tree[i * 2 + 1] | self.tree[i * 2 + 2]

    def update(self, index, char):
        i = self.N - 1 + index
        self.tree[i] = set(char)

        while i > 0:
            i = (i - 1) // 2
            self.tree[i] = self.tree[i * 2 + 1] | self.tree[i * 2 + 2]

    def get(self, a, b):
        return self.query(a, b, 0, 0, self.N)

    def query(self, a, b, k, l, r):
        if r <= a or b <= l:
            return set()

        if a <= l and r <= b:
            return self.tree[k]

        left = self.query(a, b, 2 * k + 1, l, (l + r) // 2)
        right = self.query(a, b, 2 * k + 2, (l + r) // 2, r)
        return left | right


def solve():

    N = int(input())
    S = list(input())
    tree = SegTree(N, S)

    Q = int(input())
    for _ in range(Q):
        t_q, in_1, in_2 = input().split()
        if t_q == '1':
            i_q = int(in_1)
            c_q = in_2
            tree.update(i_q-1, c_q)
        elif t_q == '2':
            l_q = int(in_1)
            r_q = int(in_2)
            print(len(tree.get(l_q-1, r_q)))


solve()


Fixed submission:
class SegTree:

    def __init__(self, N, S):
        self.N = 1
        while self.N < N:
            self.N *= 2
        self.tree = [0 for i in range(2 * self.N - 1)]
        for i in range(len(S)):
            self.tree[self.N - 1 + i] = 1 << (ord(S[i]) - ord('a'))
        for i in range(self.N - 2, -1, -1):
            self.tree[i] = self.tree[i * 2 + 1] | self.tree[i * 2 + 2]

    def update(self, index, char):
        i = self.N - 1 + index
        self.tree[i] = 1 << (ord(char) - ord('a'))

        while i > 0:
            i = (i - 1) // 2
            self.tree[i] = self.tree[i * 2 + 1] | self.tree[i * 2 + 2]

    def get(self, a, b):
        return self.query(a, b, 0, 0, self.N)

    def query(self, a, b, k, l, r):
        if r <= a or b <= l:
            return 0
        elif a <= l and r <= b:
            return self.tree[k]
        else:
            left = self.query(a, b, 2 * k + 1, l, (l + r) // 2)
            right = self.query(a, b, 2 * k + 2, (l + r) // 2, r)
            return left | right


def solve():

    N = int(input())
    S = list(input())
    tree = SegTree(N, S)

    Q = int(input())
    for _ in range(Q):
        t_q, in_1, in_2 = input().split()
        if t_q == '1':
            i_q = int(in_1)
            c_q = in_2
            tree.update(i_q-1, c_q)
        elif t_q == '2':
            l_q = int(in_1)
            r_q = int(in_2)
            print(bin(tree.get(l_q-1, r_q)).count('1'))


solve()

Buggy python submission (verdict: Time Limit Exceeded):
class SegTree:

    def __init__(self, N):
        self.N = 1
        while self.N < N:
            self.N *= 2
        self.tree = [set() for i in range(2 * self.N - 1)]

    def update(self, index, char):
        i = self.N - 1 + index
        self.tree[i] = set(char)

        while i > 0:
            i = (i - 1) // 2
            left = self.tree[i * 2 + 1]
            right = self.tree[i * 2 + 2]
            self.tree[i] = left | right

    def get(self, a, b):
        return self.query(a, b, 0, 0, self.N)

    def query(self, a, b, k, l, r):
        if r <= a or b <= l:
            return set()

        if a <= l and r <= b:
            return self.tree[k]

        left = self.query(a, b, 2 * k + 1, l, (l + r) // 2)
        right = self.query(a, b, 2 * k + 2, (l + r) // 2, r)
        return left | right


def solve():

    N = int(input())
    tree = SegTree(N)

    S = list(input())
    for i in range(N):
        tree.update(i, S[i])

    Q = int(input())
    for _ in range(Q):
        t_q, in_1, in_2 = input().split()
        if t_q == '1':
            i_q = int(in_1)
            c_q = in_2
            tree.update(i_q-1, c_q)
        elif t_q == '2':
            l_q = int(in_1)
            r_q = int(in_2)
            print(len(tree.get(l_q-1, r_q)))


solve()


Fixed submission:
class SegTree:

    def __init__(self, N, S):
        self.N = 1
        while self.N < N:
            self.N *= 2
        self.tree = [0 for i in range(2 * self.N - 1)]
        for i in range(len(S)):
            self.tree[self.N - 1 + i] = 1 << (ord(S[i]) - ord('a'))
        for i in range(self.N - 2, -1, -1):
            self.tree[i] = self.tree[i * 2 + 1] | self.tree[i * 2 + 2]

    def update(self, index, char):
        i = self.N - 1 + index
        self.tree[i] = 1 << (ord(char) - ord('a'))

        while i > 0:
            i = (i - 1) // 2
            self.tree[i] = self.tree[i * 2 + 1] | self.tree[i * 2 + 2]

    def get(self, a, b):
        return self.query(a, b, 0, 0, self.N)

    def query(self, a, b, k, l, r):
        if r <= a or b <= l:
            return 0
        elif a <= l and r <= b:
            return self.tree[k]
        else:
            left = self.query(a, b, 2 * k + 1, l, (l + r) // 2)
            right = self.query(a, b, 2 * k + 2, (l + r) // 2, r)
            return left | right


def solve():

    N = int(input())
    S = list(input())
    tree = SegTree(N, S)

    Q = int(input())
    for _ in range(Q):
        t_q, in_1, in_2 = input().split()
        if t_q == '1':
            i_q = int(in_1)
            c_q = in_2
            tree.update(i_q-1, c_q)
        elif t_q == '2':
            l_q = int(in_1)
            r_q = int(in_2)
            print(bin(tree.get(l_q-1, r_q)).count('1'))


solve()

Buggy python submission (verdict: Time Limit Exceeded):
class SegTree:

    def __init__(self, N):
        self.N = 1
        while self.N < N:
            self.N *= 2
        self.tree = [{} for i in range(2 * self.N - 1)]

    def update(self, index, char):
        i = self.N - 1 + index
        assert len(self.tree[i]) <= 1

        if len(self.tree[i]) == 1:
            old_char, _ = self.tree[i].popitem()
            new_char = char
            self.tree[i][new_char] = 1

            while i > 0:
                i = (i - 1) // 2
                assert old_char in self.tree[i] and self.tree[i][old_char] > 0
                self.tree[i][old_char] -= 1
                self.tree[i][new_char] = self.tree[i].get(new_char, 0) + 1

        else:
            self.tree[i][char] = 1

            while i > 0:
                i = (i - 1) // 2
                self.tree[i][char] = self.tree[i].get(char, 0) + 1
    
    def get(self, a, b):
        return self.query(a, b, 0, 0, self.N)

    def query(self, a, b, k, l, r):
        if r <= a or b <= l:
            return {}

        if a <= l and r <= b:
            return self.tree[k].copy()

        left = self.query(a, b, 2 * k + 1, l, (l + r) // 2)
        right = self.query(a, b, 2 * k + 2, (l + r) // 2, r)
        res = left
        for char in right.keys():
            res[char] = res.get(char, 0) + right[char]
        return res


def solve():

    N = int(input())
    tree = SegTree(N)

    S = list(input())
    for i in range(N):
        tree.update(i, S[i])

    Q = int(input())
    for _ in range(Q):
        t_q, in_1, in_2 = input().split()
        if t_q == '1':
            i_q = int(in_1)
            c_q = in_2
            tree.update(i_q-1, c_q)
        elif t_q == '2':
            l_q = int(in_1)
            r_q = int(in_2)
            dic = tree.get(l_q-1, r_q)
            res = 0
            for char in dic.keys():
                if dic[char] > 0:
                    res += 1
            print(res)


solve()


Fixed submission:
class SegTree:

    def __init__(self, N, S):
        self.N = 1
        while self.N < N:
            self.N *= 2
        self.tree = [0 for i in range(2 * self.N - 1)]
        for i in range(len(S)):
            self.tree[self.N - 1 + i] = 1 << (ord(S[i]) - ord('a'))
        for i in range(self.N - 2, -1, -1):
            self.tree[i] = self.tree[i * 2 + 1] | self.tree[i * 2 + 2]

    def update(self, index, char):
        i = self.N - 1 + index
        self.tree[i] = 1 << (ord(char) - ord('a'))

        while i > 0:
            i = (i - 1) // 2
            self.tree[i] = self.tree[i * 2 + 1] | self.tree[i * 2 + 2]

    def get(self, a, b):
        return self.query(a, b, 0, 0, self.N)

    def query(self, a, b, k, l, r):
        if r <= a or b <= l:
            return 0
        elif a <= l and r <= b:
            return self.tree[k]
        else:
            left = self.query(a, b, 2 * k + 1, l, (l + r) // 2)
            right = self.query(a, b, 2 * k + 2, (l + r) // 2, r)
            return left | right


def solve():

    N = int(input())
    S = list(input())
    tree = SegTree(N, S)

    Q = int(input())
    for _ in range(Q):
        t_q, in_1, in_2 = input().split()
        if t_q == '1':
            i_q = int(in_1)
            c_q = in_2
            tree.update(i_q-1, c_q)
        elif t_q == '2':
            l_q = int(in_1)
            r_q = int(in_2)
            print(bin(tree.get(l_q-1, r_q)).count('1'))


solve()