Problem:
カーテン
もうすぐ夏がやってくる．あなたは夏に向けて部屋の模様替えをすることにした．今年の夏はとても日差しが強いことが予想されており，まぶしいのが苦手なあなたには辛い季節になりそうだ．そこで，あなたは部屋の明るさを調節するために，部屋の窓にカーテンを取り付けようと考えた．
取り付けるカーテンは長方形であり，辺が地面に対して垂直，もしくは平行であるように取り付ける．また，あなたの部屋の窓は非常に特殊な形をしており，各辺が地面に平行または垂直であるような
N
角形で表される．そのため，カーテンを取り付けたときにカーテンに覆われていない窓の面積がどのくらいになるのかを求めるのは難しい．部屋の明るさを調節するためにも，カーテンを取り付ける位置を決めた時にどのくらい窓が覆えるかを知ることは重要である．そこで，あなたは窓とカーテンの設置位置と形状が与えられたときに，カーテンに覆われていない窓の面積を求めるプログラムを作ることにした．
例として次のような窓とカーテンの設置の仕方を考える．この場合はカーテンに隠れていない窓の面積は 8 となる．この例はサンプル入力の 3 ケース目に対応する．
Input
入力は複数データセットからなる．
各データセットは次の形式で与えられる．
N
x
1
y
1
:
:
x
N
y
N
a
1
b
1
a
2
b
2
a
3
b
3
a
4
b
4
最初の行には窓の持つ頂点数を表す整数
N
が与えられる (
4 ≤ N ≤ 100
)．続く
N
行には窓の相異なる頂点のx座標を表す整数
x
i
とy座標を表す整数
y
i
が与えられる (
-20,000 ≤ x
i
, y
i
≤ 20,000, 1 ≤ i ≤ N
)．ここで，y軸の正の向きはx軸の正の向きから90度分反時計回りに回転させた方向とする．さらに，続く 4 行にはカーテンの相異なる頂点のx座標を表す整数
a
j
と y座標を表す整数
b
j
が与えられる (
-20,000 ≤ a
j
, b
j
≤ 20,000, 1 ≤ j ≤ 4
)．窓，カーテンともに，それぞれの頂点は反時計回り順に与えられる．また，窓，カーテンを表す図形はそれぞれ自己交差がない図形である．
入力の終わりは1つの 0 からなる行で示す．
Output
各データセットについて，カーテンに覆われていない窓の面積を 1 行に出力せよ．ただし，面積は必ず整数値になることに注意せよ．
Sample Input
4
0 0
10 0
10 10
0 10
0 0
5 0
5 10
0 10
6
0 0
10 0
10 5
5 5
5 10
0 10
2 0
8 0
8 10
2 10
12
1 1
1 3
-1 3
-1 1
-3 1
-3 -1
-1 -1
-1 -3
1 -3
1 -1
3 -1
3 1
2 2
-2 2
-2 -2
2 -2
4
20000 20000
-20000 20000
-20000 -20000
20000 -20000
1000 1000
-1000 1000
-1000 -1000
1000 -1000
4
1000 1000
-1000 1000
-1000 -1000
1000 -1000
20000 20000
-20000 20000
-20000 -20000
20000 -20000
4
0 0
10 0
10 10
0 10
20 0
30 0
30 10
20 10
0
Output for Sample Input
50
30
8
1596000000
0
100

Submitted solutions:

code_snippet: #include <bits/stdc++.h>
#include <unordered_map>
#include <stdlib.h>
using namespace std;
#define rep(i, a, n) for(ll i = a; i < n; i++)
#define rrep(i, a, n) for(ll i = a; i >= n; i--)
#define ll long long
#define pii pair<int, int>
#define pll pair<ll, ll>
#define all(x) (x).begin(), (x).end()
//constexpr ll MOD = 1000000007;
constexpr ll MOD = 998244353;
constexpr int IINF = 1001001001;
constexpr ll INF = 1LL<<60;
template<class t,class u> void chmax(t&a,u b){if(a<b)a=b;}
template<class t,class u> void chmin(t&a,u b){if(b<a)a=b;}


ll gcd(ll a, ll b){
    if(a%b == 0){
      return b;
    }else{
      return gcd(b, a%b);
    }
}

ll lcm(ll a, ll b){
    return a*b / gcd(a, b);
}

ll powMod(ll x, ll n) {
    if (n == 0) return 1 % MOD;
    ll val = powMod(x, n / 2);
    val *= val;
    val %= MOD;
    if (n % 2 == 1) val *= x;
    return val % MOD;
}

template <class T, T (*op)(T, T), T (*e)(), class F, T (*mapping)(F, T), F (*composition)(F, F), F (*id)()> 
class LazySegmentTree {
    ll _n, size, log;
    vector<T> d;
    vector<F> lz;

    void update(ll k) { d[k] = op(d[2 * k], d[2 * k + 1]); }

    void all_apply(ll k, F f){
        d[k] = mapping(f, d[k]);
        if (k < size) lz[k] = composition(f, lz[k]);
    }

    void push(ll k){
        all_apply(2*k, lz[k]);
        all_apply(2*k+1, lz[k]);
        lz[k] = id();
    }

public:
    LazySegmentTree() : LazySegmentTree(0) {}
    explicit LazySegmentTree(ll n) : LazySegmentTree(vector<T>(n, e())) {} // explicit で明示的に型を指定する
    explicit LazySegmentTree(const vector<T> &v) : _n(int(v.size())) {
        // sizeは_nを超える最小の2のべき乗
        size = 1;
        while(size < _n) size *= 2, log++; 

        // log は木の高さ（sizeの桁数）
        log = 0;
        while (!(size & (1 << log))) log++;

        d = vector<T>(2*size, e());
        lz = vector<F>(size, id());

        for(ll i = 0; i < _n; i++) d[size+i] = v[i];
        for(ll i = size-1; i >= 1; i--){
            update(i);
        }
    }

    void set(ll p, T x){
        assert(0 <= p && p < _n);
        p += size;
        for(ll i = log; i >= 1; i--) push(p >> i);
        d[p] = x;
        for(ll i = 1; i <= log; i++) update(p >> i);
    }

    T get(ll p) {
        assert(0 <= p && p < _n);
        p += size;
        for(ll i = log; i >= 1; i--) push(p >> i);
        return d[p];
    }


    T prod(ll l, ll r) {
        assert(0 <= l && l <= r && r <= _n);
        if(l == r) return e();

        l += size;
        r += size;

        for(ll i = log; i >= 1; i--){
            if(((l >> i) << i) != l) push(l >> i);
            if(((r >> i) << i) != r) push((r-1) >> i);
        }
        
        T sml = e(), smr = e();
        while(l < r){
            if(l&1) sml = op(sml, d[l++]);
            if(r&1) smr = op(d[--r], smr);
            l >>= 1;
            r >>= 1;
        }

        return op(sml, smr);
    }

    T all_prod() {return d[1]; }

    void apply(ll p, F f){
        assert(0 <= p && p < _n);
        p += size;
        for(ll i = log; i >= 1; i--) push(p >> i); 
        d[p] = mapping(f, d[p]);
        for(ll i = 1; i <= log; i++) update(p >> i);
    }

    void apply(ll l, ll r, F f){
        assert(0 <= l && l <= r && r <= _n);
        if(l == r) return;

        l += size;
        r += size;

        for(ll i = log; i >= 1; i--){
            if(((l >> i) << i) != l) push(l >> i);
            if(((r >> i) << i) != r) push((r-1) >> i);
        }

        {
            ll l2 = l, r2 = r;
            while(l < r){
                if(l&1) all_apply(l++, f);
                if(r&1) all_apply(--r, f);
                l >>= 1;
                r >>= 1;
            }
            l = l2;
            r = r2;
        }

        for(ll i = 1; i <= log; i++){
            if(((l >> i) << i) != l) update(l >> i);
            if(((r >> i) << i) != r) update((r-1) >> i);
        }
    }

    // f(op(a[l], a[l + 1], ..., a[r - 1])) = trueとなる最大のｒ
    template <bool (*g)(T)> ll max_right(ll l) {
        return max_right(l, [](T x) { return g(x); });
    }
    template <class G> ll max_right(ll l, G g) {
        assert(0 <= l && l <= _n);
        assert(g(e()));
        if (l == _n) return _n;
        l += size;
        for (ll i = log; i >= 1; i--) push(l >> i);
        T sm = e();
        do {
            while (l % 2 == 0) l >>= 1;
            if (!g(op(sm, d[l]))) {
                while (l < size) {
                    push(l);
                    l = (2 * l);
                    if (g(op(sm, d[l]))) {
                        sm = op(sm, d[l]);
                        l++;
                    }
                }
                return l - size;
            }
            sm = op(sm, d[l]);
            l++;
        } while ((l & -l) != l);
        return _n;
    }

    // f(op(a[l], a[l + 1], ..., a[r - 1])) = trueとなる最小のl
    template <bool (*g)(T)> ll min_left(ll r) {
        return min_left(r, [](T x) { return g(x); });
    }
    template <class G> ll min_left(ll r, G g) {
        assert(0 <= r && r <= _n);
        assert(g(e()));
        if (r == 0) return 0;
        r += size;
        for (ll i = log; i >= 1; i--) push((r - 1) >> i);
        T sm = e();
        do {
            r--;
            while (r > 1 && (r % 2)) r >>= 1;
            if (!g(op(d[r], sm))) {
                while (r < size) {
                    push(r);
                    r = (2 * r + 1);
                    if (g(op(d[r], sm))) {
                        sm = op(d[r], sm);
                        r--;
                    }
                }
                return r + 1 - size;
            }
            sm = op(d[r], sm);
        } while ((r & -r) != r);
        return 0;
    }
};

//区間加算・区間和取得
struct S{
    long long value;
    ll size;
};
using F = long long;

S op(S a, S b){ return {a.value+b.value, a.size+b.size}; }
S e(){ return {0, 0}; }
S mapping(F f, S x){ return {x.value + f*x.size, x.size}; }
F composition(F f, F g){ return f+g; }
F id(){ return 0; }
// ll n;
// vector<S> v(n, {0, 1});
// LazySegmentTree<S, op, e, F, mapping, composition, id> seg(v);

struct Pos{
    ll x, y;
};

int main() {
    while(true){
        ll n; cin >> n;
        if(n == 0) break;
        vector<Pos> vec(n+1);
        rep(i,0,n){
            ll x, y; cin >> x >> y;
            vec[i] = {x,y};
        }
        vec[n] = vec[0];
        ll x1 = INF, x2 = -INF, y1 = INF, y2 = -INF;
        rep(i,0,4){
            ll a, b; cin >> a >> b;
            chmin(x1, a);
            chmin(y1, b);
            chmax(x2, a);
            chmax(y2, b);
        }
        vector<tuple<ll,ll,ll,ll>> event;
        ll b = 20000;
        rep(i,0,n){
            if(vec[i].y > vec[i+1].y){
                event.push_back({vec[i].x, 1, vec[i+1].y+b, vec[i].y+b});
            }
            if(vec[i].y < vec[i+1].y){
                event.push_back({vec[i].x, -1, vec[i].y+b, vec[i+1].y+b});
            }
        }
        event.push_back({x1,1,y1+b,y1+b});
        event.push_back({x2,-1,y1+b,y1+b});
        sort(all(event));
        vector<S> v(b*2+1,{0,1});
        LazySegmentTree<S,op,e,F,mapping,composition,id> seg(v);
        ll ans = 0;
        ll pre = -INF;
        for(auto [x,p,yl,yr]: event){
            if(pre != -INF){
                ans += seg.all_prod().value*(x-pre);
                if(x1 < x && x <= x2){
                    ans -= seg.prod(y1+b,y2+b).value*(x-pre);
                }
            }
            seg.apply(yl,yr,p);
            pre = x;
        }

        cout << ans << endl;
    }
    return 0;
}
accuracy: 1
time_ms: 10
memory_kb: 6612
final_rank: 10

code_snippet: #include <bits/stdc++.h>
using namespace std;
using ll = long long;
using ull = unsigned long long;
using vll = vector<ll>;
using vvll = vector<vll>;
using P = pair<int, int>;
using PP = pair<int, P>;
using PLL = pair<ll, ll>;
using PPLL = pair<ll, PLL>;
#define rep(i, n) for(ll i = 0; i < n; ++i)
#define rrep(i, n) for(ll i = n - 1; i >= 0; --i)
#define loop(i, a, b) for(ll i = a; i <= b; ++i)
#define all(v) v.begin(), v.end()
#define nC2(n) n * (n - 1) / 2
constexpr ll INF = 9009009009009009009LL;
constexpr int INF32 = 2002002002;
constexpr ll MOD = 998244353;
constexpr ll MOD107 = 1000000007;

// Linear Algebra ////////////////////////////////////////////////
const double Rad2Deg = 180.0 / M_PI;
const double Deg2Rad = M_PI / 180.0;
//////////////////////////////////////////////////////////////////

int dx[8] = {0, 1, 0, -1, 1, 1, -1, -1};
int dy[8] = {1, 0, -1, 0, 1, -1, 1, -1};

template <class T>
inline bool chmax(T &a, const T &b) {
	if (a < b) {
		a = b;
		return true;
	}
	return false;
}
template <class T>
inline bool chmin(T &a, const T &b) {
	if (a > b) {
		a = b;
		return true;
	}
	return false;
}

template <typename Container,
          typename = std::enable_if_t<
              !std::is_same_v<Container, std::string> &&
              std::is_convertible_v<decltype(std::declval<Container>().begin()),
                                    typename Container::iterator>>>
ostream &operator<<(ostream &os, const Container &container) {
    auto it = container.begin();
    auto end = container.end();

    if (it != end) {
        os << *it;
        ++it;
    }
	for (; it != end; ++it) {
		os << " " << *it;
	}
    return os;
}
template <typename T>
ostream& operator<<(ostream& os, const vector<T>& v) {
    for (size_t i = 0; i < v.size(); ++i) {
        os << v[i];
        if (i != v.size() - 1) os << " ";
    }
    return os;
}
template <typename T>
ostream& operator<<(ostream& os, const vector<vector<T>>& vv) {
	for (size_t i = 0; i < vv.size(); ++i) {
		os << vv[i];
		if (i != vv.size() - 1) os << "\n";
    }
    return os;
}
template <typename T>
istream& operator>>(istream& is, vector<T>& v) {
	assert(v.size() > 0);
	for (size_t i = 0; i < v.size(); ++i) is >> v[i];
	return is;
}
template <typename T>
istream& operator>>(istream& is, vector<vector<T>>& vv) {
	assert(vv.size() > 0);
	for (size_t i = 0; i < vv.size(); ++i) is >> vv[i];
	return is;
}

struct phash {
	template<class T1, class T2>
    inline size_t operator()(const pair<T1, T2> & p) const {
        auto h1 = hash<T1>()(p.first);
        auto h2 = hash<T2>()(p.second);

		size_t seed = h1 + h2; 
		h1 = ((h1 >> 16) ^ h1) * 0x45d9f3b;
        h1 = ((h1 >> 16) ^ h1) * 0x45d9f3b;
        h1 = (h1 >> 16) ^ h1;
        seed ^= h1 + 0x9e3779b9 + (seed << 6) + (seed >> 2);
		h2 = ((h2 >> 16) ^ h2) * 0x45d9f3b;
        h2 = ((h2 >> 16) ^ h2) * 0x45d9f3b;
        h2 = (h2 >> 16) ^ h2;
        seed ^= h2 + 0x9e3779b9 + (seed << 6) + (seed >> 2);
        return seed;
    }
};





int solve() {
	ll n;
	cin >> n;
	if (n == 0)
		return 1;

	vector<PLL> vert(n);
	rep(i, n)
	{
		cin >> vert[i].first >> vert[i].second;
		vert[i].first += 2 * 1e4;
		vert[i].second += 2 * 1e4;
	}
	vector<PLL> cur_vert(4);
	rep(i, 4) {
		 cin >> cur_vert[i].first >> cur_vert[i].second;
		 cur_vert[i].first += 2 * 1e4;
		 cur_vert[i].second += 2 * 1e4;
	}

	vvll bound(4 * 1e4 + 10, vll());
	rep(i, n) {
		auto [x, y] = vert[i];
		auto [nx, ny] = vert[(i + 1) % n];
		if (x == nx)
			continue;
		if (nx < x)
			swap(x, nx);
		loop(j, x, nx - 1) {
			bound[j].push_back(y);
		}
	}

	vvll curtain(4 * 1e4 + 10, vll());
	rep(i, 4) {
		auto [x, y] = cur_vert[i];
		auto [nx, ny] = cur_vert[(i + 1) % 4];
		if (x == nx)
			continue;
		if (nx < x)
			swap(x, nx);
		loop(j, x, nx - 1) {
			curtain[j].push_back(y);
		}
	}

	ll ans = 0;
	rep(i, bound.size()) {
		assert(bound[i].size() % 2 == 0);
		assert(curtain[i].size() == 2 || curtain[i].size() == 0);
		sort(all(bound[i]));
		sort(all(curtain[i]));
		rep(j, bound[i].size() / 2) {
			ll idx = 2 * j;
			if (curtain[i].size() == 2) {
				ll mn = curtain[i][0];
				ll mx = curtain[i][1];
				ans += abs(min(bound[i][idx], mn) - min(bound[i][idx + 1], mn));
				ans += abs(max(bound[i][idx], mx) - max(bound[i][idx + 1], mx));
			}
			else {
				ans += abs(bound[i][idx] - bound[i][idx + 1]);
			}
		}
	}

	cout << ans << "\n";

	return 0;
}

int main() {
	cin.tie(nullptr);
	ios::sync_with_stdio(false);

	while (!solve()) {}
	return 0;
}
accuracy: 1
time_ms: 200
memory_kb: 26760
final_rank: 17

code_snippet: #include <bits/stdc++.h>
using namespace std;
#define rep(i, n) for (long long i = 0; i < (long long)(n); i++)
#define rrep(i,start,end) for (long long i = start;i >= (long long)(end);i--)
#define repn(i,end) for(long long i = 0; i <= (long long)(end); i++)
#define reps(i,start,end) for(long long i = start; i < (long long)(end); i++)
#define repsn(i,start,end) for(long long i = start; i <= (long long)(end); i++)
#define each(p,a) for(auto &p:a)
typedef long long ll;
typedef unsigned long long ull;
typedef long double ld;
typedef vector<long long> vll;
typedef vector<pair<long long ,long long>> vpll;
typedef vector<vector<long long>> vvll;
typedef set<ll> sll;
typedef map<long long , long long> mpll;
typedef pair<long long ,long long> pll;
typedef tuple<long long , long long , long long> tpl3;
#define LL(...) ll __VA_ARGS__; input(__VA_ARGS__)
#define LD(...) ld __VA_ARGS__; input(__VA_ARGS__)
#define Str(...) string __VA_ARGS__; input(__VA_ARGS__)
#define Ch(...) char __VA_ARGS__; input(__VA_ARGS__)
#define all(a)  (a).begin(),(a).end()
#define UNIQUE(v) v.erase( unique(v.begin(), v.end()), v.end() );
#define sz(x) (int)x.size()
// << std::fixed << std::setprecision(10)
const ll INF = 1LL << 60;
const ld EPS = 1e-9;
 
