#include <cstdio>
#include <vector>
#include <utility>
#include <algorithm>
#include <cmath>

#if 0
#define dbg(...) fprintf(stderr, __VA_ARGS__),fflush(stderr)
#else
#define dbg(...)
#endif

using namespace std;

typedef long long ll;
typedef pair <double, double> pdd;
typedef pair <int, int> pii;

#define assert(cond) my_assert(cond, #cond)

void my_assert(bool cond, const char * msg) {
    if (!cond) {
        fprintf(stderr, "Assertion failed '%s'", msg);
        throw 42;
    }
}

struct Point {
    Point() {}
    Point(int x, int y) : x(x), y(y) {}

    Point rotate90() const {
        return Point(-y, x);
    }

    Point operator + (const Point & p) const {
        return Point(x + p.x, y + p.y);
    }

    Point operator - (const Point & p) const {
        return Point(x - p.x, y - p.y);
    }

    Point operator - () const {
        return Point(-x, -y);
    }

    ll operator * (const Point & p) const {
        return ll(x) * p.y - ll(y) * p.x;
    }

    ll operator % (const Point & p) const {
        return ll(x) * p.x + ll(y) * p.y;
    }

    double abs() const {
        return sqrt(*this % *this);
    }

    Point & operator -= (const Point & p) {
        return *this = *this - p;
    }

    bool operator == (const Point & p) const {
        return x == p.x && y == p.y;
    }

    bool operator != (const Point & p) const {
        return !(*this == p);
    }

    void read() {
        scanf("%d%d", &x, &y);
    }

    void print(const char * name) const {
        dbg("%s = (%d, %d)\n", name, x, y);
    }
private:
    int x, y;
};

struct Polygon {
private:
    int n;
    vector <Point> p;
public:
    void read() {
        scanf("%d", &n);
        p.resize(n);
        for (int i = 0; i < n; ++i) {
            p[i].read();
        }
    }

    int size() const {
        return n;
    }

    const Point & operator[](int index) const {
        if (index < 0) {
            return p[index + n];
        } else if (index < n) {
            return p[index];
        } else {
            return p[index - n];
        }
    }
};

int binSearch(const Polygon & p, const Point & v, int from) {
    int L = from;
    for (int iter = 0; v * (p[L + 1] - p[L]) == 0; ++iter) {
        ++L;
        assert(iter < 3);
    }
    assert(v * (p[L + 1] - p[L]) > 0);

    int R = L + p.size();
    while (L + 1 < R) {
        int M = (L + R) / 2;

        Point vM = p[M + 1] - p[M];
        if (v * vM <= 0) {
            R = M;
        } else if (vM * (p[L + 1] - p[L]) > 0) {
            R = M;
        } else {
            L = M;
        }
    }
    return (L + 1) % p.size();
}

pii findExtremePoints(const Polygon & p, Point v) {
    int L = 0;
    for (int iter = 0; v * (p[L + 1] - p[L]) == 0; ++iter) {
        ++L;
        assert(iter < 3);
    }
    bool negated = false;
    if (v * (p[L + 1] - p[L]) < 0) {
        v = -v;
        negated = true;
    }
    int A = binSearch(p, v, L);
    int B = binSearch(p, -v, A);
    if (negated) {
        v = -v;
        negated = false;
        swap(A, B);
    }
    dbg("findExtremePoints for ");
    v.print("v");
    dbg("results %d and %d\n", A, B);
    return pii(A, B);
}

int sign(ll x) {
    if (x > 0) {
        return 1;
    } else if (x < 0) {
        return -1;
    } else {
        return 0;
    }
}

bool tryIntersectLineAndSegment(const Point & a, const Point & b, const Point & c, const Point & d, double & t) {
// a and b are points on line, c and d are ends of segment
    Point v1 = b - a;
    Point v2 = d - c;
    ll mult = v1 * v2;
    if (mult == 0) {
        return false;
    }
    if (sign(v1 * (c - a)) * sign(v1 * (d - a)) == 1) {
        return false;
    }
    t = double((c - a) * v2) / mult;
    return true;
}

bool belongsToLine(const Point & a, const Point & b, const Point & p, double & t) {
    dbg("belongsToLine\n");
    a.print("a");
    b.print("b");
    p.print("p");
    Point v = b - a;
    if (v * (p - a) != 0) {
        return false;
    }
    t = double((p - a) % v) / (v % v);
    return true;
}

