#include <bits/stdc++.h>
using namespace std;
namespace mine {
long long qread() {
  long long ans = 0, f = 1;
  char c = getchar();
  while (c < '0' or c > '9') {
    if (c == '-') f = -1;
    c = getchar();
  }
  while ('0' <= c and c <= '9') ans = ans * 10 + c - '0', c = getchar();
  return ans * f;
}
void write(long long num) {
  if (num < 0) putchar('-'), num = -num;
  if (num >= 10) write(num / 10);
  putchar('0' + num % 10);
}
void write1(long long num) {
  write(num);
  putchar(' ');
}
void write2(long long num) {
  write(num);
  putchar('\n');
}
template <typename T>
inline bool chmax(T &a, const T &b) {
  return a < b ? a = b, 1 : 0;
}
template <typename T>
inline bool chmin(T &a, const T &b) {
  return a > b ? a = b, 1 : 0;
}
long long gcd(long long x, long long y) { return y ? gcd(y, x % y) : x; }
bool IN(long long x, long long l, long long r) { return l <= x and x <= r; }
void gg1() {
  write2(-1);
  exit(0);
}
void gg2() {
  puts("No");
  exit(0);
}
const double eps = 1e-8;
const int INF = 0x3f3f3f3f;
const int MOD = 998244353;
int mm(const int x) { return x >= MOD ? x - MOD : x; }
template <typename T>
void add(T &x, const int &y) {
  x = (x + y >= MOD ? x + y - MOD : x + y);
}
long long qpower(long long x, long long e, int mod = MOD) {
  long long ans = 1;
  while (e) {
    if (e & 1) ans = ans * x % mod;
    x = x * x % mod;
    e >>= 1;
  }
  return ans;
}
long long invm(long long x) { return qpower(x, MOD - 2); }
const int N = 1e6 + 10;
struct Mat {
  int n, m;
  long long a[64][64];
  Mat() {
    memset(a, 0, sizeof a);
    n = m = 64;
  }
  friend Mat operator*(Mat a, Mat b) {
    Mat ret;
    ret.n = a.n, ret.m = b.m;
    assert(a.m == b.n);
    for (int k = (0), I = (a.m - 1); k <= I; k++)
      for (int i = (0), I = (a.n - 1); i <= I; i++)
        for (int j = (0), I = (b.m - 1); j <= I; j++)
          add(ret.a[i][j], a.a[i][k] * b.a[k][j] % MOD);
    return ret;
  }
} A[3], B[40];
bool ok[3][3];
int go[4][4][4];
int f[4], g[4];
int a[N];
vector<pair<int, int> > in[N];
void main() {
  int n = qread();
  for (int i = (1), I = (n); i <= I; i++) a[i] = qread();
  int m = qread();
  while (m--) {
    int x = qread(), y = qread();
    in[x].push_back({y, qread()});
  }
  for (int i = (1), I = (n); i <= I; i++)
    in[i].push_back({a[i] + 1, 0}), sort((in[i]).begin(), (in[i]).end());
  for (int i = (0), I = (2); i <= I; i++)
    for (int j = (0), I = (2); j <= I; j++) ok[i][j] = qread();
  for (int i = (0), I = (3); i <= I; i++)
    for (int j = (0), I = (3); j <= I; j++)
      for (int k = (0), I = (3); k <= I; k++) go[i][j][k] = i * 16 + j * 4 + k;
  for (int col = (0), I = (2); col <= I; col++)
    for (int a = (0), I = (3); a <= I; a++)
      for (int b = (0), I = (3); b <= I; b++)
        for (int c = (0), I = (3); c <= I; c++) {
          bool use[4];
          memset(use, 0, sizeof use);
          if (ok[col][0]) use[c] = 1;
          if (ok[col][1]) use[b] = 1;
          if (ok[col][2]) use[a] = 1;
          int sg = 3;
          for (int i = (2), I = (0); i >= I; i--)
            if (!use[i]) sg = i;
          add(A[col].a[go[a][b][c]][go[b][c][sg]], 1),
              add(B[0].a[go[a][b][c]][go[b][c][sg]], 1);
        }
  for (int i = (1), I = (30); i <= I; i++) B[i] = B[i - 1] * B[i - 1];
  f[0] = 1;
  for (int i = (1), I = (n); i <= I; i++) {
    Mat now;
    now.n = 1;
    now.a[0][go[1][2][3]] = 1;
    int lst = 0;
    for (auto t : in[i]) {
      int ln = t.first - lst - 1;
      lst = t.first;
      for (int j = (0), I = (30); j <= I; j++)
        if (ln & (1ll << (j))) now = now * B[j];
      if (lst <= a[i]) now = now * A[t.second - 1];
    }
    memset(g, 0, sizeof g);
    for (int lst = (0), I = (3); lst <= I; lst++)
      for (int a = (0), I = (3); a <= I; a++)
        for (int b = (0), I = (3); b <= I; b++)
          for (int c = (0), I = (3); c <= I; c++)
            add(g[lst ^ c], f[lst] * now.a[0][go[a][b][c]] % MOD);
    swap(f, g);
  }
  write(f[0]);
}
};  // namespace mine
signed main() {
  srand(time(0));
  mine::main();
}
