#include <bits/stdc++.h>
using namespace std;
const int MX_SZ = 105;
struct request {
  int type;
  int r;
  int x, y, val;
  request(int type0, int r0) {
    type = type0;
    r = r0;
  }
  request(int type0, int x0, int y0, int val0) {
    type = type0;
    x = x0;
    y = y0;
    val = val0;
  }
};
int main() {
  ios_base::sync_with_stdio(false);
  int n, m, q;
  cin >> n >> m >> q;
  int a[MX_SZ][MX_SZ];
  memset(a, 0, sizeof(a));
  vector<request> v;
  for (int i = 0; i < q; i++) {
    int type;
    cin >> type;
    if (type != 3) {
      int r;
      cin >> r;
      v.push_back(request(type, r));
    } else {
      int x, y, val;
      cin >> x >> y >> val;
      v.push_back(request(type, x, y, val));
    }
  }
  reverse(v.begin(), v.end());
  int tmp[MX_SZ];
  for (int i = 0; i < q; i++) {
    if (v[i].type == 1) {
      for (int j = 1; j <= m; j++) {
        if (j == m) {
          tmp[1] = a[v[i].r][j];
        } else {
          tmp[j + 1] = a[v[i].r][j];
        }
      }
      for (int j = 1; j <= m; j++) {
        a[v[i].r][j] = tmp[j];
      }
    }
    if (v[i].type == 2) {
      for (int j = 1; j <= n; j++) {
        if (j == n) {
          tmp[1] = a[j][v[i].r];
        } else {
          tmp[j + 1] = a[j][v[i].r];
        }
      }
      for (int j = 1; j <= n; j++) {
        a[j][v[i].r] = tmp[j];
      }
    }
    if (v[i].type == 3) {
      a[v[i].x][v[i].y] = v[i].val;
    }
  }
  for (int i = 1; i <= n; i++) {
    for (int j = 1; j <= m; j++) {
      cout << a[i][j] << " ";
    }
    cout << '\n';
  }
}
