#include<cmath>
#include<cstdio>
#include<cstring>
#include<algorithm>
typedef unsigned int uint;
typedef unsigned long long ulli;
typedef long long ll;
typedef double db;
namespace IO{
	int const SIZE=(1<<10);
	char put[SIZE],get[SIZE];
	int plen,glen=SIZE;

	void pc(char const &x){
		if(plen==SIZE){
			printf("%s",put+1);
			plen=0;
		}
		put[++plen]=x;
	}
	inline void read(int &x){
		x=0;char ch=getchar();bool f=0;
		while(ch<'0'||ch>'9'){if(ch=='-') f=1;ch=getchar();}
		while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}
		if(f) x=-x;
	}
	inline void write(int x){
		if(!x){pc('0');return;}
		if(x<0){x=-x;pc('-');}
		int num=0;char ch[25];
		while(x){ch[++num]=(x%10)^48;x/=10;}
		while(num) pc(ch[num--]);
	}
}
namespace algo{
	template<typename T>
	inline T max(T a,T b){return a>b?a:b;}
	template<typename T>
	inline T min(T a,T b){return a<b?a:b;}
	template<typename T>
	inline T const &abs(T x){return x<0?-x:x;}
	template<typename T>
	inline void swap(T &a,T &b){T t=a;a=b;b=t;}
	template<typename T>
	T gcd(T a,T b){return b==0?a:gcd(b,a%b);}
}

int const N=100010;
int n,k,a[N],ans;
bool fig[110][110];

void work1(){
	for(int i=1;i<=n;++i)
		for(int j=1;j<i;++j){
			if(a[i]>a[j]) fig[i][j]=1,fig[j][i]=0;
			else fig[i][j]=0,fig[j][i]=1;
		}
	int l,r;
	for(int i=1;i<=k;++i){
		scanf("%d%d",&l,&r);
		for(int j=1;j<=n;++j)
			if(l<=a[j]&&a[j]<=r)
				for(int k=1;k<j;++k)
					if(l<=a[k]&&a[k]<=r){
						fig[j][k]^=1;fig[k][j]^=1;
					}
	}
	for(int i=1;i<=n;++i)
		for(int j=1;j<i;++j)
			if(fig[i][j]||fig[j][i])
				for(int k=1;k<j;++k){
					if(fig[j][k]&&fig[k][i]) ++ans;
					else if(fig[k][j]&&fig[i][k]) ++ans;
				}
}

int main(){
//	freopen("fight.in","r",stdin);
//	freopen("fight.out","w",stdout);
	scanf("%d%d",&n,&k);
	if(k==0){
		puts("0");
		return 0;
	}
	for(int i=1;i<=n;++i) IO::read(a[i]);
	work1();
	printf("%d",ans);
	return 0;
}


#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<string>
#include<cmath>
#include<queue>
#include<map>
#define N 300003
#include<bitset>
#include<deque>
#include<cstdlib>
#include<set>
#include<ctime>
#define ll long long
using namespace std;
ll read()
{
	ll x=0,f=1;
	char c=getchar();
	while(c>'9'||c<'0')
	{
		if(c=='-') f=-1;
		c=getchar();
	}
	while(c>='0'&&c<='9')
	{
		x=x*10+c-'0';
		c=getchar();
	}
	return f*x;
}
int n,k,a[N],top;
struct TREE{
	bool re;
	int x;
}tr[N*8];
ll ans;
void pushup(int x)
{
	int l=x<<1,r=x<<1|1;
	tr[x].x=tr[l].x+tr[r].x;
}
void pushdown(int x,int len)
{
	int l=x<<1,r=x<<1|1,lenr=len>>1,lenl=len-(len>>1);
	if(tr[x].re)
	{
		tr[x].re=0;
		tr[l].re^=1;
		tr[r].re^=1;
		tr[l].x=lenl-tr[l].x;
		tr[r].x=lenr-tr[r].x;
	}
}
struct node{
	int id,l,r;
}st[N<<1];
bool cmp(node x,node y)
{
	return x.id<y.id;
}
void rever(int rt,int l,int r,int first,int end)
{

	if(first>end) return ;
	if(first<=l&&r<=end)
	{
		tr[rt].re^=1;
		tr[rt].x=r-l+1-tr[rt].x;
		return ;
	}
	pushdown(rt,r-l+1);
	int mid=l+r>>1;
	if(first<=mid) rever(rt<<1,l,mid,first,end);
	if(end>mid) rever(rt<<1|1,mid+1,r,first,end);
	pushup(rt);
}
int query(int rt,int l,int  r,int first,int end)
{
	if(first>end) return 0;
	if(first<=l&&r<=end)
	{
		return tr[rt].x;
	}
	int mid=l+r>>1;
	pushdown(rt,r-l+1);
	int ans=0;
	if(first<=mid) ans+=query(rt<<1,l,mid,first,end);
	if(end>mid) ans+=query(rt<<1|1,mid+1,r,first,end);
	return ans;
}
int main()
{
//	freopen("fight.in","r",stdin);
//	freopen("fight.out","w",stdout);
	n=read(),k=read();
	for(int i=1;i<=n;++i) 	a[i]=read();
	sort(a+1,a+1+n);
	for(int i=1;i<=k;++i)
	{
		int L=read(),R=read();
		int t1=lower_bound(a+1,a+1+n,L)-a,t2=upper_bound(a+1,a+1+n,R)-a;
	////	if(t1>t2||t1==n+1) continue;
	if(t1==t2)continue;
		st[++top]=(node){t1,t1,t2-1};
		st[++top]=(node){t2,t1,t2-1};
	}
	sort(st+1,st+1+top,cmp);
	int now=1;
	ans=1ll*n*(n-1)*(n-2)/6;
	for(int i=1;i<=n;++i)
	{
		while(st[now].id==i&&now<=top)
		{
			rever(1,1,n,st[now].l,st[now].r);
			++now;
		}
		int tmp=(i-1-query(1,1,n,1,i-1))+query(1,1,n,i+1,n);
		ans-=1ll*tmp*(tmp-1)/2;
		//ans-=1ll*(i-1-query(1,1,n,1,i-1))*query(1,1,n,i+1,n);
	//	cout<<i<<":"<<ans<<endl;
	}
	cout<<ans<<'\n';
	return 0;
 }


#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<vector>
#define ll long long
using namespace std;
const int maxn=1e5+9;
int n,k;
int a[maxn];
int ans[maxn<<2],tag[maxn<<2];
int ls(int p){return p<<1;}
int rs(int p){return p<<1|1;}
int push_up(int p){ans[p]=ans[ls(p)]+ans[rs(p)];}
void f(ll p,ll l,ll r)
{
	tag[p]^=1;
	ans[p]=r-l+1-ans[p];
}
void push_down(ll p,ll l, ll r)
{
	if(tag[p])
	{
		ll mid=l+r>>1;
		f(ls(p),l,mid);
		f(rs(p),mid+1,r);
		tag[p]=0;
	}
}
void update(ll nl,ll nr,ll l,ll r,ll p)
{
	if(nl<=l&&nr>=r){f(p,l,r);return;}
	ll mid=l+r>>1;
	push_down(p,l,r);
	if(nl<=mid) update(nl,nr,l,mid,ls(p));
	if(nr>mid) update(nl,nr,mid+1,r,rs(p));
	push_up(p);
}
ll query(ll nl,ll nr,ll l,ll r,ll p)
{
	ll res=0;
	if(nl<=l&&nr>=r){return ans[p];}
	ll mid=l+r>>1;
	push_down(p,l,r);
	if(nl<=mid)res+=query(nl,nr,l,mid,ls(p));
	if(nr>mid) res+=query(nl,nr,mid+1,r,rs(p));
	return res;
}
ll C(ll n,ll m)
{
	if(m==1)return n;
	if(n==m)return 1;
	return C(n-1,m)+C(n-1,m-1);
}
int l,r;
vector<int>vl[maxn],vr[maxn];
int main()
{
	cin>>n>>k;
	int tot=C(n,3);
	for(int i=0;i<n;i++)scanf("%d",&a[i]);// cin>>a[i];
	sort(a,a+n);
	while(k--)
	{
//		cin>>l>>r;
		scanf("%d%d",&l,&r);
		l=lower_bound(a,a+n,l)-a;
		r=upper_bound(a,a+n,r)-a-1;
		if(l>r)continue;
		vl[l].push_back(r);
		vr[r].push_back(l);
	}
	for(int i=0;i<n;i++)
	{
		for(int j=0;j<vl[i].size();j++)update(i,vl[i][j],0,n-1,1);
		int res=0;
		if(i)res+=i-query(0,i-1,0,n-1,1);
		if(i<n-1)res+=query(i+1,n-1,0,n-1,1);
//		cout<<res<<endl;
		tot-=res*(res-1)/2;
		for(int j=0;j<vr[i].size();j++)update(vr[i][j],i,0,n-1,1);
	}
	cout<<tot<<endl;
}


#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<vector>
#define ll long long
using namespace std;
const long long maxn=1e5+9;
long long n,k;
int a[maxn];
long long ans[maxn<<2],tag[maxn<<2];
long long ls(long long p){return p<<1;}
long long rs(long long p){return p<<1|1;}
long long push_up(long long p){ans[p]=ans[ls(p)]+ans[rs(p)];}
void f(ll p,ll l,ll r)
{
	tag[p]^=1;
	ans[p]=r-l+1-ans[p];
}
void push_down(ll p,ll l, ll r)
{
	if(tag[p])
	{
		ll mid=l+r>>1;
		f(ls(p),l,mid);
		f(rs(p),mid+1,r);
		tag[p]=0;
	}
}
void update(ll nl,ll nr,ll l,ll r,ll p)
{
	if(nl<=l&&nr>=r){f(p,l,r);return;}
	ll mid=l+r>>1;
	push_down(p,l,r);
	if(nl<=mid) update(nl,nr,l,mid,ls(p));
	if(nr>mid) update(nl,nr,mid+1,r,rs(p));
	push_up(p);
}
ll query(ll nl,ll nr,ll l,ll r,ll p)
{
	ll res=0;
	if(nl<=l&&nr>=r){return ans[p];}
	ll mid=l+r>>1;
	push_down(p,l,r);
	if(nl<=mid)res+=query(nl,nr,l,mid,ls(p));
	if(nr>mid) res+=query(nl,nr,mid+1,r,rs(p));
	return res;
}

int l,r;
vector<long long>vl[maxn],vr[maxn];
int main()
{
	cin>>n>>k;
	long long tot=1l*n*(n-1)*(n-2)/6;
	for(long long i=0;i<n;i++)scanf("%d",&a[i]);// cin>>a[i];
	sort(a,a+n);
	while(k--)
	{
//		cin>>l>>r;
		scanf("%d%d",&l,&r);
		l=lower_bound(a,a+n,l)-a;
		r=upper_bound(a,a+n,r)-a-1;
		if(l>r)continue;
		vl[l].push_back(r);
		vr[r].push_back(l);
	}
	for(int i=0;i<n;i++)
	{
		for(int j=0;j<(int)vl[i].size();j++)update(i,vl[i][j],0,n-1,1);
		long long res=0;
		if(i)res+=i-query(0,i-1,0,n-1,1);
		if(i<n-1)res+=query(i+1,n-1,0,n-1,1);
//		cout<<res<<endl;
		tot-=res*(res-1)/2;
		for(int j=0;j<(int)vr[i].size();j++)update(vr[i][j],i,0,n-1,1);
	}
	cout<<tot<<endl;
}


#include<iostream>
#include<cstring>
#include<algorithm>
#include<vector>
#define N 110000
using namespace std;
struct D{
	int l,r;
};
vector<D>a,b;
int L[N*5],R[N*5],len[N*5],tag[N*5],val[N*5],s[N];
int n,m;
long long ans;
inline void swap(int &a,int &b){
    int t=a;
    a=b;
    b=t;
}
void build(int x,int l,int r){
    len[x]=r-l+1;
    L[x]=l,R[x]=r;
    if(l>=r)
        return;
    int mid=(l+r)>>1;
    build(x<<1,l,mid);
    build(x<<1|1,mid+1,r);
}
void pushdown(int x){
    if(!tag[x])
        return;
    tag[x<<1]^=1;
    val[x<<1]=len[x<<1]-val[x<<1];
    tag[x<<1|1]^=1;
    val[x<<1|1]=len[x<<1|1]-val[x<<1|1];
    tag[x]=0;
}
void modify(int x,int l,int r){
    if(L[x]>=l&&R[x]<=r){
        val[x]=len[x]-val[x];
        tag[x]^=1;
        return;
    }
    pushdown(x);
    int mid=(L[x]+R[x])>>1;
    if(l<=mid)
        modify(x<<1,l,r);
    if(r>mid)
        modify(x<<1|1,l,r);
    val[x]=val[x<<1]+val[x<<1|1];
}
int query(int x,int l,int r){
    if(L[x]>=l&&R[x]<=r)
        return val[x];
    pushdown(x);
    int res=0;
    int mid=(L[x]+R[x])>>1;
    if(l<=mid)
        res+=query(x<<1,l,r);
    if(r>mid)
        res+=query(x<<1|1,l,r);
    return res;
}
bool cmp(D x,D y){
	return x.l<y.l;
}
bool cmp2(D x,D y){
	return x.r<y.r;
}
int main(){
    ios::sync_with_stdio(false);
    cin.tie(NULL);
    cout.tie(NULL);
    cin>>n>>m;
    ans=1LL*n*(n-1)*(n-2)/6;
    build(1,0,n);
    for(int i=1;i<=n;i++)
    	cin>>s[i];
    sort(s+1,s+n+1);
    D h;
    h.l=h.r=0;
    a.push_back(h),b.push_back(h);
    for(int i=1;i<=m;i++){
    	int x,y;
    	cin>>x>>y;
    	x=lower_bound(s+1,s+n+1,x)-s;
    	y=upper_bound(s+1,s+n+1,y)-s-1;
//    	if(y==0)
//    		continue;
    	D t;
    	t.l=x,t.r=y;
    	a.push_back(t),b.push_back(t);
	}
	m=a.size()-1;
	sort(a.begin(),a.end(),cmp);
	sort(b.begin(),b.end(),cmp2);
	int p=0,q=0;
	for(int i=1;i<=n;i++){
		long long d=0;
		while(p<m&&a[p+1].l<=i){
			p++;
			modify(1,a[p].l,a[p].r);
		}
		while(q<m&&b[q+1].r<i){
			q++;
			modify(1,b[q].l,b[q].r);
		}
		if(i>1)
			d+=(i-1)-query(1,1,i-1);
		if(i<n)
			d+=query(1,i+1,n);
		ans-=(d*(d-1))/2;
	}
	cout<<ans;
    return 0;
}


#include<iostream>
#include<cstring>
#include<algorithm>
#include<vector>
#define N 110000
using namespace std;
struct D{
	int l,r;
};
vector<D>a,b;
int L[N*5],R[N*5],len[N*5],tag[N*5],val[N*5],s[N];
int n,m;
long long ans;
inline void swap(int &a,int &b){
    int t=a;
    a=b;
    b=t;
}
void build(int x,int l,int r){
    len[x]=r-l+1;
    L[x]=l,R[x]=r;
    if(l>=r)
        return;
    int mid=(l+r)>>1;
    build(x<<1,l,mid);
    build(x<<1|1,mid+1,r);
}
void pushdown(int x){
    if(!tag[x])
        return;
    tag[x<<1]^=1;
    val[x<<1]=len[x<<1]-val[x<<1];
    tag[x<<1|1]^=1;
    val[x<<1|1]=len[x<<1|1]-val[x<<1|1];
    tag[x]=0;
}
void modify(int x,int l,int r){
    if(L[x]>=l&&R[x]<=r){
        val[x]=len[x]-val[x];
        tag[x]^=1;
        return;
    }
    pushdown(x);
    int mid=(L[x]+R[x])>>1;
    if(l<=mid)
        modify(x<<1,l,r);
    if(r>mid)
        modify(x<<1|1,l,r);
    val[x]=val[x<<1]+val[x<<1|1];
}
int query(int x,int l,int r){
    if(L[x]>=l&&R[x]<=r)
        return val[x];
    pushdown(x);
    int res=0;
    int mid=(L[x]+R[x])>>1;
    if(l<=mid)
        res+=query(x<<1,l,r);
    if(r>mid)
        res+=query(x<<1|1,l,r);
    return res;
}
bool cmp(D x,D y){
	return x.l<y.l;
}
bool cmp2(D x,D y){
	return x.r<y.r;
}
int main(){
    ios::sync_with_stdio(false);
    cin.tie(NULL);
    cout.tie(NULL);
    cin>>n>>m;
    ans=1LL*n*(n-1)*(n-2)/6;
    build(1,1,n);
    for(int i=1;i<=n;i++)
    	cin>>s[i];
    sort(s+1,s+n+1);
    D h;
    h.l=h.r=0;
    a.push_back(h),b.push_back(h);
    for(int i=1;i<=m;i++){
    	int x,y;
    	cin>>x>>y;
    	x=lower_bound(s+1,s+n+1,x)-s;
    	y=upper_bound(s+1,s+n+1,y)-s-1;
    	if(y==0)
    		continue;
    	D t;
    	t.l=x,t.r=y;
    	a.push_back(t),b.push_back(t);
	}
	m=a.size()-1;
	sort(a.begin(),a.end(),cmp);
	sort(b.begin(),b.end(),cmp2);
	int p=0,q=0;
	for(int i=1;i<=n;i++){
		long long d=0;
		while(p<m&&a[p+1].l<=i){
			p++;
			modify(1,a[p].l,a[p].r);
		}
		while(q<m&&b[q+1].r<i){
			q++;
			modify(1,b[q].l,b[q].r);
		}
		if(i>1)
			d+=(i-1)-query(1,1,i-1);
		if(i<n)
			d+=query(1,i+1,n);
		ans-=(d*(d-1))/2;
	}
	cout<<ans;
    return 0;
}


#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
typedef long long ll;
ll read()
{
	char ch=' ';
	ll f=1;ll x=0;
	while(ch<'0'||ch>'9')
	{
		if(ch=='-') f=-1;ch=getchar();
	}
	while(ch>='0'&&ch<='9')
	{
	    x=x*10+ch-'0';ch=getchar();
	}
	return x*f;
}
const ll N=1e5+100;
ll z[N];
struct node
{
	ll l,r;
}c[N];
bool cmp1(node a,node b)
{
	return a.l<b.l;
}
bool cmp2(node a,node b)
{
	return a.r>b.r;
}
struct tree
{
	ll cnt0;
	ll cnt1;
	ll tag;
}t[N<<2];
ll in[N];