inline ll lfloor(ll x,ll m){return (x - ((x % m+ m)%m))/m;}
inline ll positive_mod(ll a,ll m){return (a % m + m)%m;}
inline ll popcnt(ull a){ return __builtin_popcountll(a);}
template<class T> bool chmin(T& a, T b){if(a > b){a = b;return true;}return false;}
template<class T> bool chmax(T& a, T b){if(a < b){a = b;return true;}return false;}
template<typename T> std::istream &operator>>(std::istream&is,std::vector<T>&v){for(T &in:v){is>>in;}return is;}
template<typename T> std::ostream &operator<<(std::ostream&os,const std::vector<T>&v){for(auto it=std::begin(v);it!=std::end(v);){os<<*it<<((++it)!=std::end(v)?" ":"");}return os;}
template<typename T1, typename T2>std::ostream &operator<< (std::ostream &os, std::pair<T1,T2> p){os << "{" << p.first << "," << p.second << "}";return os;}
template<class... T>void input(T&... a){(cin >> ... >> a);}
void print(){cout << endl;}
template<class T, class... Ts>void print(const T& a, const Ts&... b){cout << a;((cout << ' ' << b), ...);cout << endl;}
template<class T> void pspace(const T& a){ cout << a << ' ';}
void perr(){cerr << endl;}
template<class T, class... Ts>void perr(const T& a, const Ts&... b){cerr << a;((cerr << ' ' << b), ...);cerr << endl;}
void yes(bool i = true){ return print(i?"yes":"no"); }
void Yes(bool i = true){ return print(i?"Yes":"No"); }
void YES(bool i = true){ return print(i?"YES":"NO"); }
template <class T> vector<T> &operator++(vector<T> &v) {for(auto &e : v) e++;return v;}
template <class T> vector<T> operator++(vector<T> &v, signed) {auto res = v;for(auto &e : v) e++;return res;}
template <class T> vector<T> &operator--(vector<T> &v) {for(auto &e : v) e--;return v;}
template <class T> vector<T> operator--(vector<T> &v, signed) {auto res = v;for(auto &e : v) e--;return res;}
//grid探索用
vector<ll> _ta = {0,0,1,-1,1,1,-1,-1};
vector<ll> _yo = {1,-1,0,0,1,-1,1,-1};
bool isin(ll now_i,ll now_j,ll h,ll w){return (0<=now_i && now_i < h && 0 <= now_j && now_j < w);}
  
ll lpow(ll x,ll n){ll ans = 1;while(n >0){if(n & 1)ans *= x;x *= x;n >>= 1;}return ans;}
ll Modlpow(ll x,ll n,ll m){ll ans = 1;ll a = x%m;while(n >0){if(n & 1){ans *= a;ans%= m;}a *= a;a %= m;n >>= 1;}return ans;} 
const ll MOD9 = 998244353LL;
const ll MOD10 = 1000000007LL;

// for AOJ or ICPC or etc..
// 全部が0だったらtrueを返す
template<class Tp> bool zero (const Tp &x) {return x == 0;}
template<class Tp, class... Args> bool zero (const Tp &x, const Args& ...args) {return zero(x) and zero(args...);}


//参考 https://github.com/saphmitchy/deliair-lib
// 型名
// R:Real, P:Point, L:Line, S:Segment, C:Circle, VP:vector<Point>

#define X(p) real(p)
#define Y(p) imag(p)

using R = ld;
using P = complex<R>;
using VP = vector<P>;

//const R EPS = 1e-9; // ここは適宜調節する,いつものやつから消す
const R pi = acos(-1.0);

int sgn(R a) {
    return (a < -EPS) ? -1 : (a > EPS) ? 1 : 0;
} // 符号関数

bool eq(R a, R b) {//実数の一致判定
    return sgn(b - a) == 0;
}

P operator*(P p, R d) {//ベクトルのd倍
    return P(X(p) * d, Y(p) * d);
}

P operator/(P p, R d) {//ベクトルの1/d倍
    return p * (1 / d);
}

istream &operator>>(istream &is, P &p) {
    // R a, b; // 入力が小数
    int a, b; // 入力が整数
    is >> a >> b;
    p = P(a, b);
    return is;
}

ostream &operator<<(ostream &os, P p) {
    return os << X(p) << ' ' << Y(p);
}

R getarg(P b,P a){//ベクトルbはベクトルaを何radian回転させる必要があるか
  assert(sgn(abs(a)) != 0);//長さが0はだめ
  return arg(b/a);
}

bool cp_x(P p, P q) {//ベクトルの比較x軸で比較->y軸で比較
    if (!eq(X(p), X(q)))
        return X(p) < X(q);
    return Y(p) < Y(q);
}

bool cp_y(P p, P q) {//ベクトルの比較y軸で比較->x軸で比較
    if (!eq(Y(p), Y(q)))
        return Y(p) < Y(q);
    return X(p) < X(q);
}

struct L {//直線ab
    P a, b;
    L() {}
    L(P a, P b) : a(a), b(b) {}

    // 入出力（必要なら）
    friend ostream &operator<<(ostream &os, L &l) {
        return os << l.a << ' ' << l.b;
    }
    friend istream &operator>>(istream &is, L &l) {
        return is >> l.a >> l.b;
    }
};

struct S : L {//線分ab
    S() {}
    S(P a, P b) : L(a, b) {}
};

struct C {//中心p 半径rの円
    P p;
    R r;
    C() {}
    C(P p, R r) : p(p), r(r) {}
};

P rot(P p, R t) {//ベクトルの回転
    return p * P(cos(t), sin(t));
}

//2つのベクトルの内積
R dot(P p, P q) {
    return X(p) * X(q) + Y(p) * Y(q);
}

//2つのベクトルの外積
R det(P p, P q) {
    return X(p) * Y(q) - Y(p) * X(q);
}

// https://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=CGL_1_C&lang=jp
int ccw(P a, P b, P c) { // 線分 ab に対する c の位置関係 
    b -= a, c -= a;//ベクトルab,ベクトルacにした
    if (sgn(det(b, c)) == 1)//外積右ねじ正
        return +1; // COUNTER_CLOCKWISE a,b,cが反時計回り
    if (sgn(det(b, c)) == -1)
        return -1; // CLOCKWISE
    if (dot(b, c) < 0.0)
        return +2; // ONLINE_BACK
    if (norm(b) < norm(c))
        return -2; // ONLINE_FRONT
    return 0;      // ON_SEGMENT
}

bool para(L a, L b) { // 平行判定
    return eq(det(a.b - a.a, b.b - b.a), 0.0);
}

bool orth(L a, L b) { // 垂直判定
    return eq(dot(a.b - a.a, b.b - b.a), 0.0);
}

P proj(L l, P p) { // 垂線の足
    R t = dot(p - l.a, l.b - l.a) / norm(l.b - l.a);
    return l.a + (l.b - l.a) * t;
}

// これいる？
// P proj(S s, P p) {
//     R t = dot(p - s.a, s.b - s.a) / norm(s.b - s.a);
//     return s.a + (s.b - s.a) * t;
// }

P refl(L l, P p) { // 線対称の位置にある点
    return p + (proj(l, p) - p) * 2.0;
}

bool inter(L l, P p) { // 交点を持つか判定
    return abs(ccw(l.a, l.b, p)) != 1;
}

bool inter(S s, P p) {
    return ccw(s.a, s.b, p) == 0;
}

bool inter(L l, L m) {
    if (!eq(det(l.b - l.a, m.b - m.a), 0.0))
        return true;
    return eq(det(l.b - l.a, m.b - l.a), 0.0);
}

bool inter(L l, S s) {
    return sgn(det(l.b - l.a, s.a - l.a) * det(l.b - l.a, s.b - l.a)) <= 0;
}

bool inter(S s, L l) {
    return inter(l, s);
}

bool inter(S s, S t) {
    if (ccw(s.a, s.b, t.a) * ccw(s.a, s.b, t.b) > 0)
        return false;
    return ccw(t.a, t.b, s.a) * ccw(t.a, t.b, s.b) <= 0;
}

R dist(P p, P q) {
    return abs(q - p);
}

R dist(L l, P p) {
    return abs(p - P(proj(l, p)));
}

R dist(S s, P p) {
    P h = proj(s, p);
    if (inter(s, h))
        return abs(h - p);
    return min(abs(s.a - p), abs(s.b - p));
}

R dist(L l, L m) {
    return inter(l, m) ? 0.0 : dist(l, m.a);
}

R dist(S s, S t) {
    if (inter(s, t))
        return 0.0;
    return min({dist(s, t.a), dist(s, t.b), dist(t, s.a), dist(t, s.b)});
}

R dist(L l, S s) {
    if (inter(l, s))
        return 0.0;
    return min(dist(l, s.a), dist(l, s.b));
}

R dist(S s, L l) {
    return dist(l, s);
}

bool inter(C c, L l) {
    return sgn(c.r - dist(l, c.p)) >= 0;
}

bool inter(C c, P p) {
    return eq(abs(p - c.p), c.r);
}

// 共通接線の本数
// 交点なし:4
// 外接:3
// 2点で交わる:2
// 内接:1
// 一方がもう一方を内包:0
int inter(C c1, C c2) {
    if (c1.r < c2.r)
        swap(c1, c2);
    R d = abs(c1.p - c2.p);
    int a = sgn(d - c1.r - c2.r);
    if (a >= 0)
        return 3 + a;
    return 1 + sgn(d - c1.r + c2.r);
}

VP crosspoint(L l, L m) {
    VP ret;
    if (!inter(l, m))
        return ret;
    R A = det(l.b - l.a, m.b - m.a);
    R B = det(l.b - l.a, l.b - m.a);
    if (eq(A, 0.0) && eq(B, 0.0)) {
        ret.emplace_back(m.a);
    } else {
        ret.emplace_back(m.a + (m.b - m.a) * B / A);
    }
    return ret;
}

VP crosspoint(S s, S t) {
    return inter(s, t) ? crosspoint(L(s), L(t)) : VP();
}

VP crosspoint(C c, L l) {//円と直線の交点
    P h = proj(l, c.p);
    P e = (l.b - l.a) / abs(l.b - l.a);
    VP ret;
    if (!inter(c, l))
        return ret;
    if (eq(dist(l, c.p), c.r)) {
        ret.emplace_back(h);
    } else {
        R b = sqrt(c.r * c.r - norm(h - c.p));
        ret.push_back(h + e * b), ret.push_back(h - e * b);
    }
    return ret;
}

VP crosspoint(C c, S s) {//円と線分の交点
    P h = proj(s, c.p);
    P e = (s.b - s.a) / abs(s.b - s.a);
    VP ret;
    if (!inter(c, s))
        return ret;
    if (eq(dist(s, c.p), c.r)) {
        ret.emplace_back(h);
    } else {
        R b = sqrt(c.r * c.r - norm(h - c.p));
        if(ccw(s.a,s.b,h - e * b) == 0){//s.aに近い方から線分上なら追加する
          ret.push_back(h - e * b);
        }
        if(ccw(s.a,s.b,h + e * b)==0){
          ret.push_back(h + e * b);
        }
    }
    return ret;
}

VP crosspoint(C c1, C c2) {//2つの円の交わる点
    R d = abs(c1.p - c2.p);
    R a = acos((c1.r * c1.r + d * d - c2.r * c2.r) / (2 * c1.r * d));
    R t = atan2(Y(c2.p) - Y(c1.p), X(c2.p) - X(c1.p));
    VP ret;
    if (inter(c1, c2) % 4 == 0) // 交わらないとき
        return ret;
    if (eq(a, 0.0)) {
        ret.emplace_back(P(c1.p + rot(P(c1.r, 0.0), t)));
    } else {
        P p1 = c1.p + rot(P(c1.r, 0.0), t + a);
        P p2 = c1.p + rot(P(c1.r, 0.0), t - a);
        ret.emplace_back(p1), ret.emplace_back(p2);
    }
    return ret;
}

VP cut(VP p, L l, bool border = true) { // 直線が多角形に切り取られる区間
    int n = sz(p);
    p.emplace_back(p[0]), p.emplace_back(p[1]);
    VP ret;
    rep(i, n) {
        if (!eq(dist(l, p[i]), 0) && !eq(dist(l, p[i + 1]), 0)) {
            S s(p[i], p[i + 1]);
            if (eq(dist(l, s), 0)) {
                auto res = crosspoint(l, s);
                ret.emplace_back(res[0]);
            }
        }
        if (eq(dist(l, p[i + 1]), 0)) {
            if ((eq(dist(l, p[i]), 0) || eq(dist(l, p[i + 2]), 0)) && !border)
                continue;
            S s(p[i], p[i + 2]);
            if (eq(dist(l, s), 0))
                ret.emplace_back(p[i + 1]);
        }
    }
    return ret;
}

VP rectangle(S s, R r) { // sを軸とした幅rの長方形
    P d = (s.a - s.b) * P(0, 1);
    d *= r / sqrt(norm(d));
    return VP{s.a + d, s.a - d, s.b - d, s.b + d};
}

L vertical_bisector(P p, P q) { // 垂直二等分線
    L l;
    l.a = (p + q) * 0.5;
    l.b = l.a + rot(q - p, pi * 0.5);
    return l;
}

L angle_bisector(P a,P b,P c){//角abcの二等分線(角bの２等分線)
  L l;
  l.a = b;
  R ang = atan2(Y(c-b),X(c-b)) - atan2(Y(a-b),X(a-b));//なす角
  ang/=2.0;
  l.b = l.a + rot(a-b,ang);
  return l;
}

C Apollonius(P p, P q, R a, R b) { // アポロニウスの円
    P p1 = (p * b + q * a) / (a + b), p2 = (-p * b + q * a) / (a - b);
    C c;
    c.p = (p1 + p2) * 0.5;
    c.r = abs(p1 - p2) * 0.5;
    return c;
}

R area(VP p) { // 多角形の面積
    R ret = 0.0;
    int n = sz(p);
    rep(i, n) ret += det(p[i], p[(i + 1) % n]);
    return abs(ret * 0.5);
}

int in_polygon(VP p, P q) { // IN:2, ON:1, OUT:0
    int n = sz(p);
    int ret = 0;
    rep(i, n) {
        P a = p[i] - q, b = p[(i + 1) % n] - q;
        if (eq(det(a, b), 0.0) && sgn(dot(a, b)) <= 0)
            return 1;
        if (Y(a) > Y(b))
            swap(a, b);
        if (sgn(Y(a)) <= 0 && sgn(Y(b)) == 1 && sgn(det(a, b)) == 1)
            ret ^= 2;
    }
    return ret;
}

VP tangent(C c, P p) { // 点 p を通る円 c の接線と c の接点
    return crosspoint(c, C(p, sqrt(norm(p - c.p) - c.r * c.r)));
}

vector<L> tangent(C c1, C c2) { // 共通接線
    vector<L> ret;
    if (c1.r < c2.r)
        swap(c1, c2);
    R r = abs(c2.p - c1.p);
    if (eq(r, 0.0))
        return ret;
    P u = (c2.p - c1.p) / r;
    P v = rot(u, pi * 0.5);
    for (R s : {1.0, -1.0}) {
        R h = (c1.r + c2.r * s) / r;
        if (eq(abs(h), 1.0)) {
            ret.emplace_back(c1.p + u * c1.r, c1.p + (u + v) * c1.r);
        } else if (abs(h) < 1.0) {
            P uu = u * h, vv = v * sqrt(1.0 - h * h);
            ret.emplace_back(c1.p + (uu + vv) * c1.r, c2.p - (uu + vv) * c2.r * s);
            ret.emplace_back(c1.p + (uu - vv) * c1.r, c2.p - (uu - vv) * c2.r * s);
        }
    }
    return ret;
}

VP convex_hull(VP p) { // 凸包
    sort(all(p), cp_x);
    p.erase(unique(all(p)), end(p));
    int n = sz(p), k = 0;
    if (n == 1)
        return p;
    VP ch(2 * n);
    for (int i = 0; i < n; ch[k++] = p[i++]) {
        while (k >= 2 && sgn(det(ch[k - 1] - ch[k - 2], p[i] - ch[k - 1])) <= 0)
            k--;
    }
    for (int i = n - 2, t = k + 1; i >= 0; ch[k++] = p[i--]) {
        while (k >= t && sgn(det(ch[k - 1] - ch[k - 2], p[i] - ch[k - 1])) <= 0)
            k--;
    }
    ch.resize(k - 1);
    return ch;
}

R closest_pair(VP p) { // 最近点対の距離
    if (sz(p) <= 1)
        return 1e18;
    sort(all(p), cp_x);
    VP memo(sz(p));

    function<R(int, int)> rec = [&](int l, int r) {
        if (r - l <= 1)
            return R(1e18);
        int m = (l + r) >> 1;
        R x = X(p[m]);
        R ret = min(rec(l, m), rec(m, r));
        inplace_merge(p.begin() + l, p.begin() + m, p.begin() + r, cp_y);
        int cnt = 0;
        reps(i, l, r) {
            if (abs(X(p[i]) - x) >= ret)
                continue;
            rep(j, cnt) {
                P d = p[i] - memo[cnt - j - 1];
                if (Y(d) >= ret)
                    break;
                chmin(ret, abs(d));
            }
            memo[cnt++] = p[i];
        }
        return ret;
    };

    return rec(0, sz(p));
}

R farthest_pair(VP p) {//最遠点対の距離
  VP ps = convex_hull(p);
  ll n = ps.size();
  if(n == 2){//凸包が潰れてる
    return dist(ps[0],ps[1]);
  }
  ll i = 0,j = 0;
  rep(k,n){//x軸方向に最も遠い点対を求める
    if(cp_x(ps[k],ps[i]))i = k;
    if(cp_x(ps[j],ps[k]))j = k;
  }
  R ret = 0;
  ll si = i,sj = j;
  while(i != sj || j != si){//180度反転しきるまで
    ret = max(ret,dist(ps[i],ps[j]));
    if(det(ps[(i+1)%n] - ps[i],ps[(j+1)%n]-ps[j]) < 0){
      i = (i + 1) % n;
    }else{
      j = (j + 1) % n;
    }
  }
  return ret;
}

// 原点, 点 a, 点 b とで囲まれる領域の面積 (三角形 ver と扇型 ver)
R calc_element(P a, P b, R cr,bool triangle){
  if(triangle)return det(a,b)/2;
  else{
    P tmp = b * (P(X(a),-Y(a)));
    R ang = atan2(Y(tmp),X(tmp));
    return cr * cr * ang/2;
  }
}

// 円 C と、三角形 ((0, 0), ia, ib) との共通部分の面積
R common_area(C c, P ia,P ib){
  P a = ia - c.p , b = ib - c.p;
  if(eq(abs(a-b),0))return 0;
  bool isin_a = (sgn(c.r - abs(a))>= 0);
  bool isin_b = (sgn(c.r - abs(b))>= 0);
  if(isin_a && isin_b)return calc_element(a,b,c.r,true);//aもbも円の中

  C oc(P(0,0),c.r);
  S seg(a,b);
  VP cr = crosspoint(oc,seg);
  if(cr.empty())return calc_element(a,b,c.r,false);
  P s = cr[0],t = cr.back();
  return calc_element(s,t,c.r,true) + calc_element(a,s,c.r,isin_a) + calc_element(t,b,c.r,isin_b);

}


R common_area(C c, VP vp){// 円cと多角形の共通部分の面積
  R ret = 0;
  ll n = vp.size();
  rep(i,n){
    ret += common_area(c,vp[i],vp[(i+1)%n]);
  }
  return ret;
}

