Buggy python submission (verdict: Time Limit Exceeded):
import sys
input = sys.stdin.buffer.readline
sys.setrecursionlimit(10 ** 7)


class BinaryIndexTree:  # 1-indexed
    def __init__(self, N):
        """
        INPUT
        N [int] -> 全部0で初期化
        N [list] -> そのまま初期化
        """
        if isinstance(N, int):
            self.N = N
            self.depth = N.bit_length()
            self.tree = [0] * (N + 1)
            self.elem = [0] * (N + 1)
        elif isinstance(N, list):
            self.N = len(N)
            self.depth = self.N.bit_length()
            self.tree = [0] + N
            self.elem = [0] + N
            self._init()
        else:
            raise "INVALID INPUT: input must be int or list"

    def _init(self):
        size = self.N
        for i in range(1, self.N):
            if i + (i & -i) > size:
                continue
            self.tree[i + (i & -i)] += self.tree[i]

    def add(self, i, x):
        self.elem[i] += x
        while i <= self.N:
            self.tree[i] += x
            i += i & -i

    def sum(self, i):
        res = 0
        while i > 0:
            res += self.tree[i]
            i -= i & -i
        return res

    def lower_bound(self, val):
        if val <= 0:
            return 0
        i = 0
        k = 1 << self.depth
        while k:
            if i + k <= self.N and self.tree[i + k] < val:
                val -= self.tree[i + k]
                i += k
            k >>= 1
        return i + 1


N, Q = map(int, input().split())
U = 5 * 10 ** 5 + 10

C = tuple(map(int, input().split()))
LR = []
for i in range(Q):
    l, r = map(int, input().split())
    LR.append((r, l, i))
LR.sort()

ans = [-1] * Q
pos = 0
bit = BinaryIndexTree(N + 5)
seen = [-1] * U
for i, c in enumerate(C, 1):
    if seen[c] != -1:
        bit.add(seen[c], -1)
    bit.add(i, 1)
    seen[c] = i
    while pos < Q and LR[pos][0] == i:
        r, l, j = LR[pos]
        ans[j] = bit.sum(r) - bit.sum(l - 1)
        pos += 1

print(*ans, sep="\n")

Fixed submission:
from collections import defaultdict
import sys
input = sys.stdin.buffer.readline
sys.setrecursionlimit(10 ** 7)


class BinaryIndexTree:  # 1-indexed
    def __init__(self, N):
        """
        INPUT
        N [int] -> 全部0で初期化
        N [list] -> そのまま初期化
        """
        if isinstance(N, int):
            self.N = N
            self.depth = N.bit_length()
            self.tree = [0] * (N + 1)
            self.elem = [0] * (N + 1)
        elif isinstance(N, list):
            self.N = len(N)
            self.depth = self.N.bit_length()
            self.tree = [0] + N
            self.elem = [0] + N
            self._init()
        else:
            raise "INVALID INPUT: input must be int or list"

    def _init(self):
        size = self.N
        for i in range(1, self.N):
            if i + (i & -i) > size:
                continue
            self.tree[i + (i & -i)] += self.tree[i]

    def add(self, i, x):
        self.elem[i] += x
        while i <= self.N:
            self.tree[i] += x
            i += i & -i

    def sum(self, i):
        res = 0
        while i > 0:
            res += self.tree[i]
            i -= i & -i
        return res

    def lower_bound(self, val):
        if val <= 0:
            return 0
        i = 0
        k = 1 << self.depth
        while k:
            if i + k <= self.N and self.tree[i + k] < val:
                val -= self.tree[i + k]
                i += k
            k >>= 1
        return i + 1


N, Q = map(int, input().split())
U = 5 * 10 ** 5 + 10

C = tuple(map(int, input().split()))
LR = [list() for _ in range(U)]
for i in range(Q):
    l, r = map(int, input().split())
    LR[r].append((l, i))

ans = [-1] * Q
bit = BinaryIndexTree(N + 5)
seen = defaultdict(int)
for i, c in enumerate(C, 1):
    if seen[c]:
        bit.add(seen[c], -1)
    bit.add(i, 1)
    seen[c] = i
    if LR[i]:
        R = bit.sum(i)
        for L, x in LR[i]:
            ans[x] = R - bit.sum(L - 1)


print(*ans, sep="\n")

Buggy python submission (verdict: Time Limit Exceeded):
class SegmentTree:
    def __init__(self, N, arr=None, op=None):
        """
        INPUT
        N: 配列のサイズ
        segment tree: 1-indexedで構築
        original array: 0-indexed
                 1
           2           3
         4    5     6     7
        8 9 10 11 12 13 14 15
        ---------------------
        0 1 2  3  4  5  6  7
        """
        self.N = N
        self.op = op
        self.tree = [set()] * (2 * N + 1)
        if arr is not None:
            self._build(arr)

    def _build(self, arr):
        op = self.op
        N = self.N
        for i, a in enumerate(arr, N):
            self.tree[i] = set([a])
        for i in reversed(range(1, N)):
            self.tree[i] = op(self.tree[i << 1], self.tree[i << 1 | 1])

    def update(self, i, x):
        """
        arr[i]の値をxに変更する
        i: 0-indexed
        """
        i += self.N
        op = self.op
        self.tree[i] = x
        while i > 1:
            i >>= 1
            self.tree[i] = op(self.tree[i << 1], self.tree[i << 1 | 1])

    def query(self, L, R):
        """
        L,R: 0-indexed
        半開区間[L,R)の累積演算した値を返す
        """
        op = self.op
        res = set()
        L += self.N
        R += self.N
        while L < R:
            if L & 1:
                res = op(res, self.tree[L])
                L += 1
            if R & 1:
                R -= 1
                res = op(res, self.tree[R])
            L >>= 1
            R >>= 1
        return len(res)


