#include <algorithm>
#include <cstdio>
#include <vector>
#include <set>
#include <map>
using namespace std;
#define FOR(i,a,b) for(int (i)=(a); (i)!=(b); ++(i))
struct Segment {
int L, R, count;
Segment(){};
Segment(int L, int R) {
this->count = 0;
this->L = L;
this->R = R;
}
};
void cover(vector<Segment> &segments, int L, int R) {
FOR(i,0,segments.size()) {
if (segments[i].L >= L && segments[i].R <= R) {
++segments[i].count;
}
}
}
unsigned long long int solve(vector<pair<int,int> > &P, int MAX) {
set<int> S;
S.insert(0); S.insert(MAX);
FOR(i,0,P.size()) S.insert(P[i].first);
FOR(i,0,P.size()) S.insert(P[i].second);
vector<int> points(S.begin(), S.end());
sort(points.begin(), points.end());
vector<Segment> segments(points.size() - 1);
FOR(i,0,points.size() - 1) segments[i] = Segment(points[i], points[i+1]);
int result = 0;
FOR(i,0,segments.size()) {
FOR(j,0,segments.size()) segments[j].count = 0;
FOR(j,0,P.size()) {
if (P[j].first <= segments[i].L && segments[i].R <= P[j].second) {
cover(segments, P[j].first, P[j].second);
} else {
cover(segments, 0, P[j].first);
cover(segments, P[j].second, MAX);
}
}
int subresult = 0;
FOR(j,0,segments.size()) {
if (segments[j].count == P.size()) {
subresult += segments[j].R - segments[j].L;
}
}
result = max(result, subresult);
}
return result;
}
int n, X, Y, x1, y1, x2, y2;
int main() {
scanf("%d %d %d", &n, &X, &Y);
vector<pair<int,int> > V(n), H(n);
FOR(i,0,n) {
scanf("%d %d %d %d", &x1, &y1, &x2, &y2);
if (x1 > x2) swap(x1, x2);
if (y1 > y2) swap(y1, y2);
H[i] = make_pair(x1, x2);
V[i] = make_pair(y1, y2);
}
printf("%llu\n", solve(H, X) * solve(V, Y));
}