void update(ll rt)
{
	t[rt].cnt0=t[rt<<1].cnt0+t[rt<<1|1].cnt0;
	t[rt].cnt1=t[rt<<1].cnt1+t[rt<<1|1].cnt1;
	return ;
}
void build(ll rt,ll l,ll r)
{
	t[rt].cnt0=1;
	t[rt].cnt1=0;
	t[rt].tag=0;
	if(l==r)
	{
		return ;
	}
	ll mid=(l+r) >> 1;
	build(rt<<1,l,mid);
	build(rt<<1|1,mid+1,r);
	update(rt);
}
void pushdown(ll rt)
{
	t[rt].tag=0;
	swap(t[rt<<1].cnt0,t[rt<<1].cnt1);
	swap(t[rt<<1|1].cnt0,t[rt<<1|1].cnt1);
	t[rt<<1].tag=1;t[rt<<1|1].tag=1;
}
void modify(ll rt,ll l,ll r,ll x,ll y)
{
	if(l>=x&&r<=y)
	{
		swap(t[rt].cnt0,t[rt].cnt1);
		t[rt].tag^=1;
		return ;
	}
	if(t[rt].tag==1)
	{
		pushdown(rt);
	}
	ll mid=(l+r) >> 1;
	if(x<=mid)
	{
		modify(rt<<1,l,mid,x,y);
	}
	if(y>mid)
	{
		modify(rt<<1|1,mid+1,r,x,y);
	}
	update(rt);
}
ll query(ll rt,ll l,ll r,ll x,ll y)
{
	if(l>=x&&r<=y)
	{
		return t[rt].cnt1;
	}
	if(t[rt].tag==1)
	{
		pushdown(rt);
	}
	ll mid=(l+r) >> 1;
	ll ret=0;
	if(x<=mid)
	{
		ret+=query(rt<<1,l,mid,x,y);
	}
	if(y>mid)
	{
		ret+=query(rt<<1|1,mid+1,r,x,y);
	}
	return ret;
}
int main()
{
	ll n,m;
	n=read();m=read();
	ll i,j;
	for(i=1;i<=n;i++)
	{
		z[i]=read();
	}
	sort(z+1,z+1+n);
	for(i=1;i<=m;i++)
	{
		c[i].l=read();
		c[i].r=read();
		c[i].l=lower_bound(z+1,z+1+n,c[i].l)-z;
		c[i].r=upper_bound(z+1,z+1+n,c[i].r)-z-1;
		//cout<<c[i].l<<' '<<c[i].r<<endl;
	}
	sort(c+1,c+1+m,cmp1);
	build(1,1,n);
	for(i=1,j=1;i<n;i++)
	{
		while(c[j].l<=i&&j<=m)
		{
			modify(1,1,n,c[j].l,c[j].r);
			j++;
		}
		in[i]=query(1,1,n,i+1,n);
	}
	build(1,1,n);
	sort(c+1,c+1+m,cmp2);
	for(i=n,j=1;i>1;i--)
	{
		while(c[j].r>=i&&j>=1)
		{
			modify(1,1,n,c[j].l,c[j].r);
			j++;
		}
		in[i]+=i-1-query(1,1,n,1,i-1);
	}
	ll ans=n*(n-1)*(n-2)/6;
	for(i=1;i<=n;i++)
	{
		ans-=in[i]*(in[i]-1)/2;
	}
	cout<<ans<<endl;
	return 0;
}


#include<bits/stdc++.h>
#define int long long
using namespace std;
struct nod{
	int l,r,sum,lazy;
}tree[400010];
struct node{
	int l,r;
}a[100010],b[100010];
int s[100010];
int n,k,ans;
int read(){
	int r=0,f=1;char c=getchar();
	while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
	while(c<='9'&&c>='0') r=(r<<1)+(r<<3)+c-'0',c=getchar();
	return r*f;
}
void put(int x){
	if(x<0){putchar('-');x=~x+1;}
	if(x>9) put(x/10);
	putchar(x%10+'0');
}
void build(int p,int l,int r){
	tree[p].l=l,tree[p].r=r;
	if(l==r) return ;
	int mid=l+r>>1;
	build(p<<1,l,mid);build((p<<1)+1,mid+1,r);
//	tree[p].sum=tree[p<<1].sum+tree[(p<<1)+1].sum;
}
void spread(int p){
	if(!tree[p].lazy) return ;
	tree[p<<1].sum=tree[p<<1].r-tree[p<<1].l+1-tree[p<<1].sum;
	tree[(p<<1)+1].sum=tree[(p<<1)+1].r-tree[(p<<1)+1].l+1-tree[(p<<1)+1].sum;
	tree[p<<1].lazy^=1;
	tree[(p<<1)+1].lazy^=1;
	tree[p].lazy=0;
}
void change(int p,int l,int r){
//	cout<<p<<" "<<tree[p].l<<" "<<tree[p].r<<" "<<tree[p].sum<<" "<<tree[p].lazy<<endl;
	if(tree[p].l>=l&&tree[p].r<=r){tree[p].sum=tree[p].r-tree[p].l+1-tree[p].sum,tree[p].lazy^=1;return ;}
	spread(p);
	int mid=tree[p].l+tree[p].r>>1;
	if(l<=mid) change(p<<1,l,r);
	if(r>mid) change((p<<1)+1,l,r);
	tree[p].sum=tree[p<<1].sum+tree[(p<<1)+1].sum;
//	cout<<p<<" "<<tree[p].l<<" "<<tree[p].r<<" "<<tree[p].sum<<" "<<tree[p].lazy<<endl;
}
int ask(int p,int l,int r){
	if(tree[p].l>=l&&tree[p].r<=r)/*{*/
//		if(tree[p].lazy) return tree[p].r-tree[p].l+1-tree[p].sum;
		return tree[p].sum;
//	}
	spread(p);
	int mid=tree[p].l+tree[p].r>>1,anss=0;
	if(l<=mid) anss+=ask(p<<1,l,r);
	if(r>mid) anss+=ask((p<<1)+1,l,r);
	return anss;
}
int cmp1(node x,node y){return x.l<y.l;}
int cmp2(node x,node y){return x.r<y.r;}
signed main(){
	n=read(),k=read(),ans=n*(n-1)*(n-2)/6;
	for(int i=1;i<=n;i++) s[i]=read();
	sort(s+1,s+1+n);build(1,1,n);
	for(int i=1;i<=k;i++) a[i].l=b[i].l=lower_bound(s+1,s+1+n,read())-s,a[i].r=b[i].r=upper_bound(s+1,s+1+n,read())-s-1;
	sort(a+1,a+1+k,cmp1),sort(b+1,b+1+k,cmp2);
	int p=0,q=0;
	for(int i=1;i<=n;i++){
		int kv=0;
		while(p<k&&a[p+1].l<=i){p++;/*cout<<endl<<endl<<a[p].l<<" "<<a[p].r<<endl;*/change(1,a[p].l,a[p].r);/*cout<<endl<<endl;*/}
		while(q<k&&b[q+1].r<i){q++;/*cout<<endl<<endl<<b[q].l<<" "<<b[q].r<<endl;*/change(1,b[q].l,b[q].r);/*cout<<endl<<endl;*/}
		if(i>1) kv+=i-1-ask(1,1,i-1);
//		put(kv);puts("");
		if(i<n) kv+=ask(1,i+1,n);
//		put(kv);puts("");
		ans-=kv*(kv-1)/2;
	}
	put(ans);puts("");
	return 0;
}


#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;
const int N = 1e5+10;
typedef long long ll;

int n,k,s[N],l,r;
struct Seg{
	ll lz,sum;
}t[N<<2];
ll ans,res;
vector<int>upl[N],upr[N];

inline void read(int &x){
	x=0;char ch=getchar();
	while(ch<'0' || ch>'9')ch=getchar();
	while(ch>='0' && ch<='9')x=x*10+ch-'0',ch=getchar();
	return;
}

inline void pushdown(int p,int L,int R){
	if(!t[p].lz)return;
	int mid=(L+R)>>1;
	t[p].lz^=1;t[p<<1].lz^=1;t[p<<1|1].lz^=1;
	t[p<<1].sum=mid-L+1-t[p<<1].sum;
	t[p<<1|1].sum=R-mid-t[p<<1|1].sum;
	return;
}

void update(int p,int L,int R,int l,int r){
	if(l<=L && R<=r){
		t[p].lz^=1;
		t[p].sum=R-L+1-t[p].sum;
		return;
	}
	pushdown(p,L,R);int mid=(L+R)>>1;
	if(l<=mid)update(p<<1,L,mid,l,r);
	if(r>mid)update(p<<1|1,mid+1,R,l,r);
	t[p].sum=t[p<<1].sum+t[p<<1|1].sum;
	return;
}

ll query(int p,int L,int R,int l,int r){
	if(l<=L && R<=r){
		return t[p].sum;
	}
	pushdown(p,L,R);
	int mid=(L+R)>>1;ll tmp=0;
	if(l<=mid)tmp+=query(p<<1,L,mid,l,r);
	if(r>mid)tmp+=query(p<<1|1,mid+1,R,l,r);
	return tmp;
}

int main(){

	read(n);read(k);
	for(int i=0;i<n;++i)read(s[i]);
	sort(s,s+n);
	while(k--){
		read(l);read(r);
		l=lower_bound(s,s+n,l)-s;
		r=upper_bound(s,s+n,r)-s-1;
		if(l>r)continue;
		upl[l].push_back(r);upr[r].push_back(l);
	}
	ans=1ll*n*(n-1)*(n-2)/6;
	for(int i=0;i<n;++i){
		for(int j=0;j<upl[i].size();++j)update(1,0,n-1,i,upl[i][j]);
		res=0;
		if(i)res+=i-query(1,0,n-1,0,i-1);
		if(i<n-1)res+=query(1,0,n-1,i+1,n-1);
		ans-=1ll*(res-1)*res/2;
		for(int j=0;j<upr[i].size();++j)update(1,0,n-1,upr[i][j],i);
	}
	printf("%lld\n",ans);

	return 0;
}


#include<iostream>
#include<cstdio>
#include<algorithm>
#include<vector>
using namespace std;
#define in read()
#define fur(i,a,b) for(int i=a;i<=b;i++)
#define xx 110000
#define int long long
#define ll long long
inline int read()
{
    int x=0,f=1;char ch=getchar();
    for(;!isalnum(ch);ch=getchar()) if(ch=='-') f=-1;
    for(;isalnum(ch);ch=getchar()) x=x*10+ch-'0';
    return x*f;
}
int s2[xx],s1[xx],s[xx],cnt[xx];
int tree[xx],n,c[4][xx],all=0;
struct prom{int a,b;}t[xx];
struct linetree{int l,r,tot,sum;bool tag;}lt[xx<<2];
inline bool cmp(prom x,prom y){return x.a<y.a;}
vector<int>e[xx];
inline int look2(int x)
{
    int head=1,tail=all,ans=1;
    while(head<=tail)
    {
        int mid=(head+tail)>>1;
        if(s1[mid]<=x) ans=mid,head=mid+1;
        else tail=mid-1;
    }
    return ans;
}
inline int look1(int x)
{
    int head=1,tail=all,ans=all;
    while(head<=tail)
    {
        int mid=(head+tail)>>1;
        if(s1[mid]>=x) ans=mid,tail=mid-1;
        else head=mid+1;
    }
    return ans;
}
inline void up(int k)
{
    int q=k<<1;
    lt[k].sum=lt[q].sum+lt[q+1].sum;
    lt[k].tot=lt[q].tot+lt[q+1].tot;
}
inline void down(int k)
{
    if(lt[k].tag)
    {
        int q=k<<1;
        lt[q].sum=lt[q].tot-lt[q].sum;
        lt[q+1].sum=lt[q+1].tot-lt[q+1].sum;
        lt[q].tag^=1;
        lt[q+1].tag^=1;
        lt[k].tag^=1;
    }
}
inline void build(int k,int i,int j)
{
    lt[k].l=i;
    lt[k].r=j;
    if(i==j)
    {
        lt[k].tot=cnt[i];
        return;
    }
    int q=k<<1,mid=(i+j)>>1;
    build(q,i,mid);
    build(q+1,mid+1,j);
    up(k);
}
inline void change(int k,int i,int j)
{
    if(i<=lt[k].l&&j>=lt[k].r)
    {
        lt[k].sum=lt[k].tot-lt[k].sum;
        lt[k].tag^=1;
        return;
    }
    down(k);
    int q=k<<1,mid=lt[q].r;
    if(i<=mid) change(q,i,j);
    if(j>mid) change(q+1,i,j);
    up(k);
}
inline int askus(int k,int i,int j)
{
	if(i>j) return 0;
    if(i<=lt[k].l&&j>=lt[k].r) return lt[k].tot-lt[k].sum;
    down(k);
    int q=k<<1,mid=lt[q].r,res=0;
    if(i<=mid) res+=askus(q,i,j);
    if(j>mid) res+=askus(q+1,i,j);
    return res;
}
inline int askrs(int k,int i,int j)
{
	if(i>j) return 0;
    if(i<=lt[k].l&&j>=lt[k].r) return lt[k].sum;
    down(k);
    int q=k<<1,mid=lt[q].r,res=0;
    if(i<=mid) res+=askrs(q,i,j);
    if(j>mid) res+=askrs(q+1,i,j);
    return res;
}
signed main()
{
    n=in;
    fur(i,1,n)
    {
        c[0][i]=1;c[1][i]=i;
        fur(j,2,min(i,3ll)) c[j][i]=c[j-1][i-1]+c[j][i-1];
    }
    int k=in;
    fur(i,1,n) s2[i]=s1[i]=s[i]=in;
    sort(s2+1,s2+n+1);
    fur(i,1,n)
    {
        while(s2[i]==s2[i+1]) i++;
        s1[++all]=s2[i];
    }
    fur(i,1,n) s[i]=look1(s[i]),cnt[s[i]]++;
    sort(s+1,s+n+1);
    build(1,1,s[n]);
    fur(i,1,k) t[i].a=in,t[i].b=in;
    fur(i,1,k) t[i].a=look1(t[i].a),t[i].b=look2(t[i].b);
    sort(t+1,t+k+1,cmp);
    int ans=c[3][n],tnt=1;
    fur(i,1,s[n])
    {
        while(t[tnt].a<=i&&tnt<=k)
        {
            change(1,t[tnt].a,t[tnt].b);
            e[t[tnt].b].push_back(t[tnt].a);
            tnt++;
        }
        fur(j,0,(int)e[i-1].size()-1) change(1,e[i-1][j],i-1ll);
        int res=0;
        res+=askus(1,1,i-1);
        res+=askrs(1,i+1,s[n]);
        ans-=cnt[i]*c[2][res];
		ans-=c[2][cnt[i]];
    }
    printf("%lld\n",ans);
    return 0;
}


#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<string>
#include<cmath>
#include<queue>
#include<map>
#define N 3003
#include<bitset>
#include<deque>
#include<cstdlib>
#include<set>
#include<ctime>
#define ll long long
using namespace std;
ll read()
{
	ll x=0,f=1;
	char c=getchar();
	while(c>'9'||c<'0')
	{
		if(c=='-') f=-1;
		c=getchar();
	}
	while(c>='0'&&c<='9')
	{
		x=x*10+c-'0';
		c=getchar();
	}
	return f*x;
}
int n,k,a[N],num,top,b[N];
struct TREE{
	bool re;
	int x;
}tr[N*8];
ll ans;
bitset<N>bs[N];
void pushup(int x)
{
	int l=x<<1,r=x<<1|1;
	tr[x].x=tr[l].x+tr[r].x;
}
void pushdown(int x,int len)
{
	int l=x<<1,r=x<<1|1,lenl=len>>1,lenr=len-(len>>1);
	if(tr[x].re)
	{
		tr[x].re=0;
		tr[l].re^=1;
		tr[r].re^=1;
		tr[l].x=lenl-tr[l].x;
		tr[r].x=lenr-tr[r].x;
	}
}
struct node{
	int id,op,l,r;
}st[N];
bool cmp(node x,node y)
{
	return x.id<y.id;
}
void build(int rt,int l,int r)
{
	tr[rt].re=0;
	if(l==r){
		tr[rt].re=tr[rt].x=0;
		return ;
	}
	int mid=l+r>>1;
	build(rt<<1,l,mid);
	build(rt<<1|1,mid+1,r);
}
void rever(int rt,int l,int r,int first,int end)
{
	if(first<=l&&r<=end)
	{
		tr[rt].re^=1;
		tr[rt].x=r-l+1-tr[rt].x;
		return ;
	}
	pushdown(rt,r-l+1);
	int mid=l+r>>1;
	if(first<=mid) rever(rt<<1,l,mid,first,end);
	if(end>mid) rever(rt<<1|1,mid+1,r,first,end);
	pushup(rt);
}
int query(int rt,int l,int  r,int first,int end)
{
	if(first>end) return 0;
	if(first<=l&&r<=end)
	{
		return tr[rt].x;
	}
	int mid=l+r>>1;
	pushdown(rt,r-l+1);
	int ans=0;
	if(first<=mid) ans+=query(rt<<1,l,mid,first,end);
	if(end>mid) ans+=query(rt<<1|1,mid+1,r,first,end);
	return ans;
}
int erflow(int x)
{
	int l=1,r=n,ans=n+1;
	while(l<=r)
	{
		int mid=l+r>>1;
		if(a[mid]>=x) ans=mid,r=mid-1;
		else l=mid+1;
	 }
	 return x;
}
int erfupp(int x)
{
	int l=1,r=n,ans=n+1;
	while(l<=r)
	{
		int mid=l+r>>1;
		if(a[mid]>x) ans=mid,r=mid-1;
		else l=mid+1;
	 }
	 return x;
}
int main()
{
//	freopen("fight.in","r",stdin);
//	freopen("fight.out","w",stdout);
	n=read(),k=read();
	for(int i=1;i<=n;++i) 	a[i]=read();
	sort(a+1,a+1+n);
	for(int i=1;i<=k;++i)
	{
		int L=read(),R=read();
		int t1=erflow(L),t2=erfupp(R);
		if(t1>t2||t1==n+1) continue;
		st[++top]=(node){t1,1,t1,t2-1};
		st[++top]=(node){t2,-1,t1,t2-1};
	}
	sort(st+1,st+1+top,cmp);
/*	for(int i=1;i<=top;++i)
	{
		if(i==1||st[i].x!=st[i-1].x) num++;
		if(st[i].op==0) a[st[i].id]=num;
		else if(st[i].op==1) l[st[i].id]=num;
		else r[st[i].id]=num;
	}
	for(int i=1;i<=n;++i)
	{
		if(i==1||a[i]!=a[i-1]) num++;
		b[i]=num;
	}*/
	int now=1;
	ans=1ll*n*(n-1)*(n-2)/6;
//	cout<<ans<<endl;
	for(int i=1;i<=n;++i)
	{
		while(st[now].id==i&&now<=top)
		{
			rever(1,1,n,st[now].l,st[now].r);
			++now;
		}
		ans-=1ll*(i-1-query(1,1,n,1,i-1))*query(1,1,n,i+1,n);
	//	cout<<i<<":"<<ans<<endl;
	}
	cout<<ans<<'\n';
	return 0;
 }


