#include <bits/stdc++.h>
int IntMaxVal = (int)1e20;
int IntMinVal = (int)-1e20;
long long LongMaxVal = (long long)1e20;
long long LongMinVal = (long long)-1e20;
using namespace std;
template <typename T>
struct argument_type;
template <typename T, typename U>
struct argument_type<T(U)> {};
template <typename T1, typename T2>
istream& operator>>(istream& is, pair<T1, T2>& s) {
  is >> s.first >> s.second;
  return is;
}
template <typename T>
ostream& operator<<(ostream& os, const vector<T>& v) {
  for (int i = 0; i < v.size(); i++) os << v[i] << ' ';
  os << endl;
  return os;
}
template <typename T1, typename T2>
ostream& operator<<(ostream& s, pair<T1, T2>& t) {
  s << t.first << ' ' << t.second;
  return s;
}
int MaxRange = 1000 * 1000 * 1000;
class Item {
 public:
  int weight;
  int power;
  long long distance2;
  long long range2;
};
bool byDistance(const Item& i1, const Item& i2) {
  return i1.distance2 < i2.distance2;
}
auto dummyItem = make_pair(IntMaxVal, -1);
template <typename T>
class MinTree {
  int gp2(int n) {
    int x = 2;
    while (x < n) x *= 2;
    return x;
  }
  int n;
  vector<T> data;

 public:
  void reset() { data.assign(2 * n, dummyItem); }
  void init(int n) {
    this->n = n = gp2(n);
    reset();
  }
  T combine(T p1, T p2) {
    if (p1.first < p2.first)
      return p1;
    else
      return p2;
  }
  void set(int i, T item) {
    i += n;
    data[i] = item;
    i /= 2;
    while (i) {
      data[i] = combine(data[2 * i], data[2 * i + 1]);
      i /= 2;
    }
  }
  void remove(int i) {
    i += n;
    data[i].first = IntMaxVal;
    i /= 2;
    while (i) {
      data[i] = combine(data[2 * i], data[2 * i + 1]);
      i /= 2;
    }
  }
  T getValue(int l, int r, int i, int fullL, int fullR) {
    if (l == fullL && r + 1 == fullR)
      return data[i];
    else {
      int m = (fullL + fullR) / 2;
      if (l < m && r >= m)
        return combine(getValue(l, m - 1, 2 * i, fullL, m),
                       getValue(m, r, 2 * i + 1, m, fullR));
      else if (l < m)
        return getValue(l, r, 2 * i, fullL, m);
      else
        return getValue(l, r, 2 * i + 1, m, fullR);
    }
  }
  T getValue(int l, int r) { return getValue(l, r, 1, 0, n); }
};
MinTree<pair<int, int> > minDistItems;
int main() {
  srand(time(NULL));
  ios_base::sync_with_stdio(false);
  cin.tie(NULL);
  long long x;
  cin >> x;
  ;
  long long y;
  cin >> y;
  ;
  int p;
  cin >> p;
  ;
  long long initialRange;
  cin >> initialRange;
  ;
  int n;
  cin >> n;
  ;
  initialRange *= initialRange;
  vector<Item> items(n);
  for (int i = 0; i < n; ++i) {
    long long xi;
    cin >> xi;
    ;
    long long yi;
    cin >> yi;
    ;
    cin >> items[i].weight >> items[i].power;
    long long ri;
    cin >> ri;
    ;
    items[i].range2 = ri * ri;
    long long dx = abs(xi - x);
    long long dy = abs(yi - y);
    if (dx > MaxRange || dy > MaxRange)
      items[i].distance2 = LongMaxVal;
    else
      items[i].distance2 = dx * dx + dy * dy;
  }
  sort(items.begin(), items.end(), byDistance);
  vector<int> q;
  q.push_back(-1);
  minDistItems.init(n);
  for (int i = 0; i < n; ++i)
    minDistItems.set(i, make_pair(items[i].weight, i));
  for (int i = 0; i < q.size(); ++i) {
    int ii = q[i];
    long long range2 = ii == -1 ? initialRange : items[ii].range2;
    auto power = ii == -1 ? p : items[ii].power;
    if (range2 < items.front().distance2) continue;
    int l = 0;
    int r = n;
    while (l + 1 < r) {
      int mid = (l + r) / 2;
      if (items[mid].distance2 <= range2)
        l = mid;
      else
        r = mid;
    }
    while (true) {
      auto item = minDistItems.getValue(0, l);
      if (item.first > power) break;
      minDistItems.remove(item.second);
      q.push_back(item.second);
    }
  }
  cout << q.size() - 1;
}
