#include <bits/stdc++.h>
using ll = long long;
using ld = long double;
using namespace std;
struct mistake {};
template <class T>
struct segment_tree {
  vector<T> t;
  int n;
  T neutral;
  function<T(T, T)> sum;
  T get(int v, int tl, int tr, int l, int r) {
    if (r < tl || tr < l) {
      return neutral;
    }
    if (l <= tl && tr <= r) {
      return t[v];
    }
    int tm = (tl + tr) / 2;
    return sum(get(v + v + 1, tl, tm, l, r), get(v + v + 2, tm + 1, tr, l, r));
  }
  void set(int v, int tl, int tr, int index, T value) {
    if (tl == tr) {
      t[v] += value;
      return;
    }
    int tm = (tl + tr) / 2;
    if (index <= tm) {
      set(v + v + 1, tl, tm, index, value);
    } else {
      set(v + v + 2, tm + 1, tr, index, value);
    }
    t[v] = sum(t[v + v + 1], t[v + v + 2]);
  }

 public:
  segment_tree(int n, function<T(T, T)> sum = std::plus<T>(), T neutral = T())
      : sum(sum), neutral(neutral), n(n) {
    t.resize(4 * n);
  }
  T get(int l, int r) {
    if (!(0 <= l && l <= r && r < n)) {
      throw mistake();
    }
    return get(0, 0, n - 1, l, r);
  }
  void set(int index, T value) {
    if (!(0 <= index && index < n)) {
      throw mistake();
    }
    set(0, 0, n - 1, index, value);
  }
};
int main() {
  ios_base::sync_with_stdio(false);
  cout.precision(60);
  cout << boolalpha << fixed;
  const ld EPS = 1e-11l;
  int n;
  ld w;
  cin >> n >> w;
  vector<ld> s(n), v(n);
  for (int i = 0; i < n; i++) {
    cin >> s[i] >> v[i];
  }
  if (abs(w) < EPS) {
    vector<ld> y(n);
    for (int i = 0; i < n; i++) {
      y[i] = v[i] / s[i];
    }
    sort(y.begin(), y.end());
    ll result = 0;
    for (int i = 0; i < n;) {
      int j;
      for (j = i; j < n && abs(y[i] - y[j]) < EPS; j++) {
      }
      result += (j - i) * 1ll * (j - i - 1) / 2;
      i = j;
    }
    cout << result << endl;
    return 0;
  }
  vector<pair<ld, ld>> p(n);
  vector<ld> a_set(n), b_set(n);
  for (int i = 0; i < n; i++) {
    p[i] = {(w + v[i]) / s[i], (w - v[i]) / s[i]};
    a_set[i] = p[i].first;
    b_set[i] = p[i].second;
  }
  sort(a_set.begin(), a_set.end());
  a_set.resize(unique(a_set.begin(), a_set.end(),
                      [=](ld a, ld b) { return abs(a - b) < EPS; }) -
               a_set.begin());
  sort(b_set.begin(), b_set.end());
  b_set.resize(unique(b_set.begin(), b_set.end(),
                      [=](ld a, ld b) { return abs(a - b) < EPS; }) -
               b_set.begin());
  vector<pair<int, int>> c(n);
  for (int i = 0; i < n; i++) {
    c[i] = {upper_bound(a_set.begin(), a_set.end(), p[i].first - EPS) -
                a_set.begin(),
            upper_bound(b_set.begin(), b_set.end(), p[i].second - EPS) -
                b_set.begin()};
  }
  sort(c.begin(), c.end(), [](pair<int, int> a, pair<int, int> b) {
    return a.second < b.second || (a.second == b.second && a.first < b.first);
  });
  segment_tree<int> t(n);
  ll result = 0;
  for (int i = n - 1; i >= 0; i--) {
    auto [x, y] = c[i];
    result += t.get(x, n - 1);
    t.set(x, 1);
  }
  cout << result << endl;
  return 0;
}