#include<iostream>
#include<cstring>
#include<algorithm>
#define N 110000
using namespace std;
struct D{
	long long l,r;
}a[N],b[N];
long long L[N*5],R[N*5],len[N*5],tag[N*5],val[N*5],s[N];
long long n,m;
long long ans;
inline void swap(long long &a,long long &b){
    long long t=a;
    a=b;
    b=t;
}
void build(long long x,long long l,long long r){
    len[x]=r-l+1;
    L[x]=l,R[x]=r;
    if(l>=r)
        return;
    long long mid=(l+r)>>1;
    build(x<<1,l,mid);
    build(x<<1|1,mid+1,r);
}
void pushdown(long long x){
    if(!tag[x])
        return;
    tag[x<<1]^=1;
    val[x<<1]=len[x<<1]-val[x<<1];
    tag[x<<1|1]^=1;
    val[x<<1|1]=len[x<<1|1]-val[x<<1|1];
    tag[x]=0;
}
void modify(long long x,long long l,long long r){
    if(L[x]>=l&&R[x]<=r){
        val[x]=len[x]-val[x];
        tag[x]^=1;
        return;
    }
    pushdown(x);
    long long mid=(L[x]+R[x])>>1;
    if(l<=mid)
        modify(x<<1,l,r);
    if(r>mid)
        modify(x<<1|1,l,r);
    val[x]=val[x<<1]+val[x<<1|1];
}
long long query(long long x,long long l,long long r){
    if(L[x]>=l&&R[x]<=r)
        return val[x];
    pushdown(x);
    long long res=0;
    long long mid=(L[x]+R[x])>>1;
    if(l<=mid)
        res+=query(x<<1,l,r);
    if(r>mid)
        res+=query(x<<1|1,l,r);
    return res;
}
bool cmp(D x,D y){
	return x.l<y.l;
}
bool cmp2(D x,D y){
	return x.r<y.r;
}
int main(){
    ios::sync_with_stdio(false);
    cin.tie(NULL);
    cout.tie(NULL);
    cin>>n>>m;
    ans=1LL*n*(n-1)*(n-2)/6;
    build(1,1,n);
    long long t;
    for(long long i=1;i<=n;i++)
    	cin>>s[i];
    sort(s+1,s+n+1);
    for(long long i=1;i<=m;i++){
    	long long x,y;
    	cin>>x>>y;
    	x=lower_bound(s+1,s+n+1,x)-s;
    	y=upper_bound(s+1,s+n+1,y)-s-1;
    //	printf("Debug 1: %d %d\n",x,y);
    	a[i].l=b[i].l=x;
    	a[i].r=b[i].r=y;
	}
	sort(a+1,a+m+1,cmp);
	sort(b+1,b+m+1,cmp2);
	long long p=0,q=0;
	for(long long i=1;i<=n;i++){
		long long d=0;
	//	printf("I Move to %d\n",i);
		while(p<m&&a[p+1].l<=i){
			p++;
			if(b[p].r!=0)
				modify(1,a[p].l,a[p].r);
			//printf("P Move to %d. Modify %d %d\n",p,a[p].l,a[p].r);
		}
		while(q<m&&b[q+1].r<i){
			q++;
			if(b[q].r!=0)
				modify(1,b[q].l,b[q].r);
			//printf("Q Move to %d. Modify %d %d\n",q,a[q].l,a[q].r);
		}
		if(i>1)
			d+=(i-1)-query(1,1,i-1);
		if(i<n)
			d+=query(1,i+1,n);
	//	printf("D: %d\n",d);
		ans-=(d*(d-1))/2;
		//printf("Current Ans: %d\n",ans);
	}
	cout<<ans;
    return 0;
}


#include<iostream>
#include<algorithm>
#define N 110000
using namespace std;
struct D{
	int l,r;
}a[N],b[N];
int L[N*4],R[N*4],len[N*4],tag[N*4],val[N*4],s[N];
int n,m;
long long ans;
inline void swap(int &a,int &b){
    int t=a;
    a=b;
    b=t;
}
void build(int x,int l,int r){
    len[x]=r-l+1;
    L[x]=l,R[x]=r;
    if(l>=r)
        return;
    int mid=(l+r)>>1;
    build(x<<1,l,mid);
    build(x<<1|1,mid+1,r);
}
void pushdown(int x){
    if(!tag[x])
        return;
    tag[x<<1]^=1;
    val[x<<1]=len[x<<1]-val[x<<1];
    tag[x<<1|1]^=1;
    val[x<<1|1]=len[x<<1|1]-val[x<<1|1];
    tag[x]=0;
}
void modify(int x,int l,int r){
    if(L[x]>=l&&R[x]<=r){
        val[x]=len[x]-val[x];
        tag[x]^=1;
        return;
    }
    pushdown(x);
    int mid=(L[x]+R[x])>>1;
    if(l<=mid)
        modify(x<<1,l,r);
    if(r>mid)
        modify(x<<1|1,l,r);
    val[x]=val[x<<1]+val[x<<1|1];
}
int query(int x,int l,int r){
    if(L[x]>=l&&R[x]<=r)
        return val[x];
    pushdown(x);
    int res=0;
    int mid=(L[x]+R[x])>>1;
    if(l<=mid)
        res+=query(x<<1,l,r);
    if(r>mid)
        res+=query(x<<1|1,l,r);
    return res;
}
bool cmp(D x,D y){
	return x.l<y.l;
}
bool cmp2(D x,D y){
	return x.r<y.r;
}
int main(){
    ios::sync_with_stdio(false);
    cin.tie(NULL);
    cout.tie(NULL);
    cin>>n>>m;
    ans=1LL*n*(n-1)*(n-2)/6;
    build(1,0,n);
    for(int i=1;i<=n;i++)
    	cin>>s[i];
    sort(s+1,s+n+1);
    for(int i=1;i<=m;i++){
    	int x,y;
    	cin>>x>>y;
    	x=lower_bound(s+1,s+n+1,x)-s;
    	y=upper_bound(s+1,s+n+1,y)-s-1;
    	a[i].l=b[i].l=x;
    	a[i].r=b[i].r=y;
	}
	sort(a+1,a+m+1,cmp);
	sort(b+1,b+m+1,cmp2);
	int p=0,q=0;
	for(int i=1;i<=n;i++){
		long long d=0;
		while(p<m&&a[p+1].l<=i){
			p++;
			modify(1,a[p].l,a[p].r);
		}
		while(q<m&&b[q+1].r<i){
			q++;
			modify(1,b[q].l,b[q].r);
		}
		if(i>1)
			d+=(i-1)-query(1,1,i-1);
		if(i<n)
			d+=query(1,i+1,n);
		ans-=(d*(d-1))/2;
	}
	cout<<ans;
    return 0;
}


#include<iostream>
#include<cstdio>
#include<vector>
#include<algorithm>
#define rint register int
#define mp make_pair
using namespace std;
typedef long long LL;
const int N=100010;

int n,nn,k;
int a[N],sum[N*4],rev[N*4];
LL ans,now;
vector< pair<int,int> > rec,rerec;

inline int re(){
	register int x=0;register char ch=getchar();
	while(ch<'0'||ch>'9')ch=getchar(); while(ch>='0'&&ch<='9')x=x*10+ch-'0',ch=getchar();
	return x;
}

inline void pushdown(rint x,rint l,rint r){
	if (!rev[x]) return;
	rint mid=(l+r)>>1;
	rev[x]=0;rev[x<<1]^=1;rev[x<<1|1]^=1;
	sum[x<<1]=mid-l+1-sum[x<<1];
	sum[x<<1|1]=r-mid-sum[x<<1|1];
}

void reverse(rint x,rint l,rint r,rint ql,rint qr){
	if (l>qr || r<ql) return;
	if (ql<=l && r<=qr){
		rev[x]^=1;sum[x]=r-l+1-sum[x];
		return;
	}
	rint mid=(l+r)>>1;pushdown(x,l,r);
	reverse(x<<1,l,mid,ql,qr);
	reverse(x<<1|1,mid+1,r,ql,qr);
	sum[x]=sum[x<<1]+sum[x<<1|1];
}

int query(rint x,rint l,rint r,rint ql,rint qr){
	if (l>qr || r<ql) return 0;
	if (ql<=l && r<=qr) return sum[x];
	rint mid=(l+r)>>1;pushdown(x,l,r);
	return query(x<<1,l,mid,ql,qr)+query(x<<1|1,mid+1,r,ql,qr);
}

int main(){
	//freopen("fight.in","r",stdin);
	//freopen("fight.out","w",stdout);
	n=re();k=re();
	for (int i=1;i<=n;++i) a[i]=re();
	sort(a+1,a+n+1);//nn=unique(sa+1,sa+n+1)-sa-1;
	int x,y,l,r;ans=(LL)n*(LL)(n-1)*(LL)(n-2)/6;
	while (k--){
		x=re();y=re();
		l=lower_bound(a+1,a+n+1,x)-a;
		r=upper_bound(a+1,a+n+1,y)-a-1;
		if (l>r) continue;
		rec.push_back(mp(l,r));
		rerec.push_back(mp(r,l));
	}
	sort(rec.begin(),rec.end());
	sort(rerec.begin(),rerec.end());
	for (int i=1,j=0,g=0;i<=n;++i){
		while (j<rec.size() && rec[j].first==i) reverse(1,1,n,i,rec[j].second),j++;
		now=0;
		if (i<n) now+=query(1,1,n,i+1,n);
		if (i>1) now+=i-1-query(1,1,n,1,i-1);
		now=now*(now-1)/2;ans-=now;
		while (g<rerec.size() && rerec[g].first==i) reverse(1,1,n,rerec[g].second,i),g++;
	}
	cout<<ans;
	return 0;
}


#include<cstdio>
#include<cstring>
#include<algorithm>
#define ll long long
#define rint register int
#define lson l,mid,rec<<1
#define rson mid+1,r,rec<<1|1
using namespace std;
const int mx=100005;
int n,m;
struct node
{
	int l,r;

}c[mx];
int a[mx],d[mx],sum[mx<<2];
bool col1[mx<<2],col2[mx<<2];
inline ll read()
{
	ll x=0;int f=1;char ch=getchar();
	while(ch>'9'||ch<'0'){if(ch=='-') f=-1;ch=getchar();}
	while(ch>='0'&&ch<='9'){x=(x<<3)+(x<<1)+ch-48;ch=getchar();}
	return x*f;
}
bool cmp1(node a,node b)
{
	if(a.l==b.l) return a.r<b.r;
	return a.l<b.l;
}
bool cmp2(node a,node b)
{
	if(a.r==b.r) return a.l>b.l;
	return a.r>b.r;
}
void pushdown(int rec,int len)
{
	if(col2[rec])
	{
		col1[rec<<1]^=1;col2[rec<<1]^=1;col1[rec<<1|1]^=1;col2[rec<<1|1]^=1;
		sum[rec<<1]=(len-(len>>1))-sum[rec<<1];
		sum[rec<<1|1]=(len>>1)-sum[rec<<1|1];
		col2[rec]=0;
	}
}
void update(int l,int r,int rec,int st,int en)
{
	if(st<=l&&r<=en)
	{
		col1[rec]^=1;col2[rec]^=1;
		sum[rec]=r-l+1-sum[rec];
	}
	else
	{
		int mid=l+r>>1;
		pushdown(rec,r-l+1);
		if(en<=mid)	update(lson,st,en);
		else if(st>mid)	update(rson,st,en);
		else update(lson,st,en),update(rson,st,en);
		sum[rec]=sum[rec<<1]+sum[rec<<1|1];
	}
}
int query(int l,int r,int rec,int st,int en)
{
	if(st<=l&&r<=en) return sum[rec];
	else
	{
		int mid=l+r>>1;
		pushdown(rec,r-l+1);
		if(en<=mid)	return query(lson,st,en);
		else if(st>mid)	return query(rson,st,en);
		else return query(lson,st,en)+query(rson,st,en);
	}
}
inline int er(int x)
{
	int l=1,r=n,mid;
	while(l<r){
		mid=(l+r)>>1;
		if(a[mid]>=x) r=mid;
		else l=mid+1;
	}
	return l;
}
int main()
{
	int l,r,k,i,j;
	ll ans;n=read();m=read();
	if(m==0){
		printf("0");return 0;
	}
	for(i=1;i<=n;++i) a[i]=read();
	sort(a+1,a+n+1);
	for(i=1;i<=m;++i){
		c[i].l=read();c[i].r=read();
		//c[i].l=er(c[i].l);c[i].r=er(c[i].r)-1;
		c[i].l=lower_bound(a+1,a+n+1,c[i].l)-a;
		c[i].r=upper_bound(a+1,a+n+1,c[i].r)-a-1;
	}
	sort(c+1,c+m+1,cmp1);
	for(i=1,j=1;i<=m;++i){
		while(j!=n&&j<c[i].l){
			d[j]=query(1,n,1,j+1,n);++j;
		}
		if(c[i].l<=c[i].r) update(1,n,1,c[i].l,c[i].r);
	}
	while(j!=n){
		d[j]=query(1,n,1,j+1,n);++j;
	}
	memset(col1,0,sizeof(col1));memset(col2,0,sizeof(col2));memset(sum,0,sizeof(sum));
	sort(c+1,c+m+1,cmp2);
	for(i=1,j=n;i<=m;++i){
		while(j!=1&&j>c[i].r){
			d[j]+=j-1-query(1,n,1,1,j-1);--j;
		}
		if(c[i].l<=c[i].r) update(1,n,1,c[i].l,c[i].r);
	}
	while(j!=1){
		d[j]+=j-1-query(1,n,1,1,j-1);--j;
	}
	for(i=1,ans=(ll)n*(n-1)*(n-2)/6;i<=n;++i)
		ans-=(ll)d[i]*(d[i]-1)/2;
	printf("%lld",ans);
	return 0;
}


#include<cstdio>
#include<iostream>
#include<algorithm>
using namespace std;
#define ll long long
#define maxn 500010
long long read()
{
    long long x=0,f=1;char ch=getchar();
    while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
    return x*f;
}
int n,m,k,L,R,tot,l,r;
int a[1007],f[1007][1007];
int main()
{
//	freopen("fight.in","r",stdin);
//	freopen("fight.out","w",stdout);
	n=read();
	k=read();
	if(k==0)
	{
		cout<<"0"<<endl;
	}
	for(int i=1;i<=n;i++)
	{
		a[i]=read();
	}
	for(int i=1;i<=n;i++)
	{
		for(int j=1;j<=n;j++)
		{
			if(a[i]==a[j]) continue;
			if(a[i]>a[j])
			{
				f[i][j]=1;
				f[j][i]=-1;
			}
			if(a[i]<a[j])
			{
				f[i][j]=-1;
				f[j][i]=1;
			}
		}
	}
	for(int i=1;i<=k;i++)
	{
		cin>>l>>r;
		for(int i=1;i<=n;i++)
		{
			for(int j=1;j<=n;j++)
			{
				if(i!=j&&a[i]<=r&&a[i]>=l&&a[j]<=r&&a[j]>=l)
				{
					f[i][j]*=-1;
				}
			}
		}
	}
	for(int i=1;i<=n;i++)
	{
		for(int j=1;j<=n;j++)
		{
			cout<<f[i][j]<<" ";
		}
		cout<<endl;
	}
	for(int i=1;i<=n;i++)
	{
		for(int j=1;j<=n;j++)
		{
			for(int k=1;k<=n;k++)
			{
				if(i!=j&&j!=k&&i!=k&&f[i][j]==1&&f[j][k]==1&&f[k][i]==1)
				{
					tot++;
				}
			}
		}
	}
	cout<<tot/3<<endl;
	return 0;
}


#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
struct node
{
	int l,r,cnt,lazy;
	node *lson,*rson;
	inline void upd(){cnt=lson->cnt+rson->cnt;}
	inline void mark(){lazy^=1;cnt=(r-l+1)-cnt;}
	inline void fa_lazy(){if(lazy){lson->mark();rson->mark();lazy=0;}}
}*root,pool[233333];
int top;
node *build(int l,int r)
{
	node *tmp=&pool[top++];
	tmp->l=l;tmp->r=r;tmp->cnt=0;tmp->lazy=0;
	if(l!=r)
	{
		int mid=(l+r)/2;
		tmp->lson=build(l,mid);
		tmp->rson=build(mid+1,r);
	}
	return tmp;
}
void change(node *cur,int l,int r)
{
	if(cur->l==l&&cur->r==r)
	{
		cur->mark();
		return;
	}
	if(cur->lazy)cur->fa_lazy();
	if(cur->lson->r>=r)change(cur->lson,l,r);
	else if(cur->rson->l<=l)change(cur->rson,l,r);
	else change(cur->lson,l,cur->lson->r),change(cur->rson,cur->rson->l,r);
	cur->upd();
}
int query(node *cur,int l,int r)
{
	if(cur->l==l&&cur->r==r)
	{
		return cur->cnt;
	}
	if(cur->lazy)cur->fa_lazy();
	if(cur->lson->r>=r)return query(cur->lson,l,r);
	else if(cur->rson->l<=l)return query(cur->rson,l,r);
	else return query(cur->lson,l,cur->lson->r)+query(cur->rson,cur->rson->l,r);
}
struct que
{
	int t,l,r;
	inline bool operator<(const que &x)const{return t<x.t;}
}q[777777];
int qtop;
int n,k;
int a[233333],ans[233333];
int main()
{
	scanf("%d%d",&n,&k);
	for(int i=1;i<=n;i++)scanf("%d",&a[i]);
	sort(a+1,a+n+1);
	int x,y,l,r,L,R,mid;
	for(int i=1;i<=k;i++)
	{
		scanf("%d%d",&x,&y);
		L=1,R=n;
		while(L<R)
		{
			mid=(L+R)/2;
			if(a[mid]<x)L=mid+1;
			else R=mid;
		}
		l=L;
		L=1,R=n;
		while(L<R)
		{
			mid=(L+R+1)/2;
			if(a[mid]>y)R=mid-1;
			else L=mid;
		}
		r=L;
		if(l<=r)
		{
			qtop++;q[qtop].l=l;q[qtop].r=r;q[qtop].t=l;
			qtop++;q[qtop].l=l;q[qtop].r=r;q[qtop].t=r+1;
		}
	}
	qtop++;q[qtop].l=1;q[qtop].r=n;q[qtop].t=1;
	for(int i=1;i<=n;i++)
	{
		qtop++;q[qtop].l=i;q[qtop].r=i;q[qtop].t=i+1;
	}
	sort(q+1,q+qtop+1);
	root=build(1,n);
	int p=1;
	for(int t=1;t<=n;t++)
	{
		while(q[p].t<=t)
		{
//			cout<<q[p].t<<' '<<q[p].l<<' '<<q[p].r<<endl;
			change(root,q[p].l,q[p].r);
			p++;
		}
		if(t>1)ans[t]+=query(root,1,t-1);
		if(t<n)ans[t]+=query(root,t+1,n);
	}
	long long cnt=1ll*n*(n-1)*(n-2)/6;
	for(int i=1;i<=n;i++)
	{
		cnt-=1ll*ans[i]*(ans[i]-1)/2;
	}
	printf("%lld\n",cnt);
	return 0;
}


