Fibonotci

Fibonotci sequence is an integer recursive sequence defined by the recurrence relation Fn = sn - 1·Fn - 1 + sn - 2·Fn - 2 with F0 = 0, F1 = 1

Sequence s is an infinite and almost cyclic sequence with a cycle of length N. A sequence s is called almost cyclic with a cycle of length N if , for i ≥ N, except for a finite number of values s i, for which  ( i ≥ N).

Following is an example of an almost cyclic sequence with a cycle of length 4:s = (5,3,8,11,5,3,7,11,5,3,8,11,…)

Notice that the only value of s for which the equality  does not hold is s 6 ( s 6 = 7 and s 2 = 8). You are given s 0, s 1, …s N - 1 and all the values of sequence s for which  ( i ≥ N).

Find .

Input

The first line contains two numbers K and P. The second line contains a single number N. The third line contains N numbers separated by spaces, that represent the first N numbers of the sequence s. The fourth line contains a single number M, the number of values of sequence s for which . Each of the following M lines contains two numbers j and v, indicating that  and s j = v. All j-s are distinct.

  • 1 ≤ N, M ≤ 50000
  • 0 ≤ K ≤ 1018
  • 1 ≤ P ≤ 109
  • 1 ≤ s i ≤ 109, for all i = 0, 1, …N - 1
  • N ≤ j ≤ 1018
  • 1 ≤ v ≤ 109
  • All values are integers

Output

Output should contain a single integer equal to .

Examples

input

10 8
3
1 2 1
2
7 3
5 4

output

4

Solution:

#include <bits/stdc++.h>

using namespace std;

const int N = 400010;

int n;
int md;

inline void add(int &a, int b) {
a += b;
if (a >= md) {
a -= md;
}
}

inline int mul(int a, int b) {
return (long long) a * b % md;
}

struct Matrix {
int a[2][2];

Matrix(int diag = 1) {
a[0][0] = diag;
a[0][1] = 0;
a[1][0] = 0;
a[1][1] = diag;
}
};

inline Matrix mul(Matrix &a, Matrix b) {
Matrix c(0);
for (int i = 0; i < 2; i++) {
    for (int j = 0; j < 2; j++) {
      c.a[i][j] = ((long long)a.a[i][0] * b.a[0][j] + (long long)a.a[i][1] * b.a[1][j]) % md;
    }
  }
  return c;
}

inline Matrix power(Matrix a, long long b) {
  Matrix res(1);
  while (b > 0) {
if (b & 1) {
res = mul(res, a);
}
a = mul(a, a);
b >>= 1;
}
return res;
}

int s[N], value[N];
long long pos[N];
Matrix tree[N];

void build(int x, int l, int r) {
if (l < r) {
    int y = (l + r) >> 1;
build(x + x, l, y);
build(x + x + 1, y + 1, r);
tree[x] = mul(tree[x + x], tree[x + x + 1]);
} else {
tree[x] = Matrix(0);
tree[x].a[1][0] = 1;
tree[x].a[0][1] = s[(l + n - 2) % n];
tree[x].a[1][1] = s[(l + n - 1) % n];
}
}

Matrix get(int x, int l, int r, int ll, int rr) {
if (r < ll || rr < l || ll > rr) {
return Matrix(1);
}
if (ll <= l && r <= rr) {
    return tree[x];
  }
  int y = (l + r) >> 1;
Matrix res(1);
if (ll <= y) {
    res = get(x + x, l, y, ll, rr);
  }
  if (rr > y) {
res = mul(res, get(x + x + 1, y + 1, r, ll, rr));
}
return res;
}

map <long long, int> mp;

inline void proceed(Matrix &res, long long pos) {
Matrix other(0);
other.a[1][0] = 1;
if (mp.find(pos - 2) == mp.end()) {
other.a[0][1] = s[(pos - 2 + n) % n];
} else {
other.a[0][1] = mp[pos - 2];
}
if (mp.find(pos - 1) == mp.end()) {
other.a[1][1] = s[(pos - 1 + n) % n];
} else {
other.a[1][1] = mp[pos - 1];
}
res = mul(res, other);
}

int main() {
long long k;
scanf("%I64d %d", &k, &md);
if (md == 1) {
printf("%d\n", 0);
return 0;
}
if (k == 0) {
printf("%d\n", 0 % md);
return 0;
}
if (k == 1) {
printf("%d\n", 1 % md);
return 0;
}
scanf("%d", &n);
for (int i = 0; i < n; i++) {
    scanf("%d", s + i);
    s[i] %= md;
  }
  build(1, 0, n - 1);
  Matrix all = tree[1];
  vector <long long> special;
int m;
scanf("%d", &m);
mp.clear();
for (int i = 0; i < m; i++) {
    scanf("%I64d %d", pos + i, value + i);
    value[i] %= md;
    special.push_back(pos[i] + 1);
    special.push_back(pos[i] + 2);
    mp[pos[i]] = value[i];
  }
  special.push_back(k);
  sort(special.begin(), special.end());
  special.resize(unique(special.begin(), special.end()) - special.begin());
  while (!special.empty() && special.back() > k) {
special.pop_back();
}
Matrix res(1);
long long cur = 1;
for (int id = 0; id < (int)special.size(); id++) {
    long long nxt = special[id];
    long long from = cur + 1;
    long long to = nxt - 1;
    if (from <= to) {
      if (from / n == to / n) {
        res = mul(res, get(1, 0, n - 1, from % n, to % n));
      } else {
        res = mul(res, get(1, 0, n - 1, from % n, n - 1));
        res = mul(res, power(all, to / n - from / n - 1));
        res = mul(res, get(1, 0, n - 1, 0, to % n));
      }
    }
    proceed(res, nxt);
    cur = nxt;
  }
  printf("%d\n", res.a[1][1]);
  return 0;
}