Problem: Petya has a polygon consisting of n vertices. All sides of the Petya's polygon are parallel to the coordinate axes, and each two adjacent sides of the Petya's polygon are perpendicular. It is guaranteed that the polygon is simple, that is, it doesn't have self-intersections and self-touches. All internal area of the polygon (borders are not included) was painted in black color by Petya.

Also, Petya has a rectangular window, defined by its coordinates, through which he looks at the polygon. A rectangular window can not be moved. The sides of the rectangular window are parallel to the coordinate axes.

<image> Blue color represents the border of a polygon, red color is the Petya's window. The answer in this case is 2.

Determine the number of black connected areas of Petya's polygon, which can be seen through the rectangular window.

Input

The first line contain four integers x_1, y_1, x_2, y_2 (x_1 < x_2, y_2 < y_1) — the coordinates of top-left and bottom-right corners of the rectangular window. 

The second line contains a single integer n (4 ≤ n ≤ 15 000) — the number of vertices in Petya's polygon.

Each of the following n lines contains two integers — the coordinates of vertices of the Petya's polygon in counterclockwise order. Guaranteed, that the given polygon satisfies the conditions described in the statement.

All coordinates of the rectangular window and all coordinates of the vertices of the polygon are non-negative and do not exceed 15 000.

Output

Print the number of black connected areas of Petya's polygon, which can be seen through the rectangular window.

Example

Input

5 7 16 3
16
0 0
18 0
18 6
16 6
16 1
10 1
10 4
7 4
7 2
2 2
2 6
12 6
12 12
10 12
10 8
0 8


Output

2

Note

The example corresponds to the picture above.

Solution (in CPP):

