#include <bits/stdc++.h>
using namespace std;
struct query {
  int type, row, col, val;
};
vector<query> queries;
vector<vector<int>> matrix;
int main() {
  int n, m, q;
  cin >> n >> m >> q;
  queries.resize(q);
  for (int i = 0; i < q; i++) {
    cin >> queries[i].type;
    switch (queries[i].type) {
      case 1:
        cin >> queries[i].row;
        queries[i].row--;
        break;
      case 2:
        cin >> queries[i].col;
        queries[i].col--;
        break;
      case 3:
        cin >> queries[i].row;
        queries[i].row--;
        cin >> queries[i].col;
        queries[i].col--;
        cin >> queries[i].val;
        break;
    }
  }
  reverse(queries.begin(), queries.end());
  matrix.resize(n);
  for (int i = 0; i < n; i++) matrix[i].resize(m);
  for (int t = 0; t < q; t++) {
    int tmp;
    switch (queries[t].type) {
      case 1:
        tmp = matrix[queries[t].row][m - 1];
        for (int i = m - 1; i > 0; i--)
          matrix[queries[t].row][i] = matrix[queries[t].row][i - 1];
        matrix[queries[t].row][0] = tmp;
        break;
      case 2:
        tmp = matrix[n - 1][queries[t].col];
        for (int i = n - 1; i > 0; i--)
          matrix[i][queries[t].col] = matrix[i - 1][queries[t].col];
        matrix[0][queries[t].col] = tmp;
        break;
      case 3:
        matrix[queries[t].row][queries[t].col] = queries[t].val;
        break;
    }
  }
  for (int i = 0; i < n; i++) {
    for (int j = 0; j < m; j++) cout << matrix[i][j] << ' ';
    cout << endl;
  }
  return 0;
}
