#include <bits/stdc++.h>
using namespace std;
const int T = 100005;
int pos1, pos2, N, K, i, a, b, len;
int s[T], A[T], B[T];
long long ans, cur;
struct node {
  int X, Y1, Y2, check;
};
node d[2 * T];
bool cmp(node P, node Q) { return P.X < Q.X; }
struct tree {
  int l, r, sum, save;
};
tree g[T * 8];
void build(int a, int b, int u) {
  g[u] = (tree){a, b, 0, 0};
  if (a == b) return;
  int mid = (a + b) >> 1;
  build(a, mid, 2 * u);
  build(mid + 1, b, 2 * u + 1);
}
void update(int a, int b, int u) {
  if (g[u].save) {
    g[u].save = 0;
    g[u].sum = g[u].r - g[u].l + 1 - g[u].sum;
    g[2 * u].save = !g[2 * u].save;
    g[2 * u + 1].save = !g[2 * u + 1].save;
  }
  int left = g[u].l;
  int right = g[u].r;
  if (left > b || a > right) return;
  if (a <= left && right <= b) {
    g[2 * u].save = !g[2 * u].save;
    g[2 * u + 1].save = !g[2 * u + 1].save;
    g[u].sum = g[u].r - g[u].l + 1 - g[u].sum;
    return;
  }
  update(a, b, 2 * u);
  update(a, b, 2 * u + 1);
  g[u].sum = g[2 * u].sum + g[2 * u + 1].sum;
}
void doit(node V) { update(V.Y1, V.Y2, 1); }
int getsum(int a, int b, int u) {
  if (a > b) return 0;
  if (g[u].save) {
    g[u].save = 0;
    g[u].sum = g[u].r - g[u].l + 1 - g[u].sum;
    g[2 * u].save = !g[2 * u].save;
    g[2 * u + 1].save = !g[2 * u + 1].save;
  }
  int left = g[u].l;
  int right = g[u].r;
  if (left > b || a > right) return 0;
  if (a <= left && right <= b) return g[u].sum;
  int h = getsum(a, b, 2 * u) + getsum(a, b, 2 * u + 1);
  g[u].sum = g[2 * u].sum + g[2 * u + 1].sum;
  return h;
}
map<int, int> M;
int main() {
  scanf("%d %d", &N, &K);
  for (i = 1; i <= N; i++) scanf("%d", s + i);
  s[N + 1] = 1000 * 1000 * 1000 + 5;
  build(1, N, 1);
  sort(s + 1, s + N + 1);
  for (i = 1; i <= K; i++) {
    scanf("%d %d", &a, &b);
    A[i] = lower_bound(s + 1, s + N + 2, a) - s;
    B[i] = lower_bound(s + 1, s + N + 2, b) - s;
    if (s[B[i]] > b) B[i]--;
  }
  for (i = 1; i <= N; i++) s[i] = i;
  for (i = 1; i <= K; i++) {
    d[len++] = (node){A[i], A[i], B[i], 1};
    d[len++] = (node){B[i], A[i], B[i], 0};
  }
  sort(d, d + len, cmp);
  pos1 = 0;
  pos2 = 0;
  for (i = 1; i <= N; i++) {
    while (d[pos1].X <= i && pos1 < len) {
      if (d[pos1].check) doit(d[pos1]);
      pos1++;
    }
    while (d[pos2].X <= i - 1 && pos2 < len) {
      if (d[pos2].check == 0) doit(d[pos2]);
      pos2++;
    }
    cur =
        (i > 1) * (i - 1 - getsum(1, i - 1, 1)) + (i < N) * getsum(i + 1, N, 1);
    ans += (long long)cur * (cur - 1) / 2;
  }
  cout << (long long)((long long)N * (N - 1)) * (N - 2) / 6 - ans << endl;
}
