#include <bits/stdc++.h>
using namespace std;
struct matrix {
  int g[2][2];
};
matrix tree[300000];
matrix tmp, result;
struct query {
  long long x;
  int y, z;
  inline bool operator<(const query t) const {
    if (x != t.x)
      return x < t.x;
    else
      return y < t.y;
  }
};
query p[200000];
int g[100000];
int i, j, k, l, n, o, w, y;
long long m, t, x;
inline matrix operator*(const matrix &x, const matrix &y) {
  matrix z;
  for (int i = 0; i < 2; i++)
    for (int j = 0; j < 2; j++) z.g[i][j] = 0;
  for (int i = 0; i < 2; i++)
    for (int j = 0; j < 2; j++)
      for (int k = 0; k < 2; k++)
        z.g[i][j] = (z.g[i][j] + 1LL * x.g[i][k] * y.g[k][j]) % o;
  return z;
}
inline void power(long long m) {
  if (m == 1)
    tmp = tree[1];
  else {
    power(m / 2);
    tmp = tmp * tmp;
    if (m & 1) tmp = tmp * tree[1];
  }
  return;
}
inline void buildtree(int l, int r, int node) {
  if (l == r)
    tree[node].g[1][0] = 1, tree[node].g[0][1] = g[l] % o,
    tree[node].g[1][1] = g[l + 1] % o;
  else {
    int mid = (l + r) >> 1;
    buildtree(l, mid, node << 1);
    buildtree(mid + 1, r, node << 1 | 1);
    tree[node] = tree[node << 1] * tree[node << 1 | 1];
  }
  return;
}
inline void inserttree(int l, int r, int x, int y, int z, int node) {
  if (l == r)
    if (!z)
      tree[node].g[0][1] = y % o;
    else
      tree[node].g[1][1] = y % o;
  else {
    int mid = (l + r) >> 1;
    if (x <= mid)
      inserttree(l, mid, x, y, z, node << 1);
    else
      inserttree(mid + 1, r, x, y, z, node << 1 | 1);
    tree[node] = tree[node << 1] * tree[node << 1 | 1];
  }
  return;
}
inline void emptree(int l, int r, int x, int node) {
  if (l == r)
    tree[node].g[0][0] = 1, tree[node].g[0][1] = 0, tree[node].g[1][0] = 0,
    tree[node].g[1][1] = 1;
  else {
    int mid = (l + r) >> 1;
    if (x <= mid)
      emptree(l, mid, x, node << 1);
    else
      emptree(mid + 1, r, x, node << 1 | 1);
    tree[node] = tree[node << 1] * tree[node << 1 | 1];
  }
  return;
}
int main() {
  scanf("%I64d%d", &m, &o);
  if (m == 0) {
    printf("0");
    return 0;
  }
  if (m == 1) {
    printf("%d", 1 % o);
    return 0;
  }
  m--;
  scanf("%d", &n);
  for (i = 1; i <= n; i++) scanf("%d", &g[i]);
  g[n + 1] = g[1];
  buildtree(1, n, 1);
  result.g[0][1] = 1;
  scanf("%d", &w);
  for (i = 1; i <= w; i++) {
    scanf("%I64d%d", &x, &y);
    if (x <= m) k++, p[k] = (query){x, y, 1};
    if (x + 1 <= m) k++, p[k] = (query){x + 1, y, 0};
  }
  k++, p[k] = (query){m, 1000000001, 1};
  sort(p + 1, p + k + 1);
  for (i = 1, t = 0; i <= k; i = j) {
    for (j = i; (j <= k) && ((p[i].x - 1) / n == (p[j].x - 1) / n); j++)
      ;
    if ((p[i].x - 1) / n > t)
      power((p[i].x - 1) / n - t), result = result * tmp;
    t = (p[i].x - 1) / n + 1;
    if (j == k + 1)
      for (l = (m - 1) % n + 2; l <= n; l++) emptree(1, n, l, 1);
    for (l = i; (l < j) && (l < k); l++)
      inserttree(1, n, (p[l].x - 1) % n + 1, p[l].y, p[l].z, 1);
    result = result * tree[1];
    for (l = i; (l < j) && (l < k); l++)
      if (p[l].z)
        inserttree(1, n, (p[l].x - 1) % n + 1, g[(p[l].x) % n + 1], p[l].z, 1);
      else
        inserttree(1, n, (p[l].x - 1) % n + 1, g[(p[l].x - 1) % n + 1], p[l].z,
                   1);
  }
  printf("%d", result.g[0][1]);
  return 0;
}