double intersectLineAndHalfPolygon(const Polygon & p, const Point & a, const Point & v, int L, int R) {
    if (R < L) {
        R += p.size();
    }
    Point v2 = v.rotate90();
    dbg("intersectLineAndHalfPolygon for L = %d, R = %d\n", L, R);
    a.print("a");
    v.print("v");
    v2.print("v2");
    ll zzz = a % v2;
    assert(p[L] % v2 > zzz);
    assert(p[R] % v2 < zzz);
    while (L + 1 < R) {
        int M = (L + R) / 2;
        if (p[M] % v2 >= zzz) {
            L = M;
        } else {
            R = M;
        }
    }
    double res;
    assert(tryIntersectLineAndSegment(a, a + v, p[L], p[L + 1], res));
    return res;
}

bool tryIntersectLineAndPolygon(const Polygon & p, const Point & a, const Point & b, pdd & res) {
    double tempD;
    pii extremes = findExtremePoints(p, b - a);
    if (!tryIntersectLineAndSegment(a, b, p[extremes.first], p[extremes.second], tempD)) {
        dbg("There is no intersection with polygon\n");
        return false;
    }
    if (belongsToLine(a, b, p[extremes.first], res.first)) {
        if (!belongsToLine(a, b, p[extremes.first + 1], res.second)) {
            res.second = res.first;
        }
        dbg("There is 1st intersection with polygon border (%.5lf %.5lf)\n", res.first, res.second);
        return true;
    }
    if (belongsToLine(a, b, p[extremes.second], res.first)) {
        if (!belongsToLine(a, b, p[extremes.second + 1], res.second)) {
            res.second = res.first;
        }
        dbg("There is 2nd intersection with polygon border (%.5lf %.5lf)\n", res.first, res.second);
        return true;
    }

    res.first = intersectLineAndHalfPolygon(p, a, b - a, extremes.first, extremes.second);
    res.second = -intersectLineAndHalfPolygon(p, a, a - b, extremes.second, extremes.first);
    dbg("There is internal intersection (%.5lf %.5lf)\n", res.first, res.second);
    return true;
}

pdd processMoving(const Polygon & p, const Point & v, Point & a, Point & b) {
    a.print("a");
    b.print("b");
    v.print("v");

    vector <double> intersections;

    if (v != Point(0, 0)) {
        pii extremes = findExtremePoints(p, v);
        double tempD;
        if (tryIntersectLineAndSegment(a, b, p[extremes.first], p[extremes.first] + v, tempD)) {
            intersections.push_back(tempD);
        }
        if (tryIntersectLineAndSegment(a, b, p[extremes.second], p[extremes.second] + v, tempD)) {
            intersections.push_back(tempD);
        }
    }

    pdd tempP;
    if (tryIntersectLineAndPolygon(p, a, b, tempP)) {
        intersections.push_back(tempP.first);
        intersections.push_back(tempP.second);
    }

    a -= v;
    b -= v;

    if (tryIntersectLineAndPolygon(p, a, b, tempP)) {
        intersections.push_back(tempP.first);
        intersections.push_back(tempP.second);
    }

    if (intersections.empty()) {
        return pdd(0.0, 0.0);
    }

    sort(intersections.begin(), intersections.end());
    return pdd(intersections[0], intersections.back());
}

struct Event {
    int type;
    double x;

    Event(int type, double x) : type(type), x(x)  {
    }

    bool operator < (const Event & e) const {
        if (fabs(x - e.x) > 1e-11) {
            return x < e.x;
        }
        return type < e.type;
    }
};

int main() {
    freopen("snow.in", "r", stdin);
    freopen("snow.out", "w", stdout);

    Point a, b;
    a.read();
    b.read();

    Polygon p;
    p.read();

    vector <pdd> segments;

    int m;
    scanf("%d", &m);
    segments.push_back(processMoving(p, Point(0, 0), a, b));
    for (int i = 0; i < m; ++i) {
        Point v;
        v.read();
        segments.push_back(processMoving(p, v, a, b));
        dbg("(%.5lf %.5lf)\n", segments.back().first, segments.back().second);
    }
    vector <Event> events;
    for (pdd & seg : segments) {
        if (seg.first > seg.second) {
            swap(seg.first, seg.second);
        }
        events.push_back(Event(0, seg.first));
        events.push_back(Event(1, seg.second));
    }
    sort(events.begin(), events.end());
    
    double result = 0.0;
    double openLeftX = 0.0;
    int openCnt = 0;
    for (const Event & ev : events) {
        if (ev.type == 0) {
            openCnt++;
            if (openCnt == 1) {
                openLeftX = ev.x;
            }
        } else {
            openCnt--;
            if (openCnt == 0) {
                result += ev.x - openLeftX;
                dbg("add (%.5lf %5lf)\n", openLeftX, ev.x);
            }
        }
    }
    printf("%.20lf\n", result * (b - a).abs());
    return 0;
}