#include <bits/stdc++.h>
using namespace std;
unsigned long long fact(unsigned long long n, unsigned long long m) {
  return n ? n * fact(n - 1, m) % m : 1;
}
unsigned long long gcd(unsigned long long a, unsigned long long b) {
  return a ? gcd(b % a, b) : b;
}
unsigned long long lcm(unsigned long long a, unsigned long long b) {
  return a / gcd(a, b) * b;
}
unsigned long long qpow(unsigned long long a, unsigned long long b,
                        unsigned long long m) {
  return b ? (b % 2 ? b : 1) * qpow(a * a % m, b / 2, m) % m : 1;
}
bool isPow2(unsigned long long x) { return !(x & (x - 1)); }
static const bool PARALLEL_MULTITEST = true;
static const bool MULTILINE_OUTPUT = true;
static const bool LAUNCH_STRESSTEST = false;
static const string INPUT_FILE = "";
static const string OUTPUT_FILE = "";
static const string DBG_INPUT_FILE = "input.txt";
static const string DBG_OUTPUT_FILE = "output.txt";
static const string DBG_ERROR_FILE = "error.txt";
struct Solver {
  struct IData {
    int type, x1, x2, value;
  };
  vector<IData> inp;
  int mtx[101][101] = {{0}};
  int rshifts[200] = {{0}};
  int cshifts[200] = {{0}};
  int n, m, k;
  void readData(istream &cin) {
    cin >> n >> m >> k;
    inp.resize(k);
    for (int i = 0; i < int(k); ++i) {
      cin >> inp[i].type >> inp[i].x1;
      if (inp[i].type == 3) {
        cin >> inp[i].x2 >> inp[i].value;
      }
      --inp[i].x1;
      --inp[i].x2;
    }
  }
  void solve(ostream &cout, ostream &cerr) {
    reverse(inp.begin(), inp.end());
    for (auto &x : inp) {
      if (x.type == 3) {
        mtx[x.x1][x.x2] = x.value;
      } else if (x.type == 1) {
        int b = mtx[x.x1][m - 1];
        for (int i = (m - 1); i >= (1); --i) {
          mtx[x.x1][i] = mtx[x.x1][i - 1];
        }
        mtx[x.x1][0] = b;
      } else {
        int b = mtx[n - 1][x.x1];
        for (int i = (n - 1); i >= (1); --i) {
          mtx[i][x.x1] = mtx[i - 1][x.x1];
        }
        mtx[0][x.x1] = b;
      }
    }
    for (int i = 0; i < int(n); ++i) {
      for (int j = 0; j < int(m); ++j) {
        cout << mtx[i][j] << " ";
      }
      cout << endl;
    }
  }
};
int main() {
  std::ios::sync_with_stdio(false);
  if (!INPUT_FILE.empty()) freopen(INPUT_FILE.c_str(), "rt", stdin);
  if (!OUTPUT_FILE.empty()) freopen(OUTPUT_FILE.c_str(), "wt", stdout);
  auto solver = Solver();
  solver.readData(cin);
  solver.solve(cout, cerr);
  return 0;
}