#include<iostream>
#include<cstdio>
#include<algorithm>
#include<vector>
using namespace std;
#define in read()
#define fur(i,a,b) for(int i=a;i<=b;i++)
#define xx 110000
#define int long long
inline int read()
{
	int x=0,f=1;char ch=getchar();
	for(;!isalnum(ch);ch=getchar()) if(ch=='-') f=-1;
	for(;isalnum(ch);ch=getchar()) x=x*10+ch-'0';
	return x*f;
}
int s2[xx],s1[xx],s[xx],cnt[xx];
int tree[xx],n,c[4][xx],all=0;
struct prom{int a,b;}t[xx];
struct linetree{int l,r,tot,sum;bool tag;}lt[xx<<2];
inline bool cmp(prom x,prom y){return x.a<y.a;}
vector<int>e[xx];
inline int look2(int x)
{
	int head=1,tail=all,ans=1;
	while(head<=tail)
	{
		int mid=(head+tail)>>1;
		if(s1[mid]<=x) ans=mid,head=mid+1;
		else tail=mid-1;
	}
	return ans;
}
inline int look1(int x)
{
	int head=1,tail=all,ans=all;
	while(head<=tail)
	{
		int mid=(head+tail)>>1;
		if(s1[mid]>=x) ans=mid,tail=mid-1;
		else head=mid+1;
	}
	return ans;
}
inline void up(int k)
{
	int q=k<<1;
	lt[k].sum=lt[q].sum+lt[q+1].sum;
	lt[k].tot=lt[q].tot+lt[q+1].tot;
}
inline void down(int k)
{
	if(lt[k].tag)
	{
		int q=k<<1;
		lt[q].sum=lt[q].tot-lt[q].sum;
		lt[q+1].sum=lt[q+1].tot-lt[q+1].sum;
		lt[q].tag^=1;
		lt[q+1].tag^=1;
		lt[k].tag^=1;
	}
}
inline void build(int k,int i,int j)
{
	lt[k].l=i;
	lt[k].r=j;
	if(i==j)
	{
		lt[k].tot=cnt[i];
		return;
	}
	int q=k<<1,mid=(i+j)>>1;
	build(q,i,mid);
	build(q+1,mid+1,j);
	up(k);
}
inline void change(int k,int i,int j)
{
	if(i<=lt[k].l&&j>=lt[k].r)
	{
		lt[k].sum=lt[k].tot-lt[k].sum;
		lt[k].tag^=1;
		return;
	}
	down(k);
	int q=k<<1,mid=lt[q].r;
	if(i<=mid) change(q,i,j);
	if(j>mid) change(q+1,i,j);
	up(k);
}
inline int askus(int k,int i,int j)
{
	if(i<=lt[k].l&&j>=lt[k].r) return lt[k].tot-lt[k].sum;
	down(k);
	int q=k<<1,mid=lt[q].r,res=0;
	if(i<=mid) res+=askus(q,i,j);
	if(j>mid) res+=askus(q+1,i,j);
	return res;
}
inline int askrs(int k,int i,int j)
{
	if(i<=lt[k].l&&j>=lt[k].r) return lt[k].sum;
	down(k);
	int q=k<<1,mid=lt[q].r,res=0;
	if(i<=mid) res+=askrs(q,i,j);
	if(j>mid) res+=askrs(q+1,i,j);
	return res;
}
signed main()
{
	n=in;
	fur(i,1,n)
	{
		c[0][i]=1;c[1][i]=i;
		fur(j,2,min(i,3ll)) c[j][i]=c[j-1][i-1]+c[j][i-1];
	}
	int k=in;
	fur(i,1,n) s2[i]=s1[i]=s[i]=in;
	sort(s2+1,s2+n+1);
	fur(i,1,n)
	{
		while(s2[i]==s2[i+1]) i++;
		s1[++all]=s2[i];
	}
	fur(i,1,n) s[i]=look1(s[i]),cnt[s[i]]++;
	sort(s+1,s+n+1);
	build(1,1,s[n]);
	fur(i,1,k) t[i].a=in,t[i].b=in;
	fur(i,1,k) t[i].a=look1(t[i].a),t[i].b=look2(t[i].b);
	sort(t+1,t+k+1,cmp);
	int ans=c[3][n],tnt=0;
	fur(i,1,s[n])
	{
		while(t[tnt].a<=i)
		{
			change(1,t[tnt].a,t[tnt].b);
			e[t[tnt].b].push_back(t[tnt].a);
			tnt++;
		}
		int res=0;
		if(i>1) res+=askus(1,i-1,1);
		if(i<s[n]) res+=askrs(1,i+1,s[n]);
		res*=cnt[i];
		ans-=c[2][res];
		fur(j,0,(int)e[i].size()-1) change(1,e[i][j],i);
	}
	printf("%lld\n",ans);
	return 0;
}


#include<bits/stdc++.h>
#define lp long long
using namespace std;
const lp ml=2e5+10;
struct wxz{
	lp l,r;
	lp sum,add;
}t[ml];
lp n,m;
lp a[ml],b[ml];
lp u[ml],v[ml];
lp yhsj[ml][5];
lp q,ans,pre=0,js;
lp inline read(){
   lp r=0,f=1;
   char c=getchar();
   while(c<'0'||c>'9'){if(c=='-')f=-12;c=getchar();}
   while(c>='0'&&c<='9')r=(r<<1)+(r<<3)+(c^48),c=getchar();
   return r*f;
}
vector < lp > a1[ml],a2[ml];
void init(){
	yhsj[1][1]=1;
	for(lp i=2;i<=n+1;i++)
	for(lp j=1;j<=4;j++)yhsj[i][j]=yhsj[i-1][j-1]+yhsj[i-1][j];
}
void spread(lp bh){
	if(t[bh].add==1){
		t[bh].add=0;
		t[bh<<1].sum=t[bh<<1].r-t[bh<<1].l+1-t[bh<<1].sum;
		t[bh<<1|1].sum=t[bh<<1|1].r-t[bh<<1|1].l+1-t[bh<<1|1].sum;
		t[bh<<1].add=t[bh<<1|1].add^=1;
		t[bh].sum=t[bh<<1].sum+t[bh<<1|1].sum;
	}
}
void build(lp l,lp r,lp bh){
	t[bh].l=l,t[bh].r=r;
	if(l==r)return;
	lp mid=(l+r)>>1;
	build(l,mid,bh<<1);
	build(mid+1,r,bh<<1|1);
}
void change(lp l,lp r,lp bh){
	if(l<=t[bh].l&&r>=t[bh].r){t[bh].add^=1;t[bh].sum=(t[bh].r-t[bh].l+1)-t[bh].sum;return;}
	lp mid=(t[bh].l+t[bh].r)>>1;
	spread(bh);
	if(l<=mid)change(l,r,bh<<1);
	if(r>mid)change(l,r,bh<<1|1);
	t[bh].sum=t[bh<<1].sum+t[bh<<1|1].sum;
}
lp ask(lp l,lp r,lp bh){
	if(l<=t[bh].l&&r>=t[bh].r)return t[bh].sum;
	lp mid=(t[bh].l+t[bh].r)>>1,res=0;
	spread(bh);
	if(l<=mid)res+=ask(l,r,bh<<1);
	if(r>mid)res+=ask(l,r,bh<<1|1);
	return res;
}
int main()
{
	n=read(),m=read();
	init();
	for(lp i=1;i<=n;i++)a[i]=read(),b[i]=a[i];
	for(lp i=1;i<=m;i++)u[i]=read(),v[i]=read();
	sort(b+1,b+1+n);
	q=n;
	b[++q]=1e15;
	for(lp i=1;i<=m;i++){
		lp k1=lower_bound(b+1,b+1+q,u[i])-b,k2=upper_bound(b+1,b+1+q,v[i])-b-1;
		a1[k1].push_back(k2);
		a2[k2+1].push_back(k1);
	}
	ans=yhsj[n+1][4];
	build(1,n,1);
	for(lp i=1;i<=n;i++){
		for(lp j=0;j<a1[i].size();j++)change(i,a1[i][j],1);
		for(lp j=0;j<a2[i].size();j++)change(a2[i][j],i-1,1);
		lp kp=0;
		if(i>1)kp+=i-1-ask(1,i-1,1);
		if(i<n)kp+=ask(i+1,n,1);
		ans-=yhsj[kp+1][3];
	}
	cout<<ans;
return 0;
}


#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cstdlib>
#include<stack>
#define ll long long
using namespace std;
const int maxn=100010;
ll read()
{
	ll x=0,f=1;
	char ch=getchar();
	while(ch<'0'||ch>'9')
	{
		if(ch=='-')
		{
			f=-1;
			ch=getchar();
		}
	}
	while(ch>='0'&&ch<='9')
	{
		x=x*10+ch-'0';
		ch=getchar();
	}
	return x*f;
}
ll ans=0;
int n,k;
ll a[maxn];
bool b[1010][1010];
void print()
{
	for(int i=1;i<=n;i++)
	{
		for(int j=1;j<=n;j++)
		{
			cout<<b[i][j]<<' ';
		}
		cout<<endl;
	}
}
void check(ll L,ll R)
{
	for(int i=1;i<=n;i++)
	{
		for(int j=i+1;j<=n;j++)
		{
			if(a[i]<a[j]&&a[i]>=L&&a[i]<=R&&a[j]>=L&&a[j]<=R)
			{
				b[i][j]=true;
				b[j][i]=false;
				continue;
			}
			if(a[i]>a[j]&&a[j]>=L&&a[j]<=R&&a[i]>=L&&a[i]<=R)
			{
				b[j][i]=true;
				b[i][j]=false;
				continue;
			}
		}
	}
}
int main()
{
//	freopen("fight.in","r",stdin);
//	freopen("fight.out","w",stdout);
	memset(b,false,sizeof(b));
	n=read(),k=read();
	//10 pts
	if(k==0)
	{
		printf("0");
		return 0;
	}
	//O(k*n^2)
	for(int i=1;i<=n;i++)
	{
		a[i]=read();
	}
	for(int i=1;i<=n;i++)
	{
		for(int j=i+1;j<=n;j++)
		{
			if(a[i]<a[j])
			{
				b[j][i]=true;
			}
			else b[i][j]=true;
		}
	}
//	print();
	for(int i=1;i<=k;i++)
	{
		ll L,R;
		scanf("%lld%lld",&L,&R);
		check(L,R);
	}
	for(int i=1;i<=n;i++)
	{
		for(int j=1;j<=n;j++)
		{
			for(int k=1;k<=n;k++)
			{
				if(i!=j&&j!=k&&k!=i&&b[i][j]==true&&b[j][k]==true&&b[k][i]==true)
				{
					ans++;
				//	cout<<i<<' '<<j<<' '<<k<<endl;
				}
			}
		}
	}
	printf("%lld",ans/3);
	fclose(stdin);
	fclose(stdout);
	return 0;
}


#include<bits/stdc++.h>
#define ll long long
using namespace std;
int n,k,a,b,L,R,cnt,d;
int s[100005];
struct qu{
	int pos,l,r;
}q[200005];
int sum[1600005][2],bj[1600005];
ll ans;

int cmp(qu u,qu v){
	return u.pos<v.pos;
}

void build(int x,int l,int r){
	sum[x][0]=r-l+1;
	bj[x]=sum[x][1]=0;
	if(l==r) return;
	int mid=(l+r)/2;
	build(2*x,l,mid);
	build(2*x+1,mid+1,r);
}

void pushdown(int x){
	swap(sum[x][0],sum[x][1]);
	bj[2*x]^=1;
	bj[2*x+1]^=1;
	bj[x]=0;
}

void updata(int x,int l,int r,int nl,int nr){
	if(bj[x]) pushdown(x);
	if(l>nr||r<nl) return;
	if(l>=nl&&r<=nr){
		bj[x]^=1;pushdown(x);
		return;
	}
	int mid=(l+r)/2;
	updata(2*x,l,mid,nl,nr);
	updata(2*x+1,mid+1,r,nl,nr);
	for(int i=0;i<2;i++) sum[x][i]=sum[2*x][i]+sum[2*x+1][i];
}

int query(int x,int l,int r,int nl,int nr,int id){
	if(bj[x]) pushdown(x);
	if(l>nr||r<nl) return 0;
	if(l>=nl&&r<=nr) return sum[x][id];
	int mid=(l+r)/2;
	return query(2*x,l,mid,nl,nr,id)+query(2*x+1,mid+1,r,nl,nr,id);
}

int main(){
	scanf("%d %d",&n,&k);
	for(int i=1;i<=n;i++) scanf("%d",&s[i]);
	sort(s+1,s+n+1);
	for(int i=1,l,r;i<=k;i++){
		scanf("%d %d",&a,&b);
		l=1,r=n,L=n+1;
		while(l<=r){
			int mid=(l+r)/2;
			if(s[mid]>=a) L=min(L,mid),r=mid-1;else l=mid+1;
		}
		l=1,r=n,R=0;
		while(l<=r){
			int mid=(l+r)/2;
			if(s[mid]<=b) R=max(R,mid),l=mid+1;else r=mid-1;
		}
		if(L<=R){
			q[++cnt]=(qu){L,L,R};
			if(R+1<=n) q[++cnt]=(qu){R+1,L,R};
		}
	}
	sort(q+1,q+cnt+1,cmp);
	build(1,1,n);
	R=1;
	ans=1ll*n*(n-1)*(n-2)/6;
	for(int i=1;i<=n;i++){
		while(R<=cnt&&q[R].pos==i) updata(1,1,n,q[R].l,q[R].r),R++;
		d=0;
		if(i>1) d+=query(1,1,n,1,i-1,0);
		if(i<n) d+=query(1,1,n,i+1,n,1);
		ans-=1ll*d*(d-1)/2;
	}
	printf("%lld\n",ans);

	return 0;
}


#include <bits/stdc++.h>
#define ls (p<<1)
#define rs (p<<1|1)
#define Mid ((l+r)>>1)
typedef long long ll;

const int N=1e5+5,M=N*4;
int n,m,s[N],Tag[M],Val[M];
ll Ans;
struct Modi{int l,r;}a[N],b[N];

inline void Pushdown(int p,int l,int r)
{if(Tag[p])Tag[ls]^=1,Tag[rs]^=1,Val[ls]=Mid-l+1-Val[ls],Val[rs]=r-Mid-Val[rs],Tag[p]=0;}

void Modify(int p,int l,int r,int L,int R)
{
	if(L<=l&&r<=R){Tag[p]^=1,Val[p]=r-l+1-Val[p];return;}
	if(Pushdown(p,l,r),L<=Mid)Modify(ls,l,Mid,L,R);
	if(R>Mid)Modify(rs,Mid+1,r,L,R);
	Val[p]=Val[ls]+Val[rs];
}

int Query(int p,int l,int r,int L,int R)
{
	if(L<=l&&r<=R)return Val[p];
	int Res=0;
	if(Pushdown(p,l,r),L<=Mid)Res=Query(ls,l,Mid,L,R);
	if(R>Mid)Res+=Query(rs,Mid+1,r,L,R);
	return Res;
}

int main()
{
	//freopen("in.txt","r",stdin);
	scanf("%d%d",&n,&m);
	for(int i=1;i<=n;++i)scanf("%d",s+i);
	std::sort(s+1,s+n+1);
	for(int i=1,x,y;i<=m;++i)
	{
		scanf("%d%d",&x,&y);
		x=std::lower_bound(s+1,s+n+1,x)-s;
		y=std::upper_bound(s+1,s+n+1,y)-s-1;
		a[i]=b[i]=(Modi){x,y};
	}
	std::sort(a+1,a+m+1,[&](const Modi& a,const Modi& b){return a.l<b.l;});
	std::sort(b+1,b+m+1,[&](const Modi& a,const Modi& b){return a.r<b.r;});
	for(int i=1,p=0,q=0,c;i<=n;++i)
	{
		while(p<m&&a[p+1].l<=i)++p,Modify(1,0,n,a[p].l,a[p].r);
		while(q<m&&b[q+1].r< i)++q,Modify(1,0,n,b[q].l,b[q].r);
		c=(i>1?i-1-Query(1,0,n,1,i-1):0)+(i<n?Query(1,0,n,i+1,n):0);
		Ans+=c*(c-1ll)/2;
	}

	return printf("%lld\n",n*(n-1ll)*(n-2)/6-Ans),0;
}


#include<cstdio>
#include<algorithm>
#include<vector>
#include<utility>
using namespace std;
typedef pair<int,int> pii;
int n,k,l,r,a[110000]; long long ans;
int sum[410000],rev[410000];
vector<pii> vec[110000];
void pushdown(int now,int l,int r){
	int mid=(l+r)>>1;
	if (rev[now]){
		rev[now<<1]^=1; rev[now<<1|1]^=1;
		sum[now<<1]=(mid-l+1)-sum[now<<1];
		sum[now<<1|1]=(r-mid)-sum[now<<1|1];
		rev[now]=0;
	}
}
void change(int now,int l,int r,int x,int y){
	if (l>r||x>y) return;
	if (l==x&&r==y){
		sum[now]=(r-l+1)-sum[now];
		rev[now]^=1; return;
	}
	pushdown(now,l,r); int mid=(l+r)>>1;
	if (y<=mid) change(now<<1,l,mid,x,y);
	else if (x>mid) change(now<<1|1,mid+1,r,x,y);
	else { change(now<<1,l,mid,x,mid); change(now<<1|1,mid+1,r,mid+1,y);}
	sum[now]=sum[now<<1]+sum[now<<1|1];
}
int query(int now,int l,int r,int x,int y){
	if (l==x&&r==y) return sum[now];
	pushdown(now,l,r); int mid=(l+r)>>1;
	if (y<=mid) return query(now<<1,l,mid,x,y);
	else if (x>mid) return query(now<<1|1,mid+1,r,x,y);
	else return query(now<<1,l,mid,x,mid)+query(now<<1|1,mid+1,r,mid+1,y);
}
int main(){
	scanf("%d%d",&n,&k);
	for (int i=1;i<=n;i++) scanf("%d",&a[i]);
	sort(a+1,a+n+1);
	for (int i=1;i<=k;i++){
		scanf("%d%d",&l,&r);
		l=lower_bound(a+1,a+n+1,l)-a;
		r=upper_bound(a+1,a+n+1,r)-a-1;
		vec[l].push_back(pii(l,r));
		vec[r+1].push_back(pii(l,r));
	}
	for (int i=1;i<=n;i++){
		int sz=vec[i].size();
		for (int j=0;j<sz;j++) change(1,1,n,vec[i][j].first,vec[i][j].second);
		int tmp=0;
		if (i>1) tmp+=(i-1)-query(1,1,n,1,i-1);
		if (i<n) tmp+=query(1,1,n,i+1,n);
		ans+=1ll*tmp*(tmp-1)/2;
	}
	printf("%lld\n",1ll*n*(n-1)*(n-2)/6-ans);
	return 0;
}


#include<bits/stdc++.h>
using namespace std;const int MAX=1e5+9;int l,r,n,k,seg[MAX*4],lz[MAX*4],a[MAX];long long ans,t;vector<pair<int,int>>o[MAX];void shift(int s,int e,int m,int id){if(lz[id]){lz[id*2+1]^=1,lz[id*2+2]^=1;seg[id*2+1]=m-s-seg[id*2+1];seg[id*2+2]=e-m-seg[id*2+2];lz[id]^=1;}}void upd(int l,int r,int s=0,int e=n,int id=0){if(r<=s||e<=l)return;if(l<=s&&e<=r){seg[id]=e-s-seg[id],lz[id]^=1;return;}int mid=s+e>>1;shift(s,e,mid,id);upd(l,r,s,mid,id*2+1),upd(l,r,mid,e,id*2+2);seg[id]=seg[id*2+1]+seg[id*2+2];}int get(int l,int r,int s=0,int e=n,int id=0){if(r<=s||e<=l)return 0;if(l<=s&&e<=r)return seg[id];int mid=s+e>>1;shift(s,e,mid,id);return get(l,r,s,mid,id*2+1)+get(l,r,mid,e,id*2+2);}int main(){ios_base::sync_with_stdio(false),cin.tie(0),cout.tie(0);cin>>n>>k,ans=-1LL*n*(n-2)*(n-1)/6;for(int i=0;i<n;i++)cin>>a[i];sort(a,a+n);for(int i=0;i<k;i++)cin>>l>>r,l=lower_bound(a,a+n,l)-a,r=upper_bound(a,a+n,r)-a,o[l].push_back({l,r}),o[r].push_back({l,r});for(int i=0;i<n;i++){for(auto j:o[i])upd(j.first,j.second);if(i)upd(i-1,i);t=get(0,n);if(get(i,i+1))t--;ans+=t*(n-t-1);}cout<<ans/2;return 0;}


