#include <stdio.h>
#include <string.h>
#include <algorithm>
#include <iostream>
#include <math.h>
#include <assert.h>
#include <vector>
#include <queue>
#include <string>
#include <map>
#include <set>

using namespace std;
typedef long long ll;
typedef unsigned int uint;
typedef unsigned long long ull;
static const double EPS = 1e-3;
static const double PI = acos(-1.0);

#define REP(i, n) for (int i = 0; i < (int)(n); i++)
#define FOR(i, s, n) for (int i = (s); i < (int)(n); i++)
#define FOREQ(i, s, n) for (int i = (s); i <= (int)(n); i++)
#define FORIT(it, c) for (__typeof((c).begin())it = (c).begin(); it != (c).end(); it++)
#define MEMSET(v, h) memset((v), h, sizeof(v))


typedef double Weight;
struct Edge {
  int src;
  int dest;
  Weight weight;
  Edge(int src, int dest, Weight weight) : src(src), dest(dest), weight(weight) {;}
  bool operator<(const Edge &rhs) const {
    if (weight != rhs.weight) { return weight > rhs.weight; }
    if (src != rhs.src) { return src < rhs.src; }
    return dest < rhs.dest;
  }
};
typedef vector<Edge> Edges;
typedef vector<Edges> Graph;
typedef vector<Weight> Array;
typedef vector<Array> Matrix;

void PrintMatrix(const Matrix &matrix) {
  for (int y = 0; y < (int)matrix.size(); y++) {
    for (int x = 0; x < (int)matrix[y].size(); x++) {
      printf("%f ", matrix[y][x]);
    }
    puts("");
  }
}


int MaxFlow(const Graph &g, int s, int t) {
  const int n = g.size();
  Matrix capacity(n, Array(n, 0));
  for (int i = 0; i < n; i++) {
    for (Edges::const_iterator it = g[i].begin(); it != g[i].end(); it++) {
      capacity[it->src][it->dest] += it->weight;
    }
  }
  REP(y, n) REP(x, n) {
    capacity[y][x] = floor(capacity[y][x] + 1e-7);
  }
  int ret = 0;
  vector<int> parent(n);
  while (true) {
    fill(parent.begin(), parent.end(), -1);
    queue<Edge> que;
    que.push(Edge(s, s, 0));
    while (!que.empty()) {
      Edge node = que.front();
      que.pop();
      if (parent[node.dest] != -1) { continue; }
      parent[node.dest] = node.src;
      if (node.dest == t) { break; }
      int from = node.dest;
      for (Edges::const_iterator it = g[from].begin(); it != g[from].end(); it++) {
        int to = it->dest;
        if (capacity[from][to] == 0 || parent[to] != -1) { continue; }
        que.push(Edge(from, to, 0));
      }
    }
    if (parent[t] == -1) { break; }
    Weight flow = 2000000000;
    int from = parent[t];
    int to = t;
    while (from != to) {
      flow = min(flow, capacity[from][to]);
      from = parent[from];
      to = parent[to];
    }
    from = parent[t];
    to = t;
    while (from != to) {
      capacity[from][to] -= flow;
      capacity[to][from] += flow;
      from = parent[from];
      to = parent[to];
    }
    ret += flow;
  }
  return ret;
}

void AddEdge(Graph &g, int from, int to, Weight capacity) {
  g[from].push_back(Edge(from, to, capacity));
  g[to].push_back(Edge(to, from, 0));
}

#include <complex>

typedef complex<double> Point;
typedef vector<Point> Polygon;

static const double INF = 1e+10;

#define CURR(P, i) (P[i])
#define NEXT(P, i) (P[(i + 1) % P.size()])

struct Line : public vector<Point> {
  Line() {;}
  Line(Point a, Point b) { push_back(a); push_back(b); }
};

struct Circle {
  Point p;
  double r;
  Circle() {;}
  Circle(Point p, double r) : p(p), r(r) {;}
};

namespace std {
  bool operator<(const Point &lhs, const Point &rhs) {
    return lhs.real() == rhs.real() ? lhs.imag() < rhs.imag() : lhs.real() < rhs.real();
  }
}

inline double cross(const Point &a, const Point &b) {
  return imag(conj(a) * b);
}

inline double dot(const Point &a, const Point &b) {
  return real(conj(a) * b);
}

inline int ccw(Point a, Point b, Point c) {
  b -= a;
  c -= a;
  if (cross(b, c) > 0) { return 1; }
  if (cross(b, c) < 0) { return -1; }
  if (dot(b, c) < 0) { return 2; }
  if (norm(b) < norm(c)) { return -2; }
  return 0;
}


