#include <cstdio>
#include <algorithm>
#include <map>
#include <vector>

using namespace std;

const int TSIZE = (1 << 22);

struct point
{
    int x, y;
    int type;

    point(int _x, int _y, int _type)
    {
        x = _x; y = _y; type = _type;
    }

    bool operator<(point other) const
    {
        return y < other.y || (y == other.y && x < other.x);
    }
};

int n, m;
int tree[TSIZE];

int get_index(int index)
{
    return (TSIZE >> 1) + index;
}

void update(int index, int value)
{
    index = get_index(index);

    tree[index] = value;
    index >>= 1;
    while(index)
    {
        tree[index] = max(tree[index * 2], tree[index * 2 + 1]);
        index >>= 1;
    }
}

int query(int l, int r)
{
    l = get_index(l); r = get_index(r);

    if(l == r)
    {
        return tree[l];
    }
    int ans = max(tree[l], tree[r]);

    while(l + 1 != r)
    {
        if((l & 1) == 0) ans = max(ans, tree[l + 1]);
        if((r & 1) == 1) ans = max(ans, tree[r - 1]);
        l >>= 1; r >>= 1;
    }
    return ans;
}

map < pair <int, int>, bool> marked;

vector <point> v;

void solve()
{
    scanf("%d %d", &n, &m);

    int q;
    scanf("%d", &q);

    //update(1, 0, MAXM, 2, 5, 1);

    //printf("%d\n", query(1, 0, MAXM, 2, 4));
    while(q--)
    {
        int x, y, x1, y1;
        scanf("%d %d %d %d", &x, &y, &x1, &y1);
        if(x == x1)
        {
            for(int i = y; i <= y1; i++)
            {
                if(!marked[{x, i}])
                {
                    v.push_back(point(x, i, 1));
                    marked[{x, i}] = true;
                }
                //marked[get_ind(x, i)] = true;
            }
        }
        else
        {
            for(int i = x; i <= x1; i++)
            {
                if(!marked[{i, y}])
                {
                    v.push_back(point(i, y, 1));
                    marked[{i, y}] = true;
                }
                //marked[get_ind(i, y)] = true;
            }
        }
    }

    for(int i = 1; i <= n; i++)
    {
        v.push_back(point(i, m + 1, 0));
    }
    for(int i = 1; i <= m; i++)
    {
        if(!marked[{1, i}])
        v.push_back(point(1, i, 0));
        if(!marked[{n, i}])
        v.push_back(point(n, i, 0));
    }

    sort(v.begin(), v.end());

    int ans = 0;

    //update(1, 5);
    //update(2, 6);
    //update(3, 3);

    //printf("%d\n", query(2, 3));

    int tempY = v[0].y;

    for(int i = 0; i < v.size(); i++)
    {
        if(tempY != v[i].y)
        {
            int j = i - 1;
            while(j - 1 >= 0 && v[j].y == v[j - 1].y)
            {
                if(v[j].type == 1)
                {
                    update(v[j].x, v[j].y);
                }
                j--;
            }
            if(v[j].type == 1)
            {
                update(v[j].x, v[j].y);
            }
        }
        int qr = query(v[i].x, v[i].x);
        int temp = v[i].y - qr - 1;
        //update(v[i].x, v[i].y);
        //printf("%d %d %d %d\n", v[i].x, v[i].y, temp, qr);
        int tnp = 1;
        int l = 1, r = v[i].x - 1;
        int tAns = 0;
        while(l <= r)
        {
            int middle = (l + r) / 2;
            int co = v[i].y - query(middle, v[i].x - 1) - 1;

            if(co >= temp)
            {
                tAns = middle;
                r = middle - 1;
            }
            else
            {
                l = middle + 1;
            }
        }
        if(tAns != 0)
        {
            tnp += v[i].x - tAns;
        }

        l = v[i].x + 1; r = n;
        tAns = 0;

        while(l <= r)
        {
            int middle = (l + r) / 2;
            int co = v[i].y - query(v[i].x + 1, middle) - 1;

            if(co >= temp)
            {
                tAns = middle;
                l = middle + 1;
            }
            else
            {
                r = middle - 1;
            }
        }
        if(tAns != 0)
        {
            tnp += tAns - v[i].x;
        }

        int current = min(tnp, temp);
        //printf("%d %d %d\n", v[i].x, v[i].y, tnp);
        ans = max(ans, current);
        tempY = v[i].y;
    }
    printf("%d\n", ans);
}

int main()
{
    solve();

    return 0;
}

/*
6 5
4
1 2 1 5
1 4 5 4
5 2 5 2
1 2 1 5
*/

/*
3 4
4
1 1 1 1
3 3 3 3
2 4 2 4
3 2 3 2
*/
