#include <bits/stdc++.h>
using namespace std;
const long long llmax = 9223372036854775807;
const long long llmin = -9223372036854775808;
const int intmin = -2147483648;
const int intmax = 2147483647;
const long long mod = 1e9 + 7;
const double pi = 3.141592653589793238;
long long gcd(long long a, long long b) {
  if (a == 0 || b == 0)
    return a + b;
  else
    return gcd(b, a % b);
}
template <typename A, typename B>
inline A fexp(A x, B p) {
  A ans = 1;
  for (; p; p >>= 1, x = 1LL * x * x % mod)
    if (p & 1) ans = 1LL * ans * x % mod;
  return ans;
}
template <typename T>
inline void read(T &x) {
  x = 0;
  T f = 1;
  char ch;
  do {
    ch = getchar();
    if (ch == '-') f = -1;
  } while (ch < '0' || ch > '9');
  do x = x * 10 + ch - '0', ch = getchar();
  while (ch <= '9' && ch >= '0');
  x *= f;
}
vector<long long> primes;
template <class T>
bool isPrime(T x) {
  if (x <= 4 || x % 2 == 0 || x % 3 == 0) return x == 2 || x == 3;
  for (T i = 5; i * i <= x; i += 6)
    if (x % i == 0 || x % (i + 2) == 0) return 0;
  return 1;
}
int Tcnt = 0;
template <class TT>
class ST {
  struct Node {
    int l, r;
    long long sm, bjc, bjj;
    long long min;
    long long max;
    long long oor;
    long long andd;
  };
  vector<TT> A;
  vector<Node> T;

 public:
  ST(vector<TT> &AA) {
    A.emplace_back(0);
    for (int i = 0; i < AA.size(); i++) A.emplace_back(AA[i]);
    T.resize(A.size() << 2);
    build(1, 1, (int)A.size() - 1);
  }
  long long QuerySum(int l, int r) { return querySum(1, l, r); }
  long long QueryOr(int l, int r) { return queryOr(1, l, r); }
  long long QueryAnd(int l, int r) { return queryAnd(1, l, r); }
  long long QueryMax(int l, int r) { return queryMax(1, l, r); }
  long long QueryMin(int l, int r) { return queryMin(1, l, r); }
  void Add(int l, int r, TT x) { add(1, l, r, x); }
  void Mul(int l, int r, TT x) { mul(1, l, r, x); }

