#include <bits/stdc++.h>
#define endl '\n'

#define SZ(x) ((int)x.size())
#define ALL(V) V.begin(), V.end()
#define L_B lower_bound
#define U_B upper_bound
#define pb push_back
#pragma GCC optimize("O3")

using namespace std;
template<class T, class T1> int chkmin(T &x, const T1 &y) { return x > y ? x = y, 1 : 0; }
template<class T, class T1> int chkmax(T &x, const T1 &y) { return x < y ? x = y, 1 : 0; }
const int MAXN = (1 << 18);

vector<int> sorted;

struct node
{
    int suff, pref, ans, len;
    node() { suff = pref = ans = 0; len = 0; }
    node(int l) { suff = pref = ans = len = l; }
};

node merge(node l, node r)
{
    node ret;
    ret.suff = r.suff;
    ret.pref = l.pref;
    ret.len = l.len + r.len;

    ret.ans = max(r.ans, l.ans);
    chkmax(ret.ans, r.pref + l.suff);

    if(r.suff == r.len) ret.suff += l.suff;
    if(l.pref == l.len) ret.pref += r.pref;
    
    return ret;
}

int bal[4 * MAXN];
node tr[4 * MAXN];

void init(int l, int r, int idx)
{
    if(l == r)
    {
        bal[idx] = 0;
        tr[idx] = node(sorted[l + 1] - sorted[l]);
        return;
    }

    int mid = (l + r) >> 1;
    init(l, mid, 2 * idx + 1);
    init(mid + 1, r, 2 * idx + 2);

    bal[idx] = 0;
    tr[idx] = merge(tr[2 * idx + 1], tr[2 * idx + 2]);
}

void pull(int l, int r, int idx)
{
    if(bal[idx] == 0) 
    {
        if(l == r) tr[idx] = node(sorted[l + 1] - sorted[l]);
        else tr[idx] = merge(tr[2 * idx + 1], tr[2 * idx + 2]);
    }
    else 
    {
        tr[idx] = node(sorted[r + 1] - sorted[l]);
        tr[idx].ans = 0;
        tr[idx].pref = 0;
        tr[idx].suff = 0;
    }
}

void add(int ql, int qr, int val, int l, int r, int idx)
{
    if(ql <= l && r <= qr)
    {
        bal[idx] += val;
        pull(l, r, idx);
        return;
    }

    int mid = (l + r) >> 1;
    if(ql <= mid) add(ql, qr, val, l, mid, 2 * idx + 1);
    if(mid < qr) add(ql, qr, val, mid + 1, r, 2 * idx + 2);

    pull(l, r, idx);
}

struct Event
{
    int x, ly, ry, len;
    Event() { x = ly = ry = len = 0; }

    Event(int _x, int _ly, int _ry, int _l)
    {
        x = _x;
        ly = _ly;
        ry = _ry;
        len = _l;
    }
};

int n, m, q;
vector<Event> ev;

int read_int();

void read()
{
    n = read_int();
    m = read_int();
    q = read_int();
    for(int i = 0; i < q; i++)
    {
        int ux, uy, dx, dy;
        ux = read_int();
        uy = read_int();
        dx = read_int();
        dy = read_int();
        ev.pb(Event(ux, uy, dy, dx - ux));
        sorted.pb(uy);
        sorted.pb(dy + 1);
    }

    sorted.pb(1);
}

bool cmp(Event F, Event S) { return F.x < S.x; }

int K;

bool check(int len)
{
    init(0, K, 0);

    priority_queue<pair<int, int> > rem;
    for(int i = 0; i < SZ(ev); )
    {
        while(!rem.empty() && -rem.top().first < ev[i].x)
        {
            int it = rem.top().second;
            add(ev[it].ly, ev[it].ry, -1, 0, K, 0);
            rem.pop();
        }
        
        if(i != 0 && tr[0].ans >= len) 
            return true;
        
        int j = i;
        while(i < SZ(ev) && ev[i].x == ev[j].x) i++;
    
        for(int o = j; o < i; o++)
        {
            int need = ev[o].x + len + ev[o].len;
            if(need <= n) rem.push({-need, o});
            add(ev[o].ly, ev[o].ry, 1, 0, K, 0);
        }
    }

    while(!rem.empty())
    {
        int it = rem.top().second;
        add(ev[it].ly, ev[it].ry, -1, 0, K, 0);
        rem.pop();
    }

    if(tr[0].ans >= len) return true;
    return false;
}

void solve()
{
    ev.pb(Event(0, 1, m, 0));

    sort(ALL(ev), cmp);
    sort(ALL(sorted));
    sorted.pb(m + 1);
    sorted.erase(unique(ALL(sorted)), sorted.end());

    K = SZ(sorted) - 2;

    for(auto &it: ev)
    {
        it.ly = L_B(ALL(sorted), it.ly) - sorted.begin();
        it.ry = U_B(ALL(sorted), it.ry) - sorted.begin() - 1;
    }

    int low = 1, high = min(n, m), mid, ret = 0;
    while(low <= high)
    {
        mid = (low + high) >> 1;
        if(check(mid)) 
            ret = mid, low = mid + 1;
        else
            high = mid - 1;
    }

    cout << ret << endl;
}

int main()
{
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);

    read();
    solve();
    return 0;
}

int psb = 0;
char buff[MAXN];

void next_char() { if(++psb == MAXN) fread(buff, 1, MAXN, stdin), psb = 0; }

int read_int()
{
    int ret = 0;
    for(; buff[psb] < '0' || buff[psb] > '9'; next_char());
    for(; buff[psb] >= '0' && buff[psb] <= '9'; next_char())
        ret = ret * 10 + buff[psb] - '0';

    return ret;
}
