Yash is finally tired of computing the length of the longest Fibonacci-ish sequence. He now plays around with more complex things such as Fibonacci-ish potentials.
Fibonacci-ish potential of an array a i is computed as follows:
- Remove all elements j if there exists i < j such that a i = a j.
- Sort the remaining elements in ascending order, i.e. a 1 < a 2 < … < a n.
- Compute the potential as P(a) = a 1·F 1 + a 2·F 2 + … + a n·F n, where F i is the i-th Fibonacci number (see notes for clarification).
You are given an array a i of length n and q ranges from l j to r j. For each range j you have to compute the Fibonacci-ish potential of the array b i, composed using all elements of a i from l j to r j inclusive. Find these potentials modulo m.
Input
The first line of the input contains integers of n and m (1 ≤ n, m ≤ 30 000) — the length of the initial array and the modulo, respectively.
The next line contains n integers a i (0 ≤ a i ≤ 109) — elements of the array.
Then follow the number of ranges q (1 ≤ q ≤ 30 000).
Last q lines contain pairs of indices l i and r i (1 ≤ l i ≤ r i ≤ n) — ranges to compute Fibonacci-ish potentials.
Output
Print q lines, i-th of them must contain the Fibonacci-ish potential of the i-th range modulo m.
Example
input
5 10
2 1 2 1 2
2
2 4
4 5
output
3
3
Note
For the purpose of this problem define Fibonacci numbers as follows:
- F 1 = F 2 = 1.
- F n = F n - 1 + F n - 2 for each n > 2.
In the first query, the subarray [1,2,1] can be formed using the minimal set {1,2}. Thus, the potential of this subarray is 1*1+2*1=3.
#include <bits/stdc++.h>
using namespace std;
#define real REAL
const int N = 200010;
const int BLOCK = 250;
int m;
int from[N], to[N], res[N];
pair <int, int> ev[N];
int real[N], a[N];
int id[N];
inline bool cmp(int x, int y) {
int u = from[x] / BLOCK;
int v = from[y] / BLOCK;
if (u != v) {
return u < v;
}
return to[x] < to[y];
}
int a11[N], a12[N], a13[N];
int a21[N], a22[N], a23[N];
void build(int x, int l, int r) {
a11[x] = 1; a12[x] = 0; a13[x] = 0;
a21[x] = 0; a22[x] = 1; a23[x] = 0;
if (l < r) {
int y = (l + r) >> 1;
build(x + x, l, y);
build(x + x + 1, y + 1, r);
}
}
void modify(int x, int l, int r, int pos, int action) {
if (l == r) {
if (action == 1) {
a11[x] = 1; a12[x] = 1; a13[x] = real[pos];
a21[x] = 1; a22[x] = 0; a23[x] = 0;
} else {
a11[x] = 1; a12[x] = 0; a13[x] = 0;
a21[x] = 0; a22[x] = 1; a23[x] = 0;
}
return;
}
int y = (l + r) >> 1;
if (pos <= y) {
modify(x + x, l, y, pos, action);
} else {
modify(x + x + 1, y + 1, r, pos, action);
}
// gather
a11[x] = (a11[x + x] * a11[x + x + 1] + a12[x + x] * a21[x + x + 1]) % m;
a12[x] = (a11[x + x] * a12[x + x + 1] + a12[x + x] * a22[x + x + 1]) % m;
a21[x] = (a21[x + x] * a11[x + x + 1] + a22[x + x] * a21[x + x + 1]) % m;
a22[x] = (a21[x + x] * a12[x + x + 1] + a22[x + x] * a22[x + x + 1]) % m;
a13[x] = (a11[x + x] * a13[x + x + 1] + a12[x + x] * a23[x + x + 1] + a13[x + x]) % m;
a23[x] = (a21[x + x] * a13[x + x + 1] + a22[x + x] * a23[x + x + 1] + a23[x + x]) % m;
}
int t;
int have[N];
int OPS;
void add(int what) {
if (have[what] == 0) {
OPS++;
modify(1, 0, t - 1, what, 1);
}
have[what]++;
}
void del(int what) {
have[what]--;
if (have[what] == 0) {
OPS++;
modify(1, 0, t - 1, what, 0);
}
}
int main() {
int n;
scanf("%d %d", &n, &m);
for (int i = 0; i < n; i++) {
scanf("%d", &ev[i].first);
ev[i].second = i;
}
sort(ev, ev + n);
t = -1;
for (int i = 0; i < n; i++) {
if (i == 0 || ev[i].first != ev[i - 1].first) {
t++;
real[t] = ev[i].first % m;
}
a[ev[i].second] = t;
}
t++;
for (int i = 0; i < t; i++) {
have[i] = 0;
}
build(1, 0, t - 1);
int tt;
scanf("%d", &tt);
for (int qq = 0; qq < tt; qq++) {
scanf("%d %d", from + qq, to + qq);
from[qq]--; to[qq]--;
res[qq] = 0;
id[qq] = qq;
}
sort(id, id + tt, cmp);
int ll = from[0], rr = from[0] - 1;
OPS = 0;
for (int qq = 0; qq < tt; qq++) {
while (rr > to[id[qq]]) {
del(a[rr]);
rr--;
}
while (ll < from[id[qq]]) {
del(a[ll]);
ll++;
}
while (rr < to[id[qq]]) {
rr++;
add(a[rr]);
}
while (ll > from[id[qq]]) {
ll--;
add(a[ll]);
}
res[id[qq]] = a13[1];
// if ((qq + 1) % 500 == 0) cerr << qq+1 << " processed, OPS = " << OPS << endl;
}
for (int qq = 0; qq < tt; qq++) {
printf("%d\n", (res[qq] % m + m) % m);
}
// cerr << clock() << " ms" << endl;
return 0;
}