bool intersectLL(const Line &l, const Line &m) {
  return abs(cross(l[1] - l[0], m[1] - m[0])) > EPS ||
    abs(cross(l[1] - l[0], m[0] - l[0])) < EPS;
}

bool intersectSS(const Line &s, const Line &t) {
  return ccw(s[0], s[1], t[0]) * ccw(s[0], s[1], t[1]) <= 0 &&
    ccw(t[0], t[1], s[0]) * ccw(t[0], t[1], s[1]) <= 0;
}

bool intersectSP(const Line &s, const Point &p) {
  return abs(s[0] - p) + abs(s[1] - p) - abs(s[1] - s[0]) < EPS;
}


Point projection(const Line &l, const Point &p) {
  double t = dot(p - l[0], l[0] - l[1]) / norm(l[0] - l[1]);
  return l[0] + t * (l[0] - l[1]);
}

Point reflection(const Line &l, const Point &p) {
  return p + 2.0 * (projection(l, p) - p);
}

double distanceSP(const Line &s, const Point &p) {
  const Point r = projection(s, p);
  if (intersectSP(s, r)) { return abs(r - p); }
  return min(abs(s[0] - p), abs(s[1] - p));
}


Point crosspointSS(const Line &l, const Line &m) {
  double A = cross(l[1] - l[0], m[1] - m[0]);
  double B = cross(l[1] - l[0], l[1] - m[0]);
  if (abs(A) < EPS && abs(B) < EPS) {
    throw 1;
    assert(false);
    if (intersectSP(l, m[0])) { return m[0]; }
    if (intersectSP(l, m[1])) { return m[1]; }
    if (intersectSP(m, l[0])) { return l[0]; }
    if (intersectSP(m, l[1])) { return l[1]; }
    return m[0];
  }
  if (abs(A) < EPS) { assert(false); }
  return m[0] + B / A * (m[1] - m[0]);
}

int n, m;
int w[100];
Line ls[100];
set<Point> ps;
map<Point, int> mapto;

int main() {
  while (scanf("%d", &n) > 0) {
    ps.clear();
    mapto.clear();
    REP(i, n) {
      double x1, y1, x2, y2;
      scanf("%lf %lf %lf %lf %d", &x1, &y1, &x2, &y2, &w[i]);
      x1 = round(x1 * 1e+6);
      y1 = round(y1 * 1e+6);
      x2 = round(x2 * 1e+6);
      y2 = round(y2 * 1e+6);
      ps.insert(Point(x1, y1));
      ps.insert(Point(x2, y2));
      ls[i] = Line(Point(x1, y1), Point(x2, y2));
    }
    REP(i, n) {
      REP(j, i) {
        try {
          if (intersectSS(ls[i], ls[j])) {
            Point p = crosspointSS(ls[i], ls[j]);
            p.real() = round(p.real() + EPS);
            p.imag() = round(p.imag() + EPS);
            ps.insert(p);
          }
        } catch (int e) {
        }
      }
    }
    m = 0;
    FORIT(it, ps) { mapto[*it] = m++; }
    Graph g(m + 1);
    int dest = 0xdeadbeaf;
    {
      int k;
      scanf("%d", &k);
      REP(i, k) {
        double x, y;
        scanf("%lf %lf", &x, &y);
        x = round(x * 1e+6);
        y = round(y * 1e+6);
        Point p(x, y);
        assert(ps.count(p));
        AddEdge(g, m, mapto[p], 1000000);
      }
      double x, y;
      scanf("%lf %lf", &x, &y);
      x = round(x * 1e+6);
      y = round(y * 1e+6);
      Point p(x, y);
      assert(ps.count(p));
      dest = mapto[p];
    }
    REP(i, n) {
      double len = abs(ls[i][0] - ls[i][1]);
      vector<pair<double, Point> > dists;
      //dists.push_back(make_pair(0, ls[i][0]));
      //dists.push_back(make_pair(len, ls[i][1]));
      FORIT(it, ps) {
        if (!intersectSP(ls[i], *it)) { continue; }
        dists.push_back(make_pair(abs(ls[i][0] - *it), *it));
      }
      sort(dists.begin(), dists.end());
      REP(j, dists.size() - 1) {
        double ratio = (dists[j + 1].first - dists[j].first) / len;
        double cap = w[i] * ratio;
        int from = mapto[dists[j].second];
        int to = mapto[dists[j + 1].second];
        //cout << "Cap: " << from << " " << to << " " << cap << " " << ratio << endl;
        AddEdge(g, from, to, cap);
        AddEdge(g, to, from, cap);
      }
    }
    int ans = MaxFlow(g, m, dest) + 1e-6;
    printf("%d\n", ans);
  }
}

Measured memory_bytes: 0