#include <bits/stdc++.h>
using namespace std;
template <typename T>
inline T SQR(T x) {
  return x * x;
}
template <typename T>
inline T MIN(T x, T y) {
  return (x < y) ? x : y;
}
template <typename T>
inline T MAX(T x, T y) {
  return (x > y) ? x : y;
}
template <typename T>
inline T ABS(T x) {
  return (x > 0) ? x : -x;
}
template <typename T>
inline void UPDATE_MIN(T &x, T y) {
  if (y < x) {
    x = y;
  }
}
template <typename T>
inline void UPDATE_MAX(T &x, T y) {
  if (x < y) {
    x = y;
  }
}
template <typename T>
inline int ARGMAX(T cont) {
  return max_element(cont.begin(), cont.end()) - cont.begin();
}
template <typename T>
inline int ARGMIN(T cont) {
  return min_element(cont.begin(), cont.end()) - cont.begin();
}
vector<string> split(const string &s, char c) {
  vector<string> v;
  stringstream ss(s);
  string x;
  while (getline(ss, x, c)) v.emplace_back(x);
  return move(v);
}
template <typename T, typename... Args>
inline string arrStr(T arr, int n) {
  stringstream s;
  s << "[";
  for (__typeof(n - 1) i = (0), __tmpvar__end87 = (n - 1); i < __tmpvar__end87;
       i++)
    s << arr[i] << ",";
  s << arr[n - 1] << "]";
  return s.str();
}
template <class T>
inline string TOSTR(const T &x) {
  stringstream ss;
  ss << x;
  return ss.str();
}
inline void PR(void) {}
inline void PR(int x) { printf("%d", x); }
inline void PR(long long x) { printf("%lld", x); }
inline void PR(char *s) { printf("%s", s); }
inline void PR(const char *s) { printf("%s", s); }
inline void PR(double f) { printf("%.10lf", f); }
inline void PR(long double f) { printf("%.10llf", f); }
inline void PR(vector<int> &vec) {
  for (auto x : vec) {
    PR(x);
    putc(0x20, stdout);
  }
}
template <typename T>
inline void PRS(T x) {
  PR(x);
  putc(0x20, stdout);
}
template <typename T>
inline void PRN(T x) {
  PR(x);
  putc(0x0a, stdout);
}
void PRN(void) { putc(0x0a, stdout); }
inline int gcd(int a, int b) { return a ? gcd(b % a, a) : b; }
inline long long gcd(long long a, long long b) { return a ? gcd(b % a, a) : b; }
inline long long powmod(long long a, long long p, long long m) {
  long long r = 1;
  while (p) {
    if (p & 1) r = r * a % m;
    p >>= 1;
    a = a * a % m;
  }
  return r;
}
struct pairhash {
  template <typename T, typename U>
  std::size_t operator()(const std::pair<T, U> &x) const {
    return std::hash<T>()(x.first) ^ std::hash<U>()(x.second);
  }
};
template <typename K, typename V>
V GetWithDef(const std::map<K, V> &m, const K &key, const V &defval) {
  auto it = m.find(key);
  return (it == m.end()) ? defval : it->second;
}
template <typename K, typename V>
void SetDef(std::map<K, V> &m, const K &key, const V &defval) {
  auto it = m.find(key);
  if (it == m.end()) m[key] = defval;
}
template <typename K, typename V>
V GetWithDef(const std::unordered_map<K, V> &m, const K &key, const V &defval) {
  auto it = m.find(key);
  return (it == m.end()) ? defval : it->second;
}
template <typename K, typename V>
void SetDef(std::unordered_map<K, V> &m, const K &key, const V &defval) {
  auto it = m.find(key);
  if (it == m.end()) m[key] = defval;
}
const int MOD = 1000 * 1000 * 1000 + 7;
const double PI = 3.1415926535897932384626433832795l;
inline void addto(int &a, int b) {
  a += b;
  if (a >= MOD) a -= MOD;
}
inline int add(int a, int b) {
  a += b;
  if (a >= MOD) a -= MOD;
  return a;
}
inline void subto(int &a, int b) {
  a -= b;
  if (a < 0) a += MOD;
  if (a >= MOD) a -= MOD;
}
inline int sub(int a, int b) {
  a -= b;
  if (a < 0) a += MOD;
  if (a >= MOD) a -= MOD;
  return a;
}
inline void multo(int &a, int b) { a = (long long)a * b % MOD; }
inline int mul(int a, int b) { return (long long)a * b % MOD; }
inline int mulmod(int a, int b, int mod) { return (long long)a * b % mod; }
inline int powmod(int a, int e, int mod) {
  int x;
  for (x = 1; e > 0; e >>= 1) {
    if (e & 1) x = mulmod(x, a, mod);
    a = mulmod(a, a, mod);
  }
  return x;
}
inline int invmod_prime(int a, int mod) { return powmod(a, mod - 2, mod); }
inline long long invmod_LL(long long p) {
  long long q = p;
  for (long long a = p * p; a != 1; a *= a) q *= a;
  return q;
}
int N, M, K, L, E, Q, NX, NY;
int mat[123][123] = {{1, 2, 3}, {4, 5, 6}, {6, 7, 8}};
int unknown = 1e9 + 1000;
void rotate_row(int y) {
  int f = mat[y][0];
  for (__typeof(NX - 1) x = (0), __tmpvar__end246 = (NX - 1);
       x < __tmpvar__end246; x++)
    mat[y][x] = mat[y][x + 1];
  mat[y][NX - 1] = f;
}
void unrotate_row(int y) {
  int f = mat[y][NX - 1];
  for (__typeof(NX) x = (NX)-1, __tmpvar__end251 = (1); x >= __tmpvar__end251;
       x--)
    mat[y][x] = mat[y][x - 1];
  mat[y][0] = f;
}
void rotate_col(int x) {
  int f = mat[0][x];
  for (__typeof(NY - 1) y = (0), __tmpvar__end256 = (NY - 1);
       y < __tmpvar__end256; y++)
    mat[y][x] = mat[y + 1][x];
  mat[NY - 1][x] = f;
}
void unrotate_col(int x) {
  int f = mat[NY - 1][x];
  for (__typeof(NY) y = (NY)-1, __tmpvar__end261 = (1); y >= __tmpvar__end261;
       y--)
    mat[y][x] = mat[y - 1][x];
  mat[0][x] = f;
}
int main() {
  ios_base::sync_with_stdio(0);
  scanf("%d%d%d", &NY, &NX, &Q);
  for (__typeof(NY) y = (0), __tmpvar__end281 = (NY); y < __tmpvar__end281; y++)
    for (__typeof(NX) x = (0), __tmpvar__end281 = (NX); x < __tmpvar__end281;
         x++)
      mat[y][x] = unknown;
  vector<pair<int, int>> queries;
  for (__typeof(Q) i = (0), __tmpvar__end284 = (Q); i < __tmpvar__end284; i++) {
    int t;
    scanf("%d", &t);
    int pos;
    if (t == 1) {
      scanf("%d", &pos);
      rotate_row(pos - 1);
      queries.push_back(make_pair(1, pos - 1));
    }
    if (t == 2) {
      scanf("%d", &pos);
      rotate_col(pos - 1);
      queries.push_back(make_pair(2, pos - 1));
    }
    if (t == 3) {
      int y, x, val;
      scanf("%d%d%d", &y, &x, &val);
      y--;
      x--;
      assert(mat[y][x] == unknown || mat[y][x] == val);
      mat[y][x] = val;
    }
  }
  for (__typeof((int)queries.size()) i = ((int)queries.size()) - 1,
                                     __tmpvar__end307 = (0);
       i >= __tmpvar__end307; i--) {
    int t = queries[i].first;
    int pos = queries[i].second;
    if (t == 1) unrotate_row(pos);
    if (t == 2) unrotate_col(pos);
  }
  for (__typeof(NY) y = (0), __tmpvar__end314 = (NY); y < __tmpvar__end314;
       y++) {
    for (__typeof(NX) x = (0), __tmpvar__end315 = (NX); x < __tmpvar__end315;
         x++) {
      int v = mat[y][x];
      if (v == unknown) v = 0;
      PRS(v);
    }
    PRN();
  }
  return 0;
}
