#include <bits/stdc++.h>
using namespace std;
int p[200][200];
struct query {
  int t, r, c, a;
  query(int t, int r, int c, int a) : t(t), r(r), c(c), a(a) {}
};
vector<query> Q;
int main() {
  int n, m;
  scanf("%d %d", &n, &m);
  int q;
  scanf("%d", &q);
  int t;
  int x, y;
  int a;
  int r, c;
  for (int i = 0; i < q; i++) {
    scanf("%d", &t);
    if (t == 1) {
      scanf("%d", &r);
      Q.push_back(query(t, r, 0, 0));
    } else if (t == 2) {
      scanf("%d", &c);
      Q.push_back(query(t, 0, c, 0));
    } else {
      scanf("%d %d %d", &x, &y, &a);
      Q.push_back(query(t, x, y, a));
    }
  }
  reverse(Q.begin(), Q.end());
  for (int i = 0; i < q; i++) {
    t = Q[i].t;
    if (t == 1) {
      r = Q[i].r;
      for (int i = m; i >= 1; i--) {
        p[r][i + 1] = p[r][i];
      }
      p[r][1] = p[r][m + 1];
    } else if (t == 2) {
      c = Q[i].c;
      for (int i = n; i >= 1; i--) {
        p[i + 1][c] = p[i][c];
      }
      p[1][c] = p[n + 1][c];
    } else {
      x = Q[i].r;
      y = Q[i].c;
      a = Q[i].a;
      p[x][y] = a;
    }
  }
  for (int i = 1; i <= n; i++) {
    for (int j = 1; j <= m; j++) {
      printf("%d ", p[i][j]);
    }
    printf("\n");
  }
  return 0;
}
