Language: C++

#pragma GCC optimize("Ofast,no-stack-protector,unroll-loops,fast-math,O3")
#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
#include <bits/stdc++.h>
#include <ext/rope>
#include <random>
#include <chrono>
#include <ext/pb_ds/assoc_container.hpp> 
#include <ext/pb_ds/tree_policy.hpp> 
 
#define file ""
 
#define all(x) x.begin(), x.end()
 
#define sc second
#define fr first
 
#define pb push_back
#define mp make_pair
 
#define pss pair<line*, line*>   
 
using namespace std;
using namespace __gnu_cxx;
using namespace __gnu_pbds; 
 
typedef long long ll;
typedef pair <int, int> pii;
typedef pair <ll, ll> pll;

template<typename T>
using ordered_set = tree<pair<int, int>, null_type,less<pair<int, int>>, rb_tree_tag, tree_order_statistics_node_update> ;
                                 
const ll inf = 1e18;
const int MOD = 1e9 + 7;
 
const int dx[] = {-1, +1, -2, +2, -2, +2, -1, +1};
const int dy[] = {-2, -2, -1, -1, +1, +1, +2, +2};
 
int const N = 4e5 + 5;
int const M = 1e8	;

int n, q;
map<int, int> last;
int a[N];

struct line{
	line *l, *r;
	int val;
	line (int sum) : l(nullptr), r(nullptr), val(sum) {}
	line (line *l, line *r) : l(l), r(r), val(0) {
	 	if (!l) val += l -> val;
	 	if (!r) val += r -> val;
	}
	line (line *v) {
	 	l = v -> l;
	 	r = v -> r;
	 	val = v -> val;
	}
} *t[N];

line* build(int l, int r) {
 	if (l == r) {
 	 	return new line(0);
 	}
 	int m = l + r >> 1;
 	return new line (build(l, m), build(m + 1, r));
}

int get(line* p, int ul, int ur, int l, int r) {
	if (l > ur || ul > r)
		return 0;
	if (l <= ul && ur <= r)
		return p -> val;
	int um = ul + ur >> 1;
	return get(p -> l, ul, um, l, r) + get(p -> r, um + 1, ur, l, r);
}

line* update(line* k, int l, int r, int pos, int vl) {
	if (l == r) {
		return new line(k -> val + vl);
	}
	int m = l + r >> 1;
	line* p = new line(k); 
	if (pos <= m) p -> l = update(k -> l, l, m, pos, vl);
	else p -> r = update(k -> r, m + 1, r, pos, vl);
	p -> val = p -> l -> val + p -> r -> val;
	return p;
}



int main() {                 
#ifdef Masq                                                         
  freopen(".in", 	"r", stdin);
  freopen(".out", "w", stdout);  
#endif
	ios_base :: sync_with_stdio(false);               
  cin.tie(nullptr);
  srand(time(nullptr));
 	cin >> n >> q;
 	for (int i = 1; i <= n; i++)
 		cin >> a[i];
 	t[0] = build(1, n);
 	for (int i = 1; i <= n; i++) {
 		t[i] = t[i - 1];
 	 	if (last[a[i]] != 0) t[i] = update(t[i], 1, n, last[a[i]], -1);
		t[i] = update(t[i], 1, n, i, +1);
		last[a[i]] = i;
 	}
 	while (q--) {   	
 		int l, r;
 		cin >> l >> r;
 		cout << get(t[r], 1, n, l, n) << endl;
 	}
 	return 0;                 
}

Compiler output:
In file included from /usr/include/c++/14/string:43,
                 from /usr/include/c++/14/bitset:52,
                 from /usr/include/x86_64-linux-gnu/c++/14/bits/stdc++.h:52,
                 from a.cc:3:
/usr/include/c++/14/bits/allocator.h: In destructor 'std::_Rb_tree<int, std::pair<const int, int>, std::_Select1st<std::pair<const int, int> >, std::less<int>, std::allocator<std::pair<const int, int> > >::_Rb_tree_impl<std::less<int>, true>::~_Rb_tree_impl()':
/usr/include/c++/14/bits/allocator.h:182:7: error: inlining failed in call to 'always_inline' 'std::allocator< <template-parameter-1-1> >::~allocator() noexcept [with _Tp = std::_Rb_tree_node<std::pair<const int, int> >]': target specific option mismatch
  182 |       ~allocator() _GLIBCXX_NOTHROW { }
      |       ^
In file included from /usr/include/c++/14/map:62,
                 from /usr/include/x86_64-linux-gnu/c++/14/bits/stdc++.h:152:
/usr/include/c++/14/bits/stl_tree.h:658:16: note: called from here
  658 |         struct _Rb_tree_impl
      |                ^~~~~~~~~~~~~