#include <bits/stdc++.h>
using namespace std;
const int MOD = 998244353;
template <class T>
struct modular {
  T val;
  explicit operator T() const { return val; }
  modular() { val = 0; }
  modular(const long long& v) {
    val = (-MOD <= v && v <= MOD) ? v : v % MOD;
    if (val < 0) val += MOD;
  }
  friend ostream& operator<<(ostream& os, const modular& a) {
    return os << a.val;
  }
  friend bool operator==(const modular& a, const modular& b) {
    return a.val == b.val;
  }
  friend bool operator!=(const modular& a, const modular& b) {
    return !(a == b);
  }
  friend bool operator<(const modular& a, const modular& b) {
    return a.val < b.val;
  }
  modular operator-() const { return modular(-val); }
  modular& operator+=(const modular& m) {
    if ((val += m.val) >= MOD) val -= MOD;
    return *this;
  }
  modular& operator-=(const modular& m) {
    if ((val -= m.val) < 0) val += MOD;
    return *this;
  }
  modular& operator*=(const modular& m) {
    val = (long long)val * m.val % MOD;
    return *this;
  }
  friend modular pow(modular a, long long p) {
    modular ans = 1;
    for (; p; p /= 2, a *= a)
      if (p & 1) ans *= a;
    return ans;
  }
  friend modular inv(const modular& a) { return pow(a, MOD - 2); }
  modular& operator/=(const modular& m) { return (*this) *= inv(m); }
  friend modular operator+(modular a, const modular& b) { return a += b; }
  friend modular operator-(modular a, const modular& b) { return a -= b; }
  friend modular operator*(modular a, const modular& b) { return a *= b; }
  friend modular operator/(modular a, const modular& b) { return a /= b; }
};
template <class T>
struct vec {
  int n;
  vector<T> d;
  vec(int _n) : n(_n) { d = vector<T>(n); }
  vec() : vec(0) {}
  int operator*(const vec& v) {
    assert(n == v.n);
    int ret = 0;
    for (int i = 0; i < n; ++i) ret += d[i] * v.d[i];
    return ret;
  }
  vec& operator+=(const vec& v) {
    assert(n == v.n);
    for (int i = 0; i < n; ++i) d[i] += v.d[i];
    return *this;
  }
  vec& operator-=(const vec& v) {
    assert(n == v.n);
    for (int i = 0; i < n; ++i) d[i] -= v.d[i];
    return *this;
  }
  vec operator+(const vec& v) { return vec(*this) += v; }
  vec operator-(const vec& v) { return vec(*this) -= v; }
};
template <class T>
struct mat {
  int r, c;
  vector<vector<T>> d;
  mat(int _r, int _c) : r(_r), c(_c) { d.assign(r, vector<T>(c)); }
  mat() : mat(0, 0) {}
  mat(const vector<vector<T>>& _d) : r(_d.size()), c(_d[0].size()) { d = _d; }
  mat& operator+=(const mat& m) {
    assert(r == m.r && c == m.c);
    for (int i = 0; i < r; ++i)
      for (int j = 0; j < c; ++j) d[i][j] += m.d[i][j];
    return *this;
  }
  mat& operator-=(const mat& m) {
    assert(r == m.r && c == m.c);
    for (int i = 0; i < r; ++i)
      for (int j = 0; j < c; ++j) d[i][j] -= m.d[i][j];
    return *this;
  }
  mat operator*(const mat& m) {
    assert(c == m.r);
    mat x(r, m.c);
    for (int i = 0; i < r; ++i)
      for (int j = 0; j < c; ++j)
        for (int k = 0; k < m.c; ++k) x.d[i][k] += d[i][j] * m.d[j][k];
    return x;
  }
  mat operator+(const mat& m) { return mat(*this) += m; }
  mat operator-(const mat& m) { return mat(*this) -= m; }
  mat operator*=(const mat& m) { return *this = (*this) * m; }
};
template <class T>
vec<T> pr(mat<T> m, vec<T> v) {
  assert(m.c == v.n);
  vec<T> ret(m.r);
  for (int i = 0; i < m.r; ++i)
    for (int j = 0; j < m.c; ++j) ret.d[i] += m.d[i][j] * v.d[j];
  return ret;
}
mat<modular<int>> T(64, 64);
mat<modular<int>> tpow[30];
vec<modular<int>> dp;
int F[3][3];
int grundy(int r1, int r2, int r3, int c) {
  int g[4] = {0, 0, 0, 0};
  if (F[c][0]) g[r3] = 1;
  if (F[c][1]) g[r2] = 1;
  if (F[c][2]) g[r1] = 1;
  int gn = 0;
  while (g[gn]) gn++;
  return gn;
}
void extend(int c) {
  vec<modular<int>> ret(64);
  for (int r1 = 0; r1 < 4; ++r1)
    for (int r2 = 0; r2 < 4; ++r2)
      for (int r3 = 0; r3 < 4; ++r3) {
        int g = grundy(r1, r2, r3, c);
        ret.d[r2 * 16 + r3 * 4 + g] += dp.d[r1 * 16 + r2 * 4 + r3];
      }
  dp = ret;
}
void fill(int j) {
  for (int k = 0; k < 30; ++k)
    if (j & (1 << k)) dp = pr(tpow[k], dp);
}
int main() {
  ios_base::sync_with_stdio(false);
  cin.tie(NULL);
  int n;
  cin >> n;
  int a[n];
  for (int i = 0; i < n; ++i) cin >> a[i];
  vector<pair<int, int>> b[n];
  int m;
  cin >> m;
  for (int i = 0; i < m; ++i) {
    int x, y, c;
    cin >> x >> y >> c;
    b[x - 1].push_back(make_pair(y, c - 1));
  }
  for (int i = 0; i < 3; ++i)
    for (int j = 0; j < 3; ++j) cin >> F[i][j];
  for (int i = 0; i < n; ++i) sort(b[i].begin(), b[i].end());
  for (int r1 = 0; r1 < 4; ++r1)
    for (int r2 = 0; r2 < 4; ++r2)
      for (int r3 = 0; r3 < 4; ++r3)
        for (int c = 0; c < 3; ++c) {
          int g = grundy(r1, r2, r3, c);
          T.d[r2 * 16 + r3 * 4 + g][r1 * 16 + r2 * 4 + r3] += 1;
        }
  tpow[0] = T;
  for (int i = 1; i < 30; ++i) tpow[i] = tpow[i - 1] * tpow[i - 1];
  modular<int> ret[4];
  ret[0] = 1;
  for (int i = 0; i < n; ++i) {
    dp = vec<modular<int>>(64);
    dp.d[3 * 16 + 3 * 4 + 3] += 1;
    int lst = 0;
    for (auto& cur : b[i]) {
      fill(cur.first - 1 - lst);
      extend(cur.second);
      lst = cur.first;
    }
    if (lst < a[i]) fill(a[i] - lst);
    modular<int> tot[4];
    for (int j = 0; j < 64; ++j) tot[j % 4] += dp.d[j];
    modular<int> ncur[4];
    for (int pp = 0; pp < 4; ++pp)
      for (int qq = 0; qq < 4; ++qq) ncur[pp ^ qq] += ret[pp] * tot[qq];
    swap(ret, ncur);
  }
  cout << ret[0] << endl;
  return 0;
}
