#include <bits/stdc++.h>
static char buff[(int)1e6 + 17];
static constexpr long long inf = (long long)1e9 + 7ll;
inline void config_io(const bool& __fastio) {
  if (__fastio) {
    std::ios_base::sync_with_stdio(false);
    std::cin.tie(nullptr);
  }
  if (!std::string("").empty()) {
    assert(
        freopen(""
                ".in",
                "r", stdin));
    assert(
        freopen(""
                ".out",
                "w", stdout));
  }
}
using namespace std;
const int maxn = (int)1e2 + 17;
struct query {
  int t;
  int i, j, x;
};
int n, m, q;
vector<query> qq;
int f[maxn][maxn];
int r[maxn], c[maxn];
int main() {
  config_io(false);
  scanf("%d %d %d", &n, &m, &q);
  for (int k = 0; k < q; ++k) {
    int t;
    scanf("%d", &t);
    if (t == 1) {
      int i;
      scanf("%d", &i);
      --i;
      qq.push_back({1, i, 0, 0});
    }
    if (t == 2) {
      int j;
      scanf("%d", &j);
      --j;
      qq.push_back({2, 0, j, 0});
    }
    if (t == 3) {
      int i, j, x;
      scanf("%d %d %d", &i, &j, &x);
      --i, --j;
      f[i][j] = x;
      qq.push_back({3, i, j, x});
    }
  }
  reverse(qq.begin(), qq.end());
  for (int k = 0; k < q; ++k) {
    int t = qq[k].t;
    if (t == 1) {
      int i = qq[k].i;
      vector<int> kek;
      for (int j = 0; j < m; ++j) kek.push_back(f[i][(m + j - 1) % m]);
      for (int j = 0; j < m; ++j) f[i][j] = kek[j];
    }
    if (t == 2) {
      int j = qq[k].j;
      vector<int> kek;
      for (int i = 0; i < n; ++i) kek.push_back(f[(n + i - 1) % n][j]);
      for (int i = 0; i < n; ++i) f[i][j] = kek[i];
    }
    if (t == 3) {
      int i = qq[k].i, j = qq[k].j, x = qq[k].x;
      f[i][j] = x;
    }
  }
  for (int i = 0; i < n; ++i) {
    for (int j = 0; j < m; ++j) printf("%d ", f[i][j]);
    printf("\n");
  }
  return 0;
}