R common_area(C p, C q) {// 円と円の共通部分の面積
    R d = abs(p.p - q.p);
    if (d >= p.r + q.r - EPS) return 0;
    else if (d <= abs(p.r - q.r) + EPS) return min(p.r, q.r) * min(p.r, q.r) * pi;
    R pcos = (p.r*p.r + d*d - q.r*q.r) / (p.r*d*2);
    R pang = acosl(pcos);
    R parea = p.r*p.r*pang - p.r*p.r*sin(pang*2)/2;
    R qcos = (q.r*q.r + d*d - p.r*p.r) / (q.r*d*2);
    R qang = acosl(qcos);
    R qarea = q.r*q.r*qang - q.r*q.r*sin(qang*2)/2;
    return parea + qarea;
}

vector<VP> divisions(vector<L> lf, R lim = 1e9) {
    vector<L> ls;
    each(l, lf) {
        bool ok = true;
        each(m, ls) {
            if (para(l, m) & inter(l, m.a)) {
                ok = false;
                break;
            }
        }
        if (ok)
            ls.emplace_back(l);
    }
    VP lc{P(-lim, -lim), P(lim, -lim), P(lim, lim), P(-lim, lim)};
    rep(i, 4) ls.emplace_back(lc[i], lc[(i + 1) % 4]);
    int m = sz(ls);
    VP ps;
    vector<vector<int>> lp(m);
    rep(i, m) {
        reps(j, i + 1, m) {
            each(p, crosspoint(ls[i], ls[j])) {
                if (max(abs(X(p)), abs(Y(p))) < lim + EPS) {
                    lp[i].emplace_back(sz(ps)), lp[j].emplace_back(sz(ps));
                    ps.emplace_back(p);
                }
            }
        }
    }
    int n = sz(ps);
    vector<int> id(n, -1), to;
    vector<R> rg;
    vector<vector<pair<R, int>>> li(n);
    rep(i, m) {
        sort(all(lp[i]), [&ps](int a, int b) { return cp_x(ps[a], ps[b]); });
        vector<int> q;
        rep(j, sz(lp[i])) {
            int me = id[lp[i][j]], st = j;
            auto np = ps[lp[i][j]];
            while (j + 1 < sz(lp[i])) {
                if (abs(ps[lp[i][j + 1]] - np) < EPS) {
                    j++;
                    if (id[lp[i][j]] != -1)
                        me = id[lp[i][j]];
                } else
                    break;
            }
            if (me == -1)
                me = lp[i][st];
            reps(k, st, j + 1) id[lp[i][k]] = me;
            q.emplace_back(me);
        }
        rep(i, sz(q) - 1) {
            P d = ps[q[i + 1]] - ps[q[i]];
            R s = atan2(Y(d), X(d)), t = atan2(-Y(d), -X(d));
            int x = q[i], y = q[i + 1];
            li[x].emplace_back(s, sz(to));
            li[x].emplace_back(s + pi * 2, sz(to));
            to.emplace_back(y), rg.emplace_back(t);
            li[y].emplace_back(t, sz(to));
            li[y].emplace_back(t + pi * 2, sz(to));
            to.emplace_back(x), rg.emplace_back(s);
        }
    }
    rep(i, n) sort(all(li[i]));
    vector<bool> u(sz(to), false);
    vector<VP> ret;
    rep(i, n) {
        each(l, li[i]) {
            int ns = l.second;
            if (u[ns])
                continue;
            VP nv;
            int no = ns;
            bool ok = true;
            while (1) {
                if (sz(nv) > 1) {
                    P x = nv[sz(nv) - 2], y = nv[sz(nv) - 1], z = ps[to[no]];
                    int c = ccw(x, y, z);
                    if (c == 1)
                        ok = false;
                    if (c != -1)
                        nv.pop_back();
                }
                nv.emplace_back(ps[to[no]]);
                u[no] = true;
                no = upper_bound(all(li[to[no]]), pair(rg[no] + EPS, -1))->second;
                if (no == ns)
                    break;
            }
            if (ok)
                ret.emplace_back(nv);
        }
    }
    return ret;
}
//ref https://github.com/drken1215/algorithm/blob/master/Geometry/arg_sort.cpp
//verify https://atcoder.jp/contests/abc139/submissions/me
//点列を偏角ソート
void arg_sort(VP &v){
  //原点=0,(pi,2pi] = -1  (0pi,pi] = 1
  auto sign = [&](const P &p){
    if(sgn(X(p)) == 0 && sgn(Y(p)) == 0){
      return 0;
    }else if(sgn(Y(p)) == -1 || (sgn(Y(p)) == 0 && sgn(X(p)) == 1)){
      return -1;
    }else{
      return 1;
    }
  };
  auto cp = [&](const P &p,const P &q){
    if(sign(p) != sign(q)){
      return sign(p) < sign(q);
    }else{//外積>0で判定
      //同じ向きのときは未定義必要に応じて決める
      return X(p) * Y(q) - Y(p) * X(q) > 0;
    }
  };
  sort(v.begin(),v.end(),cp);
}


// 変数をちゃんと全部受け取る！
void solve(ll n){
  vpll xy(n);
  vll xord,yord;
  rep(i,n){
    LL(x,y);
    xord.push_back(x);
    yord.push_back(y);
    xy[i] = {x,y};
  }
  vpll ab(4);
  rep(i,4){
    LL(x,y);
    ab[i] = {x,y};
    xord.push_back(x);
    yord.push_back(y);
  }
  sort(all(xord));sort(all(yord));
  auto xidx = [&](ll vx){
    return lower_bound(all(xord),vx) - xord.begin();
  };
  auto yidx = [&](ll vy){
    return lower_bound(all(yord),vy) - yord.begin();
  };

  VP vp(n);
  rep(i,n){
    vp[i] = P(xidx(xy[i].first),yidx(xy[i].second));
  }
  VP sq(4);
  rep(i,4){
    sq[i] = P(xidx(ab[i].first),yidx(ab[i].second));
  }
  ll ans = 0;
  rep(i,xord.size()-1)rep(j,yord.size()-1){
    R x0 = i, x1 = i+1;
    R y0 = j, y1 = j+1;
    R xmid = (x0 + x1)/2,ymid = (y0+ y1)/2;
    if(in_polygon(vp,P(xmid,ymid)) == 2 && in_polygon(sq,P(xmid,ymid)) == 0){
      ans += (xord[i+1] - xord[i]) *(yord[j+1] - yord[j]);
    }
  }
  cout << ans << endl;

}
 
int main(){
  ios::sync_with_stdio(false);cin.tie(nullptr);
  while(true){
    LL(n);//変数数調整
    if(zero(n))break;
    solve(n);
  }
}
accuracy: 1
time_ms: 120
memory_kb: 3464
final_rank: 9

code_snippet: #include <bits/stdc++.h>

struct BIT {
    int n;
    std::vector<long long> data;
    BIT() {}
    BIT(int n): n(n), data(n + 1) {};
    void add(int i, long long v) {
        for (i++; i <= n; i += i & -i) data[i] += v;
    }
    long long sum(int i) {
        long long res{};
        for (; i > 0; i -= i & -i) res += data[i];
        return res;
    }
    long long sum(int l, int r) {
        return sum(r) - sum(l);
    }
};

struct BIT2 {
    BIT nor, spe;
    BIT2() {}
    BIT2(int n): nor(n), spe(n) {}
    void add(int i, long long v) {
        nor.add(i, v);
    }
    void add(int l, int r, long long v) {
        nor.add(l, -v * l);
        nor.add(r, v * r);
        spe.add(l, v);
        spe.add(r, -v);
    }
    long long sum(int i) {
        return nor.sum(i) + i * spe.sum(i);
    }
    long long sum(int l, int r) {
        return sum(r) - sum(l);
    }
    long long get(int i) {
        return sum(i, i + 1);
    }
};

int solve() {
    const int OFFSET = 20000;
    int n;
    std::cin >> n;
    if (n == 0) return 1;
    std::vector<std::pair<int, int>> ps;
    for (int i = 0; i < n; i++) {
        int x, y;
        std::cin >> x >> y;
        x += OFFSET;
        y += OFFSET;
        ps.emplace_back(x, y);
    }
    std::vector<std::vector<std::tuple<int, int, int>>> querys(2 * OFFSET + 1);
    for (int i = 0; i < n; i++) {
        auto lhs = ps[i];
        auto rhs = ps[(i + 1) % n];
        if (lhs.first == rhs.first) {
            if (lhs.second < rhs.second) {
                querys[lhs.first].emplace_back(lhs.second, rhs.second, -1);
            } else {
                querys[lhs.first].emplace_back(rhs.second, lhs.second, +1);
            }
        }
    }

    std::pair<int, int> x_interval = {};
    std::pair<int, int> y_interval = {};
    {
        const int INF = 1e9;
        int min_x = INF;
        int max_x = -1;
        int min_y = INF;
        int max_y = -1;
        for (int i = 0; i < 4; i++) {
            int x, y;
            std::cin >> x >> y;
            x += OFFSET;
            y += OFFSET;
            min_x = std::min(min_x, x);
            max_x = std::max(max_x, x);
            min_y = std::min(min_y, y);
            max_y = std::max(max_y, y);
        }
        x_interval = {min_x + 1, max_x + 1};
        y_interval = {min_y, max_y};
    }

    BIT2 bit(2 * OFFSET + 1);

    long long ans = 0;
    for (int i = 0; i < 2 * OFFSET + 1; i++) {
        if (x_interval.first <= i && i < x_interval.second) {
            ans += bit.sum(0, y_interval.first);
            ans += bit.sum(y_interval.second, 2 * OFFSET + 1);
        } else {
            ans += bit.sum(0, 2 * OFFSET + 1);
        }
        for (auto [l, r, v]: querys[i]) {
            bit.add(l, r, v);
        }
    }
    std::cout << ans << '\n';

    return 0;
}

int main() {
    while (!solve());
}
accuracy: 1
time_ms: 20
memory_kb: 5244
final_rank: 7

code_snippet: #include <bits/stdc++.h>
using namespace std;
using ll = long long;
using P = pair<ll, ll>;
#define rep(i, a, b) for(ll i = a; i < b; ++i)
#define rrep(i, a, b) for(ll i = a; i >= b; --i)
constexpr ll inf = 4e18;
using Real = long double;
const Real EPS = 1e-8, PI = acos(Real(-1.0));
int sign(const Real& r) {
    if(r <= -EPS) return -1;
    if(r >= +EPS) return +1;
    return 0;
}
bool eq(const Real& a, const Real& b) {
    return sign(a - b) == 0;
}
using Point = complex<Real>;
istream& operator>>(istream& is, Point& p) {
    Real a, b;
    is >> a >> b;
    p = Point(a, b);
    return is;
}
ostream& operator<<(ostream& os, const Point& p) {
    return os << p.real() << ' ' << p.imag();
}
Real cross(const Point& p1, const Point& p2) {
    return (conj(p1) * p2).imag();
}
Real area(const vector<Point>& polygon) {
    Real res = 0.0;
    int n = polygon.size();
    rep(i, 0, n) {
        res += cross(polygon[i], polygon[(i + 1) % n]);
    }
    return abs(res * 0.5);
}
int main(void) {
    cin.tie(0);
    ios::sync_with_stdio(0);
    while(1) {
        int n;
        cin >> n;
        if(n == 0) break;
        vector<Point> window(n);
        rep(i, 0, n) {
            cin >> window[i];
        }
        vector<Point> curtain(4);
        Real xmin = inf, xmax = -inf, ymin = inf, ymax = -inf;
        rep(i, 0, 4) {
            cin >> curtain[i];
            xmin = min(xmin, curtain[i].real());
            xmax = max(xmax, curtain[i].real());
            ymin = min(ymin, curtain[i].imag());
            ymax = max(ymax, curtain[i].imag());
        }
        Real res = area(window);
        // cout << round(res) << ' ';
        rep(x, round(xmin), round(xmax)) {
            vector<Real> p;
            rep(i, 0, n) {
                if(eq(window[i].real(), window[(i + 1) % n].real())) continue;
                if(min(window[i].real(), window[(i + 1) % n].real()) <= x and x < max(window[i].real(), window[(i + 1) % n].real())) {
                    p.push_back(window[i].imag());
                }
            }
            sort(p.begin(), p.end());
            // for(int i = 0; i < (int)p.size(); ++i) {
            //     cout << p[i] << " \n"[i + 1 == (int)p.size()];
            // }
            for(int i = 1; i < (int)p.size(); i += 2) {
                if(p[i] <= ymin) continue;
                if(p[i - 1] >= ymax) continue;
                res -= min(p[i], ymax) - max(p[i - 1], ymin);
            }
        }
        ll ans = round(res);
        cout << ans << '\n';
    }
}
accuracy: 1
time_ms: 350
memory_kb: 3584
final_rank: 16

code_snippet: #include<bits/stdc++.h>
using namespace std;
#define rep(i,n) for(int i=0;i<n;i++)
#define all(a) a.begin(),a.end()
using ll=long long;
template<typename T>
bool chmax(T &a,T b){
  if(a<b){
    a=b;
    return true;
  }
  return false;
}
template<typename T>
bool chmin(T &a,T b){
  if(a>b){
    a=b;
    return true;
  }
  return false;
}
struct S{
  int sz;
  int mn;
  int cnt;
};
S op(S x,S y){
  S ret;
  ret.sz=x.sz+y.sz;
  ret.mn=min(x.mn,y.mn);
  ret.cnt=0;
  if(ret.mn==x.mn)ret.cnt+=x.cnt;
  if(ret.mn==y.mn)ret.cnt+=y.cnt;
  return ret;
}
S e(){return {0,(int)1e9,0};}
S mapping(int f,S x){
  x.mn+=f;
  return x;
}
int composition(int f,int g){return f+g;}
int id(){return 0;}
struct lazy_segtree{
  int n,z,log2n;
  vector<S>dat;
  vector<int>lazy;
  lazy_segtree(vector<S>d){
    z=1;
    n=d.size();
    log2n=0;
    while(z<n)z<<=1,log2n++;
    dat.resize(z*2,e());
    lazy.resize(z*2,id());
    for(int i=z;i<z+n;i++)dat[i]=d[i-z];
    for(int i=z-1;i>=1;i--)dat[i]=op(dat[i*2],dat[i*2+1]);
  }
  S prod(int l,int r){
    l+=z,r+=z;
    for(int i=log2n;i>=1;i--){
      if(((l>>i)<<i)!=l)push(l>>i);
      if(((r>>i)<<i)!=r)push(r>>i);
    }
    S ret=e();
    while(l<r){
      if(l&1)ret=op(ret,dat[l++]);
      if(r&1)ret=op(ret,dat[--r]);
      l>>=1,r>>=1;
    }
    return ret;
  }
  void apply(int l,int r,int f){
    l+=z,r+=z;
    for(int i=log2n;i>=1;i--){
      if(((l>>i)<<i)!=l)push(l>>i);
      if(((r>>i)<<i)!=r)push((r-1)>>i);
    }
    int l2=l,r2=r;
    while(l<r){
      if(l&1)allapply(l++,f);
      if(r&1)allapply(--r,f);
      l>>=1,r>>=1;
    }
    l=l2,r=r2;
    for(int i=1;i<=log2n;i++){
      if(((l>>i)<<i)!=l)upd(l>>i);
      if(((r>>i)<<i)!=r)upd((r-1)>>i);
    }
  }
  void upd(int i){dat[i]=op(dat[i*2],dat[i*2+1]);}
  void allapply(int k,int f){
    dat[k]=mapping(f,dat[k]);
    if(k<z)lazy[k]=composition(f,lazy[k]);
  }
  void push(int i){
    allapply(i*2,lazy[i]);
    allapply(i*2+1,lazy[i]);
    lazy[i]=id();
  }
  S all_prod(){return dat[1];}
};
int main(){
  while(true){
    int n;
    cin>>n;
    if(n==0)break;
    vector<pair<int,int>>a(n);
    int mnx=1e9,mxx=-1e9,mny=1e9,mxy=-1e9;
    rep(i,n){
      cin>>a[i].first>>a[i].second;
      chmin(mnx,a[i].first);
      chmax(mxx,a[i].first);
      chmin(mny,a[i].second);
      chmax(mxy,a[i].second);
    }
    vector<pair<int,int>>car(4);
    rep(i,4){
      cin>>car[i].first>>car[i].second;
      chmin(mnx,car[i].first);
      chmax(mxx,car[i].first);
      chmin(mny,car[i].second);
      chmax(mxy,car[i].second);
    }
    rep(i,n){
      a[i].first-=mnx;
      a[i].second-=mny;
    }
    rep(i,4){
      car[i].first-=mnx;
      car[i].second-=mny;
    }
    mxx-=mnx;
    mxy-=mny;
    vector<vector<pair<int,int>>>dir(mxy+1);
    rep(i,n-1){
      if(a[i].second==a[i+1].second){
        int l=a[i].first,r=a[i+1].first;
        if(l>r)swap(l,r);
        dir[a[i].second].push_back({l,r});
      }
    }
    if(a[0].second==a[n-1].second){
      int l=a[0].first,r=a[n-1].first;
      if(l>r)swap(l,r);
      dir[a[0].second].push_back({l,r});
    }
    vector<S>dat(mxx);
    rep(i,mxx)dat[i]={1,0,1};
    lazy_segtree seg(dat);
    ll ans=0;
    sort(all(car));
    rep(i,mxy+1){
      for(auto [l,r]:dir[i]){
        S now=seg.prod(l,r);
        if(now.mn==0)seg.apply(l,r,1);
        else seg.apply(l,r,-1);
      }
      if(car[0].second<=i&&i<car[3].second){
        S left=seg.prod(0,car[0].first);
        S right=seg.prod(car[3].first,mxx);
        ans+=car[0].first;
        ans+=mxx-car[3].first;
        if(left.mn==0)ans-=left.cnt;
        if(right.mn==0)ans-=right.cnt;
      }
      else{
        S al=seg.all_prod();
        ans+=mxx;
        if(al.mn==0)ans-=al.cnt;
      }
    }
    S ed=seg.all_prod();
    cout<<ans<<endl;
  }
}
accuracy: 1
time_ms: 120
memory_kb: 7336
final_rank: 14

code_snippet: // (⁠◕⁠ᴗ⁠◕⁠✿⁠)

// #pragma GCC target("avx2")
// #pragma GCC optimize("O3")
// #pragma GCC optimize("unroll-loops")
#include <bits/stdc++.h>
#define rep(i, n) for (ll i = 0; i < (n); i++)
#define srep(i, s, n) for (ll i = s; i < (n); i++)
#define len(x) ((int)(x).size())
#define all(x) (x).begin(), (x).end()
using namespace std;
template<typename T> using vc = vector<T>;
template<typename T> using vv = vc<vc<T>>;
template<typename T> using vvv = vv<vc<T>>;
using vi = vc<int>;using vvi = vv<int>; using vvvi = vv<vi>;
using ll = long long;using vl = vc<ll>;using vvl = vv<ll>; using vvvl = vv<vl>;
using ld = long double; using vld = vc<ld>; using vvld = vc<vld>; using vvvld = vc<vvld>;
using uint = unsigned int;
using ull = unsigned long long;
const ld pi = 3.141592653589793;
const int inf = 0x3f3f3f3f;
const ll INF = 0x3f3f3f3f3f3f3f3f;
// const ll mod = 1000000007;
const ll mod = 998244353;
inline bool inside(ll y, ll x, ll H, ll W) {return 0 <= (y) and (y) < (H) and 0 <= (x) and (x) < (W); }