#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<vector>
using namespace std;
struct Tree{
	int cnt[2];
	int rev;
}T[400010];
void update(int root)
{
	for(int i=0;i<2;i++)
		T[root].cnt[i]=T[root<<1].cnt[i]+T[root<<1|1].cnt[i];
	return ;
}
void Rev(int root)
{
	T[root].rev^=1;
	swap(T[root].cnt[0],T[root].cnt[1]);
	return ;
}
void pushdown(int root)
{
	if(T[root].rev){
		Rev(root<<1);
		Rev(root<<1|1);
		T[root].rev=0;
	}
	return ;
}
void build(int root,int l,int r)
{
	if(l==r){
		T[root].cnt[0]=1;
		return ;
	}
	int mid=(l+r)>>1;
	build(root<<1,l,mid);
	build(root<<1|1,mid+1,r);
	update(root);
	return ;
}
void change(int root,int l,int r,int x,int y)
{
	if(x>y)return ;
	if(x<=l&&r<=y){
		Rev(root);
		return ;
	}
	int mid=(l+r)>>1;
	pushdown(root);
	if(x<=mid)change(root<<1,l,mid,x,y);
	if(y>mid)change(root<<1|1,mid+1,r,x,y);
	update(root);
	return ;
}
int query(int root,int l,int r,int x,int y,int z)
{
	if(x>y)return 0;
	if(x<=l&&r<=y)
		return T[root].cnt[z];
	int mid=(l+r)>>1;
	pushdown(root);int ans=0;
	if(x<=mid)ans+=query(root<<1,l,mid,x,y,z);
	if(y>mid)ans+=query(root<<1|1,mid+1,r,x,y,z);
	update(root);
	return ans;
}
int s[100010];
vector<pair<int,int> >vec[100010];
int main()
{
	int n,k;
	scanf("%d %d",&n,&k);
	for(int i=1;i<=n;i++)
		scanf("%d",&s[i]);
	sort(s+1,s+n+1);
	build(1,1,n);
	for(int i=1;i<=k;i++)
	{
		int l,r;
		scanf("%d %d",&l,&r);
		int L=lower_bound(s+1,s+n+1,l)-s;
		int R=lower_bound(s+1,s+n+1,r)-s;
		if(s[R]>r)R--;
		vec[L].push_back(make_pair(L,R));
		vec[R+1].push_back(make_pair(L,R));
	}
	long long ans=0;
	for(int i=1;i<=n;i++)
	{
		for(int j=0;j<vec[i].size();j++)
		{
			int l=vec[i][j].first;
			int r=vec[i][j].second;
			change(1,1,n,l,r);
		}
		int x=query(1,1,n,1,i-1,0)+query(1,1,n,i+1,n,1);
		ans=ans+1ll*x*(x-1)/2;
	}
	ans=1ll*n*(n-1)*(n-2)/6-ans;
	printf("%I64d\n",ans);
	return 0;
}


#include<bits/stdc++.h>
using namespace std;
const int MAX=1e5+9;
int l,r,n,k,seg[MAX*4],lz[MAX*4],a[MAX];
long long ans,t;
vector<pair<int,int> > o[MAX];
void shift(int s,int e,int m,int id)
{
	if (lz[id])
	{
		lz[id*2+1]^=1,lz[id*2+2]^=1;
		seg[id*2+1]=m-s-seg[id*2+1];
		seg[id*2+2]=e-m-seg[id*2+2];
		lz[id]^=1;
	}
}
void upd(int l,int r,int s=0,int e=n,int id=0)
{
	if (r<=s || e<=l) return ;
	if (l<=s && e<=r){seg[id]=e-s-seg[id],lz[id]^=1;return ;}
	int mid=s+e>>1;
	shift(s,e,mid,id);
	upd(l,r,s,mid,id*2+1),upd(l,r,mid,e,id*2+2);
	seg[id]=seg[id*2+1]+seg[id*2+2];
}
int get(int l,int r,int s=0,int e=n,int id=0)
{
	if (r<=s || e<=l) return 0;
	if (l<=s && e<=r) return seg[id];
	int mid=s+e>>1;
	shift(s,e,mid,id);
	return get(l,r,s,mid,id*2+1)+get(l,r,mid,e,id*2+2);
}
int main()
{
	ios_base::sync_with_stdio(false),cin.tie(0),cout.tie(0);
	cin>>n>>k,ans=-1LL*n*(n-2)*(n-1)/6;
	for (int i=0;i<n;i++) cin>>a[i];
	sort(a,a+n);
	for (int i=0;i<k;i++)
		cin>>l>>r,l=lower_bound(a,a+n,l)-a,r=upper_bound(a,a+n,r)-a,o[l].push_back({l,r}),o[r].push_back({l,r});
	for (int i=0;i<n;i++)
	{
		for (auto j:o[i]) upd(j.first,j.second);
		if (i) upd(i-1,i);
		t=get(0,n);
		if (get(i,i+1)) t--;
		ans+=t*(n-t-1);
	}
	cout<<ans/2;
	return 0;
}


#include <bits/stdc++.h>
#define inf 0x6fffffff
#define N 100086
#define ull unsigned long long
using namespace std;
typedef long long ll;
int read(){
    int x=0,f=1;char ch=getchar();
    while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
    return x*f;
}
int a[N];
int root,k1,k2,k3;
vector<int>v[N];
struct dt{int l,r;}op[N];
bool cmp(dt a,dt b){return a.l<b.l;}
int f[2][N*4],rev[N*4];
void update(int i)
{
    f[0][i]=f[0][i*2]+f[0][i*2+1];f[1][i]=f[1][i*2]+f[1][i*(2+1)];
}
void pushdown(int i)
{
    if(!rev[i])return;
    swap(f[0][i*2],f[1][i*2]);
    swap(f[0][i*2+1],f[1][i*2+1]);
    rev[i]=0;
    rev[i*2]^=1;rev[i*2+1]^=1;
}
void build(int i,int l,int r)
{
    if(l==r){f[0][i]=1;f[1][i]=0;return;}
    int mid=(l+r)/2;
    build(i*2,l,mid);build(i*2+1,mid+1,r);
    update(i);
}
void rever(int i,int l,int r,int lt,int rt)
{
    if(lt<=l&&r<=rt)
    {
        rev[i]^=1;swap(f[0][i],f[1][i]);return;
    }
    pushdown(i);int mid=(l+r)/2;
    if(lt<=mid)rever(i*2,l,mid,lt,rt);
    if(mid+1<=rt)rever(i*2+1,mid+1,r,lt,rt);
    update(i);
}
int ask(int i,int l,int r,int lt,int rt,int dd)
{
    if(lt<=l&&r<=rt)return f[dd][i];
    int mid=(l+r)/2,tmp=0;pushdown(i);
    if(lt<=mid)tmp+=ask(i*2,l,mid,lt,rt,dd);
    if(mid+1<=rt)tmp+=ask(i*2+1,mid+1,r,lt,rt,dd);
    return tmp;
}
int main()
{
    srand(time(0));
    int n=read(),k=read();
    for(int i=1;i<=n;i++)a[i]=read();
    sort(a+1,a+n+1);a[n+1]=inf;
    ll ans=((ll)n*(ll)(n-1)*(ll)(n-2))/6;
    for(int i=1;i<=k;i++)
    {
        op[i].l=read(),op[i].r=read();
        op[i].l=lower_bound(a+1,a+1+n,op[i].l)-a;
        op[i].r=upper_bound(a+1,a+1+n+1,op[i].r)-a-1;
    }
    build(1,1,n);
    sort(op+1,op+k+1,cmp);
    int j=1;
    for(int i=1;i<=n;i++)
    {
        while(op[j].l>=op[j].r&&j<=k)j++;
        while(op[j].l<=i&&j<=k)
        {
            rever(1,1,n,op[j].l,op[j].r);
            v[op[j].r].push_back(op[j].l);
            j++;
        }
        ll tmp=0;
        if(i>1)tmp+=ask(1,1,n,1,i-1,0);
        if(i<n)tmp+=ask(1,1,n,i+1,n,1);
        ans-=(tmp*(tmp-1))/2;
        for(int x=0;x<v[i].size();x++)
            rever(1,1,n,v[i][x],i);
    }
    cout<<ans<<endl;
    return 0;
}


#include <bits/stdc++.h>
#define inf 0x6fffffff
#define N 100086
#define ull unsigned long long
using namespace std;
typedef long long ll;
int read(){
    int x=0,f=1;char ch=getchar();
    while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
    return x*f;
}
int a[N];
int root,k1,k2,k3;
vector<int>v[N];
struct dt{int l,r;}op[N];
bool cmp(dt a,dt b){return a.l<b.l;}
int f[2][N*4],rev[N*4];
void update(int i)
{
    f[0][i]=f[0][i*2]+f[0][i*2+1];f[1][i]=f[1][i*2]+f[1][i*2+1];
}
void pushdown(int i)
{
    if(!rev[i])return;
    swap(f[0][i*2],f[1][i*2]);
    swap(f[0][i*2+1],f[1][i*2+1]);
    rev[i]=0;
    rev[i*2]^=1;rev[i*2+1]^=1;
}
void build(int i,int l,int r)
{
    if(l==r){f[0][i]=1;f[1][i]=0;return;}
    int mid=(l+r)/2;
    build(i*2,l,mid);build(i*2+1,mid+1,r);
    update(i);
}
void rever(int i,int l,int r,int lt,int rt)
{
    if(lt<=l&&r<=rt)
    {
        rev[i]^=1;swap(f[0][i],f[1][i]);return;
    }
    pushdown(i);int mid=(l+r)/2;
    if(lt<=mid)rever(i*2,l,mid,lt,rt);
    if(mid+1<=rt)rever(i*2+1,mid+1,r,lt,rt);
    update(i);
}
int ask(int i,int l,int r,int lt,int rt,int dd)
{
    if(lt<=l&&r<=rt)return f[dd][i];
    int mid=(l+r)/2,tmp=0;pushdown(i);
    if(lt<=mid)tmp+=ask(i*2,l,mid,lt,rt,dd);
    if(mid+1<=rt)tmp+=ask(i*2+1,mid+1,r,lt,rt,dd);
    return tmp;
}
int main()
{
    srand(time(0));
    int n=read(),k=read();
    for(int i=1;i<=n;i++)a[i]=read();
    sort(a+1,a+n+1);a[n+1]=inf;
    ll ans=((ll)n*(ll)(n-1)*(ll)(n-2))/6;
    for(int i=1;i<=k;i++)
    {
        op[i].l=read(),op[i].r=read();
        op[i].l=lower_bound(a+1,a+1+n,op[i].l)-a;
        op[i].r=upper_bound(a+1,a+1+n+1,op[i].r)-a-1;
    }
    build(1,1,n);
    sort(op+1,op+k+1,cmp);
    int j=1;
    for(int i=1;i<=n;i++)
    {
        while(op[j].l>=op[j].r&&j<=k)j++;
        while(op[j].l<=i&&j<=k)
        {
            rever(1,1,n,op[j].l,op[j].r);
            v[op[j].r].push_back(op[j].l);
            while(op[j].l>=op[j].r&&j<=k)j++;
        }
        ll tmp=0;
        if(i>1)tmp+=ask(1,1,n,1,i-1,0);
        if(i<n)tmp+=ask(1,1,n,i+1,n,1);
        ans-=(tmp*(tmp-1))/2;
        for(int x=0;x<v[i].size();x++)
            rever(1,1,n,v[i][x],i);
    }
    cout<<ans<<endl;
    return 0;
}


#include <bits/stdc++.h>
#define inf 0x6fffffff
#define N 100086
#define ull unsigned long long
using namespace std;
typedef long long ll;
int read(){
    int x=0,f=1;char ch=getchar();
    while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
    return x*f;
}
int a[N];
int root,k1,k2,k3;
vector<int>v[N];
struct dt{int l,r;}op[N];
bool cmp(dt a,dt b){return a.l<b.l;}
int f[2][N*4],rev[N*4];
void update(int i)
{
    f[0][i]=f[0][i*2]+f[0][i*2+1];f[1][i]=f[1][i*2]+f[1][i*2+1];
}
void pushdown(int i)
{
    if(!rev[i])return;
    swap(f[0][i*2],f[1][i*2]);
    swap(f[0][i*2+1],f[1][i*2+1]);
    rev[i]=0;
    rev[i*2]^=1;rev[i*2+1]^=1;
}
void build(int i,int l,int r)
{
    if(l==r){f[0][i]=1;f[1][i]=0;return;}
    int mid=(l+r)/2;
    build(i*2,l,mid);build(i*2+1,mid+1,r);
    update(i);
}
void rever(int i,int l,int r,int lt,int rt)
{
    if(lt<=l&&r<=rt)
    {
        rev[i]^=1;swap(f[0][i],f[1][i]);return;
    }
    pushdown(i);int mid=(l+r)/2;
    if(lt<=mid)rever(i*2,l,mid,lt,rt);
    if(mid+1<=rt)rever(i*2+1,mid+1,r,lt,rt);
    update(i);
}
int ask(int i,int l,int r,int lt,int rt,int dd)
{
    if(lt<=l&&r<=rt)return f[dd][i];
    int mid=(l+r)/2,tmp=0;pushdown(i);
    if(lt<=mid)tmp+=ask(i*2,l,mid,lt,rt,dd);
    if(mid+1<=rt)tmp+=ask(i*2+1,mid+1,r,lt,rt,dd);
    return tmp;
}
int main()
{
    srand(time(0));
    int n=read(),k=read();
    for(int i=1;i<=n;i++)a[i]=read();
    sort(a+1,a+n+1);a[n+1]=inf;
    ll ans=((ll)n*(ll)(n-1)*(ll)(n-2))/6;
    for(int i=1;i<=k;i++)
    {
        op[i].l=read(),op[i].r=read();
        op[i].l=lower_bound(a+1,a+1+n,op[i].l)-a;
        op[i].r=upper_bound(a+1,a+1+n+1,op[i].r)-a-1;
    }
    build(1,1,n);
    sort(op+1,op+k+1,cmp);
    int j=1;
    for(int i=1;i<=n;i++)
    {
        while(op[j].l>=op[j].r&&j<=k)j++;
        while(op[j].l<=i&&j<=k)
        {
            rever(1,1,n,op[j].l,op[j].r);
            v[op[j].r].push_back(op[j].l);
            j++;
            while(op[j].l>=op[j].r&&j<=k)j++;
        }
        ll tmp=0;
        if(i>1)tmp+=ask(1,1,n,1,i-1,0);
        if(i<n)tmp+=ask(1,1,n,i+1,n,1);
        ans-=(tmp*(tmp-1))/2;
        for(int x=0;x<v[i].size();x++)
            rever(1,1,n,v[i][x],i);
    }
    cout<<ans<<endl;
    return 0;
}


#include <bits/stdc++.h>
#define inf 0x6fffffff
#define N 100086
#define ull unsigned long long
using namespace std;
typedef long long ll;
int read(){
    int x=0,f=1;char ch=getchar();
    while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
    return x*f;
}
int a[N];
int root,k1,k2,k3;
vector<int>v[N];
struct dt{int l,r;}op[N];
bool cmp(dt a,dt b){return a.l<b.l;}
int f[2][N*4],rev[N*4];
void update(int i)
{
    f[0][i]=f[0][i*2]+f[0][i*2+1];f[1][i]=f[1][i*2]+f[1][i*2+1];
}
void pushdown(int i)
{
    if(!rev[i])return;
    swap(f[0][i*2],f[1][i*2]);
    swap(f[0][i*2+1],f[1][i*2+1]);
    rev[i]=0;
    rev[i*2]^=1;rev[i*2+1]^=1;
}
void build(int i,int l,int r)
{
    if(l==r){f[0][i]=1;f[1][i]=0;return;}
    int mid=(l+r)/2;
    build(i*2,l,mid);build(i*2+1,mid+1,r);
    update(i);
}
void rever(int i,int l,int r,int lt,int rt)
{
    if(lt<=l&&r<=rt)
    {
        rev[i]^=1;swap(f[0][i],f[1][i]);return;
    }
    pushdown(i);int mid=(l+r)/2;
    if(lt<=mid)rever(i*2,l,mid,lt,rt);
    if(mid+1<=rt)rever(i*2+1,mid+1,r,lt,rt);
    update(i);
}
int ask(int i,int l,int r,int lt,int rt,int dd)
{
    if(lt<=l&&r<=rt)return f[dd][i];
    int mid=(l+r)/2,tmp=0;pushdown(i);
    if(lt<=mid)tmp+=ask(i*2,l,mid,lt,rt,dd);
    if(mid+1<=rt)tmp+=ask(i*2+1,mid+1,r,lt,rt,dd);
    return tmp;
}
int main()
{
    srand(time(0));
    int n=read(),k=read();
    for(int i=1;i<=n;i++)a[i]=read();
    sort(a+1,a+n+1);a[n+1]=inf;
    ll ans=((ll)n*(ll)(n-1)*(ll)(n-2))/6;
    for(int i=1;i<=k;i++)
    {
        op[i].l=read(),op[i].r=read();
        op[i].l=lower_bound(a+1,a+1+n,op[i].l)-a;
        op[i].r=upper_bound(a+1,a+1+n+1,op[i].r)-a-1;
    }
    build(1,1,n);
    sort(op+1,op+k+1,cmp);
    int j=1;
    for(int i=1;i<=n;i++)
    {
        while(op[j].l>=op[j].r&&j<=k)j++;
        while(op[j].l<=i&&j<=k)
        {
            rever(1,1,n,op[j].l,op[j].r);
            v[op[j].r].push_back(op[j].l);
            j++;
        }
        ll tmp=0;
        if(i>1)tmp+=ask(1,1,n,1,i-1,0);
        if(i<n)tmp+=ask(1,1,n,i+1,n,1);
        ans-=(tmp*(tmp-1))/2;
        for(int x=0;x<v[i].size();x++)
            rever(1,1,n,v[i][x],i);
    }
    cout<<ans<<endl;
    return 0;
}


#include<bits/stdc++.h>
#define maxn 100005
#define LL long long
#define lc u<<1
#define rc lc|1
using namespace std;

int n,K,s[maxn];
int sm[maxn<<2],len[maxn<<2],tg[maxn<<2],cs;
vector<int>pL[maxn],pR[maxn];

