#include <bits/stdc++.h>
using namespace std;
const int DX[] = {-1, 0, 1, 0};
const int DY[] = {0, -1, 0, 1};
const int PRIME = 1000000007;
int n, m, q;
int cur_time = 1;
vector<long long> cur_x;
vector<bool> cats;
int event_type, event_x, event_y, event_time;
int coord_to_vindex(int r, int c) { return r * m + c; }
int coord_to_mindex(int r, int c) { return r * m * n + c; }
void dump_matrix(const vector<long long>& mat) {
  for (int i = (0); i <= (int(n * m) - 1); ++i) {
    for (int j = (0); j <= (int(n * m) - 1); ++j) {
      cerr << mat[coord_to_mindex(i, j)] << " ";
    }
    cerr << "\n";
  }
}
void dump_vector(const vector<long long>& vec) {
  for (int i = (0); i <= (int(n * m) - 1); ++i) {
    cerr << vec[i] << " ";
  }
  cerr << "\n";
}
vector<long long> make_matrix() {
  vector<long long> result(n * m * n * m);
  for (int i = (0); i <= (int(n) - 1); ++i) {
    for (int j = (0); j <= (int(m) - 1); ++j) {
      int matrix_row = coord_to_vindex(i, j);
      if (cats[matrix_row]) {
        continue;
      }
      result[coord_to_mindex(matrix_row, matrix_row)] = 1;
      for (int k = (0); k <= (int(4) - 1); ++k) {
        int ip = i + DY[k];
        int jp = j + DX[k];
        if (ip >= 0 && ip < n && jp >= 0 && jp < m) {
          int matrix_col = coord_to_vindex(ip, jp);
          result[coord_to_mindex(matrix_row, matrix_col)] = 1;
        }
      }
    }
  }
  return result;
}
vector<long long> mult_matrix_matrix(const vector<long long>& a,
                                     const vector<long long>& b) {
  vector<long long> result(a.size());
  for (int i = (0); i <= (int(m * n) - 1); ++i) {
    for (int j = (0); j <= (int(m * n) - 1); ++j) {
      for (int k = (0); k <= (int(m * n) - 1); ++k) {
        result[coord_to_mindex(i, j)] +=
            a[coord_to_mindex(i, k)] * b[coord_to_mindex(k, j)];
        result[coord_to_mindex(i, j)] %= PRIME;
      }
    }
  }
  return result;
}
void exponentiate_matrix(vector<long long>* mat, int e) {
  vector<vector<long long> > powers;
  powers.push_back(*mat);
  for (int i = 1; i <= e; i = 2 * i) {
    powers.push_back(mult_matrix_matrix(powers[powers.size() - 1],
                                        powers[powers.size() - 1]));
  }
  vector<long long> result(mat->size(), 0);
  for (int i = (0); i <= (int(n * m) - 1); ++i) {
    result[coord_to_mindex(i, i)] = 1;
  }
  for (int i = 0; e > 0; ++i) {
    if (e & 0x1) {
      result = mult_matrix_matrix(result, powers.at(i));
    }
    e >>= 1;
  }
  *mat = result;
}
vector<long long> mult_matrix_vector(const vector<long long>& mat,
                                     const vector<long long>& v) {
  vector<long long> result(v.size());
  for (int i = (0); i <= (int(v.size()) - 1); ++i) {
    for (int j = (0); j <= (int(v.size()) - 1); ++j) {
      result[i] += mat[coord_to_mindex(i, j)] * v[j];
      result[i] %= PRIME;
    }
  }
  return result;
}
void move_to_event() {
  vector<long long> mat = make_matrix();
  exponentiate_matrix(&mat, event_time - cur_time);
  cur_x = mult_matrix_vector(mat, cur_x);
  cur_time = event_time;
}
void apply_event() {
  int index = coord_to_vindex(event_x - 1, event_y - 1);
  if (event_type == 1) {
    cout << cur_x[index] << "\n";
  } else if (event_type == 2) {
    assert(cats[index] == false && "Cat appears twice?");
    cats[index] = true;
    cur_x[index] = 0;
  } else if (event_type == 3) {
    assert(cats[index] == true && "Cat disappears twice?");
    cats[index] = false;
  } else {
    assert(false && "weird event type");
  }
}
int main() {
  cin >> n >> m >> q;
  cur_x = vector<long long>(n * m, 0);
  cur_x[0] = 1;
  cats = vector<bool>(n * m, false);
  for (int i = (0); i <= (int(q) - 1); ++i) {
    cin >> event_type >> event_x >> event_y >> event_time;
    move_to_event();
    apply_event();
  }
  return 0;
}
