/*不写点什么总是不好的,但我又懒,转载zjk‘s文字解析:
这道题暴力竟然可以过,可能是数据比较弱,就是把矩形拆成两条横边和纵边,然后暴力给一条边上的每一个点加权值,
如果用线段树的话,可能是用线段树维护区间和吧,貌似很麻烦的样子。
但是这个题有很多细节需要注意(扫描线的题大都有很多细节)。
为了使包含关系的边只出现一次,再加入左边时,要在区间权值为空(即以前未出现过包含这条边的边)时才更新答案,
另外在排序时如果位置相同,把左边排在前面,这是为了解决两个矩形前后重合的情况。
*/
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int N=1e4+10;
struct node{
int l,r,h,id;
bool operator < (const node &a)const{
return h==a.h?id<a.id:h<a.h;
}
}A[N*2],B[N*2];
int n,m,cnt,f[N*4];
int main(){
scanf("%d",&n);
for(int i=1,x1,y1,x2,y2;i<=n;i++){
scanf("%d%d%d%d",&x1,&y1,&x2,&y2);
x1+=10000,y1+=10000,x2+=10000,y2+=10000;
++cnt;
A[cnt].l=x1;A[cnt].r=x2;A[cnt].h=y1;A[cnt].id=0;
B[cnt].l=y1;B[cnt].r=y2;B[cnt].h=x1;B[cnt].id=0;
++cnt;
A[cnt].l=x1;A[cnt].r=x2;A[cnt].h=y2;A[cnt].id=1;
B[cnt].l=y1;B[cnt].r=y2;B[cnt].h=x2;B[cnt].id=1;
}
sort(A+1,A+cnt+1);sort(B+1,B+cnt+1);
int ans=0;
for(int i=1;i<=cnt;i++){
for(int j=A[i].l;j<A[i].r;j++){
if(!A[i].id){if(!f[j]) ans++;f[j]++;}
else {f[j]--;if(!f[j]) ans++;}
}
}
memset(f,0,sizeof f);
for(int i=1;i<=cnt;i++){
for(int j=B[i].l;j<B[i].r;j++){
if(!B[i].id){if(!f[j]) ans++;f[j]++;}
else {f[j]--;if(!f[j]) ans++;}
}
}
printf("%d",ans);
return 0;
}