1 #include <cstdio>
2 #include <iostream>
3 #include <vector>
4 #define N 1000010
5 using namespace std;
6 vector<int> P[N],Q[N];
7 struct Tree {int l,r,x,y,v;}tree[4*N];
8 int n,m,p,l,r,ans,x1[N],x2[N],y1[N],y2[N],lazy[4*N];
9 void build(int d,int l,int r)
10 {
11 tree[d].l=l,tree[d].r=r,tree[d].x=tree[d].y=tree[d].v=r-l+1;
12 if (l==r) return;
13 int mid=l+r>>1;
14 build(d*2,l,mid),build(d*2+1,mid+1,r);
15 }
16 void Lazy_down(int d)
17 {
18 if (lazy[d])
19 {
20 tree[d].x=tree[d].y=tree[d].v=0;
21 return;
22 }
23 if (tree[d].l==tree[d].r)
24 {
25 tree[d].x=tree[d].y=tree[d].v=1;
26 return;
27 }
28 tree[d].x=tree[d*2].x+(tree[d*2].x==tree[d*2].r-tree[d*2].l+1)*tree[d*2+1].x;
29 tree[d].y=tree[d*2+1].y+(tree[d*2+1].y==tree[d*2+1].r-tree[d*2+1].l+1)*tree[d*2].y;
30 tree[d].v=max(tree[d*2+1].x+tree[d*2].y,max(tree[d*2].v,tree[d*2+1].v));
31 }
32 void change(int d,int l,int r,int L,int R,int k)
33 {
34 if (L<=l&&r<=R) { lazy[d]+=k,Lazy_down(d); return; }
35 int mid=tree[d].l+tree[d].r>>1;
36 if (L<=mid) change(d*2,l,mid,L,R,k); if (mid<R) change(d*2+1,mid+1,r,L,R,k);
37 Lazy_down(d);
38 }
39 int main()
40 {
41 scanf("%d%d%d",&n,&m,&p);
42 for (int i=1;i<=p;i++) scanf("%d%d%d%d",&x1[i],&y1[i],&x2[i],&y2[i]),P[x1[i]].push_back(i),Q[x2[i]].push_back(i);
43 build(1,1,m),l=1,r=1;
44 while (r<=n)
45 {
46 for (int i=0;i<P[r].size();i++) change(1,1,m,y1[P[r][i]],y2[P[r][i]],1);
47 ans=max(ans,min(tree[1].v,r-l+1));
48 while (tree[1].v<r-l+1)
49 {
50 for (int i=0;i<Q[l].size();i++) change(1,1,m,y1[Q[l][i]],y2[Q[l][i]],-1);
51 l++;
52 }
53 r++;
54 }
55 printf("%d",ans);
56 }