#include <bits/stdc++.h>
using namespace std;
using LL = long long;
using vi = vector<int>;
using pii = pair<int, int>;
using vpii = vector<pair<int, int>>;
using vll = vector<LL>;
using LD = long double;
template <typename T>
void check(T& a, const T& b) {
  if (a >= b) {
    a %= b;
  }
}
template <typename T>
T gcd(T u, T v) {
  if (u == v) return u;
  if (u == 0) return v;
  if (v == 0) return u;
  if (~u & 1) {
    if (v & 1)
      return gcd(u >> 1, v);
    else
      return gcd(u >> 1, v >> 1) << 1;
  }
  if (~v & 1) return gcd(u, v >> 1);
  if (u > v) return gcd((u - v) >> 1, v);
  return gcd((v - u) >> 1, u);
}
LL mulmod(LL a, LL b, const LL& m) {
  LL q = (LL)(((LD)a * (LD)b) / (LD)m);
  LL r = a * b - q * m;
  if (r > m) r %= m;
  if (r < 0) r += m;
  return r;
}
template <typename T, typename S>
T expo(T e, S n) {
  T x = 1, p = e;
  while (n) {
    if (n & 1) x = x * p;
    p = p * p;
    n >>= 1;
  }
  return x;
}
template <typename T>
T powerL(T e, T n, const T& m) {
  T x = 1, p = e;
  while (n) {
    if (n & 1) x = mulmod(x, p, m);
    p = mulmod(p, p, m);
    n >>= 1;
  }
  return x;
}
const int N = 110;
int n, m, q;
int M[N][N];
int A[N][N];
void upd(int x, int y) { M[(x - 1) / m + 1][(x - 1) % m + 1] = y; }
int main() {
  cin >> n >> m >> q;
  for (int i = 1; i <= n; i++)
    for (int h = 1; h <= m; h++) A[i][h] = (i - 1) * m + h;
  while (q--) {
    int type, r, c, x;
    cin >> type;
    if (type == 1) {
      cin >> r;
      for (int i = 1; i < m; i++) swap(A[r][i], A[r][i + 1]);
    } else if (type == 2) {
      cin >> c;
      for (int i = 1; i < n; i++) swap(A[i][c], A[i + 1][c]);
    } else {
      cin >> r >> c >> x;
      upd(A[r][c], x);
    }
  }
  for (int i = 1; i <= n; i++) {
    for (int j = 1; j <= m; j++) cout << M[i][j] << " ";
    printf("\n");
  }
}
