#include <bits/stdc++.h>
using namespace std;
template <class X, class Y>
void minimize(X &x, const Y &y) {
  if (x > y) x = y;
}
template <class X, class Y>
void maximize(X &x, const Y &y) {
  if (x < y) x = y;
}
template <class T>
T Abs(const T &x) {
  return (x < 0 ? -x : x);
}
pair<int, long long> operator+(const pair<int, long long> &a,
                               const pair<int, long long> &b) {
  return make_pair(a.first + b.first, a.second + b.second);
}
int ___prev(int x, int mod) {
  while ((x - mod) % 2 != 0) x--;
  return x;
}
int ___next(int x, int mod) {
  while ((x - mod) % 2 != 0) x++;
  return x;
}
int ID(int L, int mod) { return mod == 0 ? L / 2 : (L + 1) / 2; }
class SegmentTree {
 private:
  vector<long long> sum;
  vector<int> cnt, lazy;
  int n;
  void remove(int i, int l, int r, int u, int v) {
    if (l > v || r < u || l > r || v < u) return;
    if (lazy[i]) return;
    if (u <= l && r <= v) {
      sum[i] = cnt[i] = 0;
      lazy[i] = 1;
      return;
    }
    int m = (l + r) >> 1;
    remove(2 * i, l, m, u, v);
    remove(2 * i + 1, m + 1, r, u, v);
    sum[i] = sum[2 * i] + sum[2 * i + 1];
    cnt[i] = cnt[2 * i] + cnt[2 * i + 1];
  }
  pair<int, long long> get(int i, int l, int r, int u, int v) const {
    if (l > v || r < u || l > r || v < u) return make_pair(0, 0);
    if (lazy[i]) return make_pair(0, 0);
    if (u <= l && r <= v) return make_pair(cnt[i], sum[i]);
    int m = (l + r) >> 1;
    pair<int, long long> L = get(2 * i, l, m, u, v);
    pair<int, long long> R = get(2 * i + 1, m + 1, r, u, v);
    return L + R;
  }
  void build(int i, int l, int r, bool type) {
    if (l == r) {
      sum[i] = type == 0 ? 2 * r : 2 * r - 1;
      cnt[i] = 1;
      return;
    }
    int m = (l + r) >> 1;
    build(2 * i, l, m, type);
    build(2 * i + 1, m + 1, r, type);
    sum[i] = sum[2 * i] + sum[2 * i + 1];
    cnt[i] = cnt[2 * i] + cnt[2 * i + 1];
  }

 public:
  SegmentTree(int n = 0, bool type = 0) {
    this->n = n;
    sum.assign(4 * n + 7, 0);
    cnt.assign(4 * n + 7, 0);
    lazy.assign(4 * n + 7, 0);
    if (n > 0) build(1, 1, n, type);
  }
  void remove(int l, int r, bool type) {
    l = ID(___next(l, type), type);
    r = ID(___prev(r, type), type);
    remove(1, 1, n, l, r);
  }
  pair<int, long long> get(int l, int r, bool type) const {
    l = ID(___next(l, type), type);
    r = ID(___prev(r, type), type);
    return get(1, 1, n, l, r);
  }
};
vector<int> segAt[300300];
int minRight[300300][2], maxRight[300300][2];
int numSeg, length;
long long totSeg[300300];
void init(void) {
  scanf("%d%d", &numSeg, &length);
  for (int pmp = 0, _n = (numSeg); pmp < _n; pmp = pmp + 1) {
    int l, r;
    scanf("%d%d", &l, &r);
    segAt[l].push_back(r);
  }
}
void prepare(void) {
  memset(maxRight, -1, sizeof maxRight);
  for (int i = (1), _b = (length); i <= _b; i = i + 1) {
    for (int j = 0, _n = (2); j < _n; j = j + 1)
      maxRight[i][j] = maxRight[i - 1][j];
    for (__typeof((segAt[i]).begin()) jt = (segAt[i]).begin();
         jt != (segAt[i]).end(); jt++)
      maximize(maxRight[i][*jt % 2], *jt);
  }
  priority_queue<int, vector<int>, greater<int> > q[2];
  for (int i = (1), _b = (length); i <= _b; i = i + 1) {
    for (__typeof((segAt[i]).begin()) jt = (segAt[i]).begin();
         jt != (segAt[i]).end(); jt++)
      q[*jt % 2].push(*jt);
    for (int j = 0, _n = (2); j < _n; j = j + 1) {
      while (!q[j].empty() && q[j].top() < i) q[j].pop();
      minRight[i][j] = q[j].empty() ? 300300 : q[j].top();
    }
  }
  for (int i = (1), _b = (length); i <= _b; i = i + 1)
    totSeg[i] = totSeg[i - 1] + 1LL * i * (i + 1) / 2;
}
void process(void) {
  long long res = 0;
  SegmentTree myit[2];
  myit[0] = SegmentTree(length / 2, 0);
  myit[1] = SegmentTree((length + 1) / 2, 1);
  for (int L = (length), _a = (1); L >= _a; L = L - 1) {
    pair<int, long long> toAdd;
    if (minRight[L][1 - L % 2] <= length) {
      int lim = minRight[L][1 - L % 2];
      toAdd = myit[L % 2].get(L, lim, L % 2);
    } else {
      int lim = maxRight[L][L % 2] + 1;
      maximize(lim, L);
      toAdd = myit[L % 2].get(L, lim - 1, L % 2);
      for (int i = 0, _n = (2); i < _n; i = i + 1)
        toAdd = toAdd + myit[i].get(lim, length, i);
    }
    res += toAdd.second - 1LL * toAdd.first * (L - 1);
    for (__typeof((segAt[L]).begin()) it = (segAt[L]).begin();
         it != (segAt[L]).end(); it++) {
      int u = L, v = *it;
      myit[1 - u % 2].remove(u, v, 1 - u % 2);
      if ((v - u + 1) % 2 == 0)
        for (int i = 0, _n = (2); i < _n; i = i + 1)
          myit[i].remove(v + 1, length, i);
    }
  }
  vector<pair<int, int> > join;
  for (int i = (1), _b = (length); i <= _b; i = i + 1)
    for (__typeof((segAt[i]).begin()) jt = (segAt[i]).begin();
         jt != (segAt[i]).end(); jt++) {
      int L = i, R = *jt;
      if (join.empty() || L > join.back().second + 1)
        join.push_back(make_pair(L, R));
      else
        maximize(join.back().second, R);
    }
  if (join.front().first > 1) res -= totSeg[join.front().first - 1];
  if (join.back().second < length) res -= totSeg[length - join.back().second];
  for (int i = 0, _n = ((int)join.size() - 1); i < _n; i = i + 1)
    if (join[i + 1].first > join[i].second + 1)
      res -= totSeg[join[i + 1].first - join[i].second - 1];
  cout << res << endl;
}
int main(void) {
  init();
  prepare();
  process();
  return 0;
}