void Build(int u,int l,int r){
	sm[u] = len[u] = r-l+1;
	if(l==r) return;
	int m=l+r>>1;
	Build(lc,l,m),Build(rc,m+1,r);
}
void dtp(int u){ sm[u] = len[u] - sm[u] , tg[u] ^= 1; }
void dt(int u){ if(tg[u]) dtp(lc),dtp(rc),tg[u]=0; }
void ins(int u,int l,int r,int ql,int qr){
	if(ql>r||l>qr) return;
	if(ql<=l&&r<=qr) return (void)(dtp(u));
	int m=l+r>>1;dt(u);
	ins(lc,l,m,ql,qr),ins(rc,m+1,r,ql,qr);
	sm[u] = sm[lc] + sm[rc];
}

int main(){
	scanf("%d%d",&n,&K);
	for(int i=1;i<=n;i++) scanf("%d",&s[i]);
	sort(s+1,s+1+n);
	for(int x,y;K--;){
		scanf("%d%d",&x,&y);
		x = lower_bound(s+1,s+1+n,x)-s;
		y = upper_bound(s+1,s+1+n,y)-s-1;
		pR[x].push_back(y);
		pL[y+1].push_back(x);
	}
	LL ans = n * (n-1ll) * (n-2ll) / 6;
	Build(1,1,n);
	for(int i=1;i<=n;i++){
		ins(1,1,n,i,i);
		for(int j=0;j<pL[i].size();j++)
			ins(1,1,n,pL[i][j],i-1),cs^=1;
		for(int j=0;j<pR[i].size();j++)
			ins(1,1,n,i,pR[i][j]),cs^=1;
		int t = sm[1]-cs;
		ans -= 1ll * t * (t-1) / 2;
	}
	printf("%lld\n",ans);
}


#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <cstdlib>
#include <algorithm>
#include <vector>
#include <queue>
using namespace std;
#define ll long long
#define MAXN 111111
#define lson node<<1
#define rson node<<1|1

int read()
{
	int ret=0,neg=1;
	char c=getchar();
	while (c<'0' || c>'9'){
		if (c=='-') neg=-1;
		c=getchar();
	}
	while (c>='0' && c<='9'){
		ret=ret*10+c-'0';
		c=getchar();
	}
	return ret*neg;
}

int n,m;

int tree[MAXN<<2],lazy[MAXN<<2];

void pushdown(int node,int l,int r,int mid)
{
	if (!lazy[node]) return;
	tree[lson]=(mid-l+1)-tree[lson];
	tree[rson]=(r-mid)-tree[rson];
	lazy[lson]^=1;
	lazy[rson]^=1;
	lazy[node]=0;
}

void change(int node,int l,int r,int x,int y)
{
	if (x>y) return;
	if (l==x && y==r){
		tree[node]=(r-l+1)-tree[node];
		lazy[node]^=1;
		return;
	}
	int mid=((r-l)>>1)+l;
	pushdown(node,l,r,mid);
	if (y<=mid) change(lson,l,mid,x,y);
	else if (x>mid) change(rson,mid+1,r,x,y);
	else{
		change(lson,l,mid,x,mid);
		change(rson,mid+1,r,mid+1,y);
	}
	tree[node]=tree[lson]+tree[rson];
}

int query(int node,int l,int r,int x,int y)
{
	if (x>y) return 0;
	if (l==x && r==y) return tree[node];
	int mid=((r-l)>>1)+l;
	pushdown(node,l,r,mid);
	if (y<=mid) return query(lson,l,mid,x,y);
	if (x>mid) return query(rson,mid+1,r,x,y);
	return query(lson,l,mid,x,mid)+query(rson,mid+1,r,mid+1,y);
}

vector <int> add[MAXN],erase[MAXN];
int a[MAXN];

int main()
{
//	freopen("fight.in","r",stdin);
//	freopen("fight.out","w",stdout);
	n=read();m=read();
	for (int i=1;i<=n;i++) a[i]=read();
	sort(a+1,a+n+1);
	int x,y;
	a[n+1]=0x7fffffff;
	for (int i=1;i<=m;i++){
		x=read();y=read();
		x=lower_bound(a+1,a+n+1,x)-a;
		y=upper_bound(a+1,a+n+1,y)-a;
		add[x].push_back(min(n,y-1));
		erase[y].push_back(x);
//		cerr<<x<<' '<<y<<'\n';
	}
//	puts("success");
	ll ans=1ll*n*(n-1)*(n-2)/6;
//	cerr<<ans<<'\n';
	for (int i=1;i<=n;i++){
//		puts("success");
		int len=add[i].size();
		for (int j=0;j<len;j++)
			change(1,1,n,i,add[i][j]);
//		puts("success");
		len=erase[i].size();
		for (int j=0;j<len;j++)
			change(1,1,n,erase[i][j],i-1);
//		puts("success");
		int tmp=i-1-query(1,1,n,1,i-1)+query(1,1,n,i+1,n);
		ans-=1ll*tmp*(tmp-1)/2;
//		cerr<<ans<<'\n';
	}
	printf("%lld",ans);
}


#include <bits/stdc++.h>

#define ls u<<1
#define rs u<<1|1

#define debug(x) cout << #x << " = " << x << endl;
#define swap Swap
#define max Max
#define min Min

using namespace std;

inline char gc() {
    static char buf[1000010], *p1 = buf, *p2 = buf;
    return p1 == p2 && (p2 = (p1 = buf)+fread(buf, 1, 1000000, stdin), p1 == p2) ? EOF : *p1++;
}

template<typename T> inline void read(T& x) {
    char ch = getchar(); T a = 0, b = 1;
    while (ch != '-' && (ch < '0' || ch > '9')) ch = getchar();
    if (ch == '-') ch = getchar(), b = -1;
    while (ch >= '0' && ch <= '9') a = a*10+ch-'0', ch = getchar();
    x = a*b;
}

template<typename T> inline void write(T x, char ch = '\0') {
    if (x < 0) putchar('-'), x = -x;
    if (x > 9) write(x/10);
    putchar(x%10+'0');
    if (ch != '\0') putchar(ch);
}

template<typename T> inline void Swap(T& x, T& y) {x = x^y; y = x^y; x = x^y;}
template<typename T> inline void chkmin(T& x, T y) {x = (y < x ? y : x);}
template<typename T> inline void chkmax(T& x, T y) {x = (y > x ? y : x);}
template<typename T> inline T Min(T x, T y) {return x < y ? x : y;}
template<typename T> inline T Max(T x, T y) {return x > y ? x : y;}

const int maxn = 1e5;

typedef long long ll;

int n, m, s[maxn+10], sum[maxn*4+10], tag[maxn*4+10], cnt;

ll ans;

vector<int> L[maxn+10], R[maxn+10];

void maintain(int u) {
	sum[u] = sum[ls]+sum[rs];
}

void pushdown(int u, int l, int r) {
	if (!tag[u]) return;
	int mid = (l+r)>>1;
	sum[ls] = (mid-l+1)-sum[ls]; tag[ls] ^= 1;
	sum[rs] = (r-mid)-sum[rs]; tag[rs] ^= 1;
	tag[u] = 0;
}

void build(int u, int l, int r) {
	if (l == r) return (void)(sum[u] = 1);
	int mid = (l+r)>>1;
	build(ls, l, mid);
	build(rs, mid+1, r);
	maintain(u);
}

void update(int u, int l, int r, int L, int R) {
	//if (L > R || L > r || R < l) return;
	if (L <= l && r <= R) return (void)(sum[u] = (r-l+1)-sum[u], tag[u] ^= 1);
	int mid = (l+r)>>1;  pushdown(u, l, r);
	if (L <= mid) update(ls, l, mid, L, R);
	if (R > mid) update(rs, mid+1, r, L, R);
	maintain(u);
}

int main() {
	//freopen("code.in", "r", stdin);
	//freopen("code.out", "w", stdout);
	read(n); read(m);
	for (int i = 1; i <= n; ++i)
		read(s[i]);
	sort(s+1, s+1+n);
	for (int i = 1; i <= m; ++i) {
		int x, y;
		read(x); read(y);
		x = lower_bound(s+1, s+1+n, x)-s;
		y = upper_bound(s+1, s+1+n, y)-s;
		L[x].push_back(y-1);
		R[y].push_back(x);
	}
	build(1, 1, n);
	ll ans = 1ll*n*(n-1)*(n-2)/6;
	for (int i = 1; i <= n; ++i) {
		update(1, 1, n, i, i);
		for (int j = 0; j < R[i].size(); ++j)
			update(1, 1, n, R[i][j], i-1), cnt ^= 1;
		for (int j = 0; j < L[i].size(); ++j)
			update(1, 1, n, i, L[i][j]), cnt ^= 1;
		ans -= 1ll*(sum[1]-cnt)*(sum[1]-cnt-1)/2;
	}
	printf("%lld\n", ans);
	return 0;
}


#include <bits/stdc++.h>

#define ls u<<1
#define rs u<<1|1

#define debug(x) cout << #x << " = " << x << endl;
#define swap Swap
#define max Max
#define min Min

using namespace std;

inline char gc() {
    static char buf[1000010], *p1 = buf, *p2 = buf;
    return p1 == p2 && (p2 = (p1 = buf)+fread(buf, 1, 1000000, stdin), p1 == p2) ? EOF : *p1++;
}

template<typename T> inline void read(T& x) {
    char ch = getchar(); T a = 0, b = 1;
    while (ch != '-' && (ch < '0' || ch > '9')) ch = getchar();
    if (ch == '-') ch = getchar(), b = -1;
    while (ch >= '0' && ch <= '9') a = a*10+ch-'0', ch = getchar();
    x = a*b;
}

template<typename T> inline void write(T x, char ch = '\0') {
    if (x < 0) putchar('-'), x = -x;
    if (x > 9) write(x/10);
    putchar(x%10+'0');
    if (ch != '\0') putchar(ch);
}

template<typename T> inline void Swap(T& x, T& y) {x = x^y; y = x^y; x = x^y;}
template<typename T> inline void chkmin(T& x, T y) {x = (y < x ? y : x);}
template<typename T> inline void chkmax(T& x, T y) {x = (y > x ? y : x);}
template<typename T> inline T Min(T x, T y) {return x < y ? x : y;}
template<typename T> inline T Max(T x, T y) {return x > y ? x : y;}

const int maxn = 1e5;

typedef long long ll;

int n, m, s[maxn+10], sum[maxn*4+10], tag[maxn*4+10], cnt;

ll ans;

vector<int> L[maxn+10], R[maxn+10];

void maintain(int u) {
	sum[u] = sum[ls]+sum[rs];
}

void pushdown(int u, int l, int r) {
	if (!tag[u]) return;
	int mid = (l+r)>>1;
	sum[ls] = (mid-l+1)-sum[ls]; tag[ls] ^= 1;
	sum[rs] = (r-mid)-sum[rs]; tag[rs] ^= 1;
	tag[u] = 0;
}

void build(int u, int l, int r) {
	if (l == r) return (void)(sum[u] = 1);
	int mid = (l+r)>>1;
	build(ls, l, mid);
	build(rs, mid+1, r);
	maintain(u);
}

void update(int u, int l, int r, int L, int R) {
	//if (L > R || L > r || R < l) return;
	if (L <= l && r <= R) return (void)(sum[u] = (r-l+1)-sum[u], tag[u] ^= 1);
	int mid = (l+r)>>1;  pushdown(u, l, r);
	if (L <= mid) update(ls, l, mid, L, R);
	if (R > mid) update(rs, mid+1, r, L, R);
	maintain(u);
}

int main() {
	//freopen("code.in", "r", stdin);
	//freopen("code.out", "w", stdout);
	read(n); read(m);
	for (int i = 1; i <= n; ++i)
		read(s[i]);
	sort(s+1, s+1+n);
	for (int i = 1; i <= m; ++i) {
		int x, y;
		read(x); read(y);
		x = lower_bound(s+1, s+1+n, x)-s;
		y = upper_bound(s+1, s+1+n, y)-s;
		L[x].push_back(y-1);
		R[y].push_back(x);
	}
	build(1, 1, n);
	ll ans = 1ll*n*(n-1)*(n-2)/6;
	for (int i = 1; i <= n; ++i) {
		update(1, 1, n, i, i);
		for (int j = 0; j < R[i].size(); ++j)
			update(1, 1, n, R[i][j], i-1), cnt ^= 1;
		for (int j = 0; j < L[i].size(); ++j)
			update(1, 1, n, i, L[i][j]), cnt ^= 1;
		ans -= 1ll*(sum[1]-cnt)*(sum[1]-cnt-1)/2;
	}
	printf("%d\n", ans);
	return 0;
}


#include <bits/stdc++.h>

#define ls u<<1
#define rs u<<1|1

#define debug(x) cout << #x << " = " << x << endl;
#define swap Swap
#define max Max
#define min Min

using namespace std;

inline char gc() {
    static char buf[1000010], *p1 = buf, *p2 = buf;
    return p1 == p2 && (p2 = (p1 = buf)+fread(buf, 1, 1000000, stdin), p1 == p2) ? EOF : *p1++;
}

template<typename T> inline void read(T& x) {
    char ch = getchar(); T a = 0, b = 1;
    while (ch != '-' && (ch < '0' || ch > '9')) ch = getchar();
    if (ch == '-') ch = getchar(), b = -1;
    while (ch >= '0' && ch <= '9') a = a*10+ch-'0', ch = getchar();
    x = a*b;
}

template<typename T> inline void write(T x, char ch = '\0') {
    if (x < 0) putchar('-'), x = -x;
    if (x > 9) write(x/10);
    putchar(x%10+'0');
    if (ch != '\0') putchar(ch);
}

template<typename T> inline void Swap(T& x, T& y) {x = x^y; y = x^y; x = x^y;}
template<typename T> inline void chkmin(T& x, T y) {x = (y < x ? y : x);}
template<typename T> inline void chkmax(T& x, T y) {x = (y > x ? y : x);}
template<typename T> inline T Min(T x, T y) {return x < y ? x : y;}
template<typename T> inline T Max(T x, T y) {return x > y ? x : y;}

const int maxn = 1e5;

typedef long long ll;

int n, m, s[maxn+10], sum[maxn*4+10], tag[maxn*4+10], cnt;

ll ans;

vector<int> L[maxn+10], R[maxn+10];

void maintain(int u) {
	sum[u] = sum[ls]+sum[rs];
}

void pushdown(int u, int l, int r) {
	if (!tag[u]) return;
	int mid = (l+r)>>1;
	sum[ls] = (mid-l+1)-sum[ls]; tag[ls] ^= 1;
	sum[rs] = (r-mid)-sum[rs]; tag[rs] ^= 1;
	tag[u] = 0;
}

void build(int u, int l, int r) {
	if (l == r) return (void)(sum[u] = 1);
	int mid = (l+r)>>1;
	build(ls, l, mid);
	build(rs, mid+1, r);
	maintain(u);
}

void update(int u, int l, int r, int L, int R) {
	if (L > R || L > r || R < l) return;
	if (L <= l && r <= R) return (void)(sum[u] = (r-l+1)-sum[u], tag[u] ^= 1);
	int mid = (l+r)>>1;  pushdown(u, l, r);
	if (L <= mid) update(ls, l, mid, L, R);
	if (R > mid) update(rs, mid+1, r, L, R);
	maintain(u);
}

int main() {
	//freopen("code.in", "r", stdin);
	//freopen("code.out", "w", stdout);
	read(n); read(m);
	for (int i = 1; i <= n; ++i)
		read(s[i]);
	sort(s+1, s+1+n);
	for (int i = 1; i <= m; ++i) {
		int x, y;
		read(x); read(y);
		x = lower_bound(s+1, s+1+n, x)-s;
		y = upper_bound(s+1, s+1+n, y)-s;
		L[x].push_back(y-1);
		R[y].push_back(x);
	}
	build(1, 1, n);
	ll ans = 1ll*n*(n-1)*(n-2)/6;
	for (int i = 1; i <= n; ++i) {
		update(1, 1, n, i, i);
		for (int j = 0; j < R[i].size(); ++j)
			update(1, 1, n, R[i][j], i-1), cnt ^= 1;
		for (int j = 0; j < L[i].size(); ++j)
			update(1, 1, n, i, L[i][j]), cnt ^= 1;
		ans -= 1ll*(sum[1]-cnt)*(sum[1]-cnt-1)/2;
	}
	printf("%lld\n", ans);
	return 0;
}


#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<vector>
#define ll long long
using namespace std;
const long long maxn=1e5+9;
long long n,k;
long long a[maxn];
long long ans[maxn<<2],tag[maxn<<2];
long long ls(long long p){return p<<1;}
long long rs(long long p){return p<<1|1;}
long long push_up(long long p){ans[p]=ans[ls(p)]+ans[rs(p)];}
void f(ll p,ll l,ll r)
{
	tag[p]^=1;
	ans[p]=r-l+1-ans[p];
}
void push_down(ll p,ll l, ll r)
{
	if(tag[p])
	{
		ll mid=l+r>>1;
		f(ls(p),l,mid);
		f(rs(p),mid+1,r);
		tag[p]=0;
	}
}
void update(ll nl,ll nr,ll l,ll r,ll p)
{
	if(nl<=l&&nr>=r){f(p,l,r);return;}
	ll mid=l+r>>1;
	push_down(p,l,r);
	if(nl<=mid) update(nl,nr,l,mid,ls(p));
	if(nr>mid) update(nl,nr,mid+1,r,rs(p));
	push_up(p);
}
ll query(ll nl,ll nr,ll l,ll r,ll p)
{
	ll res=0;
	if(nl<=l&&nr>=r){return ans[p];}
	ll mid=l+r>>1;
	push_down(p,l,r);
	if(nl<=mid)res+=query(nl,nr,l,mid,ls(p));
	if(nr>mid) res+=query(nl,nr,mid+1,r,rs(p));
	return res;
}
ll C(ll n,ll m)
{
	if(m==1)return n;
	if(n==m)return 1;
	return C(n-1,m)+C(n-1,m-1);
}
long long l,r;
vector<long long>vl[maxn],vr[maxn];
int main()
{
	cin>>n>>k;
	long long tot=C(n,3);
	for(long long i=0;i<n;i++)scanf("%d",&a[i]);// cin>>a[i];
	sort(a,a+n);
	while(k--)
	{
//		cin>>l>>r;
		scanf("%d%d",&l,&r);
		l=lower_bound(a,a+n,l)-a;
		r=upper_bound(a,a+n,r)-a-1;
		if(l>r)continue;
		vl[l].push_back(r);
		vr[r].push_back(l);
	}
	for(long long i=0;i<n;i++)
	{
		for(long long j=0;j<vl[i].size();j++)update(i,vl[i][j],0,n-1,1);
		long long res=0;
		if(i)res+=i-query(0,i-1,0,n-1,1);
		if(i<n-1)res+=query(i+1,n-1,0,n-1,1);
//		cout<<res<<endl;
		tot-=res*(res-1)/2;
		for(long long j=0;j<vr[i].size();j++)update(vr[i][j],i,0,n-1,1);
	}
	cout<<tot<<endl;
}


