Buggy python submission (verdict: Time Limit Exceeded):

class SegmentTree:
    def __init__(self, n):
        # 0-indexed.
        x = 1
        while x < n:
            x *= 2

        self.n = x
        self.base = 0
        self.dat = [self.base] * (2 * x - 1)

    def update(self, k, v):
        # Update dat[k] to v.
        k += self.n - 1
        self.dat[k] = v
        while k > 0:
            k = (k - 1) // 2
            self.dat[k] = self.dat[k * 2 + 1] + self.dat[k * 2 + 2]

    def query(self, a, b, k=0, l=0, r=0):
        # Returns value in [a, b).
        if l >= r:
            r = self.n

        if b <= l or r <= a:
            return self.base

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

        vl = self.query(a, b, k * 2 + 1, l, (l + r) // 2)
        vr = self.query(a, b, k * 2 + 2, (l + r) // 2, r)
        return vl + vr


N = int(input())
S = list(input())
Q = int(input())

trees = [SegmentTree(N + 1) for _ in range(26)]
for i in range(N):
    trees[ord(S[i]) - ord("a")].update(i, 1)

for _ in range(Q):
    s, *x = input().split()
    if s == "1":
        i = int(x[0]) - 1
        c = x[1]
        trees[ord(S[i]) - ord("a")].update(i, 0)
        trees[ord(c) - ord("a")].update(i, 1)
        S[i] = c
    else:
        l, r = map(int, x)
        cnt = 0
        for i in range(26):
            cnt += int(trees[i].query(l - 1, r) > 0)
        print(cnt)


Fixed submission:
N = int(input())
S = list(input())
Q = int(input())
X = [input().split() for _ in range(Q)]


class BIT:
    def __init__(self, n):
        self.size = n
        self.tree = [0] * (n + 1)
        
    def sum(self, i):
        if i == 0:
            return 0
        
        s = 0
        while i > 0:
            s += self.tree[i]
            i -= i & -i
        return s
    
    def add(self, i, x):
        while i <= self.size:
            self.tree[i] += x
            i += i & -i


MAX = 5 * 10 ** 5 + 2
d = dict()

for c in range(ord("a"), ord("z") + 1):
    s = chr(c)
    d[s] = BIT(MAX)
    for i, v in enumerate(S):
        if v == s:
            d[s].add(i + 1, 1)


for t, i, c in X:
    if t == "1":
        i = int(i)
        
        if S[i - 1] != c:
            # Delete index
            d[S[i - 1]].add(i, -1)
            
            # Insert index
            d[c].add(i, 1)
            S[i - 1] = c
    else:
        l = int(i)
        r = int(c)
        
        res = 0
        for c in range(ord("a"), ord("z") + 1):
            s = chr(c)
            res += int(d[s].sum(r) - d[s].sum(l - 1) > 0)

        print(res)

Buggy python submission (verdict: Runtime Error):
from bisect import bisect_left
from collections import defaultdict

N = int(input())
S = input()
Q = int(input())
X = [input().split() for _ in range(Q)]

d = defaultdict(list)
for i in range(N):
    d[S[i]].append(i + 1)
    
ss = list(S)
for t, i, c in X:
    if t == "1":
        i = int(i)
        
        # Delete index
        d[ss[i - 1]].remove(i)
        ss[i - 1] = c

        # Insert index
        d[c].insert(bisect_left(d[c], i), i)
    else:
        l = int(i)
        r = int(c)
        
        res = 0
        for key in d:
            l_idx = bisect_left(d[key], l)
            r_idx = bisect_left(d[key], r)
            res += int((l_idx < r_idx) or (l_idx == 0 and l <= d[key][l_idx] <= r))

        print(res)



Fixed submission:
N = int(input())
S = list(input())
Q = int(input())
X = [input().split() for _ in range(Q)]


class BIT:
    def __init__(self, n):
        self.size = n
        self.tree = [0] * (n + 1)
        
    def sum(self, i):
        if i == 0:
            return 0
        
        s = 0
        while i > 0:
            s += self.tree[i]
            i -= i & -i
        return s
    
    def add(self, i, x):
        while i <= self.size:
            self.tree[i] += x
            i += i & -i


MAX = 5 * 10 ** 5 + 2
d = dict()

for c in range(ord("a"), ord("z") + 1):
    s = chr(c)
    d[s] = BIT(MAX)
    for i, v in enumerate(S):
        if v == s:
            d[s].add(i + 1, 1)


for t, i, c in X:
    if t == "1":
        i = int(i)
        
        if S[i - 1] != c:
            # Delete index
            d[S[i - 1]].add(i, -1)
            
            # Insert index
            d[c].add(i, 1)
            S[i - 1] = c
    else:
        l = int(i)
        r = int(c)
        
        res = 0
        for c in range(ord("a"), ord("z") + 1):
            s = chr(c)
            res += int(d[s].sum(r) - d[s].sum(l - 1) > 0)

        print(res)

Buggy python submission (verdict: Runtime Error):
from bisect import bisect_left
from collections import defaultdict

N = int(input())
S = input()
Q = int(input())
X = [input().split() for _ in range(Q)]

d = defaultdict(list)
for i in range(N):
    d[S[i]].append(i + 1)

for t, i, c in X:
    if t == "1":
        i = int(i)
        
        # Delete index
        for key in d:
            if i in d[key]:
                d[key].remove(i)

        # Insert index
        d[c].insert(bisect_left(d[c], i), i)
    else:
        l = int(i)
        r = int(c)
        
        res = 0
        for key in d:
            l_idx = bisect_left(d[key], l)
            r_idx = bisect_left(d[key], r)
            res += int((l_idx < r_idx) or (l_idx == 0 and l <= d[key][l_idx] <= r))

        print(res)



Fixed submission:
N = int(input())
S = list(input())
Q = int(input())
X = [input().split() for _ in range(Q)]


class BIT:
    def __init__(self, n):
        self.size = n
        self.tree = [0] * (n + 1)
        
    def sum(self, i):
        if i == 0:
            return 0
        
        s = 0
        while i > 0:
            s += self.tree[i]
            i -= i & -i
        return s
    
    def add(self, i, x):
        while i <= self.size:
            self.tree[i] += x
            i += i & -i


MAX = 5 * 10 ** 5 + 2
d = dict()

for c in range(ord("a"), ord("z") + 1):
    s = chr(c)
    d[s] = BIT(MAX)
    for i, v in enumerate(S):
        if v == s:
            d[s].add(i + 1, 1)


for t, i, c in X:
    if t == "1":
        i = int(i)
        
        if S[i - 1] != c:
            # Delete index
            d[S[i - 1]].add(i, -1)
            
            # Insert index
            d[c].add(i, 1)
            S[i - 1] = c
    else:
        l = int(i)
        r = int(c)
        
        res = 0
        for c in range(ord("a"), ord("z") + 1):
            s = chr(c)
            res += int(d[s].sum(r) - d[s].sum(l - 1) > 0)

        print(res)