#include <cstdio>
#include <algorithm>

using namespace std;

const int MAXN = 1e3 + 5;

int n, m;
bool marked[MAXN][MAXN];
int uMost[MAXN], lMost[MAXN];
int T[MAXN][MAXN];


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

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

    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++)
            {
                marked[x][i] = true;
            }
        }
        else
        {
            for(int i = x; i <= x1; i++)
            {
                marked[i][y] = true;
            }
        }
    }

    int ans = 0;
    for(int i = 1; i <= m; i++)
    {
        uMost[i] = !marked[1][i];
        T[1][i] = !marked[1][i];
        ans = max(ans, T[1][i]);
    }
    for(int i = 1; i <= n; i++)
    {
        lMost[i] = !marked[i][1];
        T[i][1] = !marked[i][1];
        ans = max(ans, T[i][1]);
    }
    //printf("\n");
    for(int i = 2; i <= n; i++)
    {
        for(int j = 2; j <= m; j++)
        {
            lMost[i] = marked[i][j] == true? 0 : lMost[i] + 1;
            uMost[j] = marked[i][j] == true? 0 : uMost[j] + 1;
            //printf("%d %d %d %d\n", i, j, lMost[i][j], uMost[i][j]);

            int poss = min(lMost[i], uMost[j]);
            int tMost = T[i - 1][j - 1] + 1;
            T[i][j] = min(tMost, poss);
            ans = max(T[i][j], ans);
        }
    }
    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
*/
