1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
// Karol Kosinski 2019
#include <cstdio>
#include <algorithm>
#include <map>
#include <set>
#include <stack>
#include <vector>
#define FOR(i,a,b) for(int i=(a);i<(b);++i)
#define FOD(i,b,a) for(int i=(b-1);i>=(a);--i)
//#define DEBUG(x...) printf(x)
#define DEBUG(x...)
using namespace std;

typedef long long LL;
const int N2 = 1'000'007;

struct LinePoint
{
    int pos, id;
    // id > 0 => begin, else => end
};

bool operator < (const LinePoint &a, const LinePoint &b)
{
    if (a.pos != b.pos) return a.pos < b.pos;
    return a.id < b.id;
}

LinePoint X[N2], Y[N2];

struct StackSet
{
    void push(int v)
    {
        S.push(v);
        Z.insert(v);
    }
    int top()
    {
        return S.top();
    }
    void erase(int v)
    {
        Z.erase(v);
        while (Z.find(S.top()) == Z.end()) S.pop();
    }

    stack<int> S;
    set<int> Z;
};

int find_longest(LinePoint *T, int n, int lim)
{
    sort(T, T + n);
    map<pair<int, int>, int> M;
    StackSet S;
    vector<int> V1, V2;
    
    S.push(0);
    V1.push_back(0);
    V2.push_back(0);
    FOR(i,0,n)
    {
        if (T[i].id > 0) S.push(T[i].id);
        else S.erase(-T[i].id);
        V1.push_back(S.top());
    }
    FOD(i,n,0)
    {
        if (T[i].id < 0) S.push(-T[i].id);
        else S.erase(T[i].id);
        V2.push_back(S.top());
    }
    reverse(V2.begin(), V2.end());
    int prev_pos = 0;
    FOR(i,0,n)
    {
        int d = T[i].pos - prev_pos;
        auto mp = make_pair(V1[i], V2[i]);
        auto iter = M.find(mp);
        if (iter == M.end()) M[mp] = d;
        else iter->second += d;
        prev_pos = T[i].pos;
    }
    M[make_pair(0, 0)] += lim - prev_pos;
    
    int res = 0;
    for (const auto &el : M) res = max(el.second, res);
    return res;
}

int main()
{
    int n, xlen, ylen;
    scanf("%d%d%d", &n, &xlen, &ylen);
    FOR(i,0,n)
    {
        int x1, y1, x2, y2;
        scanf("%d%d%d%d", &x1, &y1, &x2, &y2);
        X[2 * i].pos     = min(x1, x2);
        X[2 * i].id      = i + 1;
        X[2 * i + 1].pos = max(x1, x2);
        X[2 * i + 1].id  = -i - 1;
        Y[2 * i].pos     = min(y1, y2);
        Y[2 * i].id      = i + 1;
        Y[2 * i + 1].pos = max(y1, y2);
        Y[2 * i + 1].id  = -i - 1;
    }
    LL xres = find_longest(X, 2 * n, xlen);
    LL yres = find_longest(Y, 2 * n, ylen);
    printf("%lld\n", xres * yres);
    return 0;
}