 private:
  void pushup(int i) {
    T[i].sm = T[i << 1].sm + T[i << 1 | 1].sm;
    T[i].max = max(T[i << 1].max, T[i << 1 | 1].max);
    T[i].min = min(T[i << 1].min, T[i << 1 | 1].min);
    T[i].oor = (T[i << 1].oor) | (T[i << 1 | 1].oor);
    T[i].andd = (T[i << 1].andd) & (T[i << 1 | 1].andd);
  }
  void mul(int i, TT x) {
    T[i].sm *= x;
    T[i].bjc *= x;
    T[i].bjj *= x;
  }
  void add(int i, TT x) {
    T[i].sm += x * (T[i].r - T[i].l + 1);
    T[i].max += x;
    T[i].min -= x;
    T[i].bjj += x;
  }
  void pushdown(int i) {
    add(i << 1, T[i].bjj);
    add(i << 1 | 1, T[i].bjj);
    T[i].bjj = 0;
  }
  void build(int i, int l, int r) {
    T[i].l = l;
    T[i].r = r;
    T[i].bjc = 1;
    if (l == r) {
      T[i].sm = A[l];
      T[i].min = A[l];
      T[i].max = A[l];
      T[i].oor = A[l];
      T[i].andd = A[l];
      return;
    }
    int M = l + r >> 1;
    build(i << 1, l, M);
    build(i << 1 | 1, M + 1, r);
    pushup(i);
  }
  long long querySum(int i, int l, int r) {
    if (l <= T[i].l && T[i].r <= r) return T[i].sm;
    int M = T[i].l + T[i].r >> 1;
    long long ans = 0;
    pushdown(i);
    if (l <= M) ans += querySum(i << 1, l, r);
    if (r > M) ans += querySum(i << 1 | 1, l, r);
    return ans;
  }
  long long queryCount(int i, int l, int r, int c) {
    if (c > 39) return 0;
    if (l <= T[i].l && T[i].r <= r) return T[i].cnt[c];
    int M = T[i].l + T[i].r >> 1;
    long long ans = 0;
    pushdown(i);
    if (l <= M) ans += queryCount(i << 1, l, r, c);
    if (r > M) ans += queryCount(i << 1 | 1, l, r, c);
    return ans;
  }
  long long queryOr(int i, int l, int r) {
    if (l <= T[i].l && T[i].r <= r) return T[i].oor;
    int M = T[i].l + T[i].r >> 1;
    long long ans = 0;
    pushdown(i);
    if (l <= M) ans = queryOr(i << 1, l, r);
    if (r > M) ans |= queryOr(i << 1 | 1, l, r);
    return ans;
  }
  long long queryAnd(int i, int l, int r) {
    if (l <= T[i].l && T[i].r <= r) return T[i].andd;
    int M = T[i].l + T[i].r >> 1;
    long long ans = 0;
    pushdown(i);
    bool set = false;
    if (l <= M) ans = queryAnd(i << 1, l, r), set = true;
    if (r > M)
      ans =
          set ? (ans & queryAnd(i << 1 | 1, l, r)) : queryAnd(i << 1 | 1, l, r);
    return ans;
  }
  long long queryMax(int i, int l, int r) {
    if (l <= T[i].l && T[i].r <= r) return T[i].max;
    int M = T[i].l + T[i].r >> 1;
    long long ans = llmin;
    pushdown(i);
    if (l <= M) ans = max(ans, queryMax(i << 1, l, r));
    if (r > M) ans = max(ans, queryMax(i << 1 | 1, l, r));
    return ans;
  }
  long long queryMin(int i, int l, int r) {
    if (l <= T[i].l && T[i].r <= r) return T[i].min;
    int M = T[i].l + T[i].r >> 1;
    long long ans = llmax;
    pushdown(i);
    if (l <= M) ans = min(ans, queryMin(i << 1, l, r));
    if (r > M) ans = min(ans, queryMin(i << 1 | 1, l, r));
    return ans;
  }
  void add(int i, int l, int r, TT x) {
    if (l <= T[i].l && T[i].r <= r) {
      add(i, x);
      return;
    }
    int M = T[i].l + T[i].r >> 1;
    pushdown(i);
    if (l <= M) add(i << 1, l, r, x);
    if (r > M) add(i << 1 | 1, l, r, x);
    pushup(i);
  }
  void mul(int i, int l, int r, TT x) {
    if (l <= T[i].l && T[i].r <= r) {
      mul(i, x);
      return;
    }
    int M = T[i].l + T[i].r >> 1;
    pushdown(i);
    if (l <= M) mul(i << 1, l, r, x);
    if (r > M) mul(i << 1 | 1, l, r, x);
    pushup(i);
  }
};
long long func(long long n, long long m, long long r, long long x,
               long long y) {
  long long val =
      (min(n + 1, x + r) - max(x, r)) * (min(m + 1, y + r) - max(y, r));
  return val;
}
bool isPrime(long long x) {
  if (x <= 4 || x % 2 == 0 || x % 3 == 0) return x == 2 || x == 3;
  for (long long i = 5; i * i <= x; i += 6)
    if (x % i == 0 || x % (i + 2) == 0) return 0;
  return 1;
}
template <typename T>
vector<int> suffix_array(int n, const T &s, int char_bound) {
  vector<int> a(n);
  if (n == 0) {
    return a;
  }
  if (char_bound != -1) {
    vector<int> aux(char_bound, 0);
    for (int i = 0; i < n; i++) {
      aux[s[i]]++;
    }
    int sum = 0;
    for (int i = 0; i < char_bound; i++) {
      int add = aux[i];
      aux[i] = sum;
      sum += add;
    }
    for (int i = 0; i < n; i++) {
      a[aux[s[i]]++] = i;
    }
  } else {
    iota(a.begin(), a.end(), 0);
    sort(a.begin(), a.end(), [&s](int i, int j) { return s[i] < s[j]; });
  }
  vector<int> sorted_by_second(n);
  vector<int> ptr_group(n);
  vector<int> new_group(n);
  vector<int> group(n);
  group[a[0]] = 0;
  for (int i = 1; i < n; i++) {
    group[a[i]] = group[a[i - 1]] + (!(s[a[i]] == s[a[i - 1]]));
  }
  int cnt = group[a[n - 1]] + 1;
  int step = 1;
  while (cnt < n) {
    int at = 0;
    for (int i = n - step; i < n; i++) {
      sorted_by_second[at++] = i;
    }
    for (int i = 0; i < n; i++) {
      if (a[i] - step >= 0) {
        sorted_by_second[at++] = a[i] - step;
      }
    }
    for (int i = n - 1; i >= 0; i--) {
      ptr_group[group[a[i]]] = i;
    }
    for (int i = 0; i < n; i++) {
      int x = sorted_by_second[i];
      a[ptr_group[group[x]]++] = x;
    }
    new_group[a[0]] = 0;
    for (int i = 1; i < n; i++) {
      if (group[a[i]] != group[a[i - 1]]) {
        new_group[a[i]] = new_group[a[i - 1]] + 1;
      } else {
        int pre = (a[i - 1] + step >= n ? -1 : group[a[i - 1] + step]);
        int cur = (a[i] + step >= n ? -1 : group[a[i] + step]);
        new_group[a[i]] = new_group[a[i - 1]] + (pre != cur);
      }
    }
    swap(group, new_group);
    cnt = group[a[n - 1]] + 1;
    step <<= 1;
  }
  return a;
}
template <typename T>
vector<int> suffix_array(const T &s, int char_bound) {
  return suffix_array((int)s.size(), s, char_bound);
}
template <typename T>
vector<int> build_lcp(int n, const T &s, const vector<int> &sa) {
  assert((int)sa.size() == n);
  vector<int> pos(n);
  for (int i = 0; i < n; i++) {
    pos[sa[i]] = i;
  }
  vector<int> lcp(max(n - 1, 0));
  int k = 0;
  for (int i = 0; i < n; i++) {
    k = max(k - 1, 0);
    if (pos[i] == n - 1) {
      k = 0;
    } else {
      int j = sa[pos[i] + 1];
      while (i + k < n && j + k < n && s[i + k] == s[j + k]) {
        k++;
      }
      lcp[pos[i]] = k;
    }
  }
  return lcp;
}
template <typename T>
vector<int> build_lcp(const T &s, const vector<int> &sa) {
  return build_lcp((int)s.size(), s, sa);
}
template <typename T>
class fenwick {
 public:
  vector<T> fenw;
  vector<T> mxidx;
  int n;
  fenwick(int n) : n(n) {
    fenw.resize(n);
    mxidx.resize(n);
  }
  void modify(int x, T v) {
    int xin = x;
    while (x < n) {
      fenw[x] += v;
      x |= (x + 1);
    }
  }
  T get(int x) {
    T v{};
    while (x >= 0) {
      v += fenw[x];
      x = (x & (x + 1)) - 1;
    }
    return v;
  }
};
int minimumMoves(vector<int> a, vector<int> m) {
  int cnt = 0;
  for (int n = 0; n < a.size(); n++) {
    string na = to_string(a[n]);
    string nb = to_string(m[n]);
    for (int id = 0; id < na.size(); id++) {
      cnt += abs((int)na[id] - (int)nb[id]);
    }
  }
  return cnt;
}
struct less_than_key {
  inline bool operator()(const pair<string, string> &p1,
                         const pair<string, string> &p2) {
    if (p1.first < p2.first)
      return true;
    else if (p1.first > p2.first)
      return false;
    else if (p1.second < p2.second)
      return true;
  }
};
bool tb[51][51];
int main() {
  std::cin.sync_with_stdio(false);
  std::cin.tie(nullptr);
  bool test = false;
  if (test) freopen("/Users/aj/code/HackerRank/input.txt", "r", stdin);
  int n;
  double w;
  cin >> n >> w;
  vector<pair<double, double>> tms;
  vector<double> tmsl;
  for (int i = (1); i <= (n); i++) {
    double x, v;
    cin >> x >> v;
    double tr = x / (v + w);
    double tl = x / (v - w);
    tms.emplace_back(make_pair(-tr, -tl));
    tmsl.emplace_back(-tl);
  }
  sort(tms.begin(), tms.end());
  reverse(tms.begin(), tms.end());
  sort(tmsl.begin(), tmsl.end());
  fenwick<int> fn(n);
  long long ans = 0;
  double prev = -1;
  int cntprev = 0;
  for (auto &pr : tms) {
    double lv = pr.second;
    auto it = lower_bound(tmsl.begin(), tmsl.end(), lv) - tmsl.begin();
    ans += fn.get(it);
    if (prev == pr.first && w != 0)
      ans += cntprev, cntprev++;
    else
      cntprev = 1;
    prev = pr.first;
    fn.modify(it, 1);
  }
  cout << ans;
  return 0;
}