#define debug(var)  do{std::cout << #var << " : \n";view(var);}while(0)
template<typename T> void view(T e){cout << e << endl;}
template<typename T> void view(const vc<T>& v){for(const auto& e : v){ cout << e << " "; } cout << endl;}
template<typename T> void view(const vv<T>& vv){ for(const auto& v : vv){ view(v); } }

struct S {
    long long zero, one;
};

using F = bool;

S op(S l, S r) {
    return S{
        l.zero + r.zero,
        l.one + r.one,
    };
}

S e() { return S{1, 0}; }

S mapping(F l, S r) {
    if (!l) return r;
    return S{r.one, r.zero};
}

F composition(F l, F r) { return (l && !r) || (!l && r); }

F id() { return false; }


template <class S,
          S (*op)(S, S),
          S (*e)(),
          class F,
          S (*mapping)(F, S),
          F (*composition)(F, F),
          F (*id)()>
struct lazy_segtree {
  public:
    lazy_segtree() : lazy_segtree(0) {}
    lazy_segtree(int n) : lazy_segtree(std::vector<S>(n, e())) {}
    lazy_segtree(const std::vector<S>& v) : _n(int(v.size())) {
        log = 0;
        while ((1 << log) < _n) log++;
        size = 1 << log;
        d = std::vector<S>(2 * size, e());
        lz = std::vector<F>(size, id());
        for (int i = 0; i < _n; i++) d[size + i] = v[i];
        for (int i = size - 1; i >= 1; i--) {
            update(i);
        }
    }

    void set(int p, S x) {
        assert(0 <= p && p < _n);
        p += size;
        for (int i = log; i >= 1; i--) push(p >> i);
        d[p] = x;
        for (int i = 1; i <= log; i++) update(p >> i);
    }

    S get(int p) {
        assert(0 <= p && p < _n);
        p += size;
        for (int i = log; i >= 1; i--) push(p >> i);
        return d[p];
    }

    S prod(int l, int r) {
        assert(0 <= l && l <= r && r <= _n);
        if (l == r) return e();

        l += size;
        r += size;

        for (int i = log; i >= 1; i--) {
            if (((l >> i) << i) != l) push(l >> i);
            if (((r >> i) << i) != r) push(r >> i);
        }

        S sml = e(), smr = e();
        while (l < r) {
            if (l & 1) sml = op(sml, d[l++]);
            if (r & 1) smr = op(d[--r], smr);
            l >>= 1;
            r >>= 1;
        }

        return op(sml, smr);
    }

    S all_prod() { return d[1]; }

    void apply(int p, F f) {
        assert(0 <= p && p < _n);
        p += size;
        for (int i = log; i >= 1; i--) push(p >> i);
        d[p] = mapping(f, d[p]);
        for (int i = 1; i <= log; i++) update(p >> i);
    }
    void apply(int l, int r, F f) {
        assert(0 <= l && l <= r && r <= _n);
        if (l == r) return;

        l += size;
        r += size;

        for (int i = log; i >= 1; i--) {
            if (((l >> i) << i) != l) push(l >> i);
            if (((r >> i) << i) != r) push((r - 1) >> i);
        }

        {
            int l2 = l, r2 = r;
            while (l < r) {
                if (l & 1) all_apply(l++, f);
                if (r & 1) all_apply(--r, f);
                l >>= 1;
                r >>= 1;
            }
            l = l2;
            r = r2;
        }

        for (int i = 1; i <= log; i++) {
            if (((l >> i) << i) != l) update(l >> i);
            if (((r >> i) << i) != r) update((r - 1) >> i);
        }
    }

    template <bool (*g)(S)> int max_right(int l) {
        return max_right(l, [](S x) { return g(x); });
    }
    template <class G> int max_right(int l, G g) {
        assert(0 <= l && l <= _n);
        assert(g(e()));
        if (l == _n) return _n;
        l += size;
        for (int i = log; i >= 1; i--) push(l >> i);
        S sm = e();
        do {
            while (l % 2 == 0) l >>= 1;
            if (!g(op(sm, d[l]))) {
                while (l < size) {
                    push(l);
                    l = (2 * l);
                    if (g(op(sm, d[l]))) {
                        sm = op(sm, d[l]);
                        l++;
                    }
                }
                return l - size;
            }
            sm = op(sm, d[l]);
            l++;
        } while ((l & -l) != l);
        return _n;
    }

    template <bool (*g)(S)> int min_left(int r) {
        return min_left(r, [](S x) { return g(x); });
    }
    template <class G> int min_left(int r, G g) {
        assert(0 <= r && r <= _n);
        assert(g(e()));
        if (r == 0) return 0;
        r += size;
        for (int i = log; i >= 1; i--) push((r - 1) >> i);
        S sm = e();
        do {
            r--;
            while (r > 1 && (r % 2)) r >>= 1;
            if (!g(op(d[r], sm))) {
                while (r < size) {
                    push(r);
                    r = (2 * r + 1);
                    if (g(op(d[r], sm))) {
                        sm = op(d[r], sm);
                        r--;
                    }
                }
                return r + 1 - size;
            }
            sm = op(d[r], sm);
        } while ((r & -r) != r);
        return 0;
    }

  private:
    int _n, size, log;
    std::vector<S> d;
    std::vector<F> lz;

    void update(int k) { d[k] = op(d[2 * k], d[2 * k + 1]); }
    void all_apply(int k, F f) {
        d[k] = mapping(f, d[k]);
        if (k < size) lz[k] = composition(f, lz[k]);
    }
    void push(int k) {
        all_apply(2 * k, lz[k]);
        all_apply(2 * k + 1, lz[k]);
        lz[k] = id();
    }
};

ll solve(int N){
    vvi point(40040);
    rep(i, N){
        int x, y; cin >> x >> y; x += 20000, y += 20000;
        point[x].push_back(y);
    }
    int lx = inf, rx = -inf, ly = inf, ry = -inf;
    rep(i, 4){
        int a, b; cin >> a >> b; a += 20000, b += 20000;
        lx = min(lx, a);
        rx = max(rx, a);
        ly = min(ly, b);
        ry = max(ry, b);
    }
    lazy_segtree<S, op, e, F, mapping, composition, id> seg(40040);
    ll wind = 0, dif = 0;
    rep(i, 40040){
        sort(all(point[i]));
        for (int j = 0; j < len(point[i]); j += 2) seg.apply(point[i][j], point[i][j + 1], true);
        wind += seg.all_prod().one;
        if (lx <= i && i < rx) dif += seg.prod(ly, ry).one;
    }
    // cout << wind << " " << dif << endl;
    return wind - dif;
}

int main(){
    vc<ll> ans;
    while (true){
        int N; cin >> N;
        if (N == 0) break;
        ans.push_back(solve(N));
    }
    for (auto x : ans) cout << x << endl;
}
accuracy: 1
time_ms: 160
memory_kb: 7224
final_rank: 15

code_snippet: #line 2 "cp-library/src/cp-template.hpp"
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using ld = long double;
using uint = unsigned int;
using ull  = unsigned long long;
using i32 = int;
using u32 = unsigned int;
using i64 = long long;
using u64 = unsigned long long;
using i128 = __int128_t;
template < class T > bool chmin(T& a, T b) { if(a > b) { a = b; return true; } return false; }
template < class T > bool chmax(T& a, T b) { if(a < b) { a = b; return true; } return false; }
template < class T, class U > T ceil (T x, U y) { return (x > 0 ? (x + y - 1) / y :           x / y); }
template < class T, class U > T floor(T x, U y) { return (x > 0 ?           x / y : (x - y + 1) / y); }
int popcnt(i32 x) { return __builtin_popcount(x); }
int popcnt(u32 x) { return __builtin_popcount(x); }
int popcnt(i64 x) { return __builtin_popcountll(x); }
int popcnt(u64 x) { return __builtin_popcountll(x); }

#line 2 "cp-library/src/utility/rep_itr.hpp"
template < class T > struct itr_rep {
    T i, d;
    constexpr itr_rep(const T i) noexcept : i(i), d(1) {}
    constexpr itr_rep(const T i, const T d) noexcept : i(i), d(d) {}
    void operator++() noexcept { i += d; }
    constexpr int operator*() const noexcept { return i; }
    constexpr bool operator!=(const itr_rep x) const noexcept { return d > 0 ? i < x.i : i > x.i; }
};

template < class T > struct rep {
    const itr_rep< T > s, t;
    constexpr rep(const T t) noexcept : s(0), t(t) {}
    constexpr rep(const T s, const T t) noexcept : s(s), t(t) {}
    constexpr rep(const T s, const T t, const T d) noexcept : s(s, d), t(t, d) {}
    constexpr auto begin() const noexcept { return s; }
    constexpr auto end  () const noexcept { return t; }
};

template < class T > struct revrep {
    const itr_rep < T > s, t;
    constexpr revrep(const T t) noexcept : s(t - 1, -1), t(-1, -1) {}
    constexpr revrep(const T s, const T t) noexcept : s(t - 1, -1), t(s - 1, -1) {}
    constexpr revrep(const T s, const T t, const T d) noexcept : s(t - 1, -d), t(s - 1, -d) {}
    constexpr auto begin() const noexcept { return s; }
    constexpr auto end  () const noexcept { return t; }
};
#line 3 "cp-library/src/utility/io.hpp"

/* 128bit integer */
istream& operator>>(istream& is, i128& x) {
    std::string s; is >> s;
    int pm = (s[0] == '-');
    x = 0;
    for(int i : rep(pm, int(s.size()))) x = x * 10 + (s[i] - '0');
    if(pm) x *= -1;
    return is;
}
ostream& operator<<(ostream& os, const i128& x) {
    if(x == 0) return os << '0';
    i128 y = x;
    if(y < 0) { os << '-'; y *= -1; }
    std::vector<int> ny;
    while(y > 0) { ny.push_back(y % 10); y /= 10; }
    for(int i : revrep(ny.size())) os << ny[i];
    return os;
}

template < class S, class T > istream& operator>>(istream& is,       std::pair< S, T >& x) { is >> x.first        >> x.second; return is; }
template < class S, class T > ostream& operator<<(ostream& os, const std::pair< S, T >& x) { os << x.first << " " << x.second; return os; }

namespace scanner {
    struct sca {
        template < class T > operator T() {
            T s; std::cin >> s; return s;
        }
    };
    struct vec {
        int n;
        vec(int n) : n(n) {}
        template < class T > operator std::vector< T >() {
            std::vector< T > v(n);
            for(T& x : v) std::cin >> x;
            return v;
        }
    };
    struct mat {
        int h, w;
        mat(int h, int w) : h(h), w(w) {}
        template < class T > operator std::vector< std::vector< T > >() {
            std::vector m(h, std::vector< T >(w));
            for(std::vector< T >& v : m) for(T& x : v) std::cin >> x;
            return m;
        }
    };
    struct speedup {
        speedup() {
            std::cin.tie(0);
            std::ios::sync_with_stdio(0);
        }
    } speedup_instance;
}
scanner::sca in() { return scanner::sca(); }
scanner::vec in(int n) { return scanner::vec(n); }
scanner::mat in(int h, int w) { return scanner::mat(h, w); }

namespace printer {
    void precision(int d) { std::cout << std::fixed << std::setprecision(d); }
    void flush() { std::cout.flush(); }
}

template < class T >
ostream& operator<<(ostream& os, const std::vector< T > a) {
    int n = a.size();
    for(int i : rep(n)) { os << a[i]; if(i != n - 1) os << ' '; }
    return os;
}

int print() { std::cout << '\n'; return 0; }
template < class head, class... tail > int print(head&& h, tail&&... t) {
    std::cout << h; if(sizeof...(tail)) std::cout << ' ';
    return print(std::forward<tail>(t)...);
}
template < class T > int print_n(const std::vector< T > a) {
    int n = a.size();
    for(int i : rep(n)) std::cout << a[i] << "\n";
    return 0;
}


#line 2 "cp-library/src/utility/key_val.hpp"

template < class K, class V >
struct key_val {
    K key; V val;
    key_val() {}
    key_val(K key, V val) : key(key), val(val) {}
    template < std::size_t Index >
    std::tuple_element_t< Index, key_val >& get() {
        if constexpr (Index == 0) return key;
        if constexpr (Index == 1) return val;
    }
};

namespace std {

template < class K, class V > struct tuple_size < key_val< K, V > > : integral_constant< size_t, 2 > {};
template < class K, class V > struct tuple_element < 0, key_val< K, V > > { using type = K; };
template < class K, class V > struct tuple_element < 1, key_val< K, V > > { using type = V; };

}
#line 2 "cp-library/src/utility/vec_op.hpp"
template < class T > key_val< int, T > max_of(const vector< T >& a) {
    int i = std::max_element(a.begin(), a.end()) - a.begin();
    return {i, a[i]};
}
template < class T > key_val< int, T > min_of(const vector< T >& a) {
    int i = std::min_element(a.begin(), a.end()) - a.begin();
    return {i, a[i]};
}
template < class S, class T > S sum_of(const vector< T >& a) {
    S sum = 0;
    for(const T x : a) sum += x;
    return sum;
}
template < class S, class T > vector< S > freq_of(const vector< T >& a, T L, T R) {
    vector< S > res(R - L, S(0));
    for(const T x : a) res[x - L] += 1;
    return res;
}
template < class S, class T > struct prefix_sum {
    vector< S > s;
    prefix_sum(const vector< T >& a) : s(a) {
        s.insert(s.begin(), S(0));
        for(int i : rep(a.size())) s[i + 1] += s[i];
    }
    // [L, R)
    S sum(int L, int R) { return s[R] - s[L]; }
};
#line 3 "cp-library/src/utility/heap.hpp"

template < class T > using heap_min = std::priority_queue< T, std::vector< T >, std::greater< T > >;
template < class T > using heap_max = std::priority_queue< T, std::vector< T >, std::less< T > >;

#line 27 "cp-library/src/cp-template.hpp"

#line 1 "cp-library/src/algorithm/bin_search.hpp"
template < class T, class F >
T bin_search(T ok, T ng, F f) {
    while(abs(ng - ok) > 1) {
        T mid = (ok + ng) / 2;
        (f(mid) ? ok : ng) = mid;
    }
    return ok;
}

template < class T, class F >
T bin_search_real(T ok, T ng, F f, int step = 80) {
    while(step--) {
        T mid = (ok + ng) / 2;
        (f(mid) ? ok : ng) = mid;
    }
    return ok;
}
#line 2 "cp-library/src/algorithm/argsort.hpp"

template < class T > std::vector< int > argsort(const std::vector< T > &a) {
    std::vector< int > ids((int)a.size());
    std::iota(ids.begin(), ids.end(), 0);
    std::sort(ids.begin(), ids.end(), [&](int i, int j) {
        return a[i] < a[j] || (a[i] == a[j] && i < j);
    });
    return ids;
}
#line 1 "macro.hpp"
namespace macro {

using size_type = int;
template < class container > void  sort(container& a) { std::sort(std:: begin(a), std:: end(a)); }
template < class container > void rsort(container& a) { std::sort(std::rbegin(a), std::rend(a)); }
template < class container > void reverse(container& a) { std::reverse(std::begin(a), std::end(a)); }
template < class container > void unique(container& a) {
    std::sort(std::begin(a), std::end(a));
    a.erase(std::unique(std::begin(a), std::end(a)), std::end(a));
}
template < class container > container  sorted(const container& a) { container b = a;  sort(b); return std::move(b); }
template < class container > container rsorted(const container& a) { container b = a; rsort(b); return std::move(b); }
template < class container, class compare > void sort(container& a, const compare& cmp) { std::sort(std::begin(a), std::end(a), cmp); }
template < class container, class compare > container sorted(const container& a, const compare& cmp) { container b = a; sort(b, cmp); return std::move(b); }
template < class container, class value > size_type lower_bound(const container& a, const value& x) { return std::lower_bound(std::begin(a), std::end(a), x) - std::begin(a); }
template < class container, class value > size_type upper_bound(const container& a, const value& x) { return std::upper_bound(std::begin(a), std::end(a), x) - std::begin(a); }

const std::vector<std::pair<size_type, size_type>> dir4 = { {+1,  0}, {-1,  0}, { 0, +1}, { 0, -1} };
const std::vector<std::pair<size_type, size_type>> dir8 = { {-1, -1}, {-1,  0}, {-1, +1}, { 0, -1}, { 0, +1}, {+1, -1}, {+1,  0}, {+1, +1} };

#ifdef _DEBUG
#define debug(x) std::cout << "[" << __LINE__ << "] " << #x << ": " << x << std::endl
#else
#define debug(x)
#endif

template < class container > void concat(container& a, const container& b) {
    a.insert(std::end(a), std::begin(b), std::end(b));
}
std::vector<size_type> iota(const size_type n) {
    std::vector<size_type> I(n);
    std::iota(std::begin(I), std::end(I), 0);
    return I;
}
template < class container > std::vector<size_type> sort_idx(const container& a) {
    const size_type n = a.size();
    std::vector<size_type> I = iota(n);
    std::sort(std::begin(I), std::end(I), [&](size_type i, size_type j) { return a[i] < a[j] or (a[i] == a[j] and i < j); });
    return I;
}
template < class container, class compare > std::vector<size_type> sort_idx(const container& a, const compare& cmp) {
    const size_type n = a.size();
    std::vector<size_type> I = iota(n);
    std::sort(std::begin(I), std::end(I), [&](size_type i, size_type j) { return cmp(a[i], a[j]) or (a[i] == a[j] and i < j); });
    return std::move(I);
}

struct grid {
    using size_type = int;
    size_type H, W;
    grid(const size_type H, const size_type W) : H(H), W(W) {}
    bool contains(const size_type i, const size_type j) {
        return 0 <= i and i < H and 0 <= j and j < W;
    }
};

using f64 = long double;

} // namespace macro

using namespace macro;
#line 3 "A.cpp"

