#include <bits/stdc++.h>
using namespace std;
void RD(int &x) { scanf("%d", &x); }
void RD(long long &x) { scanf("%I64d", &x); }
void RD(unsigned int &x) { scanf("%u", &x); }
void RD(double &x) { scanf("%lf", &x); }
void RD(int &x, int &y) { scanf("%d%d", &x, &y); }
void RD(long long &x, long long &y) { scanf("%I64d%I64d", &x, &y); }
void RD(unsigned int &x, unsigned int &y) { scanf("%u%u", &x, &y); }
void RD(double &x, double &y) { scanf("%lf%lf", &x, &y); }
void RD(int &x, int &y, int &z) { scanf("%d%d%d", &x, &y, &z); }
void RD(long long &x, long long &y, long long &z) {
  scanf("%I64d%I64d%I64d", &x, &y, &z);
}
void RD(unsigned int &x, unsigned int &y, unsigned int &z) {
  scanf("%u%u%u", &x, &y, &z);
}
void RD(double &x, double &y, double &z) { scanf("%lf%lf%lf", &x, &y, &z); }
void RD(char &x) { x = getchar(); }
void RD(char *s) { scanf("%s", s); }
void RD(string &s) { cin >> s; }
void PR(int x) { printf("%d\n", x); }
void PR(long long x) { printf("%I64d\n", x); }
void PR(unsigned int x) { printf("%u\n", x); }
void PR(double x) { printf("%.6lf\n", x); }
void PR(char x) { printf("%c\n", x); }
void PR(char *x) { printf("%s\n", x); }
void PR(string x) { cout << x << endl; }
struct node {
  int L, R, c[2], det;
};
const int N = 100005;
node tree[N * 3];
int n, m, s[N], a[N], b[N];
vector<pair<int, int> > V;
void build(int t, int L, int R) {
  tree[t].L = L;
  tree[t].R = R;
  tree[t].det = 0;
  tree[t].c[0] = R - L + 1;
  if (L == R) return;
  int mid = (L + R) / 2;
  build(t * 2, L, mid);
  build(t * 2 + 1, mid + 1, R);
}
void cover(int t, int L, int R) {
  if (R < s[tree[t].L] || s[tree[t].R] < L) return;
  if (L <= s[tree[t].L] && s[tree[t].R] <= R) {
    tree[t].det ^= 1;
    swap(tree[t].c[0], tree[t].c[1]);
    return;
  }
  cover(t * 2, L, R);
  cover(t * 2 + 1, L, R);
  int i, j;
  for (i = 0; i < 2; i++) {
    j = i ^ tree[t].det;
    tree[t].c[j] = tree[t * 2].c[i] + tree[t * 2 + 1].c[i];
  }
}
long long query(int t, int L, int R, int k) {
  if (R < tree[t].L || L > tree[t].R || L > R) return 0;
  if (L <= tree[t].L && tree[t].R <= R) return tree[t].c[k];
  k ^= tree[t].det;
  return query(t * 2, L, R, k) + query(t * 2 + 1, L, R, k);
}
int main() {
  RD(n, m);
  int i, j, k;
  for (i = 1; i <= n; i++) RD(s[i]);
  sort(s + 1, s + n + 1);
  for (i = 1; i <= m; i++) {
    RD(a[i], b[i]);
    V.push_back(make_pair(a[i], i));
    V.push_back(make_pair(b[i] + 1, i));
  }
  sort(V.begin(), V.end());
  build(1, 1, n);
  long long ans = (long long)n * (n - 1) * (n - 2) / 6, temp;
  j = 0;
  for (i = 1; i <= n; i++) {
    while (j < V.size() && V[j].first <= s[i]) {
      k = V[j].second;
      cover(1, a[k], b[k]);
      j++;
    }
    temp = query(1, 1, i - 1, 0) + query(1, i + 1, n, 1);
    ans -= temp * (temp - 1) / 2;
  }
  PR(ans);
  return 0;
}
