#include <bits/stdc++.h>
using namespace std;
struct my {
  int64_t t, x, y, val;
  my() : t(0), x(0), y(0), val(0) {}
};
vector<my> qquery, query;
int64_t n, m, q;
int64_t field[100][100];
void init() {
  ios_base::sync_with_stdio(false);
  cin >> n >> m >> q;
  query.resize(q);
  qquery.resize(q);
}
void move_x(int64_t x) {
  int64_t temp = field[x][m - 1];
  for (int64_t i = m - 1; i >= 0; --i) {
    field[x][i] = field[x][i - 1];
  }
  field[x][0] = temp;
}
void move_y(int64_t y) {
  int64_t temp = field[n - 1][y];
  for (int64_t i = n - 1; i >= 0; --i) {
    field[i][y] = field[i - 1][y];
  }
  field[0][y] = temp;
}
void solve() {
  int64_t t, x, y, val;
  for (int64_t i = 0; i < q; ++i) {
    cin >> qquery[i].t;
    if (qquery[i].t == 1) {
      cin >> qquery[i].x;
      qquery[i].x--;
    }
    if (qquery[i].t == 2) {
      cin >> qquery[i].y;
      qquery[i].y--;
    }
    if (qquery[i].t == 3) {
      cin >> qquery[i].x >> qquery[i].y >> qquery[i].val;
      qquery[i].x--;
      qquery[i].y--;
    }
  }
  for (int64_t i = 0; i < qquery.size(); ++i) {
    query[i] = qquery[qquery.size() - 1 - i];
  }
  for (int64_t i = 0; i < q; ++i) {
    if (query[i].t == 1) {
      move_x(query[i].x);
    }
    if (query[i].t == 2) {
      move_y(query[i].y);
    }
    if (query[i].t == 3) {
      field[query[i].x][query[i].y] = query[i].val;
    }
  }
  for (int64_t i = 0; i < n; ++i) {
    for (int64_t j = 0; j < m; ++j) {
      cout << field[i][j] << " ";
    }
    cout << endl;
  }
}
int32_t main() {
  init();
  solve();
  return 0;
}
