#include <vector>
#include <algorithm>
#include <iostream>
using namespace std;

struct Edge {
    int left;
    int right;
    int y;
    bool isTop;

    Edge(int left, int right, int y, bool isTop)
	: left(left), right(right), y(y), isTop(isTop) { }

    // in case of tie, we want to see top of exiting rectangles before bottom of entering rectangles
    bool operator<(const Edge& other) const {
	return (y < other.y || (y == other.y && other.isTop < isTop));
    }
};

int main() {
    int n,w,h;
    cin >> n;
    while (n != 0) {
	cin >> w >> h;

	vector<Edge> events;
	for (int i=0; i<n; i++) {
	    int xl,yl,xh,yh;
	    cin >> xl >> yl >> xh >> yh;
	    events.push_back(Edge(xl,xh,yh,true));
	    events.push_back(Edge(xl,xh,yl,false));
	}
	sort(events.begin(), events.end());  // sorted with y going from low to high

	long long uncovered, maxDepth, maxCovered;
	uncovered = maxDepth = maxCovered = 0;

	vector<int> sweep(w,0);     // all zeros initially
	long sweepZeros = w;        // number of cells with zero depth
	long sweepMax   = w;        // number of cells with GLOBAL max depth
	int prevY = 0;

	// your part goes here...






	cout << uncovered << " " << maxDepth << " " << maxCovered << endl;
	cin >> n;
    }

}
