#include <algorithm>
#include <array>
#include <cstddef>
#include <cstdint>
#include <iostream>
#include <limits>
#include <string>
#include <tuple>
#include <vector>

using usize = std::size_t;
using isize = std::ptrdiff_t;
using u64 = std::uint64_t;
using u32 = std::uint32_t;

struct seg1d {
  std::vector<u32> c;

  seg1d(usize n) : c(n * 2, 0) {}

  void add(usize i, u32 x) {
    i += c.size() / 2;
    while (i != 0) {
      c[i] += x;
      i /= 2;
    }
  }

  bool state(usize i) { return c[i + c.size() / 2] == 1; }

  u32 fold(usize l, usize r) {
    l += c.size() / 2;
    r += c.size() / 2;
    u32 ret = 0;
    while (l != r) {
      if (l % 2 != 0) {
        ret += c[l];
        l += 1;
      }
      l /= 2;
      if (r % 2 != 0) {
        r -= 1;
        ret += c[r];
      }
      r /= 2;
    }
    return ret;
  }
};

struct seg2d {
  std::vector<seg1d> c;

  seg2d(usize n, usize m) : c(n * 2, seg1d(m)) {}

  void add(usize i, usize j, u32 x) {
    i += c.size() / 2;
    while (i != 0) {
      c[i].add(j, x);
      i /= 2;
    }
  }

  bool state(usize i, usize j) { return c[i + c.size() / 2].state(j); }

  u32 fold(usize l, usize r, usize ll, usize rr) {
    l += c.size() / 2;
    r += c.size() / 2;
    u32 ret = 0;
    while (l != r) {
      if (l % 2 != 0) {
        ret += c[l].fold(ll, rr);
        l += 1;
      }
      l /= 2;
      if (r % 2 != 0) {
        r -= 1;
        ret += c[r].fold(ll, rr);
      }
      r /= 2;
    }
    return ret;
  }
};

#include <set>
#include <utility>

int main() {
  std::ios::sync_with_stdio(false);
  std::cin.tie(nullptr);

  usize H, W;
  u64 T;
  usize q;
  std::cin >> H >> W >> T >> q;

  struct ivent_t {
    u64 time;
    usize type;
    usize h, w, hh, ww;
    // 0: make, 1: get, 2: set, 3: query

    bool operator<(const ivent_t &r) const {
      return std::tie(time, type) < std::tie(r.time, r.type);
    }
  };

  std::set<ivent_t> ivent;
  for (usize i = 0; i != q; ++i) {
    u64 t;
    int c;
    usize h, w;
    std::cin >> t >> c >> h >> w;
    --h;
    --w;
    if (c == 0) {
      ivent.insert({t, 2, h, w, 0, 0});
    } else if (c == 1) {
      ivent.insert({t, 1, h, w, 0, 0});
    } else {
      usize hh, ww;
      std::cin >> hh >> ww;
      ivent.insert({t, 3, h, w, hh, ww});
    }
  }

  seg2d make(H, W), set(H, W);

  const auto state = [&](usize h, usize w) {
    bool ss = set.state(h, w);
    bool ms = make.state(h, w);
    if (ss) {
      return 1;
    } else if (ms) {
      return 2;
    } else {
      return 0;
    }
  };

  // 0: none, 1: set, 2: make

  while (!ivent.empty()) {
    auto v = *ivent.begin();
    ivent.erase(ivent.begin());
    switch (v.type) {
    case 0: {
      set.add(v.h, v.w, -1);
      make.add(v.h, v.w, 1);
    } break;
    case 1: {
      if (state(v.h, v.w) == 2) {
        make.add(v.h, v.w, -1);
      }
    } break;
    case 2: {
      if (state(v.h, v.w) == 0) {
        set.add(v.h, v.w, 1);
        ivent.insert({v.time + T, 0, v.h, v.w, 0, 0});
      }
    } break;
    case 3: {
      usize b = set.fold(v.h, v.hh, v.w, v.ww);
      usize a = make.fold(v.h, v.hh, v.w, v.ww);
      std::cout << a << " " << b << "\n";
    } break;
    }
  }

  return 0;
}


Measured memory_bytes: 137524