template < class T > struct point {
    T x, y;
    point() : x(0), y(0) {}
    point(T x, T y) : x(x), y(y) {}
    point(std::pair< T, T > p) : x(p.first), y(p.second) {}
    point& operator+=(const point& p) { x += p.x, y += p.y; return *this; }
    point& operator-=(const point& p) { x -= p.x, y -= p.y; return *this; }
    point& operator*=(const T r) { x *= r, y *= r; return *this; }
    point& operator/=(const T r) { x /= r, y /= r; return *this; }
    point operator+(const point& p) const { return point(*this) += p; }
    point operator-(const point& p) const { return point(*this) -= p; }
    point operator*(const T r) const { return point(*this) *= r; }
    point operator/(const T r) const { return point(*this) /= r; }
    point operator-() const { return {-x, -y}; }
    bool operator==(const point& p) const { return x == p.x and y == p.y; }
    bool operator!=(const point& p) const { return x != p.x or  y != p.y; }
    bool operator<(const point& p) const { return x == p.x ? y < p.y : x < p.x; }
    point< T > rot(double theta) {
        static_assert(is_floating_point_v< T >);
        double cos_ = std::cos(theta), sin_ = std::sin(theta);
        return {cos_ * x - sin_ * y, sin_ * x + cos_ * y};
    }
};
template < class T > istream& operator>>(istream& is, point< T >& p) { return is >> p.x >> p.y; }
template < class T > ostream& operator<<(ostream& os, point< T >& p) { return os << p.x << " " << p.y; }
template < class T > T dot(const point< T >& a, const point< T >& b) { return a.x * b.x + a.y * b.y; }
template < class T > T det(const point< T >& a, const point< T >& b) { return a.x * b.y - a.y * b.x; }
template < class T > T norm(const point< T >& p) { return p.x * p.x + p.y * p.y; }
template < class T > double abs(const point< T >& p) { return std::sqrt(norm(p)); }
template < class T > double angle(const point< T >& p) { return std::atan2(p.y, p.x); }
template < class T > int sign(const T x) {
    T e = (is_integral_v< T > ? 1 : 1e-8);
    if(x <= -e) return -1;
    if(x >= +e) return +1;
    return 0;
}
template < class T > bool equals(const T& a, const T& b) { return sign(a - b) == 0; }
template < class T > int ccw(const point< T >& a, point< T > b, point< T > c) {
    b -= a, c -= a;
    if(sign(det(b, c)) == +1) return +1; // counter clockwise
    if(sign(det(b, c)) == -1) return -1; //         clockwise
    if(sign(dot(b, c)) == -1) return +2; // c-a-b
    if(norm(b) < norm(c)) return -2;     // a-b-c
    return 0;                            // a-c-b
}

template < class T > struct line {
    point< T > a, b;
    line() {}
    line(point< T > a, point< T > b) : a(a), b(b) {}
};
template < class T > point< T > projection(const line< T >& l, const point< T >& p) {
    static_assert(is_floating_point_v< T >);
    return l.a + (l.a - l.b) * dot(p - l.a, l.a - l.b) / norm(l.a - l.b);
}
template < class T > point< T > reflection(const line< T >& l, const point< T >& p) {
    static_assert(is_floating_point_v< T >);
    return p + (projection(l, p) - p) * T(2);
}
template < class T > bool orthogonal(const line< T >& a, const line< T >& b) { return equals(dot(a.b - a.a, b.b - b.a), T(0)); }
template < class T > bool parallel  (const line< T >& a, const line< T >& b) { return equals(det(a.b - a.a, b.b - b.a), T(0)); }
template < class T > point< T > cross_point_ll(const line< T >& l, const line< T >& m) {
    static_assert(is_floating_point_v< T >);
    T A = det(l.b - l.a, m.b - m.a);
    T B = det(l.b - l.a, l.b - m.a);
    if(equals(abs(A), T(0)) and equals(abs(B), T(0))) return m.a;
    return m.a + (m.b - m.a) * B / A;
}

template < class T > using segment = line< T >;
template < class T > bool intersect_ss(const segment< T >& s, const segment< T >& t) {
    return ccw(s.a, s.b, t.a) * ccw(s.a, s.b, t.b) <= 0 and ccw(t.a, t.b, s.a) * ccw(t.a, t.b, s.b) <= 0;
}
template < class T > double distance_sp(const segment< T >& s, const point< T >& p) {
    static_assert(is_floating_point_v< T >);
    point r = projection(s, p);
    if(ccw(s.a, s.b, r) == 0) return abs(r - p);
    return std::min(abs(s.a - p), abs(s.b - p));
}
template < class T > double distance_ss(const segment< T >& a, const segment< T >& b) {
    if(intersect_ss(a, b)) return 0;
    return std::min({ distance_sp(a, b.a), distance_sp(a, b.b), distance_sp(b, a.a), distance_sp(b, a.b) });
}

template < class T > using polygon = std::vector< point< T > >;
template < class T > T area2(const polygon< T >& p) {
    T s = 0;
    int n = p.size();
    for(int i = 0; i < n; i++) s += det(p[i], p[(i + 1) % n]);
    return s;
}
template < class T > T area(const polygon< T >& p) { return area2(p) / T(2); }

template < class T > bool is_convex(const polygon< T >& p) {
    int n = p.size();
    for(int i = 0; i < n; i++) if(ccw(p[(i - 1 + n) % n], p[i], p[(i + 1) % n]) == -1) return false;
    return true;
}
template < class T > int contains(const polygon< T >& g, const point< T >& p) {
    int n = g.size();
    bool in = false;
    for(int i = 0; i < n; i++) {
        point a = g[i] - p, b = g[(i + 1) % n] - p;
        if(sign(a.y - b.y) == +1) std::swap(a, b);
        if(sign(a.y) <= 0 and sign(b.y) ==+1 and sign(det(a, b)) == -1) in = !in;
        if(sign(det(a, b)) == 0 and sign(dot(a, b)) <= 0) return 1; // ON
    }
    return in ? 2 : 0;
}
template < class T > polygon< T > convex_cut(const polygon< T >& p, const line< T >& l) {
    int n = p.size();
    polygon< T > res;
    for(int i = 0; i < n; i++) {
        point now = p[i], nxt = p[(i + 1) % n];
        if(ccw(l.a, l.b, now) != -1) res.push_back(now);
        if(ccw(l.a, l.b, now) * ccw(l.a, l.b, nxt) < 0) res.push_back(cross_point_ll(line(now, nxt), l));
    }
    return res;
}
template < class T > polygon< T > convex_hull(polygon< T >& p) {
    int n = p.size(), k = 0;
    if(n <= 2) return p;
    std::sort(p.begin(), p.end());
    polygon< T > ch(n + n);
    for(int i = 0; i < n; ch[k++] = p[i++])
        while(k >= 2 and sign(det(ch[k - 1] - ch[k - 2], p[i] - ch[k - 1])) == -1) k--;
    for(int i = n - 2, t = k + 1; i >= 0; ch[k++] = p[i--])
        while(k >= t and sign(det(ch[k - 1] - ch[k - 2], p[i] - ch[k - 1])) == -1) k--;
    ch.resize(k - 1);
    return ch;
}
template < class T > T diameter2(const polygon< T >& p) {
    static_assert(is_floating_point_v< T >);
    int n = p.size(), is = 0, js = 0;
    for(int i = 1; i < n; i++) {
        if(sign(p[i].y - p[is].y) == +1) is = i;
        if(sign(p[i].y - p[js].y) == -1) js = i;
    }
    T dist_max = norm(p[is] - p[js]);
    int maxi = is, i = is, maxj = js, j = js;
    do {
        if(sign(det(p[(i + 1) % n] - p[i], p[(j + 1) % n] - p[j])) >= 0) j = (j + 1) % n; else i = (i + 1) % n;
        if(norm(p[i] - p[j]) > dist_max) {
            dist_max = norm(p[i] - p[j]);
            maxi = i, maxj = j;
        }
    } while(i != is or j != js);
    return dist_max;
}
template < class T > double diameter(const polygon< T >& p) {
    static_assert(is_floating_point_v< T >);
    return std::sqrt(diameter2(p));
}

template < class T > struct circle {
    point< T > p;
    T r;
    circle() = default;
    circle(point< T > p, T r) : p(p), r(r) {}
};
template < class T > istream& operator>>(istream& is, circle< T >& c) { return is >> c.p >> c.r; }
template < class T > int intersect_cc(circle< T > c1, circle< T > c2) {
    if(c1.r < c2.r) std::swap(c1, c2);
    T d = abs(c1.p - c2.p);
    if(sign(c1.r + c2.r - d) == -1) return 4;
    if(equals(c1.r + c2.r, d)) return 3;
    if(sign(c1.r - c2.r - d) == -1) return 2;
    if(equals(c1.r - c2.r, d)) return 1;
    return 0;
}
template < class T > std::pair<point< T >, point< T >> cross_point_cc(const circle< T >& c1, const circle< T >& c2) {
    T d = abs(c1.p - c2.p);
    T a = std::acos((c1.r * c1.r + d * d - c2.r * c2.r) / (2 * c1.r * d));
    T t = angle(c2.p - c1.p);
    point< T > p1 = c1.p + point< T >(std::cos(t + a), std::sin(t + a)) * c1.r;
    point< T > p2 = c1.p + point< T >(std::cos(t - a), std::sin(t - a)) * c1.r;
    return {p1, p2};
}

int solve(int N) {
    vector<point<f64>> p(N);
    for(int i : rep(N)) p[i] = in();
    vector<point<f64>> q(4);
    for(int i : rep(4)) q[i] = in();

    vector<int> X, Y;
    for(int i : rep(N)) X.push_back(p[i].x), Y.push_back(p[i].y);
    for(int i : rep(N)) X.push_back(q[i].x), Y.push_back(q[i].y);
    unique(X);
    unique(Y);

    auto contain = [&](vector<point<f64>>& a, segment<f64> b) {
        int cnt = 0;
        const int n = a.size();
        for(int i : rep(n)) {
            if(intersect_ss(segment<f64>(a[i], a[(i + 1) % n]), b)) cnt++;
        }
        return cnt % 2 == 1;
    };

    int ans = 0;
    for(int xi = 0; xi + 1 < int(X.size()); xi++) {
        for(int yi = 0; yi + 1 < int(Y.size()); yi++) {
            segment<f64> s(point<f64>(X[xi] + 0.5, Y[yi] + 0.5), point<f64>(X[xi] + 0.5, -30000.0));
            if(contain(p, s) and !contain(q, s)) ans += (X[xi + 1] - X[xi]) * (Y[yi + 1] - Y[yi]);
        }
    }
    return ans;
}

int main() {
    while(true) {
        int N = in();
        if(N == 0) return 0;
        print(solve(N));
    }
}
accuracy: 1
time_ms: 20
memory_kb: 3380
final_rank: 2

code_snippet: #include <bits/stdc++.h>
using namespace std;

const int M=20'000;

int main(){
    cin.tie(nullptr);
    ios::sync_with_stdio(false);
    while(1){
        int N;
        cin>>N;
        if(N==0)return 0;
        vector<int>X(N),Y(N);
        for(int i=0;i<N;i++)cin>>X[i]>>Y[i];
        vector<vector<int>>V(2*M+1);
        for(int i=0;i<N;i++){
            if(X[i]==X[(i+1)%N]){
                if(Y[i]<Y[(i+1)%N]){
                    for(int y=Y[i];y<Y[(i+1)%N];y++){
                        V[y+M].push_back(X[i]);
                    }
                }else{
                    for(int y=Y[i]-1;y>=Y[(i+1)%N];y--){
                        V[y+M].push_back(X[i]);
                    }
                }
            }
        }
        int xmin=M,xmax=-M,ymin=M,ymax=-M;
        for(int i=0;i<4;i++){
            int a,b;
            cin>>a>>b;
            xmin=min(xmin,a);
            xmax=max(xmax,a);
            ymin=min(ymin,b);
            ymax=max(ymax,b);
        }
        long long ans=0;
        for(int y=0;y<2*M+1;y++){
            sort(V[y].begin(),V[y].end());
            for(int i=0;i<(int)V[y].size();i+=2){
                ans+=V[y][i+1]-V[y][i];
            }
        }
        for(int y=ymin+M;y<ymax+M;y++){
            for(int i=0;i<(int)V[y].size();i+=2){
                if(V[y][i+1]<=xmin||V[y][i]>=xmax)continue;
                ans-=min(xmax,V[y][i+1])-max(xmin,V[y][i]);
            }
        }
        cout<<ans<<"\n";
    }
}
accuracy: 1
time_ms: 80
memory_kb: 5708
final_rank: 11

code_snippet: #include <bits/stdc++.h>
using namespace std;
void rotate90(int &x, int &y) {
  y *= -1;
  swap(x, y);
}
bool solve() {
  int N;
  cin >> N;
  if( N == 0 ) return false;
  vector<int> x(N), y(N), a(4), b(4);
  for( int i = 0; i < N; i++ ) {
    cin >> x[i] >> y[i];
  }
  for( int i = 0; i < 4; i++ ) {
    cin >> a[i] >> b[i];
  }
  while( y[0] <= y[1] ) {
    for( int i = 0; i < N; i++ ) {
      rotate90(x[i], y[i]);
    }
    for( int i = 0; i < 4; i++ ) {
      rotate90(a[i], b[i]);
    }
  }
  // cout << "=====" << endl;
  // for( int i = 0; i < N; i++ ) {
  //   cout << x[i] << " " << y[i] << endl;
  // }
  // for( int i = 0; i < 4; i++ ) {
  //   cout << a[i] << " " << b[i] << endl;
  // }
  // cout << "=====" << endl;
  int INF = 20001, CL = INF, CR = -INF, CU = -INF, CD = INF;
  for( int i = 0; i < 4; i++ ) {
    CL = min(CL, a[i]);
    CR = max(CR, a[i]);
    CU = max(CU, b[i]);
    CD = min(CD, b[i]);
  }
  // cout << CU << " " << CD << endl;
  vector<tuple<int, int, int, int>> event;
  event.push_back(make_tuple(CL, 0, 0, 0));
  event.push_back(make_tuple(CR, 0, 0, 0));
  for( int i = 0; i+1 < N; i+=2 ) {
    if( y[i] > y[i+1] ) {
      event.push_back(make_tuple(x[i], y[i+1], y[i], 1));
    }else {
      event.push_back(make_tuple(x[i], y[i], y[i+1], -1));
    }
  }
  int ans = 0, L = 2*INF+5;
  vector<int> v(L), v_sum(L);
  auto ADD = [&](int l, int r, int s) -> void {
    for( int i = l; i < r; i++ ) {
      v[i+INF] += s;
    }
    for( int i = 1; i < L; i++ ) {
      v_sum[i] = v[i]+v_sum[i-1];
    }
  };
  auto SUM = [&](int l, int r) -> int {
    return v_sum[r+INF-1]-v_sum[l+INF-1];
  };
  bool is_covered = false;
  sort(event.begin(), event.end());
  // for( auto [x, yl, yr, s] : event ) cout << x << " " << yl << " " << yr << " " << s << endl;
  for( int i = 0; i < event.size()-1; i++ ) {
    // cout << ans << endl;
    auto [xl, yl, yr, s] = event[i];
    auto [xr, _yl, _yr, _s] = event[i+1];
    if( s == 0 ) {
      is_covered = !is_covered;
    }
    ADD(yl, yr, s);
    // cout << SUM(-3, 3) <<" " << SUM(-2, 2) << endl;
    // for( int j = -10; j <= 10; j++ ) cout << v[j+INF];
    // cout << endl;
    // cout << is_covered << " " << v_sum.back() << " " << SUM(CD, CU) << endl;
    if( is_covered ) ans += (v_sum.back()-SUM(CD, CU))*(xr-xl);
    else ans += v_sum.back()*(xr-xl);
  }
  cout << ans << endl;
  return true;
}
int main(){
  while( solve() == true ) {}
}
accuracy: 1
time_ms: 50
memory_kb: 3580
final_rank: 5

code_snippet: #include <bits/stdc++.h>
using namespace std;
using ll = long long;
using pll = pair<ll, ll>;
using ld = long double;
constexpr ll INF = (1LL << 60);
#define rep(i, n) for (ll i = 0; i < ll(n); i++)
#define all(v) std::begin(v), std::end(v)
#define first fs
#define second sc
#define vec(a, T)               \
    using v##a = vector<T>;     \
    using vv##a = vector<v##a>; \
    using vvv##a = vector<vv##a>
vec(ll, ll);
vec(pll, pll);
vec(ld, ld);
vec(b, bool);

template <class T>
bool chmin(T& a, T b) {
    return a > b && (a = b, true);
}
template <class T>
bool chmax(T& a, T b) {
    return a < b && (a = b, true);
}

int main(){

    
    while(true){
        ll n;
        cin >> n;
        if(n == 0) break;

        vpll pos;
        rep(i,n){
            ll x,y;
            cin >> x >> y;
            pos.emplace_back(x,y);
        }

        ll clx = INF, crx = -INF,cly = INF,cry = -INF;
        rep(i,4){
            ll x,y;
            cin >> x >> y;
            chmin(clx,x);
            chmax(crx,x);
            chmin(cly, y);
            chmax(cry, y);
        }

        vector<array<ll,3>> segments;
        rep(i,n){
            auto [x,y] = pos[i];
            auto [nx,ny] = pos[(i+1)%n];
            if(x != nx) continue;
            segments.emplace_back(array<ll, 3>({min(y, ny), max(y, ny), x}));
        }
        sort(all(segments));

        ll segmentsidx = 0;
        priority_queue<pll, vpll, greater<pll>> pq;

        ll ans = 0;
        rep(i,40001){
            ll y = i - 20000; //[y,y+1)について考える

            while(segmentsidx < segments.size() && segments[segmentsidx][0] <= y){
                pq.emplace(segments[segmentsidx][2], segmentsidx);
                segmentsidx++;
            }
            queue<pll> buff;
            while(!pq.empty()){
                auto [x,idx] = pq.top();
                pq.pop();
                if(segments[idx][1] <= y) continue;
                buff.emplace(x,idx);
            }

            while(!buff.empty()){
                auto [lx,lidx] = buff.front();
                buff.pop();

                assert(!buff.empty());
                auto [rx,ridx] = buff.front();
                buff.pop();

                //ここに面積を求める処理を書く(考える窓の区間は [lx,rx], カーテンの区間は [clx, crx] )
                if(y < cly || cry <= y){ //y座標に関してカーテンの範囲外
                    ans += rx-lx; // [lx,rx) x [y,y+1)
                    // cerr << "1 : " << y << " " << rx - lx - 1 << endl;
                }
                else if(rx <= clx || crx <= lx){ //x座標に関してカーテンの範囲外
                    ans += rx-lx; // [lx,rx) x [y,y+1)
                    // cerr << "2 : " << y << " " << rx - lx - 1 << endl;
                }
                else if(lx <= clx && crx <= rx){ //窓の区間がカーテンの区間を完全に含んでいる場合
                    ans += (rx-lx)-(crx-clx); // [lx,rx) x [y,y+1) - [clx,crx) x [y,y+1)
                    // cerr << "3 : " << y << " "
                        //  << (rx - lx - 1) - (crx - clx - 1) << endl;
                }
                else if(lx <= clx && clx <= rx){ //カーテンの区間の一部分が窓の区間と共通部分を持つ場合1
                    ans += clx-lx;  // [lx,clx) x [y,y+1)
                    // cerr << "4 : " << y << " "
                        //  << min(clx, rx) - max(crx, lx) + 1 << endl;
                }
                else if(lx < crx && crx <= rx){ //カーテンの区間の一部分が窓の区間と共通部分を持つ場合2
                    ans += rx-crx;
                }
                else{
                    assert(clx <= lx && rx <= crx);
                }
                pq.emplace(lx,lidx);
                pq.emplace(rx,ridx);
            }

        }

        cout << ans << endl;
    }
}
accuracy: 1
time_ms: 60
memory_kb: 3332
final_rank: 4

code_snippet: #include <bits/stdc++.h>

using namespace std;

using Pt = pair<int, int>;

const int INF = 1e9;

int n;
vector<Pt> curtain, window;

tuple<int, int, int, int> getMinMax(const vector<Pt>& points) {
    int y0 = INF, y1 = -INF;
    int x0 = INF, x1 = -INF;
    for (auto& [x, y] : points) {
        y0 = min(y0, y);
        y1 = max(y1, y);
        x0 = min(x0, x);
        x1 = max(x1, x);
    }
    return {x0, y0, x1, y1};
}

