#include <cstdio>
#include <vector>
#include <queue>

struct segtree {
private:
    std::vector< std::vector<int> > array;
    int n, m;
public:
    segtree(int N, int M) {
        n = m = 1;
        while(n <= N) n *= 2;
        while(m <= M) m *= 2;
        array.resize(2*n-1, std::vector<int>(2*m-1));
    }

    // add
    void add(int x, int y, int val) {
        int nx = x+n-1;
        y += m-1;
        while(y >= 0) {
            x = nx;
            array[x][y] += val;
            while(x > 0) {
                x = (x - 1) / 2;
                array[x][y] += val;
            }
            if(y == 0) break;
            y = (y - 1) / 2;
        }
    }

    // x-query
    int query(int x1, int y1, int x2, int y2, int l=0, int r=-1, int k=0) {
        if(r < 0) r = n;
        if(x2 <= l || r <= x1) return 0;
        if(x1 <= l && r <= x2) return query2(y1, y2, k);
        int mid = (l + r) / 2;
        int vl = query(x1, y1, x2, y2, l, mid, 2*k+1);
        int vr = query(x1, y1, x2, y2, mid, r, 2*k+2);
        return vl + vr;
    }

    // y-query
    int query2(int y1, int y2, int x, int l=0, int r=-1, int k=0) {
        if(r < 0) r = m;
        if(y2 <= l || r <= y1) return 0;
        if(y1 <= l && r <= y2) return array[x][k];
        int mid = (l + r) / 2;
        int vl = query2(y1, y2, x, l, mid, 2*k+1);
        int vr = query2(y1, y2, x, mid, r, 2*k+2);
        return vl + vr;
    }
};

struct Elem {
    int x, y, time;
};

int H, W, T, Q;

int main() {
    scanf("%d%d%d%d", &H, &W, &T, &Q);
    std::queue<Elem> que;
    segtree noeat(H, W), caneat(H, W);

    for(int i=0; i<Q; i++) {
        int t, q; scanf("%d%d", &t, &q);
        while(!que.empty()) {
            Elem cur = que.front();
            if(cur.time + T <= t) {
                que.pop();
                noeat.add(cur.x, cur.y, -1);
                caneat.add(cur.x, cur.y, 1);
            }
            else break;
        }
        
        if(q == 0 || q == 1) {
            int h, w; scanf("%d%d", &h, &w);
            h--; w--;
            if(q == 0) {
                noeat.add(h, w, 1);
                que.push(Elem{h, w, t});
            }
            else {
                int val = caneat.query(h, w, h+1, w+1);
                if(val != 0) caneat.add(h, w, -1);
            }
        }
        else {
            int h1, w1, h2, w2; scanf("%d%d%d%d", &h1, &w1, &h2, &w2);
            h1--; w1--;
            int ans_noeat  = noeat.query(h1, w1, h2, w2);
            int ans_caneat = caneat.query(h1, w1, h2, w2);
            printf("%d %d\n", ans_caneat, ans_noeat);
        }
    }
    return 0;
}