#include<iostream>
#include<cstring>
#include<algorithm>
#define N 100010
using namespace std;
struct D{
	long long l,r;
}a[N],b[N];
long long L[N*4],R[N*4],len[N*4],tag[N*4],val[N*4],s[N];
long long n,m;
long long ans;
inline void swap(long long &a,long long &b){
    long long t=a;
    a=b;
    b=t;
}
void build(long long x,long long l,long long r){
    len[x]=r-l+1;
    L[x]=l,R[x]=r;
    if(l>=r)
        return;
    long long mid=(l+r)>>1;
    build(x<<1,l,mid);
    build(x<<1|1,mid+1,r);
}
void pushdown(long long x){
    if(!tag[x])
        return;
    tag[x<<1]^=1;
    val[x<<1]=len[x<<1]-val[x<<1];
    tag[x<<1|1]^=1;
    val[x<<1|1]=len[x<<1|1]-val[x<<1|1];
    tag[x]=0;
}
void modify(long long x,long long l,long long r){
    if(L[x]>=l&&R[x]<=r){
        val[x]=len[x]-val[x];
        tag[x]^=1;
        return;
    }
    pushdown(x);
    long long mid=(L[x]+R[x])>>1;
    if(l<=mid)
        modify(x<<1,l,r);
    if(r>mid)
        modify(x<<1|1,l,r);
    val[x]=val[x<<1]+val[x<<1|1];
}
long long query(long long x,long long l,long long r){
    if(L[x]>=l&&R[x]<=r)
        return val[x];
    pushdown(x);
    long long res=0;
    long long mid=(L[x]+R[x])>>1;
    if(l<=mid)
        res+=query(x<<1,l,r);
    if(r>mid)
        res+=query(x<<1|1,l,r);
    return res;
}
bool cmp(D x,D y){
	return x.l<y.l;
}
bool cmp2(D x,D y){
	return x.r<y.r;
}
int main(){
    ios::sync_with_stdio(false);
    cin.tie(NULL);
    cout.tie(NULL);
    cin>>n>>m;
    ans=(1LL*n*(n-1)*(n-2))/6;
    build(1,1,n);
    long long t;
    for(long long i=1;i<=n;i++)
    	cin>>s[i];
    sort(s+1,s+n+1);
    for(long long i=1;i<=m;i++){
    	long long x,y;
    	cin>>x>>y;
    	x=lower_bound(s+1,s+n+1,x)-s;
    	y=upper_bound(s+1,s+n+1,y)-s-1;
    //	printf("Debug 1: %d %d\n",x,y);
    	if(x<=y){
	    	a[i].l=b[i].l=x;
	    	a[i].r=b[i].r=y;
    	}
	}
	sort(a+1,a+m+1,cmp);
	sort(b+1,b+m+1,cmp2);
	long long p=0,q=0;
	for(long long i=1;i<=n;i++){
		long long d=0;
	//	printf("I Move to %d\n",i);
		while(p<m&&a[p+1].l<=i){
			p++;
			modify(1,a[p].l,a[p].r);
			//printf("P Move to %d. Modify %d %d\n",p,a[p].l,a[p].r);
		}
		while(q<m&&b[q+1].r<i){
			q++;
			modify(1,b[q].l,b[q].r);
			//printf("Q Move to %d. Modify %d %d\n",q,a[q].l,a[q].r);
		}
		if(i>1)
			d+=(i-1)-query(1,1,i-1);
		if(i<n)
			d+=query(1,i+1,n);
	//	printf("D: %d\n",d);
		ans-=(1LL*d*(d-1))/2;
		//printf("Current Ans: %d\n",ans);
	}
	printf("%lld",ans);
    return 0;
}


#include <cstdio>
#include <algorithm>

const int MAXN = 1e5 + 7;

typedef long long LL;

void Qread(int &x) {
    x = 0; register char ch = getchar(); register bool k = false;
    while (ch < '0' || ch > '9') { if (ch == '-') k = true; ch = getchar(); }
    while (ch >= '0' && ch <= '9') { x = x * 10 + ch - '0'; ch = getchar(); }
    if (k) x = -x;
}

int n, k;
int a[MAXN];
bool edge[MAXN][MAXN];
LL ans;

int main() {
    // freopen("fight.in", "r", stdin);
    // freopen("fight.out", "w", s  tdout);

    Qread(n), Qread(k);
    for (int i = 1; i <= n; i++) {
        Qread(a[i]);
    }

    std::sort(a+1, a+n+1);
    for (int i = n; i >= 1; i--)
        for (int j = i - 1; j >= 1; j--) {
            edge[i][j] = 1;
        }

    int l, r;
    for (int i = 1; i <= k; i++) {
        Qread(l), Qread(r);
        for (int i = 1; i <= n; i++)
            for (int j = i + 1; j <= n; j++) {
                if (a[i] >= l && a[i] <= r && a[j] >= l && a[j] <= r) edge[i][j] ^= 1, edge[j][i] ^= 1;
            }
    }

    for (int i = 1; i <= n; i++)
        for (int j = i + 1; j <= n; j++)
            for (int m = j + 1; m <= n; m++) {
                if (edge[i][j] && edge[j][m] && edge[m][i]) ans++;
            }

    printf("%lld\n", ans);
    return 0;
}

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


#include<bits/stdc++.h>
using namespace std;
struct nod{
	int l,r,sum,lazy;
}tree[400010];
struct node{
	int l,r;
}a[100010],b[100010];
int s[100010];
int n,k,ans;
int read(){
	int r=0,f=1;char c=getchar();
	while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
	while(c<='9'&&c>='0') r=(r<<1)+(r<<3)+c-'0',c=getchar();
	return r*f;
}
void put(int x){
	if(x<0){putchar('-');x=~x+1;}
	if(x>9) put(x/10);
	putchar(x%10+'0');
}
void build(int p,int l,int r){
	tree[p].l=l,tree[p].r=r;
	if(l==r) return ;
	int mid=l+r>>1;
	build(p<<1,l,mid);build((p<<1)+1,mid+1,r);
//	tree[p].sum=tree[p<<1].sum+tree[(p<<1)+1].sum;
}
void spread(int p){
	if(!tree[p].lazy) return ;
	tree[p<<1].sum=tree[p<<1].r-tree[p<<1].l+1-tree[p<<1].sum;
	tree[(p<<1)+1].sum=tree[(p<<1)+1].r-tree[(p<<1)+1].l+1-tree[(p<<1)+1].sum;
	tree[p<<1].lazy^=1;
	tree[(p<<1)+1].lazy^=1;
	tree[p].lazy=0;
}
void change(int p,int l,int r){
//	cout<<p<<" "<<tree[p].l<<" "<<tree[p].r<<" "<<tree[p].sum<<" "<<tree[p].lazy<<endl;
	if(tree[p].l>=l&&tree[p].r<=r){tree[p].sum=tree[p].r-tree[p].l+1-tree[p].sum,tree[p].lazy^=1;return ;}
	spread(p);
	int mid=tree[p].l+tree[p].r>>1;
	if(l<=mid) change(p<<1,l,r);
	if(r>mid) change((p<<1)+1,l,r);
	tree[p].sum=tree[p<<1].sum+tree[(p<<1)+1].sum;
//	cout<<p<<" "<<tree[p].l<<" "<<tree[p].r<<" "<<tree[p].sum<<" "<<tree[p].lazy<<endl;
}
int ask(int p,int l,int r){
	if(tree[p].l>=l&&tree[p].r<=r)/*{*/
//		if(tree[p].lazy) return tree[p].r-tree[p].l+1-tree[p].sum;
		return tree[p].sum;
//	}
	spread(p);
	int mid=tree[p].l+tree[p].r>>1,anss=0;
	if(l<=mid) anss+=ask(p<<1,l,r);
	if(r>mid) anss+=ask((p<<1)+1,l,r);
	return anss;
}
int cmp1(node x,node y){return x.l<y.l;}
int cmp2(node x,node y){return x.r<y.r;}
int main(){
	n=read(),k=read(),ans=n*(n-1)*(n-2)/6;
	for(int i=1;i<=n;i++) s[i]=read();
	sort(s+1,s+1+n);build(1,1,n);
	for(int i=1;i<=k;i++) a[i].l=b[i].l=lower_bound(s+1,s+1+n,read())-s,a[i].r=b[i].r=upper_bound(s+1,s+1+n,read())-s-1;
	sort(a+1,a+1+k,cmp1),sort(b+1,b+1+k,cmp2);
	int p=0,q=0;
	for(int i=1;i<=n;i++){
		int kv=0;
		while(p<k&&a[p+1].l<=i){p++;/*cout<<endl<<endl<<a[p].l<<" "<<a[p].r<<endl;*/change(1,a[p].l,a[p].r);/*cout<<endl<<endl;*/}
		while(q<k&&b[q+1].r<i){q++;/*cout<<endl<<endl<<b[q].l<<" "<<b[q].r<<endl;*/change(1,b[q].l,b[q].r);/*cout<<endl<<endl;*/}
		if(i>1) kv+=i-1-ask(1,1,i-1);
//		put(kv);puts("");
		if(i<n) kv+=ask(1,i+1,n);
//		put(kv);puts("");
		ans-=kv*(kv-1)/2;
	}
	put(ans);puts("");
	return 0;
}


#include<bits/stdc++.h>
#define lp long long
using namespace std;
const lp ml=1e5+10;
struct wg{
	lp lf,ri;
}p[ml];
struct wxz{
	lp l,r;
	lp sum,add;
}t[ml];//树
lp n,m;
lp a[ml],k[ml],b[ml];
lp u[ml],v[ml],nu[ml],nv[ml];
lp yhsj[ml][5],pd[ml];
lp q,ans,pre=0,js;
lp inline read(){
   lp r=0,f=1;
   char c=getchar();
   while(c<'0'||c>'9'){if(c=='-')f=-12;c=getchar();}
   while(c>='0'&&c<='9')r=(r<<1)+(r<<3)+(c^48),c=getchar();
   return r*f;
}
vector < lp > a1[ml],a2[ml];
lp cmp(wg a1,wg a2){return a1.lf<a2.lf;}
void init(){
	yhsj[1][1]=1;
	for(lp i=2;i<=n+1;i++)
	for(lp j=1;j<=4;j++)yhsj[i][j]=yhsj[i-1][j-1]+yhsj[i-1][j];//注意杨辉三角都要加1
}
void spread(lp bh){
	if(t[bh].add==1){
		t[bh].add=0;
		t[bh<<1].sum=t[bh<<1].r-t[bh<<1].l+1-t[bh<<1].sum;
		t[bh<<1|1].sum=t[bh<<1|1].r-t[bh<<1|1].l+1-t[bh<<1|1].sum;
		t[bh<<1].add=t[bh<<1|1].add^=1;
		t[bh].sum=t[bh<<1].sum+t[bh<<1|1].sum;
	}
}
void build(lp l,lp r,lp bh){
	t[bh].l=l,t[bh].r=r;
	if(l==r)return;
	lp mid=(l+r)>>1;
	build(l,mid,bh<<1);
	build(mid+1,r,bh<<1|1);
}
void change(lp l,lp r,lp bh){//懒标记为1代表有反转
	if(l<=t[bh].l&&r>=t[bh].r){t[bh].add^=1;t[bh].sum=(t[bh].r-t[bh].l+1)-t[bh].sum;return;}
	lp mid=(t[bh].l+t[bh].r)>>1;
	spread(bh);
	if(l<=mid)change(l,r,bh<<1);
	if(r>mid)change(l,r,bh<<1|1);
	t[bh].sum=t[bh<<1].sum+t[bh<<1|1].sum;
}
lp ask(lp l,lp r,lp bh){
	if(l<=t[bh].l&&r>=t[bh].r)return t[bh].sum;
	lp mid=(t[bh].l+t[bh].r)>>1,res=0;
	spread(bh);
	if(l<=mid)res+=ask(l,r,bh<<1);
	if(r>mid)res+=ask(l,r,bh<<1|1);
	return res;
}//先调线段树 ,线段树应该不会错了
int main()
{
	n=read(),m=read();
	init();
	for(lp i=1;i<=n;i++)a[i]=read(),b[i]=a[i];
	for(lp i=1;i<=m;i++)u[i]=read(),v[i]=read();
	sort(b+1,b+1+n);
	q=unique(b+1,b+1+n)-b-1;
	for(lp i=1;i<=n;i++)k[i]=lower_bound(b+1,b+1+q,a[i])-b;
	sort(k+1,k+1+n);
	b[++q]=1e15;
	for(lp i=1;i<=m;i++){
		lp k1=lower_bound(b+1,b+1+q,u[i])-b,k2=upper_bound(b+1,b+1+q,v[i])-b-1;
		a1[k1].push_back(k2);
		a2[k2+1].push_back(k1);
	}
	sort(p+1,p+1+m,cmp);
	ans=yhsj[n+1][4];
	build(1,n,1);
	for(lp i=1;i<=n;i++){
		for(lp j=0;j<a1[i].size();j++)change(i,a1[i][j],1);
		for(lp j=0;j<a2[i].size();j++)change(a2[i][j],i-1,1);
		lp kp=0;
		if(i>1)kp+=i-1-ask(1,i-1,1);
		if(i<n)kp+=ask(i+1,n,1);
		ans-=yhsj[kp+1][3];
	}
	printf("%lld\n",ans);
return 0;
}


#include<cstdio>
#include<cstring>
#include<algorithm>
#define ll long long
#define rint register int
#define lson l,mid,rec<<1
#define rson mid+1,r,rec<<1|1
using namespace std;
const int mx=100005;
int n,m;
struct node
{
	int l,r;

}c[mx];
int a[mx],d[mx],sum[mx<<2];
bool col1[mx<<2],col2[mx<<2];
inline ll read()
{
	ll x=0;int f=1;char ch=getchar();
	while(ch>'9'||ch<'0'){if(ch=='-') f=-1;ch=getchar();}
	while(ch>='0'&&ch<='9'){x=(x<<3)+(x<<1)+ch-48;ch=getchar();}
	return x*f;
}
bool cmp1(node a,node b)
{
	if(a.l==b.l) return a.r<b.r;
	return a.l<b.l;
}
bool cmp2(node a,node b)
{
	if(a.r==b.r) return a.l>b.l;
	return a.r>b.r;
}
void pushdown(int rec,int len)
{
	if(col2[rec])
	{
		col1[rec<<1]^=1;col2[rec<<1]^=1;col1[rec<<1|1]^=1;col2[rec<<1|1]^=1;
		sum[rec<<1]=(len-(len>>1))-sum[rec<<1];
		sum[rec<<1|1]=(len>>1)-sum[rec<<1|1];
		col2[rec]=0;
	}
}
void update(int l,int r,int rec,int st,int en)
{
	if(st<=l&&r<=en)
	{
		col1[rec]^=1;col2[rec]^=1;
		sum[rec]=r-l+1-sum[rec];
	}
	else
	{
		int mid=l+r>>1;
		pushdown(rec,r-l+1);
		if(en<=mid)	update(lson,st,en);
		else if(st>mid)	update(rson,st,en);
		else update(lson,st,en),update(rson,st,en);
		sum[rec]=sum[rec<<1]+sum[rec<<1|1];
	}
}
int query(int l,int r,int rec,int st,int en)
{
	if(st<=l&&r<=en) return sum[rec];
	else
	{
		int mid=l+r>>1;
		pushdown(rec,r-l+1);
		if(en<=mid)	return query(lson,st,en);
		else if(st>mid)	return query(rson,st,en);
		else return query(lson,st,en)+query(rson,st,en);
	}
}
inline int er(int x)
{
	int l=1,r=n,mid;
	while(l<r){
		mid=(l+r)>>1;
		if(a[mid]>=x) r=mid;
		else l=mid+1;
	}
	return l;
}
int main()
{
	//freopen("fight.in","r",stdin);
	//freopen("fight.out","w",stdout);
	int l,r,k,i,j;
	ll ans;n=read();m=read();
	if(m==0){
		printf("0");return 0;
	}
	for(i=1;i<=n;++i) a[i]=read();
	sort(a+1,a+n+1);
	for(i=1;i<=m;++i){
		c[i].l=read();c[i].r=read();
		c[i].l=er(c[i].l);c[i].r=er(c[i].r)-1;
		//c[i].l=lower_bound(a+1,a+n+1,c[i].l)-a;
		//c[i].r=upper_bound(a+1,a+n+1,c[i].r)-a-1;
	}
	sort(c+1,c+m+1,cmp1);
	for(i=1,j=1;i<=m;++i){
		while(j!=n&&j<c[i].l){
			d[j]=query(1,n,1,j+1,n);++j;
		}
		if(c[i].l<=c[i].r) update(1,n,1,c[i].l,c[i].r);
	}
	while(j!=n){
		d[j]=query(1,n,1,j+1,n);++j;
	}
	memset(col1,0,sizeof(col1));memset(col2,0,sizeof(col2));memset(sum,0,sizeof(sum));
	sort(c+1,c+m+1,cmp2);
	for(i=1,j=n;i<=m;++i){
		while(j!=1&&j>c[i].r){
			d[j]+=j-1-query(1,n,1,1,j-1);--j;
		}
		if(c[i].l<=c[i].r) update(1,n,1,c[i].l,c[i].r);
	}
	while(j!=1){
		d[j]+=j-1-query(1,n,1,1,j-1);--j;
	}
	for(i=1,ans=(ll)n*(n-1)*(n-2)/6;i<=n;++i)
		ans-=(ll)d[i]*(d[i]-1)/2;
	printf("%lld",ans);
	return 0;
}


#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<vector>
using namespace std;
#define ls (t<<1)
#define rs ((t<<1)|1)
typedef long long ll;
typedef pair<int,int>pii;
const int maxn=1e5+7;
const int INF=0x7f7f7f7f;
int n,k;
ll ans;
int s[maxn],sum[maxn<<2],lazy[maxn<<2];//线段树开4倍，2倍不够
vector<int>vl[maxn],vr[maxn];
void push_up(int t){
  sum[t]=sum[ls]+sum[rs];
}
void push_down(int t,int l,int r){
  if(lazy[t]){
    lazy[t]^=1;
    lazy[ls]^=1;lazy[rs]^=1;
    int mid=(l+r)/2;
    sum[ls]=mid-l+1-sum[ls];
    sum[rs]=r-mid-sum[rs];
  }
}
void update(int L,int R,int l,int r,int t){
  if(L<=l&&r<=R){
    sum[t]=r-l+1-sum[t];//取反后和进行的操作
    lazy[t]^=1;
    return;
  }
  push_down(t,l,r);
  int mid=(l+r)/2;
  if(L<=mid) update(L,R,l,mid,ls);
  if(R>mid) update(L,R,mid+1,r,rs);
  push_up(t);
}
int query(int L,int R,int l,int r,int t){
  if(L<=l&&r<=R) return sum[t];
  push_down(t,l,r);
  int mid=(l+r)/2,ret=0;
  if(L<=mid) ret+=query(L,R,l,mid,ls);
  if(R>mid) ret+=query(L,R,mid+1,r,rs);
  return ret;
}
int main(){
  cin>>n>>k;
  for(int i=0;i<n;i++) cin>>s[i];
  sort(s,s+n);
  while(k--){
    int l,r;cin>>l>>r;
    l=lower_bound(s,s+n,l)-s;
    r=upper_bound(s,s+n,r)-s-1;
    if(l>r) continue;
    vl[l].push_back(r);vr[r].push_back(l);
  }
  ll ans=1LL*n*(n-1)*(n-2)/6;
  for(int i=0;i<n;i++){
    for(int j=0;j<vl[i].size();j++) update(i,vl[i][j],0,n-1,1);
    int res=0;
    if(i>0) res+=i-query(0,i-1,0,n-1,1);
    if(i<n-1) res+=query(i+1,n-1,0,n-1,1);
    ans-=1LL*res*(res-1)/2;//乘法原理，顺序要去掉
    for(int j=0;j<vr[i].size();j++) update(vr[i][j],i,0,n-1,1);
  }
  cout<<ans<<endl;
  return 0;
}


