#include <bits/stdc++.h>
using namespace std;
struct InputReader {
  char buf[1048576];
  int p;
  inline InputReader() { p = 1048576; }
  inline void Flush() {
    p = 0;
    fread(buf, 1, 1048576, stdin);
  }
  inline char C() {
    if (p >= 1048576) Flush();
    return buf[p++];
  }
  inline char Readnum() {
    char ch = C();
    while (!isdigit(ch) && ch != '-') ch = C();
    return ch;
  }
  inline void Readalpha(char &c) {
    c = C();
    while (!isalpha(c)) c = C();
  }
  int operator()() {
    int ans = 0, fu = 1;
    char ch = Readnum();
    if (ch == '-') fu = -1, ch = C();
    while (ch >= '0' && ch <= '9') {
      ans = ans * 10 + ch - '0';
      ch = C();
    }
    return ans * fu;
  }
  long long Readll() {
    long long ans = 0LL, fu = 1LL;
    char ch = Readnum();
    if (ch == '-') fu = -1LL, ch = C();
    while (ch >= '0' && ch <= '9') {
      ans = ans * 10LL + ch - '0';
      ch = C();
    }
    return ans * fu;
  }
  inline void Readstring(string &x) {
    x.clear();
    char ch = C();
    while (!isdigit(ch) && !isalpha(ch) && ch != '#' && ch != '.') ch = C();
    while (isdigit(ch) || isalpha(ch) || ch == '#' || ch == '.') {
      x += ch;
      ch = C();
    }
  }
  inline void Readchstring(char s[]) {
    int len = 0;
    char ch = C();
    while (!isdigit(ch) && !isalpha(ch)) ch = C();
    while (isdigit(ch) || isalpha(ch)) {
      s[len++] = ch;
      ch = C();
    }
    s[len] = '\0';
  }
  inline void Specialread(char &c) {
    c = C();
    while (!isdigit(c) && !isalpha(c) && c != '#' && c != '.' && c != '=' &&
           c != 'B')
      c = C();
  }
} In;
inline void Read(int &x) { x = In(); }
inline void Read(int &x, int &y) {
  x = In();
  y = In();
}
inline void Read(int &x1, int &x2, int &x3) {
  x1 = In();
  x2 = In();
  x3 = In();
}
inline void Read(int &x1, int &x2, int &x3, int &x4) {
  x1 = In();
  x2 = In();
  x3 = In();
  x4 = In();
}
inline void Read(long long &x) { x = In.Readll(); }
inline void Read(long long &x, long long &y) {
  x = In.Readll();
  y = In.Readll();
}
inline void Read(long long &x1, long long &x2, long long &x3) {
  x1 = In.Readll();
  x2 = In.Readll();
  x3 = In.Readll();
}
inline void Read(long long &x1, long long &x2, long long &x3, long long &x4) {
  x1 = In.Readll();
  x2 = In.Readll();
  x3 = In.Readll();
  x4 = In.Readll();
}
template <typename T>
void Read(T a[], int st, int ed) {
  for (int(i) = (st); (i) <= (ed); ++(i)) Read(a[i]);
}
inline void FILEIO() {}
inline void FILEIO(string pname) {
  freopen((pname + ".in").c_str(), "r", stdin);
  freopen((pname + ".out").c_str(), "w", stdout);
}
inline void FILEIO_OICONTEST(string pname) {
  freopen((pname + ".in").c_str(), "r", stdin);
  freopen((pname + ".out").c_str(), "w", stdout);
}
void Printtime() {}
void END() {
  Printtime();
  exit(0);
}
template <typename T>
void END(T mes) {
  cout << mes << endl;
  END();
}
template <typename T>
void Print(T a[], int s, int t, char sp = ' ', char ed = '\n') {
  if (s > t) return;
  for (int i = s; i < t; i++) cout << a[i] << sp;
  cout << a[t] << ed;
  cout.flush();
}
template <typename T>
void Print(T a, int s = 0, int t = -1, char sp = ' ', char ed = '\n') {
  if (t == -1) t = a.size() - 1;
  for (int i = s; i <= t; i++) cout << a[i] << sp;
  cout << ed;
  cout.flush();
}
mt19937 Rand(0xe38195e38293);
template <typename T>
T Mymo(const T &x) {
  return x >= (998244353LL) ? x - (998244353LL) : x;
}
template <typename T>
void Mymod(T &x) {
  x = x >= (998244353LL) ? x - (998244353LL) : x;
}
inline long long Pow(long long a, long long b,
                     const long long p = (998244353LL)) {
  long long ret = 1;
  for (; b; a = a * a % p, b >>= 1LL)
    if (b & 1LL) ret = ret * a % p;
  return ret;
}
inline long long Inv(long long a, const long long p = (998244353LL)) {
  return Pow(a, p - 2LL, p);
}
inline long long Frac(const long long x) {
  long long ret = 1;
  for (int(i) = 1; (i) <= (x); ++(i)) ret = ret * i % (998244353LL);
  return ret;
}
namespace io {
const int SIZE = (1 << 20) + 1;
char ibuf[SIZE], *iS, *iT, obuf[SIZE], *oS = obuf, *oT = oS + SIZE - 1, c,
                                       qu[55];
int f, qr;
inline void Flush() {
  fwrite(obuf, 1, oS - obuf, stdout);
  oS = obuf;
}
inline void Putc(char x) {
  *oS++ = x;
  if (oS == oT) Flush();
}
template <class I>
inline void Print(I x) {
  if (!x) Putc('0');
  if (x < 0) {
    Putc('-');
    x = -x;
  }
  while (x) {
    qu[++qr] = x % 10 + '0';
    x /= 10;
  }
  while (qr) Putc(qu[qr--]);
}
struct Flusher_ {
  ~Flusher_() { Flush(); }
} io_flusher_;
}  // namespace io
const int MAXN = 1024;
vector<int> Mul(const vector<vector<int>> &a, const vector<int> &b) {
  int n = a.size(), m = b.size();
  vector<int> c(m);
  for (int(i) = 0; (i) < (n); ++(i))
    for (int(j) = 0; (j) < (m); ++(j))
      c[i] = (c[i] + 1LL * b[j] * a[i][j]) % (998244353LL);
  return c;
}
vector<vector<int>> Add(const vector<vector<int>> &a,
                        const vector<vector<int>> &b) {
  int n = a.size(), m = a[0].size();
  assert(b.size() == n);
  assert(b[0].size() == m);
  vector<vector<int>> c(n, vector<int>(m, 0));
  for (int(i) = 0; (i) < (n); ++(i))
    for (int(j) = 0; (j) < (m); ++(j)) c[i][j] = Mymo(a[i][j] + b[i][j]);
  return c;
}
vector<vector<int>> Mul(const vector<vector<int>> &a,
                        const vector<vector<int>> &b) {
  int x = a.size(), y = a[0].size(), z = b[0].size();
  assert(b.size() == y);
  vector<vector<int>> c(x, vector<int>(z, 0));
  for (int(i) = 0; (i) < (x); ++(i))
    for (int(j) = 0; (j) < (y); ++(j))
      for (int(k) = 0; (k) < (z); ++(k))
        c[i][k] = (c[i][k] + 1LL * a[i][j] * b[j][k]) % (998244353LL);
  return c;
}
vector<vector<int>> Pow(vector<vector<int>> a, int b) {
  int n = a.size();
  assert(a[0].size() == n);
  vector<vector<int>> c(n, vector<int>(n, 0));
  for (int(i) = 0; (i) < (n); ++(i)) c[i][i] = 1;
  while (b) {
    if (b & 1) c = Mul(c, a);
    if (b >>= 1) a = Mul(a, a);
  }
  return c;
}
int n, a[MAXN], m;
vector<pair<int, int>> cols[MAXN];
int can[3][3];
inline void Readin() {
  Read(n);
  Read(a, 0, n - 1);
  Read(m);
  for (int(i) = 1; (i) <= (m); ++(i)) {
    int which;
    Read(which);
    ;
    int pos;
    Read(pos);
    ;
    ;
    int col;
    Read(col);
    ;
    ;
    --which;
    --pos;
    --col;
    cols[which].push_back({pos, col});
  }
  for (int(i) = 0; (i) < (n); ++(i)) sort(cols[i].begin(), cols[i].end());
  for (int(i) = 0; (i) < (3); ++(i))
    for (int(j) = 0; (j) < (3); ++(j)) Read(can[i][j]);
}
inline vector<int> Decode(int x) { return {x >> 4, (x >> 2) & 3, x & 3}; }
inline int Encode(vector<int> x) { return x[0] << 4 | x[1] << 2 | x[2]; }
vector<vector<int>> colmat[3], fullmat(64, vector<int>(64, 0)), fullpow[32];
vector<vector<int>> CalcColMat(int color) {
  vector<vector<int>> ret(64, vector<int>(64, 0));
  for (int(bef) = 0; (bef) < (64); ++(bef)) {
    vector<int> r = Decode(bef);
    bool apped[4] = {0, 0, 0, 0};
    if (can[color][0]) apped[r[0]] = 1;
    if (can[color][1]) apped[r[1]] = 1;
    if (can[color][2]) apped[r[2]] = 1;
    int aft_sg = !apped[0] ? 0 : !apped[1] ? 1 : !apped[2] ? 2 : 3;
    int aft = Encode({aft_sg, r[0], r[1]});
    ++ret[aft][bef];
  }
  return ret;
}
void InitTran() {
  for (int(i) = 0; (i) < (3); ++(i)) {
    colmat[i] = CalcColMat(i);
    fullmat = Add(fullmat, colmat[i]);
  }
  fullpow[0] = fullmat;
  for (int(i) = 1; (i) <= (31); ++(i))
    fullpow[i] = Mul(fullpow[i - 1], fullpow[i - 1]);
}
vector<int> PowMul(int b, vector<int> v) {
  for (int(i) = (0); (i) <= (30); ++(i)) {
    if (b & 1) v = Mul(fullpow[i], v);
    b >>= 1;
  }
  return v;
}
int dp[MAXN][4];
void Dp() {
  dp[0][0] = 1;
  for (int(i) = 0; (i) < (n); ++(i)) {
    vector<int> t(64, 0);
    t[Encode({3, 3, 3})] = 1;
    int last = 0;
    for (auto [pos, col] : cols[i]) {
      t = PowMul(pos - last, t);
      t = Mul(colmat[col], t);
      last = pos + 1;
    }
    t = PowMul(a[i] - last, t);
    for (int(j) = 0; (j) < (4); ++(j))
      for (int(k) = 0; (k) < (64); ++(k)) {
        int sg = Decode(k)[0];
        dp[i + 1][j ^ sg] =
            (dp[i + 1][j ^ sg] + 1LL * dp[i][j] * t[k]) % (998244353LL);
      }
  }
}
int main() {
  FILEIO();
  Readin();
  InitTran();
  Dp();
  cout << dp[n][0] << endl;
  END();
}