Solution:
#include <bits/stdc++.h>
using namespace std;
const double PI = acos(double(-1));
const double INF = 1e10;
const double EPS = 1e-8;
inline double sqr(double x) { return x * x; }
struct PT {
  double x, y;
  PT() {}
  PT(double x, double y) : x(x), y(y) {}
};
bool operator<(const PT& p1, const PT& p2) {
  if (fabs(p1.x - p2.x) > EPS) return p1.x < p2.x;
  return p1.y + EPS < p2.y;
}
bool operator==(const PT& p1, const PT& p2) {
  return fabs(p1.x - p2.x) < EPS && fabs(p1.y - p2.y) < EPS;
}
PT operator+(PT p1, PT p2) { return PT(p1.x + p2.x, p1.y + p2.y); }
PT operator-(PT p1, PT p2) { return PT(p1.x - p2.x, p1.y - p2.y); }
PT operator*(PT p, double c) { return PT(p.x * c, p.y * c); }
PT operator/(PT p, double c) { return PT(p.x / c, p.y / c); }
double dis(PT p) { return sqrt(sqr(p.x) + sqr(p.y)); }
double dis2(PT p) { return sqr(p.x) + sqr(p.y); }
PT rot(PT p, double t) {
  return PT(p.x * cos(t) - p.y * sin(t), p.x * sin(t) + p.y * cos(t));
}
PT polar(PT p, double r, double t) {
  return PT(p.x + r * cos(t), p.y + r * sin(t));
}
double dis2(PT p1, PT p2) { return sqr(p1.x - p2.x) + sqr(p1.y - p2.y); }
double dis(PT p1, PT p2) { return sqrt(dis2(p1, p2)); }
double vect(PT p1, PT p2) { return p1.x * p2.y - p2.x * p1.y; }
double scal(PT p1, PT p2) { return p1.x * p2.x + p1.y * p2.y; }
double getAngle(PT p1, PT p2) { return atan2(p2.y - p1.y, p2.x - p1.x); }
double vect(PT p, PT p1, PT p2) { return vect(p1 - p, p2 - p); }
double scal(PT p, PT p1, PT p2) { return scal(p1 - p, p2 - p); }
double getAngle(PT p, PT p1, PT p2) {
  return getAngle(p, p2) - getAngle(p, p1);
}
double getAngle180(PT p, PT p1, PT p2) {
  return acos(scal(p, p1, p2) / dis(p, p1) / dis(p, p2));
}
double disToLine(PT p, PT p1, PT p2) {
  return fabs(vect(p, p1, p2)) / dis(p1, p2);
}
double disToSeg(PT p, PT p1, PT p2) {
  if (scal(p1, p, p2) < 0) return dis(p, p1);
  if (scal(p2, p, p1) < 0) return dis(p, p2);
  return disToLine(p, p1, p2);
}
bool onLine(PT p, PT p1, PT p2) { return fabs(vect(p1 - p, p2 - p)) < EPS; }
bool onSeg(PT p, PT p1, PT p2) {
  if (!onLine(p, p1, p2)) return 0;
  return (p1.x - p.x) * (p2.x - p.x) < EPS && (p1.y - p.y) * (p2.y - p.y) < EPS;
}
bool cross(PT p1, PT p2, PT p3, PT p4) {
  return vect(p1, p2, p3) * vect(p1, p2, p4) < -EPS &&
         vect(p3, p4, p1) * vect(p3, p4, p2) < -EPS;
}
bool common(PT p1, PT p2, PT p3, PT p4) {
  if (max(p1.x, p2.x) + EPS < min(p3.x, p4.x) ||
      max(p3.x, p4.x) + EPS < min(p1.x, p2.x))
    return 0;
  if (max(p1.y, p2.y) + EPS < min(p3.y, p4.y) ||
      max(p3.y, p4.y) + EPS < min(p1.y, p2.y))
    return 0;
  return vect(p1, p2, p3) * vect(p1, p2, p4) < EPS &&
         vect(p3, p4, p1) * vect(p3, p4, p2) < EPS;
}
PT projection(PT a, PT b, PT p) {
  return a + (a - b) * scal(p - a, a - b) / dis2(a - b);
}
int posLineLine(PT p1, PT p2, PT p3, PT p4, PT& p) {
  double s1 = vect(p1, p2, p3), s2 = vect(p1, p2, p4);
  if (fabs(s1 - s2) < EPS) {
    if (fabs(s1) < EPS) return 2;
    return 0;
  }
  p = p3 + (p4 - p3) * s1 / (s1 - s2);
  return 1;
}
int posCirLine(PT p, double r, PT p1, PT p2, PT* q) {
  double a, b, c, d2, d;
  a = dis2(p1, p2);
  b = scal(p1, p, p2);
  c = dis2(p, p1) - sqr(r);
  d2 = sqr(b) - a * c;
  if (d2 < -EPS) return 0;
  d = sqrt(fabs(d2));
  q[0] = p1 + (p2 - p1) * (b + d) / a;
  if (d2 < EPS) return 1;
  q[1] = p1 + (p2 - p1) * (b - d) / a;
  return 2;
}
int posCirCir(PT p1, double r1, PT p2, double r2, PT* q) {
  double dx, dy, d, e, f2, f;
  dx = p2.x - p1.x, dy = p2.y - p1.y;
  d = dis(p1, p2);
  e = (sqr(r1) - sqr(r2) + sqr(d)) / 2 / d;
  f2 = sqr(r1) - sqr(e);
  if (f2 < -EPS) return 0;
  f = sqrt(fabs(f2));
  q[0] = PT(p1.x + (e * dx - f * dy) / d, p1.y + (e * dy + f * dx) / d);
  if (f2 < EPS) return 1;
  q[1] = PT(p1.x + (e * dx + f * dy) / d, p1.y + (e * dy - f * dx) / d);
  return 2;
}
double calcArea(vector<PT> p) {
  double rlt = 0;
  int n = p.size();
  for (int i = 0; i < n; i++) rlt += vect(p[i], p[(i + 1) % n]);
  return rlt / 2;
}
int inPolygon(PT p, vector<PT> q) {
  PT p1, p2;
  int k = 0;
  int m = q.size();
  for (int i = 0; i < m; i++) {
    p1 = q[i], p2 = q[(i + 1) % m];
    if (onSeg(p, p1, p2)) return 2;
    if (p1.y > p2.y) swap(p1, p2);
    if (p1.y < p.y + EPS && p.y + EPS < p2.y && vect(p, p1, p2) > 0) k++;
  }
  return k % 2;
}
int posLineSegEx(PT p1, PT p2, PT p3, PT p4, PT& p) {
  double s1 = vect(p1, p2, p3), s2 = vect(p1, p2, p4);
  if (s1 * s2 > -EPS) return 0;
  p = p3 + (p4 - p3) * s1 / (s1 - s2);
  return 1;
}
vector<pair<int, int>> S;
vector<vector<PT>> cutPolygon(vector<PT> p, PT p1, PT p2) {
  for (int i = 0; i < p.size(); i++) {
    PT A = p[i], B = p[(i + 1) % p.size()];
    assert(A.x == B.x || A.y == B.y);
  }
  vector<vector<PT>> ret;
  vector<PT> vec;
  int n = p.size();
  PT q;
  vector<bool> chk;
  vector<int> vec1;
  for (int i = 0, j = 0; i < n; i++) {
    if (vect(p[i], p1, p2) > -EPS) {
      if (fabs(vect(p[i], p1, p2)) < EPS &&
          (vect(p[(i + n - 1) % n], p1, p2) < -EPS ||
           vect(p[(i + 1) % n], p1, p2) < -EPS))
        chk.push_back(0);
      else
        chk.push_back(1), vec1.push_back(j);
    } else
      chk.push_back(0);
    vec.push_back(p[i]);
    ++j;
    if (posLineSegEx(p1, p2, p[i], p[(i + 1) % n], q))
      vec.push_back(q), chk.push_back(1), vec1.push_back(j), ++j;
    assert(j == vec.size());
  }
  assert(chk.size() == vec.size());
  S.clear();
  for (int i = 0; i < vec.size(); i++) {
    if (chk[i] && chk[(i + 1) % vec.size()] &&
        (!onLine(vec[i], p1, p2) || !onLine(vec[(i + 1) % vec.size()], p1, p2)))
      S.push_back(pair<int, int>(i, (i + 1) % vec.size()));
  }
  vector<int> ids;
  for (int i = 0; i < vec.size(); i++) {
    if (onLine(vec[i], p1, p2) && chk[i]) ids.push_back(i);
  }
  assert(ids.size() % 2 == 0);
  sort(ids.begin(), ids.end(),
       [&vec](int i, int j) { return vec[i] < vec[j]; });
  if (ids.size())
    for (int i = 0; i < ids.size() - 1; i++)
      assert(vec[ids[i]] < vec[ids[i + 1]]);
  if (ids.size() > 1)
    for (int i = 0; i < ids.size(); i += 2)
      S.push_back(pair<int, int>(ids[i], ids[i + 1]));
  int con[vec.size()][2], cn[vec.size()];
  memset(cn, 0, sizeof cn);
  for (auto t : S) {
    int a = t.first, b = t.second;
    con[a][cn[a]++] = b;
    con[b][cn[b]++] = a;
  }
  bool flg[vec.size()];
  for (int i = 0; i < vec.size(); i++) flg[i] = !chk[i];
  for (int i = 0; i < vec.size(); i++) {
    if (flg[i]) continue;
    vector<PT> vp;
    int now = i;
    vp.push_back(vec[now]);
    flg[now] = 1;
    while (1) {
      int ne = con[now][0];
      if (flg[ne]) ne = con[now][1];
      if (flg[ne]) break;
      flg[ne] = 1;
      now = ne;
      vp.push_back(vec[now]);
    }
    if (calcArea(vp) < -EPS) reverse(vp.begin(), vp.end());
    ret.push_back(vp);
  }
  return ret;
}
double minX, maxX, minY, maxY;
vector<PT> vec;
int main() {
  scanf("%lf%lf%lf%lf", &minX, &maxY, &maxX, &minY);
  int n;
  scanf("%d", &n);
  for (int i = 0; i < n; i++) {
    PT tem;
    scanf("%lf%lf", &tem.x, &tem.y);
    vec.push_back(tem);
  }
  vector<vector<PT>> out[4], tem;
  out[0] = cutPolygon(vec, PT(minX, minY), PT(maxX, minY));
  for (auto it : out[0]) {
    tem = cutPolygon(it, PT(maxX, minY), PT(maxX, maxY));
    for (auto t : tem) out[1].push_back(t);
  }
  for (auto it : out[1]) {
    tem = cutPolygon(it, PT(maxX, maxY), PT(minX, maxY));
    for (auto t : tem) out[2].push_back(t);
  }
  for (auto it : out[2]) {
    tem = cutPolygon(it, PT(minX, maxY), PT(minX, minY));
    for (auto t : tem) out[3].push_back(t);
  }
  cout << out[3].size() << endl;
}