#include<bits/stdc++.h>
using namespace std;
using ll = long long;

// #undef DEBUG
// #define DEBUG
/// {{{ DEBUG --- ///
#ifdef DEBUG
template <typename T> ostream &operator<<(ostream &o, const vector<T> &v) { o << "{"; for(size_t i = 0; i < v.size(); i++) o << v[i] << (i + 1 != v.size() ? ", " : ""); o << "}"; return o; }
#ifdef USE_COUT
#define dump(...) [&](){auto __debug_tap=make_tuple(__VA_ARGS__);cout<<"["<<__LINE__<< "] "<<#__VA_ARGS__<<" = "<<__debug_tap<<"\n";}()
#else
#define dump(...) [&](){auto __debug_tap=make_tuple(__VA_ARGS__);cout<<"["<<__LINE__<< "] "<<#__VA_ARGS__<<" = "<<__debug_tap<<"\n";}()
#endif
template<class T> inline void dump2D(T &d, size_t sizey, size_t sizex) { ostream&o=
#ifdef USE_COUT
  cout;
#else
  cerr;
#endif
  for(size_t i = 0; i < sizey; i++) { for(size_t j = 0; j < sizex; j++) o << d[i][j] << " "; o << endl; } }
#else
  template <typename T> ostream &operator<<(ostream &o, const vector<T> &v) { for(size_t i = 0; i < v.size(); i++) o << v[i] << (i + 1 != v.size() ? " " : ""); return o; }
#define dump(...) (42)
#define dump2D(...) (42)
#endif
template<int n, class...T> typename enable_if<(n>=sizeof...(T))>::type _ot(ostream &, tuple<T...> const &){}
template<int n, class...T> typename enable_if<(n< sizeof...(T))>::type _ot(ostream & os, tuple<T...> const & t){ os << (n==0?"":", ") << get<n>(t); _ot<n+1>(os, t); }
template<class...T> ostream & operator<<(ostream &o, tuple<T...> const &t){ o << "("; _ot<0>(o, t); o << ")"; return o; }
template<class T, class U> ostream & operator<<(ostream &o, pair<T, U> const &p) { o << "(" << p.first << ", " << p.second << ")"; return o; }
  /// }}}--- ///
  

/// {{{
template<class T = long long>
struct BIT2D {
  int h, w;
  vector<T> dat;
  BIT2D(int h, int w): h(h), w(w), dat(h * w) {}
  void add(int y, int x, T const &val) {
    y++;
    for(; y <= h; y += y&-y) addX(y, x, val);
  }
  void set(int y, int x, T val) {
    add(y, x, val - get(y, x));
  }
  long long sum(int y, int x) {
    if(y < 0 || x < 0) return 0;
    y++;
    long long r = 0;
    for(; y > 0; y -= y&-y) r += sumX(y, x);
    return r;
  }
  T get(int y, int x) {
    return range(y, x, y, x);
  }
  long long range(int y1, int x1, int y2, int x2) {
    return sum(y2, x2) - sum(y1 - 1, x2) - sum(y2, x1 - 1) + sum(y1 - 1, x1 - 1);
  }
private:
  inline int id(int y, int x) {
    return (y - 1) * w + (x - 1);
  }
  void addX(int y, int x, T const &val) {
    x++;
    for(; x <= w; x += x&-x) dat[id(y, x)] += val;
  }
  long long sumX(int y, int x) {
    x++;
    long long r = 0;
    for(; x > 0; x -= x&-x) r += dat[id(y, x)];
    return r;
  }
};

/// }}}

int main() {
  ios::sync_with_stdio(false), cin.tie(0);
  int h, w, T, q;
  cin >> h >> w >> T >> q;
  BIT2D<> ecas(h, w), qina(h, w);
  using P = tuple<int, int, int>;
  vector<P> baked;
  int head = 0;
  for(int i = 0; i < q; i++) {
    int t, c, x1, y1, x2, y2;
    cin >> t >> c >> x1 >> y1;
    x1--; y1--;
    while(head < baked.size() && get<0>(baked[head]) <= t) {
      int x, y;
      tie(ignore, x, y) = baked[head];
      if(ecas.get(x, y)) {
        ecas.add(x, y, -1);
        qina.add(x, y, 1);
      }
      head++;
    }
    switch(c) {
      case 0: // add
        ecas.add(x1, y1, 1);
        baked.emplace_back(t + T, x1, y1);
        break;
      case 1: // eat
        qina.set(x1, y1, 0);
        break;
      case 2:
        cin >> x2 >> y2;
        x2--; y2--;
        cout << qina.range(x1, y1, x2, y2) << " " << ecas.range(x1, y1, x2, y2) << endl;
        break;
    }
  }
  return 0;
}




Measured memory_bytes: 66908