#include <bits/stdc++.h>
using namespace std;
istream& operator>>(istream& in, pair<long long, long long>& b) {
  in >> b.first >> b.second;
  return in;
}
ostream& operator<<(ostream& out, const pair<long long, long long>& b) {
  out << "{" << b.first << ", " << b.second << "}";
  return out;
}
template <typename T>
ostream& operator<<(ostream& out, const vector<T>& a) {
  for (auto k : a) out << k << " ";
  return out;
}
template <typename T1, typename T2>
inline bool chkmin(T1& x, const T2& y) {
  if (x > y) {
    x = y;
    return 1;
  }
  return 0;
}
template <typename T1, typename T2>
inline bool chkmax(T1& x, const T2& y) {
  if (x < y) {
    x = y;
    return 1;
  }
  return 0;
}
const long long INF = 1e18;
const long double PI = 4 * atan(1);
mt19937 gen(chrono::high_resolution_clock::now().time_since_epoch().count());
const long long N = 101;
long long n, m, q;
long long a[N][N];
signed main() {
  ios_base::sync_with_stdio(0);
  cin.tie(0);
  cout.tie(0);
  cin >> n >> m >> q;
  vector<vector<long long>> b;
  while (q--) {
    long long t;
    cin >> t;
    if (t != 3) {
      long long x;
      cin >> x;
      b.push_back({t, x - 1});
    } else {
      long long x, y, val;
      cin >> x >> y >> val;
      x--, y--;
      b.push_back({t, x, y, val});
    }
  }
  reverse((b).begin(), (b).end());
  for (long long i = 0; i < n; i++) {
    for (long long j = 0; j < m; j++) {
      a[i][j] = 1;
    }
  }
  for (auto w : b) {
    if (w[0] == 1) {
      for (long long i = m - 1; i > 0; i--) {
        swap(a[w[1]][i], a[w[1]][i - 1]);
      }
    } else if (w[0] == 2) {
      for (long long i = n - 1; i > 0; i--) {
        swap(a[i][w[1]], a[i - 1][w[1]]);
      }
    } else {
      a[w[1]][w[2]] = w[3];
    }
  }
  for (long long i = 0; i < n; i++) {
    for (long long j = 0; j < m; j++) {
      cout << a[i][j] << " ";
    }
    cout << "\n";
  }
}
