#include <bits/stdc++.h>
using namespace std;
int n, m, q;
int N;
int steps[5][2] = {{0, 0}, {1, 0}, {0, 1}, {-1, 0}, {0, -1}};
int ns = 5;
const int MOD = int(1e9) + 7;
inline int add(int a, int b) {
  return (a + b >= MOD) ? (a + b - MOD) : (a + b);
}
inline int sub(int a, int b) { return (a - b < 0) ? (a - b + MOD) : (a - b); }
inline void inc(int &a, int b) { a = add(a, b); }
inline int negate(int a) { return MOD - a; }
inline int mul(int a, int b) { return (a * 1ll * b) % MOD; }
const int MAX = 401;
typedef int mx[MAX][MAX];
typedef int row[MAX];
void mul(mx a, mx b, mx r) {
  memset(r, 0, sizeof(mx));
  for (size_t i = 0; i < N; i++)
    for (size_t j = 0; j < N; j++)
      for (size_t k = 0; k < N; k++)
        r[i][j] = add(r[i][j],
                      b[k][j] <= 0 || a[i][k] <= 0 ? 0 : mul(a[i][k], b[k][j]));
}
void mul(row a, mx b, row r) {
  memset(r, 0, sizeof(row));
  for (size_t j = 0; j < N; j++)
    for (size_t k = 0; k < N; k++)
      r[j] = add(r[j], b[k][j] <= 0 ? 0 : mul(a[k], b[k][j]));
}
void ones(mx a) {
  memset(a, 0, sizeof(mx));
  for (size_t i = 0; i < N; i++) a[i][i] = 1;
}
void binPow(mx a, int p, mx r) {
  ones(r);
  mx b;
  memcpy(b, a, sizeof(b));
  mx t;
  while (p) {
    if (p & 1) {
      mul(r, b, t);
      memcpy(r, t, sizeof(mx));
    }
    mul(b, b, t);
    memcpy(b, t, sizeof(mx));
    p >>= 1;
  }
}
int toIdx(int i, int j) { return i * m + j; }
pair<int, int> fromIdx(int idx) { return pair<int, int>(idx / m, idx % m); }
void composeG(mx g) {
  memset(g, 0, sizeof(mx));
  for (int i = 0; i < n; i++)
    for (int j = 0; j < m; j++) {
      int cellIdx = toIdx(i, j);
      for (int s = 0; s < ns; s++) {
        int ni = i + steps[s][0];
        int nj = j + steps[s][1];
        if (ni < 0 || ni >= n || nj < 0 || nj >= m) continue;
        int otherCellIdx = toIdx(ni, nj);
        g[cellIdx][otherCellIdx] = g[otherCellIdx][cellIdx] = 1;
      }
    }
}
void enable(mx g, int i, int j) {
  int cellIdx = toIdx(i, j);
  for (int s = 0; s < ns; s++) {
    int ni = i + steps[s][0];
    int nj = j + steps[s][1];
    if (ni < 0 || ni >= n || nj < 0 || nj >= m) continue;
    int otherCellIdx = toIdx(ni, nj);
    g[cellIdx][otherCellIdx] += 1;
    g[otherCellIdx][cellIdx] += 1;
  }
}
void disable(mx g, int i, int j) {
  int cellIdx = toIdx(i, j);
  for (int s = 0; s < ns; s++) {
    int ni = i + steps[s][0];
    int nj = j + steps[s][1];
    if (ni < 0 || ni >= n || nj < 0 || nj >= m) continue;
    int otherCellIdx = toIdx(ni, nj);
    g[cellIdx][otherCellIdx] -= 1;
    g[otherCellIdx][cellIdx] -= 1;
  }
}
void clear() {}
void solve() {
  N = n * m;
  row currentAns;
  memset(currentAns, 0, sizeof(row));
  currentAns[0] = 1;
  mx g;
  composeG(g);
  int time = 1;
  while (q--) {
    int type, x, y, t;
    scanf("%d%d%d%d", &type, &x, &y, &t);
    x--, y--;
    mx tg, mulMx;
    memcpy(tg, g, sizeof(mx));
    binPow(tg, t - time, mulMx);
    row tmp;
    mul(currentAns, mulMx, tmp);
    memcpy(currentAns, tmp, sizeof(row));
    time = t;
    if (type == 2)
      disable(g, x, y);
    else if (type == 3)
      enable(g, x, y);
    else
      printf("%d\n", currentAns[toIdx(x, y)]);
  }
}
int main() {
  while (scanf("%d%d%d", &n, &m, &q) == 3) {
    clear();
    solve();
  }
  return 0;
}