int getArea(const vector<Pt>& points) {
    auto [x0p, y0p, x1p, y1p] = getMinMax(points);
    auto [x0q, y0q, x1q, y1q] = getMinMax(curtain);
    int x0 = max(x0p, x0q);
    int x1 = min(x1p, x1q);
    int y0 = max(y0p, y0q);
    int y1 = min(y1p, y1q);
    // printf("window: (%d, %d) -> (%d, %d)\n", x0p, y0p, x1p, y1p);
    // printf("shared: (%d, %d) -> (%d, %d)\n", x0, y0, x1, y1);
    return (x1p - x0p) * (y1p - y0p) - max(0, x1 - x0) * max(0, y1 - y0);
}

int main() {
    while (cin >> n) {
        if (n == 0) {
            break;
        }
        window.resize(n);
        int minY = INF, maxY = -INF;
        for (auto& [x, y] : window) {
            cin >> x >> y;
            minY = min(minY, y);
            maxY = max(maxY, y);
        }
        curtain.resize(4);
        for (auto& [x, y] : curtain) {
            cin >> x >> y;
        }
        vector<tuple<int, int, int>> lines;
        for (int i = 0; i < n; ++i) {
            auto& [x0, y0] = window[i];
            auto& [x1, y1] = window[(i + 1) % n];
            if (x0 == x1) {
                lines.emplace_back(x0, min(y0, y1), max(y0, y1));
            }
        }
        int ans = 0;
        for (int i = minY; i < maxY; ++i) {
            int y0 = i, y1 = i + 1;
            vector<int> cur;
            for (auto& [x, ya, yb] : lines) {
                if (ya <= y0 && yb >= y1) {
                    cur.push_back(x);
                }
            }
            sort(begin(cur), end(cur));
            // printf("[%d - %d]:", y0, y1);
            // for (auto& j : cur) {
            //     cout << " " << j;
            // }
            // cout << '\n';
            for (int j = 1; j < (int)cur.size(); j += 2) {
                int prev = cur[j - 1];
                int next = cur[j];
                int add = getArea({
                    {prev, y0},
                    {next, y0},
                    {next, y1},
                    {prev, y1}
                });
                // printf("area(%d, %d) = %d\n", prev, next, add);
                ans += add;
            }
        }
        cout << ans << '\n';
    }
}
accuracy: 1
time_ms: 100
memory_kb: 3328
final_rank: 6

code_snippet: #include<bits/stdc++.h>
#define rep(i,a,...) for(int i = (a)*(strlen(#__VA_ARGS__)!=0);i<(int)(strlen(#__VA_ARGS__)?__VA_ARGS__:(a));++i)
#define per(i,a,...) for(int i = (strlen(#__VA_ARGS__)?__VA_ARGS__:(a))-1;i>=(int)(strlen(#__VA_ARGS__)?(a):0);--i)
#define foreach(i, n) for(auto &i:(n))
#define all(x) (x).begin(), (x).end()
#define bit(x) (1ll << (x))
#define lambda(RES_TYPE, ...) (function<RES_TYPE(__VA_ARGS__)>)[&](__VA_ARGS__) -> RES_TYPE
#define method(FUNC_NAME, RES_TYPE, ...) function<RES_TYPE(__VA_ARGS__)> FUNC_NAME = lambda(RES_TYPE, __VA_ARGS__)
using namespace std;
using ll = long long;
using pii = pair<int,int>;
using pll = pair<ll,ll>;
//const ll MOD = (ll)1e9+7;
const ll MOD = 998244353;
const int INF = (ll)1e9+7;
const ll INFLL = (ll)1e18;
template<class t>
using vvector = vector<vector<t>>;
template<class t>
using vvvector = vector<vector<vector<t>>>;
template<class t>
using priority_queuer = priority_queue<t, vector<t>, greater<t>>;
template<class t, class u> bool chmax(t &a, u b){if(a<b){a=b;return true;}return false;}
template<class t, class u> bool chmin(t &a, u b){if(a>b){a=b;return true;}return false;}
#ifdef DEBUG
#define debug(x) cout<<"LINE "<<__LINE__<<": "<<#x<<" = "<<x<<endl;
#else
#define debug(x) (void)0
#endif

namespace templates{
    ll modpow(ll x, ll b,ll mod=MOD){
        ll res = 1;
        while(b){
            if(b&1)res = res * x % mod;
            x = x * x % mod;
            b>>=1;
        }
        return res;
    }

    ll modinv(ll x){
        return modpow(x, MOD-2);
    }

    bool was_output = false;

    void print();
    template <class t> void print(const vector<t> &);
    template <class t, class u> void print(const pair<t, u> &);
    template <class t> void print(const t&);
    template <class Head, class... Tail> void print(const Head&, const Tail&...);

    template <class t> void println(const vector<vector<t>>&);
    template <class t> void println(const vector<t>&);
    template <class t> void println(const t&);
    template <class Head, class... Tail> void println(const Head&, const Tail&...);
    void println();
    void newline();

    void print(){
        return;
    }

    template <class t>
    void print(const vector<t>&x){
        for(const t&i:x)print(i);
    }
    template <class t, class u>
    void print(const pair<t,u>&p){
        print(p.first);
        print(p.second);
    }
    template <class t>
    void print(const t&x){
        if(was_output)cout<<" ";
        cout<<x;
        was_output = true;
    }
    template <class Head, class... Tail>
    void print(const Head&head,const Tail&...tail){
        print(head);
        print(tail...);
    }

    template<class t>
    void println(const vector<vector<t>>&x){
        for(vector<t> i:x)println(i);
    }
    template<class t>
    void println(const vector<t>&x){
        for(const t&i:x)print(i);
        println();
    }
    template <class t>
    void println(const t&x){
        print(x);
        println();
    }
    void println(){
        if(was_output){
            cout << endl;
            was_output = false;
        }
    }
    template <class Head, class... Tail>
    void println(const Head&head,const Tail&...tail){
        print(head);
        println(tail...);
    }

    void newline(){
        was_output = true;
        println();
    }

    template<class t>
    istream& operator>>(istream&is, vector<t>&x){
        for(auto &i:x)is >> i;
        return is;
    }

    template<class t, class u>
    istream& operator>>(istream&is, pair<t, u>&x){
        is >> x.first >> x.second;
        return is;
    }

    template<class t>
    ostream& operator<<(ostream&os, vector<t> &v){
        os << "{";
        for(t &i:v){
            os << i << ", ";
        }
        os << "}";
        return os;
    }

    template<class t = long long>
    t in(){
        t res; cin >> res; return res;
    }

    template<class t>
    vector<t> sorted(vector<t> line,function<bool(t,t)> comp=[](t a,t b){return a<b;}){
        sort(line.begin(),line.end(),comp);
        return line;
    }

    template<class t>
    vector<t> reversed(vector<t> line){
        reverse(line.begin(),line.end());
        return line;
    }
    string reversed(string str){
        reverse(str.begin(),str.end());
        return str;
    }

    long long gcd(long long a,long long b){
        while(b){
            a %= b;
            swap(a,b);
        }
        return a;
    }

    long long lcm(long long a,long long b){
        return a / gcd(a,b) * b;
    }

    class output_initializer{
    public:
        output_initializer(){
            ios::sync_with_stdio(false);
            cin.tie(nullptr);
            cout << setprecision(20);
        }
    };output_initializer OUTPUT_INITIALIZER_INSTANCE = output_initializer();
}

using namespace templates;

ll func(int n){
    map<int,map<int,int>> m;
    vector<pii> line(n);
    foreach(i,line)i=in<pii>();
    rep(i,n){
        pii from = line[i];
        pii to = line[(i+1)%n];
        if(from.first==to.first)continue;
        int add = from.first < to.first ? 1 : -1;
        int y = from.second;
        rep(i,min(from.first,to.first),max(from.first,to.first)){
            m[i][y] += add;
        }
    }
    {
        int n = 4;
        vector<pii> line(n);
        foreach(i,line)i=in<pii>();
        rep(i,n){
            pii from = line[i];
            pii to = line[(i+1)%n];
            if(from.first==to.first)continue;
            int add = from.first > to.first ? 1 : -1;
            int y = from.second;
            rep(i,min(from.first,to.first),max(from.first,to.first)){
                m[i][y] += add;
            }
        }
    }
    ll res = 0;
    foreach(i,m){
        int sum = 0;
        int last = 0;
        foreach(j,i.second){
            if(sum>0){
                res += j.first - last;
            }
            last = j.first;
            sum += j.second;
        }
    }
    return res;
}

int main(){
    while(true){
        int n = in();
        if(n==0)break;
        println(func(n));
    }
    return 0;
}
accuracy: 1
time_ms: 3240
memory_kb: 102492
final_rank: 20

code_snippet: // #pragma comment(linker, "/stack:200000000")

#include <bits/stdc++.h>

#include <limits>
#include <type_traits>

namespace suisen {
// ! utility
template <typename ...Types>
using constraints_t = std::enable_if_t<std::conjunction_v<Types...>, std::nullptr_t>;
template <bool cond_v, typename Then, typename OrElse>
constexpr decltype(auto) constexpr_if(Then&& then, OrElse&& or_else) {
    if constexpr (cond_v) {
        return std::forward<Then>(then);
    } else {
        return std::forward<OrElse>(or_else);
    }
}

// ! function
template <typename ReturnType, typename Callable, typename ...Args>
using is_same_as_invoke_result = std::is_same<std::invoke_result_t<Callable, Args...>, ReturnType>;
template <typename F, typename T>
using is_uni_op = is_same_as_invoke_result<T, F, T>;
template <typename F, typename T>
using is_bin_op = is_same_as_invoke_result<T, F, T, T>;

template <typename Comparator, typename T>
using is_comparator = std::is_same<std::invoke_result_t<Comparator, T, T>, bool>;

// ! integral
template <typename T, typename = constraints_t<std::is_integral<T>>>
constexpr int bit_num = std::numeric_limits<std::make_unsigned_t<T>>::digits;
template <typename T, unsigned int n>
struct is_nbit { static constexpr bool value = bit_num<T> == n; };
template <typename T, unsigned int n>
static constexpr bool is_nbit_v = is_nbit<T, n>::value;

// ?
template <typename T>
struct safely_multipliable {};
template <>
struct safely_multipliable<int> { using type = long long; };
template <>
struct safely_multipliable<long long> { using type = __int128_t; };
template <>
struct safely_multipliable<float> { using type = float; };
template <>
struct safely_multipliable<double> { using type = double; };
template <>
struct safely_multipliable<long double> { using type = long double; };
template <typename T>
using safely_multipliable_t = typename safely_multipliable<T>::type;

} // namespace suisen

// ! type aliases
using i128 = __int128_t;
using u128 = __uint128_t;
using ll = long long;
using uint = unsigned int;
using ull  = unsigned long long;

template <typename T> using vec  = std::vector<T>;
template <typename T> using vec2 = vec<vec <T>>;
template <typename T> using vec3 = vec<vec2<T>>;
template <typename T> using vec4 = vec<vec3<T>>;

template <typename T>
using pq_greater = std::priority_queue<T, std::vector<T>, std::greater<T>>;
template <typename T, typename U>
using umap = std::unordered_map<T, U>;

// ! macros (capital: internal macro)
#define OVERLOAD2(_1,_2,name,...) name
#define OVERLOAD3(_1,_2,_3,name,...) name
#define OVERLOAD4(_1,_2,_3,_4,name,...) name

#define REP4(i,l,r,s)  for(std::remove_reference_t<std::remove_const_t<decltype(r)>>i=(l);i<(r);i+=(s))
#define REP3(i,l,r)    REP4(i,l,r,1)
#define REP2(i,n)      REP3(i,0,n)
#define REPINF3(i,l,s) for(std::remove_reference_t<std::remove_const_t<decltype(l)>>i=(l);;i+=(s))
#define REPINF2(i,l)   REPINF3(i,l,1)
#define REPINF1(i)     REPINF2(i,0)
#define RREP4(i,l,r,s) for(std::remove_reference_t<std::remove_const_t<decltype(r)>>i=(l)+fld((r)-(l)-1,s)*(s);i>=(l);i-=(s))
#define RREP3(i,l,r)   RREP4(i,l,r,1)
#define RREP2(i,n)     RREP3(i,0,n)

#define rep(...)    OVERLOAD4(__VA_ARGS__, REP4   , REP3   , REP2   )(__VA_ARGS__)
#define rrep(...)   OVERLOAD4(__VA_ARGS__, RREP4  , RREP3  , RREP2  )(__VA_ARGS__)
#define repinf(...) OVERLOAD3(__VA_ARGS__, REPINF3, REPINF2, REPINF1)(__VA_ARGS__)

#define CAT_I(a, b) a##b
#define CAT(a, b) CAT_I(a, b)
#define UNIQVAR(tag) CAT(tag, __LINE__)
#define loop(n) for (std::remove_reference_t<std::remove_const_t<decltype(n)>> UNIQVAR(loop_variable) = n; UNIQVAR(loop_variable) --> 0;)

#define all(iterable) (iterable).begin(), (iterable).end()
#define input(type, ...) type __VA_ARGS__; read(__VA_ARGS__)

// ! I/O utilities

// pair
template <typename T, typename U>
std::ostream& operator<<(std::ostream& out, const std::pair<T, U> &a) {
    return out << a.first << ' ' << a.second;
}
// tuple
template <unsigned int N = 0, typename ...Args>
std::ostream& operator<<(std::ostream& out, const std::tuple<Args...> &a) {
    if constexpr (N >= std::tuple_size_v<std::tuple<Args...>>) {
        return out;
    } else {
        out << std::get<N>(a);
        if constexpr (N + 1 < std::tuple_size_v<std::tuple<Args...>>) {
            out << ' ';
        }
        return operator<<<N + 1>(out, a);
    }
}
// vector
template <typename T>
std::ostream& operator<<(std::ostream& out, const std::vector<T> &a) {
    for (auto it = a.begin(); it != a.end();) {
        out << *it;
        if (++it != a.end()) out << ' ';
    }
    return out;
}
inline void print() { std::cout << '\n'; }
template <typename Head, typename... Tail>
inline void print(const Head &head, const Tail &...tails) {
    std::cout << head;
    if (sizeof...(tails)) std::cout << ' ';
    print(tails...);
}
template <typename Iterable>
auto print_all(const Iterable& v, std::string sep = " ", std::string end = "\n") -> decltype(std::cout << *v.begin(), void()) {
    for (auto it = v.begin(); it != v.end();) {
        std::cout << *it;
        if (++it != v.end()) std::cout << sep;
    }
    std::cout << end;
}

// pair
template <typename T, typename U>
std::istream& operator>>(std::istream& in, std::pair<T, U> &a) {
    return in >> a.first >> a.second;
}
// tuple
template <unsigned int N = 0, typename ...Args>
std::istream& operator>>(std::istream& in, std::tuple<Args...> &a) {
    if constexpr (N >= std::tuple_size_v<std::tuple<Args...>>) {
        return in;
    } else {
        return operator>><N + 1>(in >> std::get<N>(a), a);
    }
}
// vector
template <typename T>
std::istream& operator>>(std::istream& in, std::vector<T> &a) {
    for (auto it = a.begin(); it != a.end(); ++it) in >> *it;
    return in;
}
template <typename ...Args>
void read(Args &...args) {
    ( std::cin >> ... >> args );
}

// ! integral utilities

// Returns pow(-1, n)
template <typename T>
constexpr inline int pow_m1(T n) {
    return -(n & 1) | 1;
}
// Returns pow(-1, n)
template <>
constexpr inline int pow_m1<bool>(bool n) {
    return -int(n) | 1;
}

// Returns floor(x / y)
template <typename T>
constexpr inline T fld(const T x, const T y) {
    return (x ^ y) >= 0 ? x / y : (x - (y + pow_m1(y >= 0))) / y;
}
template <typename T>
constexpr inline T cld(const T x, const T y) {
    return (x ^ y) <= 0 ? x / y : (x + (y + pow_m1(y >= 0))) / y;
}

template <typename T, suisen::constraints_t<suisen::is_nbit<T, 32>> = nullptr>
constexpr inline int popcount(const T x) { return __builtin_popcount(x); }
template <typename T, suisen::constraints_t<suisen::is_nbit<T, 64>> = nullptr>
constexpr inline int popcount(const T x) { return __builtin_popcountll(x); }
template <typename T, suisen::constraints_t<suisen::is_nbit<T, 32>> = nullptr>
constexpr inline int count_lz(const T x) { return x ? __builtin_clz(x)   : suisen::bit_num<T>; }
template <typename T, suisen::constraints_t<suisen::is_nbit<T, 64>> = nullptr>
constexpr inline int count_lz(const T x) { return x ? __builtin_clzll(x) : suisen::bit_num<T>; }
template <typename T, suisen::constraints_t<suisen::is_nbit<T, 32>> = nullptr>
constexpr inline int count_tz(const T x) { return x ? __builtin_ctz(x)   : suisen::bit_num<T>; }
template <typename T, suisen::constraints_t<suisen::is_nbit<T, 64>> = nullptr>
constexpr inline int count_tz(const T x) { return x ? __builtin_ctzll(x) : suisen::bit_num<T>; }
template <typename T>
constexpr inline int floor_log2(const T x) { return suisen::bit_num<T> - 1 - count_lz(x); }
template <typename T>
constexpr inline int ceil_log2(const T x)  { return floor_log2(x) + ((x & -x) != x); }
template <typename T>
constexpr inline int kth_bit(const T x, const unsigned int k) { return (x >> k) & 1; }
template <typename T>
constexpr inline int parity(const T x) { return popcount(x) & 1; }

struct all_subset {
    struct all_subset_iter {
        const int s; int t;
        constexpr all_subset_iter(int s) : s(s), t(s + 1) {}
        constexpr auto operator*() const { return t; }
        constexpr auto operator++() {}
        constexpr auto operator!=(std::nullptr_t) { return t ? (--t &= s, true) : false; }
    };
    int s;
    constexpr all_subset(int s) : s(s) {}
    constexpr auto begin() { return all_subset_iter(s); }
    constexpr auto end()   { return nullptr; }
};

// ! container

template <typename T, typename Comparator, suisen::constraints_t<suisen::is_comparator<Comparator, T>> = nullptr>
auto priqueue_comp(const Comparator comparator) {
    return std::priority_queue<T, std::vector<T>, Comparator>(comparator);
}

template <typename Iterable>
auto isize(const Iterable &iterable) -> decltype(int(iterable.size())) {
    return iterable.size();
}

template <typename T, typename Gen, suisen::constraints_t<suisen::is_same_as_invoke_result<T, Gen, int>> = nullptr>
auto generate_vector(int n, Gen generator) {
    std::vector<T> v(n);
    for (int i = 0; i < n; ++i) v[i] = generator(i);
    return v;
}

template <typename T>
void sort_unique_erase(std::vector<T> &a) {
    std::sort(a.begin(), a.end());
    a.erase(std::unique(a.begin(), a.end()), a.end());
}

// ! other utilities

// x <- min(x, y). returns true iff `x` has chenged.
template <typename T>
inline bool chmin(T &x, const T &y) {
    if (y >= x) return false;
    x = y;
    return true;
}
// x <- max(x, y). returns true iff `x` has chenged.
template <typename T>
inline bool chmax(T &x, const T &y) {
    if (y <= x) return false;
    x = y;
    return true;
}

namespace suisen {}
using namespace suisen;
using namespace std;