#include<iostream>
#include<cstdio>
#include<queue>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<set>
#include<map>
#include<vector>
#define maxn 200000
#define SZJ int
#define AK main
#define half (l+r)>>1
#define SDOI ()
using namespace std;
#define rep (i,a,b) for (int i=a;i<=b;++i)
#define erpe (i,a) for (int i=head[a];i!=-1;i=e[i].next)
#define int long long
struct hzw
{
	int l,r;
}t[maxn];
struct zmd
{
	int lc,rc,tag,sum;
}tre[maxn];
int n,k,num[maxn];
vector<int>bkt[100006];
inline bool cmp(hzw a,hzw b)
{
	if (a.l==b.l) return a.r<b.r;
	else return a.l<b.l;
}
inline void pushdown(int s,int l,int r)
{
	int mid=half;
	int tmp=tre[s].tag%2;
	if (!tmp) {tre[s].tag=0;return;}
	int lson=tre[s].lc,rson=tre[s].rc;
	tre[lson].sum=(mid-l+1)-tre[lson].sum,tre[lson].tag+=tre[s].tag;
	tre[rson].sum=(r-mid)-tre[rson].sum,tre[rson].tag+=tre[s].tag;
	tre[s].tag=0;
}
int cnt=0;
inline void build(int s,int l,int r)
{
	if (l==r) return;
	int mid=half;
	tre[s].lc=++cnt;
	build(tre[s].lc,l,mid);
	tre[s].rc=++cnt;
	build(tre[s].rc,mid+1,r);
}
inline void update(int s,int l,int r,int cl,int cr)
{
	if (l==cl&&r==cr)
	{
		tre[s].sum=(r-l+1)-tre[s].sum;
		tre[s].tag++;
		return;
	}
	if (tre[s].tag) pushdown(s,l,r);
	int mid = half;
	if (cr<=mid) update(tre[s].lc,l,mid,cl,cr);
	else if (cl>mid) update(tre[s].rc,mid+1,r,cl,cr);
	else
	{
		update(tre[s].lc,l,mid,cl,mid);
		update(tre[s].rc,mid+1,r,mid+1,cr);
	}
	tre[s].sum=tre[tre[s].lc].sum+tre[tre[s].rc].sum;
}
inline int query(int s,int l,int r,int cl,int cr)
{
	if (l==cl&&r==cr) return tre[s].sum;
	if (tre[s].tag) pushdown(s,l,r);
	int mid=half;
	if (cr<=mid) return query(tre[s].lc,l,mid,cl,cr);
	else if (cl>mid) return query(tre[s].rc,mid+1,r,cl,cr);
	else
	{
		return query(tre[s].lc,l,mid,cl,mid)+query(tre[s].rc,mid+1,r,mid+1,cr);
	}
}
#undef int
SZJ AK SDOI
{
//	freopen("data.in","r",stdin);
//	freopen("baoli.out","w",stdout);
	#define int long long
	cnt=1;
	cin>>n>>k;
	for (int i=1;i<=n;++i) scanf("%lld",&num[i]);
	sort(num+1,num+1+n);
	build(1,1,n);
	num[n+1]=1e17;
	int fina=n*(n-1)*(n-2)/6;
	for (int i=1,a,b;i<=k;++i)
	{
		scanf("%lld%lld",&a,&b);
		t[i].l=lower_bound(num+1,num+1+n,a)-num;
		t[i].r=upper_bound(num+1,num+1+n+1,b)-num-1;
		if (t[i].l>t[i].r) t[i].l=1e17,t[i].r=1e17;
	}
	sort(t+1,t+1+k,cmp);
	int now=1;
	for (int i=1;i<=n;++i)
	{
		while (t[now].l==i) update(1,1,n,t[now].l,t[now].r),bkt[t[now].r].push_back(t[now].l),now++;
		int tmp=0;
		if (i>1) tmp+=query(1,1,n,1,i-1);
		if (i<n) tmp+=(n-i)-query(1,1,n,i+1,n);
		for (int j=0;j<bkt[i].size();++j) update(1,1,n,bkt[i][j],i);
		fina-=tmp*(tmp-1)/2;
	}
	cout<<fina;
}


#include<cstdio>
#include<cstring>
#include<algorithm>
#define ll long long
#define lson rec<<1,l,mid
#define rson rec<<1|1,mid+1,r
#define rint register int
using namespace std;
const int mx=100005;
int n,k,x,y;
ll ans;
int a[mx],d[mx];
int col[mx<<2],ad[mx<<2],sm[mx<<2];
struct node{
	int l,r;
};
node c[mx];
inline int read()
{
	int x=0,f=1;char ch=getchar();
	while(ch>'9'||ch<'0'){if(ch=='-') f=-1;}
	while(ch>='0'&&ch<='9'){x=(x<<3)+(x<<1)+ch-48;ch=getchar();}
	return x*f;
}
inline bool cmp1(node a,node b)
{
	if(a.l==b.l) return a.r<b.r;
	return a.l<b.l;
}
inline bool cmp2(node a,node b)
{
	if(a.r==b.r) return a.l>b.l;
	return a.r>b.r;
}
inline void pushdown(int rec,int len)
{
	if(ad[rec]){
		int hf2=len>>1,hf1;hf1=hf2+((len&1)?1:0);
		col[rec<<1]^=1;col[rec<<1|1]^=1;
		ad[rec<<1]^=1;ad[rec<<1|1]^=1;
		sm[rec<<1]=hf1-sm[rec<<1];sm[rec<<1|1]=hf2-sm[rec<<1|1];
	}
}
void modify(int rec,int l,int r)
{
	if(x<=l&&y>=r){
		col[rec]^=1;ad[rec]^=1;sm[rec]=r-l+1-sm[rec];return;
	}
	pushdown(rec,r-l+1);int mid=(l+r)>>1;
	if(x<=mid) modify(lson);
	if(y>mid) modify(rson);
	sm[rec]=sm[rec<<1]+sm[rec<<1|1];
}
int query(int rec,int l,int r)
{
	if(x<=l&&y>=r) return sm[rec];
	pushdown(rec,r-l+1);int mid=(l+r)>>1;
	if(y<=mid) return query(lson);
	if(x>mid) return query(rson);
	return query(lson)+query(rson);
}
int main()
{
	n=read();k=read();for(rint i=1;i<=n;++i) a[i]=read();
	sort(a+1,a+1+n);
	for(rint i=1;i<=k;++i){
		c[i].l=read();c[i].r=read();
		c[i].l=lower_bound(a+1,a+1+n,c[i].l)-a;
		c[i].r=upper_bound(a+1,a+1+n,c[i].r)-a-1;
	}
	int zz=1;sort(c+1,c+1+k,cmp1);
	for(rint i=1;i<=k;++i){
		while(zz<n&&c[i].l>zz){x=zz+1;y=n;
			d[zz]=query(1,1,n);++zz;
		}
		x=c[i].l;y=c[i].r;modify(1,1,n);
	}
	while(zz<n) x=zz+1,y=n,d[zz]=query(1,1,n),++zz;
	zz=n;sort(c+1,c+1+k,cmp2);
	memset(col,0,sizeof(col));memset(ad,0,sizeof(ad));memset(sm,0,sizeof(sm));
	for(rint i=1;i<=k;++i){
		while(zz>1&&c[i].r<zz){x=1;y=zz-1;
			d[zz]+=y-x+1-query(1,1,n);--zz;
		}
		x=c[i].l;y=c[i].r;modify(1,1,n);
	}
	while(zz>1) x=1,y=zz-1,d[zz]+=y-x+1-query(1,1,n),--zz;
	ans=(ll)n*(n-1)*(n-2)/6;
	for(rint i=1;i<=n;++i) ans-=(ll)d[i]*(d[i]-1)/2;
	printf("%lld",ans);
	return 0;
}


#include<iostream>
#include<cstring>
#include<algorithm>
#define N 100010
using namespace std;
struct D{
	int l,r;
}a[N],b[N];
int L[N*4],R[N*4],len[N*4],tag[N*4],val[N*4],s[N];
int n,m;
long long ans;
char str[N/4];
inline void swap(int &a,int &b){
    int t=a;
    a=b;
    b=t;
}
void build(int x,int l,int r){
    len[x]=r-l+1;
    L[x]=l,R[x]=r;
    if(l>=r)
        return;
    int mid=(l+r)>>1;
    build(x<<1,l,mid);
    build(x<<1|1,mid+1,r);
}
void pushdown(int x){
    if(!tag[x])
        return;
    tag[x<<1]^=1;
    val[x<<1]=len[x<<1]-val[x<<1];
    tag[x<<1|1]^=1;
    val[x<<1|1]=len[x<<1|1]-val[x<<1|1];
    tag[x]=0;
}
void modify(int x,int l,int r){
    if(L[x]>=l&&R[x]<=r){
        val[x]=len[x]-val[x];
        tag[x]^=1;
        return;
    }
    pushdown(x);
    int mid=(L[x]+R[x])>>1;
    if(l<=mid)
        modify(x<<1,l,r);
    if(r>mid)
        modify(x<<1|1,l,r);
    val[x]=val[x<<1]+val[x<<1|1];
}
int query(int x,int l,int r){
    if(L[x]>=l&&R[x]<=r)
        return val[x];
    pushdown(x);
    int res=0;
    int mid=(L[x]+R[x])>>1;
    if(l<=mid)
        res+=query(x<<1,l,r);
    if(r>mid)
        res+=query(x<<1|1,l,r);
    return res;
}
bool cmp(D x,D y){
	return x.l<y.l;
}
bool cmp2(D x,D y){
	return x.r<y.r;
}
int main(){
    ios::sync_with_stdio(false);
    cin.tie(NULL);
    cout.tie(NULL);
    cin>>n>>m;
    ans=(n*(n-1)*(n-2))/6;
    build(1,1,n);
    int t;
    for(int i=1;i<=n;i++)
    	cin>>s[i];
    sort(s+1,s+n+1);
    for(int i=1;i<=m;i++){
    	int x,y;
    	cin>>x>>y;
    	x=lower_bound(s+1,s+n+1,x)-s;
    	y=upper_bound(s+1,s+n+1,y)-s-1;
    //	printf("Debug 1: %d %d\n",x,y);
    	if(x<=y){
	    	a[i].l=b[i].l=x;
	    	a[i].r=b[i].r=y;
    	}
	}
	sort(a+1,a+m+1,cmp);
	sort(b+1,b+m+1,cmp2);
	int p=0,q=0;
	for(int i=1;i<=n;i++){
		int d=0;
	//	printf("I Move to %d\n",i);
		while(p<m&&a[p+1].l<=i){
			p++;
			modify(1,a[p].l,a[p].r);
			//printf("P Move to %d. Modify %d %d\n",p,a[p].l,a[p].r);
		}
		while(q<m&&b[q+1].r<i){
			q++;
			modify(1,b[q].l,b[q].r);
			//printf("Q Move to %d. Modify %d %d\n",q,a[q].l,a[q].r);
		}
		if(i>1)
			d+=(i-1)-query(1,1,i-1);
		if(i<n)
			d+=query(1,i+1,n);
	//	printf("D: %d\n",d);
		ans-=(d*(d-1))/2;
		//printf("Current Ans: %d\n",ans);
	}
	printf("%lld",ans);
    return 0;
}


#include<bits/stdc++.h>
#define lp long long
using namespace std;
const lp ml=1e5+10;
struct wg{
	lp lf,ri;
}p[ml];
struct wxz{
	lp l,r;
	lp sum,add;
}t[ml];//树
lp n,m;
lp a[ml],k[ml],b[ml];
lp u[ml],v[ml],nu[ml],nv[ml];
lp yhsj[ml][5];
lp q,ans,pre=0;
lp inline read(){
   lp r=0,f=1;
   char c=getchar();
   while(c<'0'||c>'9'){if(c=='-')f=-12;c=getchar();}
   while(c>='0'&&c<='9')r=(r<<1)+(r<<3)+(c^48),c=getchar();
   return r*f;
}
lp cmp(wg a1,wg a2){return a1.lf<a2.lf;}
void init(){
	yhsj[1][1]=1;
	for(lp i=2;i<=n+1;i++)
	for(lp j=1;j<=4;j++)yhsj[i][j]=yhsj[i-1][j-1]+yhsj[i-1][j];//注意杨辉三角都要加1
}
void spread(lp bh){
	if(t[bh].add==1){
		t[bh].add=0;
		t[bh<<1].sum=t[bh<<1].r-t[bh<<1].l+1-t[bh<<1].sum;
		t[bh<<1|1].sum=t[bh<<1|1].r-t[bh<<1|1].l+1-t[bh<<1|1].sum;
		t[bh<<1].add=t[bh<<1|1].add=1;
		t[bh].sum=t[bh<<1].sum+t[bh<<1|1].sum;
	}
}
void build(lp l,lp r,lp bh){
	t[bh].l=l,t[bh].r=r;
	if(l==r)return;
	lp mid=(l+r)>>1;
	build(l,mid,bh<<1);
	build(mid+1,r,bh<<1|1);
}
void change(lp l,lp r,lp bh){//懒标记为1代表有反转
//cout<<l<<" "<<r<<" "<<t[bh].l<<" "<<t[bh].r<<endl;
	if(l<=t[bh].l&&r>=t[bh].r){t[bh].add=1;t[bh].sum=(t[bh].r-t[bh].l+1)-t[bh].sum;return;}
	lp mid=(t[bh].l+t[bh].r)>>1;
	spread(bh);
	if(l<=mid)change(l,r,bh<<1);
	if(r>mid)change(l,r,bh<<1|1);
	t[bh].sum=t[bh<<1].sum+t[bh<<1|1].sum;
}
lp ask(lp l,lp r,lp bh){
	if(l<=t[bh].l&&r>=t[bh].r)return t[bh].sum;
	lp mid=(t[bh].l+t[bh].r)>>1,res=0;
	spread(bh);
	if(l<=mid)res+=ask(l,r,bh<<1);
	if(r>mid)res+=ask(l,r,bh<<1|1);
	return res;
}//先调线段树 ,线段树应该不会错了
int main()
{
	n=read(),m=read();
	init();
	for(lp i=1;i<=n;i++)a[i]=read(),b[i]=a[i];
	for(lp i=1;i<=m;i++)u[i]=read(),v[i]=read();
	sort(b+1,b+1+n);
	q=unique(b+1,b+1+n)-b-1;
	for(lp i=1;i<=n;i++)k[i]=lower_bound(b+1,b+1+q,a[i])-b;
	sort(k+1,k+1+n);
	b[++q]=1e15;
	for(lp i=1;i<=m;i++)p[i].lf=upper_bound(b+1,b+1+q,u[i])-b-1,p[i].ri=upper_bound(b+1,b+1+q,v[i])-b-1;
	sort(p+1,p+1+m,cmp);
	ans=yhsj[n+1][4];
	build(1,n,1);
	for(lp i=1;i<=m;i++)cout<<p[i].lf<<" "<<p[i].ri<<endl;
	cout<<"fmreu8-----------------"<<endl;
	for(lp i=1;i<=n;i++){
		lp now=pre,val=k[i];
		for(lp j=pre+1;j<=m;j++)if(p[j].lf<=val)change(p[j].lf,p[j].ri,1),now++;else break;
		for(lp j=pre;j<=now;j++)if(p[j].ri<val)change(p[j].lf,p[j].ri,1);
		cout<<now<<endl;
		lp kp=i-1-ask(1,i-1,1)+ask(i+1,n,1);
		cout<<"second "<<kp<<endl;
		ans-=yhsj[kp+1][3];
		pre=now;
	}
	printf("%lld\n",ans);
return 0;
}


#include<cstdio>
#include<iostream>
#include<vector>
#include<algorithm>
#define rint register int
#define lson rt<<1,l,mid
#define rson rt<<1|1,mid+1,r
using namespace std;
typedef long long LL;
typedef vector<int>::iterator vit;
const int maxn=1000003;
inline void read(int &x) {
	x=0;int f=1;char ch=getchar();
	while(!isdigit(ch)) {if(ch=='-') f=-1;ch=getchar();}
	while(isdigit(ch)) x=(x<<3)+(x<<1)+ch-'0',ch=getchar();
	x*=f;
}
struct qj {int l,r;} b[maxn];
int n,k,a[maxn],sum[maxn<<2|1];
bool tag[maxn<<2|1];
vector<int> l[maxn],r[maxn];
inline void update(int rt) {
	sum[rt]=sum[rt<<1]+sum[rt<<1|1];
}
inline void color(int rt,int l,int r) {
	tag[rt]^=1;
	sum[rt]=r-l+1-sum[rt];
}
inline void push_down(int rt,int l,int r) {
	if(tag[rt]) {
		int mid=l+r>>1;
		color(lson);
		color(rson);
		tag[rt]=0;
	}
}
void modify(int rt,int l,int r,int ml,int mr) {
	if(l>=ml&&r<=mr) {
		color(rt,l,r);
		return;
	}
	push_down(rt,l,r);
	int mid=l+r>>1;
	if(ml<=mid) modify(lson,ml,mr);
	if(mr>mid) modify(rson,ml,mr);
	update(rt);
}
int query(int rt,int l,int r,int ql,int qr) {
	if(l>=ql&&r<=qr) return sum[rt];
	push_down(rt,l,r);
	int mid=l+r>>1;
	if(qr<=mid) return query(lson,ql,qr);
	if(ql>mid) return query(rson,ql,qr);
	return query(lson,ql,qr)+query(rson,ql,qr);
}
int main() {
	read(n),read(k);
	for(rint i=1;i<=n;++i) read(a[i]);
	sort(a+1,a+n+1);
	for(rint i=1;i<=k;++i) {
		read(b[i].l),read(b[i].r);
		b[i].l=lower_bound(a+1,a+n+1,b[i].l)-a;
		b[i].r=upper_bound(a+1,a+n+1,b[i].r)-a-1;
		l[b[i].l].push_back(i),r[b[i].r].push_back(i);
	}
	LL ans=(LL)n*(n-1)*(n-2)/6;
	for(rint i=1;i<=n;++i) {
		int du=0;
		if(!l[i].empty()) for(vit it=l[i].begin();it!=l[i].end();++it) modify(1,1,n,b[*it].l,b[*it].r);
		if(!r[i-1].empty()) for(vit it=r[i-1].begin();it!=r[i-1].end();++it) modify(1,1,n,b[*it].l,b[*it].r);
		if(i>1) du+=i-1-query(1,1,n,1,i-1);
		if(i<n) du+=query(1,1,n,i+1,n);
		ans-=(LL)du*(du-1)/2;
	}
	cout<<ans;
	return 0;
}