#include <bits/stdc++.h>
using namespace std;
template <class T, class T2>
inline bool chkmax(T &x, const T2 &y) {
  return x < y ? x = y, 1 : 0;
}
template <class T, class T2>
inline bool chkmin(T &x, const T2 &y) {
  return x > y ? x = y, 1 : 0;
}
const long long mod = 1e9 + 7;
template <class T>
inline void fix(T &x) {
  if (x >= mod | x <= -mod) {
    x %= mod;
  }
  if (x < 0) {
    x += mod;
  }
}
const long long MAX_N = 3e5 + 100;
long long a[MAX_N], b[MAX_N];
vector<int> g[MAX_N];
long long tree[2 * MAX_N];
void upd(long long ind, long long val) {
  ind += MAX_N;
  tree[ind] += val;
  ind /= 2;
  while (ind > 0) {
    tree[ind] = tree[ind * 2] + tree[ind * 2 + 1];
    ind /= 2;
  }
}
long long query(long long l, long long r) {
  l += MAX_N;
  r += MAX_N + 1;
  long long ret = 0;
  while (l < r) {
    if (l & 1) {
      ret += tree[l];
      l++;
    }
    if (r & 1) {
      r--;
      ret += tree[r];
    }
    l /= 2;
    r /= 2;
  }
  return ret;
}
map<pair<int, int>, int> mp;
long long in[MAX_N];
signed main() {
  ios_base::sync_with_stdio(false);
  cin.tie(NULL);
  cout.tie(NULL);
  int n, p;
  cin >> n >> p;
  for (int i = 0; i < n; i++) {
    cin >> a[i] >> b[i];
    if (a[i] > b[i]) {
      swap(a[i], b[i]);
    }
    mp[{a[i], b[i]}]++;
    in[a[i]]++;
    in[b[i]]++;
    g[b[i]].push_back(a[i]);
  }
  long long ret = 0;
  for (auto it : mp) {
    if (in[it.first.first] + in[it.first.second] - it.second >= p) {
      ret++;
    }
  }
  for (int i = 1; i <= n; i++) {
    sort(g[i].begin(), g[i].end());
    g[i].resize(unique(g[i].begin(), g[i].end()) - g[i].begin());
    ret += query(max(0ll, p - in[i]), MAX_N - 10);
    for (auto it : g[i]) {
      if (in[i] + in[it] >= p) {
        ret -= 1;
      }
    }
    upd(in[i], 1);
    continue;
    cout << i << " " << in[i] << " " << ret << "\n";
    for (int i = 0; i <= 5; i++) {
      cout << query(i, i) << " ";
    }
    cout << "\n";
  }
  cout << ret << "\n";
  return 0;
}