struct io_setup {
    io_setup(int precision = 20) {
        std::ios::sync_with_stdio(false);
        std::cin.tie(nullptr);
        std::cout << std::fixed << std::setprecision(precision);
    }
} io_setup_ {};

// ! code from here

#include <algorithm>
#include <cassert>
#include <iostream>
#include <vector>

#ifdef _MSC_VER
#include <intrin.h>
#endif

namespace atcoder {

namespace internal {

// @param n `0 <= n`
// @return minimum non-negative `x` s.t. `n <= 2**x`
int ceil_pow2(int n) {
    int x = 0;
    while ((1U << x) < (unsigned int)(n)) x++;
    return x;
}

// @param n `1 <= n`
// @return minimum non-negative `x` s.t. `(n & (1 << x)) != 0`
constexpr int bsf_constexpr(unsigned int n) {
    int x = 0;
    while (!(n & (1 << x))) x++;
    return x;
}

// @param n `1 <= n`
// @return minimum non-negative `x` s.t. `(n & (1 << x)) != 0`
int bsf(unsigned int n) {
#ifdef _MSC_VER
    unsigned long index;
    _BitScanForward(&index, n);
    return index;
#else
    return __builtin_ctz(n);
#endif
}

}  // namespace internal

}  // namespace atcoder

namespace atcoder {

template <class S,
          S (*op)(S, S),
          S (*e)(),
          class F,
          S (*mapping)(F, S),
          F (*composition)(F, F),
          F (*id)()>
struct lazy_segtree {
  public:
    lazy_segtree() : lazy_segtree(0) {}
    explicit lazy_segtree(int n) : lazy_segtree(std::vector<S>(n, e())) {}
    explicit lazy_segtree(const std::vector<S>& v) : _n(int(v.size())) {
        log = internal::ceil_pow2(_n);
        size = 1 << log;
        d = std::vector<S>(2 * size, e());
        lz = std::vector<F>(size, id());
        for (int i = 0; i < _n; i++) d[size + i] = v[i];
        for (int i = size - 1; i >= 1; i--) {
            update(i);
        }
    }

    void set(int p, S x) {
        assert(0 <= p && p < _n);
        p += size;
        for (int i = log; i >= 1; i--) push(p >> i);
        d[p] = x;
        for (int i = 1; i <= log; i++) update(p >> i);
    }

    S get(int p) {
        assert(0 <= p && p < _n);
        p += size;
        for (int i = log; i >= 1; i--) push(p >> i);
        return d[p];
    }

    S prod(int l, int r) {
        assert(0 <= l && l <= r && r <= _n);
        if (l == r) return e();

        l += size;
        r += size;

        for (int i = log; i >= 1; i--) {
            if (((l >> i) << i) != l) push(l >> i);
            if (((r >> i) << i) != r) push((r - 1) >> i);
        }

        S sml = e(), smr = e();
        while (l < r) {
            if (l & 1) sml = op(sml, d[l++]);
            if (r & 1) smr = op(d[--r], smr);
            l >>= 1;
            r >>= 1;
        }

        return op(sml, smr);
    }

    S all_prod() { return d[1]; }

    void apply(int p, F f) {
        assert(0 <= p && p < _n);
        p += size;
        for (int i = log; i >= 1; i--) push(p >> i);
        d[p] = mapping(f, d[p]);
        for (int i = 1; i <= log; i++) update(p >> i);
    }
    void apply(int l, int r, F f) {
        assert(0 <= l && l <= r && r <= _n);
        if (l == r) return;

        l += size;
        r += size;

        for (int i = log; i >= 1; i--) {
            if (((l >> i) << i) != l) push(l >> i);
            if (((r >> i) << i) != r) push((r - 1) >> i);
        }

        {
            int l2 = l, r2 = r;
            while (l < r) {
                if (l & 1) all_apply(l++, f);
                if (r & 1) all_apply(--r, f);
                l >>= 1;
                r >>= 1;
            }
            l = l2;
            r = r2;
        }

        for (int i = 1; i <= log; i++) {
            if (((l >> i) << i) != l) update(l >> i);
            if (((r >> i) << i) != r) update((r - 1) >> i);
        }
    }

    template <bool (*g)(S)> int max_right(int l) {
        return max_right(l, [](S x) { return g(x); });
    }
    template <class G> int max_right(int l, G g) {
        assert(0 <= l && l <= _n);
        assert(g(e()));
        if (l == _n) return _n;
        l += size;
        for (int i = log; i >= 1; i--) push(l >> i);
        S sm = e();
        do {
            while (l % 2 == 0) l >>= 1;
            if (!g(op(sm, d[l]))) {
                while (l < size) {
                    push(l);
                    l = (2 * l);
                    if (g(op(sm, d[l]))) {
                        sm = op(sm, d[l]);
                        l++;
                    }
                }
                return l - size;
            }
            sm = op(sm, d[l]);
            l++;
        } while ((l & -l) != l);
        return _n;
    }

    template <bool (*g)(S)> int min_left(int r) {
        return min_left(r, [](S x) { return g(x); });
    }
    template <class G> int min_left(int r, G g) {
        assert(0 <= r && r <= _n);
        assert(g(e()));
        if (r == 0) return 0;
        r += size;
        for (int i = log; i >= 1; i--) push((r - 1) >> i);
        S sm = e();
        do {
            r--;
            while (r > 1 && (r % 2)) r >>= 1;
            if (!g(op(d[r], sm))) {
                while (r < size) {
                    push(r);
                    r = (2 * r + 1);
                    if (g(op(d[r], sm))) {
                        sm = op(d[r], sm);
                        r--;
                    }
                }
                return r + 1 - size;
            }
            sm = op(d[r], sm);
        } while ((r & -r) != r);
        return 0;
    }

  private:
    int _n, size, log;
    std::vector<S> d;
    std::vector<F> lz;

    void update(int k) { d[k] = op(d[2 * k], d[2 * k + 1]); }
    void all_apply(int k, F f) {
        d[k] = mapping(f, d[k]);
        if (k < size) lz[k] = composition(f, lz[k]);
    }
    void push(int k) {
        all_apply(2 * k, lz[k]);
        all_apply(2 * k + 1, lz[k]);
        lz[k] = id();
    }
};

}  // namespace atcoder

using S = pair<int, int>;
using F = bool;

S op(S x, S y) {
    return S { x.first + y.first, x.second + y.second };
}
S e() {
    return S { 0, 0 };
}
S mapping(F f, S x) {
    int num = f ? x.second - x.first : x.first;
    return S { num, x.second };
}
F composition(F f, F g) {
    return f ^ g;
}
F id() {
    return 0;
}

using Point = pair<int, int>;

constexpr int B = 20000;
constexpr int M = 2 * B + 10;

int main() {
    while (true) {
        input(int, n);
        if (n == 0) break;

        vector<Point> poly(n);
        read(poly);
        for (auto &[x, y] : poly) x += B, y += B;

        vector<vector<pair<int, int>>> vert(M);
        rep(i, n) {
            int j = (i + 1) % n;
            auto [xi, yi] = poly[i];
            auto [xj, yj] = poly[j];
            if (xi == xj) {
                vert[xi].emplace_back(min(yi, yj), max(yi, yj));
            }
        }

        vector<Point> rect(4);
        read(rect);
        for (auto &[x, y] : rect) x += B, y += B;

        auto [qxl, qxr] = minmax({ rect[0].first,  rect[1].first,  rect[2].first,  rect[3].first  });
        auto [qyl, qyr] = minmax({ rect[0].second, rect[1].second, rect[2].second, rect[3].second });

        atcoder::lazy_segtree<S, op, e, F, mapping, composition, id> seg(vector<S>(M, { 0, 1 }));

        long long area = 0, covered = 0;
        rep(x, M) {
            for (const auto &[l, r] : vert[x]) {
                seg.apply(l, r, 1);
            }
            area += seg.all_prod().first;
            if (qxl <= x and x < qxr) {
                covered += seg.prod(qyl, qyr).first;
            }
        }
        print(area - covered);
    }
    return 0;
}
accuracy: 1
time_ms: 150
memory_kb: 5900
final_rank: 12

code_snippet: #include <iostream>
#include <vector>
#include <algorithm>


#include <algorithm>
#include <cassert>
#include <iostream>
#include <vector>


#ifdef _MSC_VER
#include <intrin.h>
#endif

namespace atcoder {

namespace internal {

int ceil_pow2(int n) {
    int x = 0;
    while ((1U << x) < (unsigned int)(n)) x++;
    return x;
}

constexpr int bsf_constexpr(unsigned int n) {
    int x = 0;
    while (!(n & (1 << x))) x++;
    return x;
}

int bsf(unsigned int n) {
#ifdef _MSC_VER
    unsigned long index;
    _BitScanForward(&index, n);
    return index;
#else
    return __builtin_ctz(n);
#endif
}

}  // namespace internal

}  // namespace atcoder


namespace atcoder {

template <class S,
          S (*op)(S, S),
          S (*e)(),
          class F,
          S (*mapping)(F, S),
          F (*composition)(F, F),
          F (*id)()>
struct lazy_segtree {
  public:
    lazy_segtree() : lazy_segtree(0) {}
    explicit lazy_segtree(int n) : lazy_segtree(std::vector<S>(n, e())) {}
    explicit lazy_segtree(const std::vector<S>& v) : _n(int(v.size())) {
        log = internal::ceil_pow2(_n);
        size = 1 << log;
        d = std::vector<S>(2 * size, e());
        lz = std::vector<F>(size, id());
        for (int i = 0; i < _n; i++) d[size + i] = v[i];
        for (int i = size - 1; i >= 1; i--) {
            update(i);
        }
    }

    void set(int p, S x) {
        assert(0 <= p && p < _n);
        p += size;
        for (int i = log; i >= 1; i--) push(p >> i);
        d[p] = x;
        for (int i = 1; i <= log; i++) update(p >> i);
    }

    S get(int p) {
        assert(0 <= p && p < _n);
        p += size;
        for (int i = log; i >= 1; i--) push(p >> i);
        return d[p];
    }

    S prod(int l, int r) {
        assert(0 <= l && l <= r && r <= _n);
        if (l == r) return e();

        l += size;
        r += size;

        for (int i = log; i >= 1; i--) {
            if (((l >> i) << i) != l) push(l >> i);
            if (((r >> i) << i) != r) push((r - 1) >> i);
        }

        S sml = e(), smr = e();
        while (l < r) {
            if (l & 1) sml = op(sml, d[l++]);
            if (r & 1) smr = op(d[--r], smr);
            l >>= 1;
            r >>= 1;
        }

        return op(sml, smr);
    }

    S all_prod() { return d[1]; }

    void apply(int p, F f) {
        assert(0 <= p && p < _n);
        p += size;
        for (int i = log; i >= 1; i--) push(p >> i);
        d[p] = mapping(f, d[p]);
        for (int i = 1; i <= log; i++) update(p >> i);
    }
    void apply(int l, int r, F f) {
        assert(0 <= l && l <= r && r <= _n);
        if (l == r) return;

        l += size;
        r += size;

        for (int i = log; i >= 1; i--) {
            if (((l >> i) << i) != l) push(l >> i);
            if (((r >> i) << i) != r) push((r - 1) >> i);
        }

        {
            int l2 = l, r2 = r;
            while (l < r) {
                if (l & 1) all_apply(l++, f);
                if (r & 1) all_apply(--r, f);
                l >>= 1;
                r >>= 1;
            }
            l = l2;
            r = r2;
        }

        for (int i = 1; i <= log; i++) {
            if (((l >> i) << i) != l) update(l >> i);
            if (((r >> i) << i) != r) update((r - 1) >> i);
        }
    }

    template <bool (*g)(S)> int max_right(int l) {
        return max_right(l, [](S x) { return g(x); });
    }
    template <class G> int max_right(int l, G g) {
        assert(0 <= l && l <= _n);
        assert(g(e()));
        if (l == _n) return _n;
        l += size;
        for (int i = log; i >= 1; i--) push(l >> i);
        S sm = e();
        do {
            while (l % 2 == 0) l >>= 1;
            if (!g(op(sm, d[l]))) {
                while (l < size) {
                    push(l);
                    l = (2 * l);
                    if (g(op(sm, d[l]))) {
                        sm = op(sm, d[l]);
                        l++;
                    }
                }
                return l - size;
            }
            sm = op(sm, d[l]);
            l++;
        } while ((l & -l) != l);
        return _n;
    }

    template <bool (*g)(S)> int min_left(int r) {
        return min_left(r, [](S x) { return g(x); });
    }
    template <class G> int min_left(int r, G g) {
        assert(0 <= r && r <= _n);
        assert(g(e()));
        if (r == 0) return 0;
        r += size;
        for (int i = log; i >= 1; i--) push((r - 1) >> i);
        S sm = e();
        do {
            r--;
            while (r > 1 && (r % 2)) r >>= 1;
            if (!g(op(d[r], sm))) {
                while (r < size) {
                    push(r);
                    r = (2 * r + 1);
                    if (g(op(d[r], sm))) {
                        sm = op(d[r], sm);
                        r--;
                    }
                }
                return r + 1 - size;
            }
            sm = op(d[r], sm);
        } while ((r & -r) != r);
        return 0;
    }

  private:
    int _n, size, log;
    std::vector<S> d;
    std::vector<F> lz;

    void update(int k) { d[k] = op(d[2 * k], d[2 * k + 1]); }
    void all_apply(int k, F f) {
        d[k] = mapping(f, d[k]);
        if (k < size) lz[k] = composition(f, lz[k]);
    }
    void push(int k) {
        all_apply(2 * k, lz[k]);
        all_apply(2 * k + 1, lz[k]);
        lz[k] = id();
    }
};

}  // namespace atcoder


#ifdef LOCAL
#define debug(...)                                                    \
    std::cerr << "LINE: " << __LINE__ << "  [" << #__VA_ARGS__ << "]:", \
        debug_out(__VA_ARGS__)
#else
#define debug(...)
#endif
 
void debug_out() { std::cerr << std::endl; }
 
template <typename Head, typename... Tail>
void debug_out(Head h, Tail... t) {
    std::cerr << " " << h;
    if (sizeof...(t) > 0) std::cout << " :";
    debug_out(t...);
}

#define rep(i, a, n) for (int i = (int)(a); i < (int)(n); i++)

using i64 = std::int64_t;

constexpr int max = 20010;

constexpr int sz = 40020;

struct S{
    long long value;
    int size;
};
using F = long long;

S op(S a, S b){ return {a.value+b.value, a.size+b.size}; }
S e(){ return {0, 0}; }
S mapping(F f, S x){ return {x.value + f*x.size, x.size}; }
F composition(F f, F g){ return f+g; }
F id(){ return 0; }

int main() {
    int n;
    while(std::cin >> n, n > 0) {
        std::vector<std::pair<int,int>> xy(n);
        for(auto &[x, y]: xy) {
            std::cin >> x >> y;
            x += max;
            y += max;
        }
        std::vector ret(sz, std::vector<std::pair<int,int>>());
        rep(i,0,n) {
            const auto &[x, y] = xy[i];
            const auto &[nx, ny] = xy[(i+1)%n];
            if(x != nx) continue;
            ret[x].emplace_back(y, ny);
        }
        std::vector<std::pair<int,int>> p(4);
        for(auto &[x,y]: p) {
            std::cin >> x >> y;
            x += max;
            y += max;
        }
        std::sort(p.begin(), p.end());
        int l = p[0].first;
        int r = p[2].first;
        int low = std::min(p[0].second, p[1].second);
        int high = std::max(p[0].second, p[1].second);
        atcoder::lazy_segtree<S, op, e, F, mapping, composition, id> seg(std::vector<S>(sz, {0, 1}));
        i64 ans = 0;
        rep(i,0,sz) {
            for(auto &[y, ny]: ret[i]) {
                if(y < ny) {
                    seg.apply(y, ny, -1);
                }
                else {
                    seg.apply(ny, y, 1);
                }
            }
            ans += seg.all_prod().value;
            if(l <= i && i < r) {
                ans -= seg.prod(low, high).value;
            }
        }
        std::cout << ans << '\n';
    }
}
accuracy: 1
time_ms: 90
memory_kb: 7732
final_rank: 13

code_snippet: #pragma GCC target("avx2")
#pragma GCC optimize("Ofast")
#pragma GCC optimize("unroll-loops")
#include <bits/stdc++.h>
//#include <atcoder/all>
using namespace std;
//using namespace atcoder;
#define DEBUG
#ifdef DEBUG
template <class T, class U>
ostream &operator<<(ostream &os, const pair<T, U> &p) {
    os << '(' << p.first << ',' << p.second << ')';
    return os;
}
template <class T> ostream &operator<<(ostream &os, const vector<T> &v) {
    os << '{';
    for(int i = 0; i < (int)v.size(); i++) {
        if(i) { os << ','; }
        os << v[i];
    }
    os << '}';
    return os;
}
void debugg() { cerr << endl; }
template <class T, class... Args>
void debugg(const T &x, const Args &... args) {
    cerr << " " << x;
    debugg(args...);
}
#define debug(...)                                                             \
    cerr << __LINE__ << " [" << #__VA_ARGS__ << "]: ", debugg(__VA_ARGS__)
#define dump(x) cerr << __LINE__ << " " << #x << " = " << (x) << endl
#else
#define debug(...) (void(0))
#define dump(x) (void(0))
#endif
using namespace std;
typedef long long ll;
typedef vector<ll> vl;
typedef vector<vl> vvl;
typedef vector<char> vc;
typedef vector<string> vs;
typedef vector<bool> vb;
typedef vector<double> vd;
typedef pair<ll,ll> P;
typedef pair<int,int> pii;
typedef vector<P> vpl;
typedef tuple<ll,ll,ll> tapu;
#define rep(i,n) for(int i=0; i<(n); i++)
#define REP(i,a,b) for(int i=(a); i<(b); i++)
#define all(x) (x).begin(), (x).end()
#define rall(x) (x).rbegin(), (x).rend()
const int inf = (1<<30)-1;
const ll linf = 1LL<<61;
const int MAX = 25000000;
int dy[8] = {0,1,0,-1,1,-1,-1,1};
int dx[8] = {-1,0,1,0,1,-1,1,-1};
const double pi = acos(-1);
const double eps = 1e-7;
template<typename T1,typename T2> inline bool chmin(T1 &a,T2 b){
	if(a>b){
		a = b; return true;
	}
	else return false;
}
template<typename T1,typename T2> inline bool chmax(T1 &a,T2 b){
	if(a<b){
		a = b; return true;
	}
	else return false;
}
template<typename T> inline void print(T &a){
    int sz = a.size();
    for(auto itr = a.begin(); itr != a.end(); itr++){
		cout << *itr;
        sz--;
        if(sz) cout << " ";
	}
    cout << "\n";
}
template<typename T1,typename T2> inline void print2(T1 a, T2 b){
	cout << a << " " << b << "\n";
}
template<typename T1,typename T2,typename T3> inline void print3(T1 a, T2 b, T3 c){
	cout << a << " " << b << " " << c << "\n";
}
void mark() {cout << "#" << "\n";}
ll pcount(ll x) {return __builtin_popcountll(x);}
//const int mod = 1e9 + 7;
const int mod = 998244353;