def union(a, b):
    return a | b


N, Q = map(int, input().split())
C = list(map(int, input().split()))
seg = SegmentTree(N, C, union)
for _ in range(Q):
    s, t = map(int, input().split())
    print(seg.query(s-1, t))

Fixed submission:
from collections import defaultdict
import sys
input = sys.stdin.buffer.readline
sys.setrecursionlimit(10 ** 7)


class BinaryIndexTree:  # 1-indexed
    def __init__(self, N):
        """
        INPUT
        N [int] -> 全部0で初期化
        N [list] -> そのまま初期化
        """
        if isinstance(N, int):
            self.N = N
            self.depth = N.bit_length()
            self.tree = [0] * (N + 1)
            self.elem = [0] * (N + 1)
        elif isinstance(N, list):
            self.N = len(N)
            self.depth = self.N.bit_length()
            self.tree = [0] + N
            self.elem = [0] + N
            self._init()
        else:
            raise "INVALID INPUT: input must be int or list"

    def _init(self):
        size = self.N
        for i in range(1, self.N):
            if i + (i & -i) > size:
                continue
            self.tree[i + (i & -i)] += self.tree[i]

    def add(self, i, x):
        self.elem[i] += x
        while i <= self.N:
            self.tree[i] += x
            i += i & -i

    def sum(self, i):
        res = 0
        while i > 0:
            res += self.tree[i]
            i -= i & -i
        return res

    def lower_bound(self, val):
        if val <= 0:
            return 0
        i = 0
        k = 1 << self.depth
        while k:
            if i + k <= self.N and self.tree[i + k] < val:
                val -= self.tree[i + k]
                i += k
            k >>= 1
        return i + 1


N, Q = map(int, input().split())
U = 5 * 10 ** 5 + 10

C = tuple(map(int, input().split()))
LR = [list() for _ in range(U)]
for i in range(Q):
    l, r = map(int, input().split())
    LR[r].append((l, i))

ans = [-1] * Q
bit = BinaryIndexTree(N + 5)
seen = defaultdict(int)
for i, c in enumerate(C, 1):
    if seen[c]:
        bit.add(seen[c], -1)
    bit.add(i, 1)
    seen[c] = i
    if LR[i]:
        R = bit.sum(i)
        for L, x in LR[i]:
            ans[x] = R - bit.sum(L - 1)


print(*ans, sep="\n")

Buggy python submission (verdict: Time Limit Exceeded):
from operator import or_
import sys
input = sys.stdin.buffer.readline
sys.setrecursionlimit(10 ** 7)


class SparseTable:
    def __init__(self, N, arr, op):
        self.N = N
        self.depth = N.bit_length()
        self.op = op
        self.arr = tuple(arr)
        self._build()

    def __call__(self, s, t):
        """
        [s, t)区間（0-indexed）での値を返す
        """
        i = (t - s).bit_length() - 1
        L = self.table[i][s]
        R = self.table[i][t - (1 << i)]
        return self.op(L, R)

    def _build(self):
        self.table = []
        self.table.append(self.arr)
        N = self.N
        for i in range(self.depth - 1):
            shift = 1 << i
            N -= shift
            t = tuple(self.op(self.table[-1][j], self.table[-1][j+shift])
                      for j in range(N))
            self.table.append(t)


N, Q = map(int, input().split())
C = [1 << (i-1) for i in map(int, input().split())] + [0]
sp = SparseTable(N+1, C, or_)
for _ in range(Q):
    s, t = map(int, input().split())
    b = bin(sp(s-1, t)).count("1")
    print(b)

Fixed submission:
from collections import defaultdict
import sys
input = sys.stdin.buffer.readline
sys.setrecursionlimit(10 ** 7)


class BinaryIndexTree:  # 1-indexed
    def __init__(self, N):
        """
        INPUT
        N [int] -> 全部0で初期化
        N [list] -> そのまま初期化
        """
        if isinstance(N, int):
            self.N = N
            self.depth = N.bit_length()
            self.tree = [0] * (N + 1)
            self.elem = [0] * (N + 1)
        elif isinstance(N, list):
            self.N = len(N)
            self.depth = self.N.bit_length()
            self.tree = [0] + N
            self.elem = [0] + N
            self._init()
        else:
            raise "INVALID INPUT: input must be int or list"

    def _init(self):
        size = self.N
        for i in range(1, self.N):
            if i + (i & -i) > size:
                continue
            self.tree[i + (i & -i)] += self.tree[i]

    def add(self, i, x):
        self.elem[i] += x
        while i <= self.N:
            self.tree[i] += x
            i += i & -i

    def sum(self, i):
        res = 0
        while i > 0:
            res += self.tree[i]
            i -= i & -i
        return res

    def lower_bound(self, val):
        if val <= 0:
            return 0
        i = 0
        k = 1 << self.depth
        while k:
            if i + k <= self.N and self.tree[i + k] < val:
                val -= self.tree[i + k]
                i += k
            k >>= 1
        return i + 1


N, Q = map(int, input().split())
U = 5 * 10 ** 5 + 10

C = tuple(map(int, input().split()))
LR = [list() for _ in range(U)]
for i in range(Q):
    l, r = map(int, input().split())
    LR[r].append((l, i))

ans = [-1] * Q
bit = BinaryIndexTree(N + 5)
seen = defaultdict(int)
for i, c in enumerate(C, 1):
    if seen[c]:
        bit.add(seen[c], -1)
    bit.add(i, 1)
    seen[c] = i
    if LR[i]:
        R = bit.sum(i)
        for L, x in LR[i]:
            ans[x] = R - bit.sum(L - 1)


print(*ans, sep="\n")