#include <bits/stdc++.h>
using namespace std;
long long rdtsc() {
  long long tmp;
  asm("rdtsc" : "=A"(tmp));
  return tmp;
}
inline int myrand() { return abs((rand() << 15) ^ rand()); }
inline int rnd(int x) { return myrand() % x; }
const int INF = (int)1e9 + 1;
const long double EPS = 1e-9;
int gcd(int a, int b) {
  for (; b; a %= b, swap(a, b))
    ;
  return a;
}
struct Point {
  int x, y;
  int read() {
    if (scanf("%d%d", &x, &y) != 2) {
      return 0;
    }
    x *= 2, y *= 2;
    return 1;
  }
  Point() {}
  Point(int _x, int _y) : x(_x), y(_y) {}
  inline Point operator-(const Point &p) const {
    return Point(x - p.x, y - p.y);
  }
  inline int operator*(const Point &p) const { return x * p.x + y * p.y; }
  inline int sabs() const { return x * x + y * y; }
  inline bool operator<(const Point &p) const {
    if (y != p.y) {
      return y < p.y;
    }
    return x < p.x;
  }
  inline bool operator==(const Point &p) const { return x == p.x && y == p.y; }
  inline bool operator!=(const Point &p) const { return x != p.x || y != p.y; }
  Point norm() const {
    int d = gcd(x, y);
    Point res(x / d, y / d);
    if (res.x < 0 || (res.x == 0 && res.y < 0)) {
      res.x = -res.x, res.y = -res.y;
    }
    return res;
  }
};
struct Line {
  int a, b, c;
  Line() {}
  Line(const Point &p1, const Point &p2) {
    Point cur(p1.y - p2.y, p2.x - p1.x);
    cur = cur.norm();
    a = cur.x, b = cur.y;
    c = -(p1.x * a + p1.y * b);
  }
  inline bool operator<(const Line &l) const {
    if (a != l.a) {
      return a < l.a;
    }
    if (b != l.b) {
      return b < l.b;
    }
    return c < l.c;
  }
};
const int maxn = (int)3e5 + 10;
Point segms[maxn][2];
pair<Line, int> lines[maxn];
int getCnt[maxn];
vector<int> dyn[maxn];
vector<Point> points[maxn];
struct compDir {
  static Point dir;
  inline bool operator()(const Point &p1, const Point &p2) {
    int val1 = p1 * dir, val2 = p2 * dir;
    return val1 < val2;
  }
};
Point compDir::dir;
void solve(pair<Line, int> *lines, int cntl, vector<Point> &points,
           vector<int> &dyn, const Point &dir) {
  points.clear();
  int cnt = 0;
  for (int i = 0; i < cntl; ++i) {
    int id = lines[i].second;
    points.push_back(segms[id][0]);
    points.push_back(segms[id][1]);
  }
  compDir::dir = dir;
  sort(points.begin(), points.end(), compDir());
  points.resize(unique(points.begin(), points.end()) - points.begin());
  dyn = vector<int>(((int)(points).size()) * 2 + 1, 0);
  for (int i = 0; i < cntl; ++i) {
    int xs[2];
    for (int j = 0; j < 2; ++j) {
      Point cur = segms[lines[i].second][j];
      xs[j] = lower_bound(points.begin(), points.end(), cur, compDir()) -
              points.begin();
      assert(xs[j] < ((int)(points).size()) && cur == points[xs[j]]);
    }
    if (xs[0] > xs[1]) {
      swap(xs[0], xs[1]);
    }
    for (int j = 0; j < 2; ++j) {
      xs[j] = 2 * xs[j] + 1;
      assert(0 <= xs[j] && xs[j] < ((int)(dyn).size()));
    }
    dyn[xs[0]] += 1;
    dyn[xs[1] + 1] -= 1;
  }
  for (int i = 1; i < ((int)(dyn).size()); ++i) {
    dyn[i] += dyn[i - 1];
  }
}
const int maxm = (int)1500 + 10;
pair<int, Point> circles[maxm];
bool solve() {
  int n, m;
  if (scanf("%d%d", &n, &m) < 2) {
    return 0;
  }
  int cntl = 0;
  for (int i = 0; i < n; ++i) {
    for (int j = 0; j < 2; ++j) {
      assert(segms[i][j].read());
    }
    lines[cntl++] = make_pair(Line(segms[i][0], segms[i][1]), i);
  }
  sort(lines, lines + cntl);
  int cnt = 0;
  for (int i = 0; i < cntl;) {
    int i0 = i;
    while (i < cntl && !(lines[i0].first < lines[i].first)) {
      getCnt[i] = -1;
      ++i;
    }
    getCnt[i0] = cnt;
    solve(lines + i0, i - i0, points[cnt], dyn[cnt],
          Point(lines[i0].first.b, -lines[i0].first.a).norm());
    ++cnt;
  }
  for (int i = 0; i < m; ++i) {
    assert(circles[i].second.read() && scanf("%d", &circles[i].first) == 1);
    circles[i].first *= 2;
  }
  int res = 0;
  for (int i = 0; i < m; ++i) {
    for (int j = i + 1; j < m; ++j) {
      if (circles[i].first != circles[j].first) {
        continue;
      }
      const Point &c1 = circles[i].second, &c2 = circles[j].second;
      Point dir = (c1 - c2);
      if (dir.sabs() <= 4 * circles[i].first * circles[i].first) {
        continue;
      }
      dir = Point(dir.y, -dir.x).norm();
      Point mid((c1.x + c2.x) / 2, (c1.y + c2.y) / 2);
      Line dirLine(mid, Point(mid.x + c2.y - mid.y, mid.y + mid.x - c2.x));
      int type =
          lower_bound(lines, lines + cntl, make_pair(dirLine, -1)) - lines;
      if (type == cntl || dirLine < lines[type].first) {
        continue;
      }
      int groupId = getCnt[type];
      assert(groupId != -1);
      vector<Point> &ps = points[groupId];
      vector<int> &dp = dyn[groupId];
      compDir::dir = dir;
      int pos = lower_bound(ps.begin(), ps.end(), c1, compDir()) - ps.begin();
      if (pos == ((int)(ps).size()) || compDir()(c1, ps[pos])) {
        pos *= 2;
      } else {
        pos *= 2;
        pos += 1;
      }
      assert(0 <= pos && pos < ((int)(dp).size()));
      res += dp[pos];
    }
  }
  printf("%d\n", res);
  return 1;
}
int main() {
  srand(rdtsc());
  while (1) {
    if (!solve()) {
      break;
    }
  }
  return 0;
}