template<typename T> struct BIT{
    vector<T> dat;
    ll sz;
    //all 1-indexed
    BIT(ll sz) : sz(sz){
        dat.assign(++sz, 0);
    }

    T sum(ll k){
        T ret = 0;
        for(++k; k > 0; k -= k & -k) ret += dat[k];
        return (ret);
    }

    void add(ll k, T x){
        for(++k; k < dat.size(); k += k & -k) dat[k] += x;
    }
    
    ll get(T k){
        if(k <= 0) return 0; 
        ll ret = 0;
        int n = 1; while(n < sz) n *= 2;
        for(int i=n/2; i>0; i/=2){
            if(ret+i < sz && dat[ret+i] < k){
                k -= dat[ret+i];
                ret += i;
            }
        }
        return ret;
    }
};

template<typename T> struct range_BIT{
    vector<BIT<T>> bit;
    int sz;

    range_BIT(int sz) : sz(sz) {
        rep(j,2) bit.push_back(BIT<T>(sz));
    }

    void add(int l, int r, T x){
        bit[0].add(l,-x*(l-1));
        bit[0].add(r+1,x*r);
        bit[1].add(l,x);
        bit[1].add(r+1,-x);
    }

    T sum(int k){
        return bit[0].sum(k) + bit[1].sum(k) * k;
    }
};


int main(){
    while(1){
        vector<vpl> addx(40404), subx(40404);
        range_BIT<int> bit(40404);
        int n; cin >> n;
        if(!n) break;
        vl x(n), y(n);
        vpl a(4);
        rep(i,n){
            cin >> x[i] >> y[i];
            x[i] += 20000, y[i] += 20000;
        }
        rep(i,4){
            cin >> a[i].first >> a[i].second;
            a[i].first += 20000, a[i].second += 20000;
        }
        sort(all(a));
        rep(i,n){
            int a = y[i], b = y[(i+1)%n];
            if(a > b){
                addx[x[i]].emplace_back(b,a);
            }else if(a < b){
                subx[x[i]].emplace_back(a,b);
            }
        }
        ll ans = 0;
        rep(x,40404){
            for(auto p : addx[x]){
                bit.add(p.first, p.second-1, 1);
            }
            for(auto p : subx[x]){
                bit.add(p.first, p.second-1, -1);
            }
            ans += bit.sum(40202);
            if(a[0].first <= x && x < a[3].first){
                ans -= bit.sum(a[3].second-1) - bit.sum(a[0].second-1);
            }
        }
        cout << ans << endl;
        
    }
}
accuracy: 1
time_ms: 20
memory_kb: 5472
final_rank: 8

code_snippet: #include <iostream>
#include <string>
#include <algorithm>
#include <vector>
#include <queue>
#include <utility>
#include <tuple>
#include <cmath>
#include <numeric>
#include <set>
#include <map>
#include <array>
#include <complex>
#include <iomanip>
#include <cassert>
#include <bitset>
using ll = long long;
using std::cin;
using std::cout;
using std::endl;
template<class T> inline bool chmax(T& a, T b) { if (a < b) { a = b; return 1; } return 0; }
template<class T> inline bool chmin(T& a, T b) { if (a > b) { a = b; return 1; } return 0; }
const int inf = (int)1e9 + 7;
const long long INF = 1LL << 60;

namespace KKT89
{
  template<typename T>
  struct Compress {
    std::vector<T> v;
    Compress() {}
    Compress(std::vector<T> _v) :v(_v) { build(); }
   
    void add(T x) {
      v.emplace_back(x);
    }
   
    void build() {
      std::sort(v.begin(), v.end());
      v.erase(unique(v.begin(), v.end()), v.end());
    }
   
    int get(T x) {
      return std::lower_bound(v.begin(), v.end(), x) - v.begin();
    }
   
    T& operator[](int i) { return v[i]; }
   
   
    int size() {
      return (int)v.size();
    }
  };
}

#include <cmath>
#include <iostream>
#include <complex>
#include <vector>
#include <cmath>
namespace geometry
{
  using Real = double;
  const Real EPS = 1e-8;
  const Real PI = std::acos((Real)(-1));

  inline int sign(const Real &r) {
    return r <= -EPS ? -1 : r >= EPS ? 1 : 0;
  }

  inline bool equals(const Real &a, const Real &b) {
    return sign(a - b) == 0;
  }

  using Point = std::complex<Real>;

  Point operator*(const Point &p, const Real &d) {
    return Point(p.real() * d, p.imag() * d);
  }

  // rotate point p counterclockwise by theta rad
  Point rotate(Real theta, const Point &p) {
    return Point(std::cos(theta) * p.real() - std::sin(theta) * p.imag(), std::sin(theta) * p.real() + std::cos(theta) * p.imag());
  }

  Real cross(const Point &a, const Point &b) {
    return a.real() * b.imag() - a.imag() * b.real();
  }

  Real dot(const Point &a, const Point &b) {
    return a.real() * b.real() + a.imag() * b.imag();
  }

  bool compare_x(const Point &a, const Point &b) {
    return equals(a.real(), b.real()) ? a.imag() < b.imag() : a.real() < b.real();
  }

  bool compare_y(const Point &a, const Point &b) {
    return equals(a.imag(), b.imag()) ? a.real() < b.real() : a.imag() < b.imag();
  }
  
  using Points = std::vector<Point>;
  using Polygon = std::vector<Point>;
  struct Line {
    Point a, b;

    Line() = default;

    Line(const Point &a, const Point &b) : a(a), b(b) {}

    Line(const Real &A, const Real &B, const Real &C) { // Ax+By=C
      if(equals(A, 0)) {
        assert(!equals(B, 0));
        a = Point(0, C / B);
        b = Point(1, C / B);
      } else if(equals(B, 0)) {
        a = Point(C / A, 0);
        b = Point(C / A, 1);
      } else {
        a = Point(0, C / B);
        b = Point(C / A, 0);
      }
    }
  };

  using Lines = std::vector<Line>;
  bool is_parallel(const Line &a, const Line &b)
  {
    return equals(cross(a.b - a.a, b.b - b.a), 0.0);
  }
  bool is_intersect_ll(const Line &l, const Line &m)
  {
    Real A = cross(l.b - l.a, m.b - m.a);
    Real B = cross(l.b - l.a, l.b - m.a);
    if(equals(std::abs<Real>(A), 0) && equals(std::abs<Real>(B), 0)) return true;
    return !is_parallel(l, m);
  }
  struct Segment : Line
  {
    Segment() = default;
    using Line::Line;
  };
  constexpr int COUNTER_CLOCKWISE = +1;
  constexpr int CLOCKWISE = -1;
  constexpr int ONLINE_BACK = +2; // c-a-b
  constexpr int ONLINE_FRONT = -2; // a-b-c
  constexpr int ON_SEGMENT = 0; // a-c-b
  int ccw(const Point &a, Point b, Point c) {
    b = b - a, c = c - a;
    if(sign(cross(b, c)) == +1) return COUNTER_CLOCKWISE;
    if(sign(cross(b, c)) == -1) return CLOCKWISE;
    if(sign(dot(b, c)) == -1) return ONLINE_BACK;
    if(std::norm(b) < std::norm(c)) return ONLINE_FRONT;
    return ON_SEGMENT;
  }
  using Segments = std::vector<Segment>;
  bool is_intersect_ss(const Segment &s, const Segment &t) 
  {
      return ccw(s.a, s.b, t.a) * ccw(s.a, s.b, t.b) <= 0 &&
             ccw(t.a, t.b, s.a) * ccw(t.a, t.b, s.b) <= 0;
  }
  Polygon convex_hull(Polygon &p, bool strict = true) {
      int n = (int)p.size(), k = 0;
      if(n <= 2) return p;
      std::sort(p.begin(), p.end(), compare_x);
      std::vector<Point> ch(2 * n);
      auto check = [&](int i) {
        return sign(cross(ch[k - 1] - ch[k - 2], p[i] - ch[k - 1])) <= -1 + strict;
      };
      for(int i = 0; i < n; ch[k++] = p[i++]) {
        while(k >= 2 && check(i)) --k;
      }
      for(int i = n - 2, t = k + 1; i >= 0; ch[k++] = p[i--]) {
        while(k >= t && check(i)) --k;
      }
      ch.resize(k - 1);
      return ch;
    }
}
void solve()
{
  int n; cin >> n; if(n == 0) exit(0);
  KKT89::Compress<int> cx, cy;
  std::vector<int> x(n), y(n);
  for (int i = 0; i < n; ++i)
  {
    cin >> x[i] >> y[i];
    for (int kkt = -1; kkt <= 1; ++kkt)
    {
      cx.add(x[i] + kkt);
      cy.add(y[i] + kkt);
    }

  }
  std::vector<int> tx(4), ty(4);
  for (int i = 0; i < 4; ++i)
  {
    cin >> tx[i] >> ty[i];
    for (int kkt = -1; kkt <= 1; ++kkt)
    {
      cx.add(tx[i] + kkt);
      cy.add(ty[i] + kkt);
    }
  }
  int lf = *std::min_element(tx.begin(), tx.end());
  int rg = *std::max_element(tx.begin(), tx.end());
  int up = *std::max_element(ty.begin(), ty.end());
  int dw = *std::min_element(ty.begin(), ty.end());
  cx.build();
  cy.build();
  ll res = 0.0;
  for (int i = 0; i + 1 < cx.size(); ++i)
  {
    for (int j = 0; j + 1 < cy.size(); ++j)
    {
      double p = (cx[i] + cx[i + 1]) / 2.0;
      double q = (cy[j] + cy[j + 1]) / 2.0;
      if(lf <= cx[i] and cx[i] < rg and dw <= cy[j] and cy[j] < up)
        continue;
      int cnt = 0;
      geometry::Segment s1(geometry::Point(p, q), geometry::Point(p, inf));
      for (int s = 0; s < n; ++s)
      {
        const int t = (s + 1) % n;
        geometry::Segment s2(geometry::Point(x[s], y[s]), geometry::Point(x[t], y[t])); 
        if(geometry::is_intersect_ss(s1, s2))
          cnt ^= 1;
      }
      if(cnt & 1)
        res += 1LL * (cx[i + 1] - cx[i]) * (cy[j + 1] - cy[j]);
    }
  }
  cout << res << "\n";
}
int main()
{
  std::cin.tie(nullptr);
  std::ios::sync_with_stdio(false);


  int kkt = 89;
  //cin >> kkt;
  while(kkt)
  {
    solve();
  }
  return 0;
}
accuracy: 1
time_ms: 10
memory_kb: 3492
final_rank: 1

code_snippet: // I SELL YOU...! 
#include<iostream>
#include<vector>
#include<algorithm>
#include<functional>
#include<queue>
#include<chrono>
#include<iomanip>
#include<map>
#include<set>
using namespace std;
using ll = long long;
using P = pair<ll,ll>;
using TP = tuple<ll,ll,ll>;
void init_io(){
  cin.tie(0);
  ios::sync_with_stdio(false);
  cout << fixed << setprecision(18);
}
const ll BASE = 20500;
const ll MAX = BASE*2;
vector<ll> a(4),b(4);
void turn_ab(){
  for(int i=2;i<4;i++){
    if(b[0]==b[i]){
      swap(a[1],a[i]);
      swap(b[1],b[i]);
      break;
    }
  }
  if(b[0]>b[2]){
    swap(b[0],b[2]);
    swap(a[0],a[2]);
    swap(b[1],b[3]);
    swap(a[1],a[3]);
  }
  if(a[0]>a[1]){
    swap(a[0],a[1]);
    swap(b[0],b[1]);
  }
  if(a[2]>a[3]){
    swap(a[2],a[3]);
    swap(b[2],b[3]);
  }
}
ll calc_sq(const set<ll>& st,int y){
  vector<ll> vx(st.begin(),st.end());
  ll n = st.size();
  ll res = 0;
  if(n==0) return 0;
  //cout << y-BASE<<endl;
  for(int i=0;i<n;i+=2){
    ll l = vx[i],r=vx[i+1];
    ll add = vx[i+1]-vx[i];
    if(b[0]<y&&y<=b[2]){
      if(vx[i]<=a[0]&&a[1]<=vx[i+1]){
        add = vx[i+1]-vx[i] - (a[1]-a[0]);
      }else{
        if(a[0]<=l&&l<=a[1]){
          l = a[1];
        }
        if(a[0]<=r&&r<=a[1]){
          r = a[0];
        }
        add = max(0ll,r-l);
      }
    }
    res += add;
    //cout << vx[i]-BASE<<" "<<vx[i+1]-BASE<<add<<endl;
  }
  return res;
}
void solve(){
  ll n;
  cin >> n;
  if(n==0) return;
  vector<ll> x(n),y(n);
  vector<vector<ll>> x_pt(MAX,vector<ll>());
  for(int i=0;i<n;i++){
    cin >> x[i] >> y[i];
    x[i] += BASE;
    y[i] += BASE;
    x_pt[y[i]].push_back(x[i]);
  }
  for(int i=0;i<4;i++){
    cin >> a[i] >> b[i];
    a[i] += BASE;
    b[i] += BASE;
  }
  turn_ab();
  ll ans = 0;
  set<ll> pre_x,next_x;
  for(int i=MAX-1;i>=0;i--){
    sort(x_pt[i].begin(),x_pt[i].end());
    ll m = x_pt[i].size();
    set<ll> lost;
    for(int j=0;j<m;j++){
      auto itr = pre_x.find(x_pt[i][j]);
      ll idx = distance(pre_x.begin(),itr);
      if(idx==(ll)pre_x.size()){
        next_x.insert(x_pt[i][j]);
      }else{
        ll nxt;
        if(j%2==0){
          nxt = x_pt[i][j+1];
        }else{
          nxt = x_pt[i][j-1];
        }
        if(pre_x.find(nxt)==pre_x.end()){
          next_x.insert(nxt);
        }else{
          lost.insert(nxt);
        }
        lost.insert(x_pt[i][j]);
      }
    }
    for(auto v:pre_x){
      if(lost.find(v)==lost.end())
        next_x.insert(v);
    }
    ans += calc_sq(next_x,i);
    pre_x = next_x;
    next_x.clear();
  }
  cout << ans << endl;
  solve();
}
signed main(){
  init_io();
  solve();
}
accuracy: 1
time_ms: 130
memory_kb: 51428
final_rank: 18

code_snippet: #include <bits/stdc++.h>
using namespace std;

const int xoff = 20000;
int n;
int xl, xu, yl, yu;
vector<tuple<int, int, int>> vtcl;

void solve() {
  int ans = 0;

  for (int y = -20000; y < 20000; y++) {
    if (y >= yl and y < yu) {
      vector<int> ls, us;
      for (auto &&[x, a, b] : vtcl) {
        if (y < a || b <= y) continue;
        if (x < xl) {
          ls.push_back(x);
        } else if (x > xu) {
          us.push_back(x);
        }
      }

      sort(begin(ls), end(ls));
      bool flag = false;
      for (int x : ls) {
        if (flag)
          ans += x;
        else
          ans -= x;
        flag ^= 1;
      }
      if (flag) ans += xl;

      sort(rbegin(us), rend(us));
      flag = false;
      for (int x : us) {
        if (flag)
          ans -= x;
        else
          ans += x;
        flag ^= 1;
      }
      if (flag) ans -= xu;

    } else {
      vector<int> xs;
      for (auto &&[x, a, b] : vtcl) {
        if (y < a || b <= y) continue;
        xs.push_back(x);
      }

      sort(begin(xs), end(xs));
      bool flag = false;
      for (int x : xs) {
        if (flag)
          ans += x;
        else
          ans -= x;
        flag ^= 1;
      }
    }
  }

  cout << ans << "\n";
}

int main() {
  while (1) {
    cin >> n;
    if (!n) break;
    vtcl.clear();
    vector<pair<int, int>> vs(n);
    for (auto &&[x, y] : vs) {
      cin >> x >> y;
      x += xoff;
    }
    for (int i = 0; i < n; i++) {
      int pi = i ? i - 1 : n - 1;
      auto [px, py] = vs[pi];
      auto [x, y] = vs[i];
      if (y == py) {
        continue;
      }
      if (y > py) swap(y, py);
      vtcl.emplace_back(x, y, py);
    }

    //
    xl = yl = xoff * 2;
    xu = 0, yu = -xoff;
    for (auto i = 0; i != 4; ++i) {
      int x, y;
      cin >> x >> y;
      x += xoff;
      xl = min(xl, x);
      yl = min(yl, y);
      xu = max(xu, x);
      yu = max(yu, y);
    }
    solve();
  }
}
accuracy: 1
time_ms: 50
memory_kb: 3440
final_rank: 3

code_snippet: #include <bits/stdc++.h>
using namespace std;
using ll = long long;
using vi = vector<int>;
using vvi = vector<vi>;
using vll = vector<ll>;
using vvll = vector<vll>;
using P = pair<int, int>;
const double eps = 1e-8;
const ll MOD = 1000000007;
const int INF = INT_MAX / 2;
const ll LINF = LLONG_MAX / 2;
template <typename T1, typename T2>
bool chmax(T1 &a, const T2 &b) {
  if(a < b) {a = b; return true;}
  return false;
}
template <typename T1, typename T2>
bool chmin(T1 &a, const T2 &b) {
  if(a > b) {a = b; return true;}
  return false;
}
template<typename T1, typename T2>
ostream& operator<<(ostream &os, const pair<T1, T2> p) {
  os << p.first << ":" << p.second;
  return os;
}
template<class T>
ostream &operator<<(ostream &os, const vector<T> &v) {
  for(int i=0;i<((int)(v.size()));++i) {
    if(i) os << " ";
    os << v[i];
  }
  return os;
}
bool solve() {
  int n; cin >> n;
  if(n == 0) return false;
  vector<P> p(n);
  for(int i=0;i<(n);++i) {
    cin >> p[i].first >> p[i].second;
  }
  vector<P> carten(4);
  int u = -INF, d = INF, l = INF, r = -INF;
  for(int i=0;i<(4);++i) {
    int x, y;
    cin >> x >> y;
    chmin(l, x);
    chmax(r, x);
    chmin(d, y);
    chmax(u, y);
  }
  l += 20000;
  r += 20000;
  u += 20000;
  d += 20000;
  vector<pair<int, bitset<40002>>> v;
  for(int i=0;i<(n);++i) {
    P p1 = p[i];
    P p2 = p[(i+1)%n];
    if(p1.first == p2.first) {
      bitset<40002> now;
      int mi = p1.second, ma = p2.second;
      if(mi > ma) swap(mi, ma);
      mi += 20000;
      ma += 20000;
      for(int j=(mi);j<(ma);++j) {
        now[j] = 1;
      }
      v.emplace_back(make_pair(p1.first + 20000, now));
    }
  }
  sort(v.rbegin(), v.rend(), [](pair<int, bitset<40002>> a, pair<int, bitset<40002>> b){return a.first < b.first;});
  bitset<40002> bs(0), tmp(0);
  for(int i=(d);i<(u);++i) {
    tmp[i] = 1;
  }
  int mask = 0;
  int area = 0;
  for(int i=0;i<(40002);++i) {
    while(!v.empty() && v.back().first == i) {
      bs ^= v.back().second;
      v.pop_back();
    }
    if(l <= i && i < r) {
      mask += (bs & tmp).count();
    }
    area += bs.count();
  }
  cout << area - mask << endl;
  return true;
}
int main() {
  cin.tie(0);
  ios::sync_with_stdio(false);
  cout << fixed << setprecision(10);
  while(solve()) {}
}
accuracy: 1
time_ms: 4650
memory_kb: 3436
final_rank: 19