#include <bits/stdc++.h>
using namespace std;
template <typename _T>
void Read(_T &x) {
  x = 0;
  char s = getchar();
  for (; s < '0' || s > '9'; s = getchar())
    ;
  for (; s >= '0' && s <= '9'; s = getchar()) x = x * 10 + s - '0';
}
template <typename _T>
void Write(_T x) {
  if (x >= 10) Write(x / 10);
  putchar(x % 10 + '0');
}
const int MAXN = 50000, MAXL = 2;
int Mod;
int Add(int x, int y) {
  x += y;
  return x >= Mod ? x - Mod : x;
}
int Sub(int x, int y) {
  x -= y;
  return x < 0 ? x + Mod : x;
}
int Mul(int x, int y) { return 1ll * x * y % Mod; }
struct Matrix {
  int n, m, a[MAXL + 2][MAXL + 2];
  Matrix operator*(const Matrix &x) const {
    Matrix Ans = {};
    Ans.n = n, Ans.m = x.m;
    for (int i = 1; i <= Ans.n; i++)
      for (int k = 1; k <= m; k++)
        for (int j = 1; j <= Ans.m; j++)
          Ans.a[i][j] = Add(Ans.a[i][j], Mul(a[i][k], x.a[k][j]));
    return Ans;
  }
  Matrix Quick_pow(Matrix x, long long po) {
    Matrix Ans = {};
    Ans.n = x.n, Ans.m = x.m;
    for (int i = 1; i <= Ans.n; i++) Ans.a[i][i] = 1;
    for (; po; po >>= 1, x = x * x)
      if (po & 1) Ans = Ans * x;
    return Ans;
  }
} Ans, p, I;
struct node {
  long long pos;
  int v;
  bool operator<(const node &oth) const { return pos < oth.pos; }
} upd[MAXN + 5];
int n, m, s[MAXN + 5];
long long k, pw[MAXN + 5], pos;
int chk1(int x) { return x == 0 ? n - 1 : x - 1; }
int chk2(int x) { return x == n ? 0 : x; }
vector<Matrix> fm;
struct pnode {
  int l, r;
  Matrix x;
};
struct Segment_Tree {
  pnode Tree[4 * MAXN + 5];
  void Build(int x, int l, int r) {
    Tree[x].l = l, Tree[x].r = r;
    if (l == r) {
      p.a[1][1] = s[l % n], p.a[2][1] = s[chk1(l % n)];
      Tree[x].x = p;
      return;
    }
    int Mid = (l + r) >> 1;
    Build(x << 1, l, Mid);
    Build(x << 1 | 1, Mid + 1, r);
    Tree[x].x = Tree[x << 1].x * Tree[x << 1 | 1].x;
  }
  Matrix Query(int x, int l, int r) {
    if (r < Tree[x].l || Tree[x].r < l) return I;
    if (l <= Tree[x].l && Tree[x].r <= r) return Tree[x].x;
    return Query(x << 1, l, r) * Query(x << 1 | 1, l, r);
  }
} Tree;
void Solve(int fir, long long pn) {
  if (pn <= 0) return;
  int ed = (n - (fir == 0 ? n : fir) + 1);
  if (ed > pn) {
    Ans = Ans * Tree.Query(1, fir, fir + pn - 1);
  } else {
    Ans = Ans * Tree.Query(1, n - ed + 1, n - 1);
    pn -= ed;
    Ans = Ans * p.Quick_pow(Tree.Tree[1].x, pn / n);
    Ans = Ans * Tree.Query(1, 0, pn - pn / n * n);
  }
}
int main() {
  I.n = 2, I.m = 2, I.a[1][1] = I.a[2][2] = 1;
  Read(k), Read(Mod);
  if (k == 0) return printf("0\n") & 0;
  if (k == 1) return printf("%d\n", 1 % Mod) & 0;
  Read(n);
  for (int i = 0; i < n; i++) Read(s[i]);
  Ans.n = 1, Ans.m = 2;
  Ans.a[1][1] = 1, Ans.a[1][2] = 0;
  p.n = 2, p.m = 2;
  p.a[1][2] = 1;
  Tree.Build(1, 0, n - 1);
  Read(m);
  for (int i = 1; i <= m; i++) Read(upd[i].pos), Read(upd[i].v);
  sort(upd + 1, upd + m + 1);
  long long lst = 1;
  for (int i = 1; i <= m; i++) {
    long long pos = upd[i].pos;
    int v = upd[i].v;
    if (pos > k - 1) break;
    Solve(lst % n, pos - lst);
    if (pos == k - 1) {
      int num = pos % n;
      p.a[1][1] = v, p.a[2][1] = s[chk1(num)];
      Ans = Ans * p;
    } else if (pos < k - 1) {
      int num = pos % n;
      long long sb = pos + 1;
      p.a[1][1] = v, p.a[2][1] = s[chk1(num)];
      fm.push_back(p);
      num = chk2(num + 1);
      sb++;
      p.a[1][1] = s[num], p.a[2][1] = v;
      fm.push_back(p);
      for (; upd[i + 1].pos == upd[i].pos + 1 && i <= m; i++) {
        fm.back().a[1][1] = upd[i + 1].v;
        num = chk2(num + 1);
        sb++;
        if (sb > k) {
          i++;
          goto there;
        }
        p.a[1][1] = s[num], p.a[2][1] = upd[i + 1].v;
        fm.push_back(p);
      }
    there:;
      for (int j = 0; j < fm.size(); j++) Ans = Ans * fm[j];
      fm.clear();
    }
    lst = upd[i].pos + 2;
  }
  Solve(lst % n, k - lst);
  printf("%d\n", Ans.a[1][1]);
  return 0;
}
