#include <bits/stdc++.h>
using namespace std;
const int MOD = 777777777;
const int maxn = 77778;
int g[3][3];
int n, m;
struct node {
  int l, r;
  int a[3][3];
} tree[maxn << 2];
void pushup(int rt) {
  for (int i = 0; i < 3; ++i) {
    for (int j = 0; j < 3; ++j) {
      tree[rt].a[i][j] = 0;
      for (int l = 0; l < 3; ++l) {
        for (int r = 0; r < 3; ++r) {
          if (!g[l][r]) continue;
          tree[rt].a[i][j] =
              (tree[rt].a[i][j] +
               (long long)tree[rt << 1].a[i][l] * tree[rt << 1 | 1].a[r][j]) %
              MOD;
        }
      }
    }
  }
}
void build(int l, int r, int rt) {
  tree[rt].l = l;
  tree[rt].r = r;
  if (l == r) {
    memset(tree[rt].a, 0, sizeof(tree[rt].a));
    for (int i = 0; i < 3; ++i) tree[rt].a[i][i] = 1;
    return;
  }
  int mid = l + r >> 1;
  build(l, mid, rt << 1);
  build(mid + 1, r, rt << 1 | 1);
  pushup(rt);
}
void update(int x, int rt, int val) {
  int l = tree[rt].l, r = tree[rt].r;
  if (l == r && l == x) {
    memset(tree[rt].a, 0, sizeof(tree[rt].a));
    if (val == -1) {
      for (int i = 0; i < 3; ++i) tree[rt].a[i][i] = 1;
    } else
      tree[rt].a[val][val] = 1;
    return;
  }
  int mid = l + r >> 1;
  if (x <= mid)
    update(x, rt << 1, val);
  else
    update(x, rt << 1 | 1, val);
  pushup(rt);
}
int main() {
  scanf("%d%d", &n, &m);
  for (int i = 0; i < 3; ++i)
    for (int j = 0; j < 3; ++j) scanf("%d", g[i] + j);
  build(1, n, 1);
  while (m--) {
    int u, v;
    scanf("%d%d", &u, &v);
    update(u, 1, v - 1);
    long long ans = 0;
    for (int i = 0; i < 3; ++i)
      for (int j = 0; j < 3; ++j) ans = (ans + tree[1].a[i][j]) % MOD;
    printf("%I64d\n", ans);
  }
  return 0;
}
