#include "bits/stdc++.h"
#define all(x) x.begin(), x.end()
#define NL std::cout << '\n'
using lnt = long long;
const int inf = 0x3f3f3f3f;
const lnt linf = 1ll << 62;
using db = long double; const db eps = 1e-12;
int sgn(db x) { return (x < -eps ? -1 : x > eps); }
struct Pt { db x, y; };
std::istream& operator>>(std::istream& is, Pt &p) {
int x, y; std::cin >> x >> y;
p.x = x; p.y = y; return is;
}
std::ostream& operator<<(std::ostream& os, Pt p) {
return os << "(" << p.x << "," << p.y << "),";
}
Pt operator-(Pt a, Pt b) { return { a.x - b.x, a.y - b.y }; }
Pt operator+(Pt a, Pt b) { return { a.x + b.x, a.y + b.y }; }
Pt operator*(Pt a, db x) { return { a.x * x, a.y * x }; }
Pt operator/(Pt a, db x) { return { a.x / x, a.y / x }; }
db dot(Pt a, Pt b) { return a.x * b.x + a.y * b.y; }
db det(Pt a, Pt b) { return a.x * b.y - a.y * b.x; }
bool operator==(Pt a, Pt b) { return !sgn(dot(a-b, a-b)); }
bool operator!=(Pt a, Pt b) { return sgn(dot(a-b, a-b)); }
bool operator<(Pt a, Pt b) { return a.x == b.x ? a.y < b.y : a.x < b.x; }
int side(Pt a, Pt b, Pt x) { return sgn(det(b-a, x-a)); }
struct Line {
Pt s, t;
Line(db a, db b, db c) {
if (sgn(b)) {
this->s = { -1 * c / a, 0 };
this->t = { -1 * c / a, (a > 0 ? -1. : 1.) };
} else {
this->s = { 0, -1. * c / b };
this->t = this->s + Pt{ 1, -1. * a / b } ;
}
}
};
Pt intersect(Line a, Line b) {
db v = det(a.t - a.s, b.s - a.s);
db u = det(a.t - a.s, b.t - a.s);
return (b.s * u - b.t * v) / (u - v);
}
bool para(Line a, Line b) {
return !sgn(det(a.t - a.s, b.t - b.s));
}
std::pair<std::vector<Pt>, std::vector<Pt>>
hullCut(std::vector<Pt> &hull, Line a) {
int l = -1, r = -1; Pt il, ir;
for (int i = hull.size() - 1, j = 0; j < hull.size(); i = j++) {
auto &u = hull[i], &v = hull[j];
int s1 = side(a.s, a.t, u), s2 = side(a.s, a.t, v);
if (!s1 && !s2) { return {hull, {}}; }
if (s1 * s2 <= 0) {
if (l == -1) { l = j; il = intersect({u, v}, a); }
else {
Pt inter = intersect({u, v}, a);
if (inter != il) { r = j; ir = inter; }
}
}
}
if (r == -1) { return { hull, {} }; }
std::vector<Pt> lhs(hull.begin() + l, hull.begin() + r);
if (lhs.empty() || ir != lhs.back()) { lhs.emplace_back(ir); }
if (il != lhs.front()) { lhs.emplace_back(il);}
std::vector<Pt> rhs(hull.begin() + r, hull.end());
rhs.insert(rhs.end(), hull.begin(), hull.begin() + l);
if (rhs.empty() || (il != rhs.back())) { rhs.emplace_back(il); }
if (ir != rhs.front()) { rhs.emplace_back(ir); }
return {lhs, rhs};
}
enum { ATOM = 128, AND, OR, XOR, NOT };
Pt polyCenter(std::vector<Pt> &v) {
Pt ret {0, 0}; db s = 0;
for (int j = 0, i = v.size() - 1; j < v.size(); i = j++) {
ret = ret + (v[i] + v[j]) * det(v[i], v[j]);
s += det(v[i], v[j]);
}
return ret / s / 3;
}
int main() {
std::ios::sync_with_stdio(0), std::cin.tie(0);
std::cout << std::fixed << std::setprecision(15);
std::vector<std::vector<Pt>> polys(1);
{
int xmi, xmx, ymi, ymx; std::cin >> xmi >> xmx >> ymi >> ymx;
polys[0].push_back({(db)xmi, (db)ymx});
polys[0].push_back({(db)xmi, (db)ymi});
polys[0].push_back({(db)xmx, (db)ymi});
polys[0].push_back({(db)xmx, (db)ymx});
}
std::string raw; std::cin >> raw;
Line tokenVal; int token;
int p = 0;
auto next = [&]() -> void {
while (p != raw.size()) {
token = raw[p++];
if (token == '[') {
static auto read = [&]() {
int ret = 0; bool neg = 0;
while (raw[p] == '-' || raw[p] == '+' || (raw[p] >= '0' && raw[p] <= '9')) {
if (raw[p] == '-') { neg = !neg; }
else if (raw[p] == '+') { }
else { ret = ret * 10 + raw[p] - '0'; }
++p;
}
if (neg) { ret = -ret; }
return ret;
};
int a = read();
++p; // parse ','
int b = read();
++p; // parse ','
int cc = read();
++p; // parse ']'
token = ATOM;
tokenVal = Line(a, b, cc);
if (b < 0) { std::swap(tokenVal.s, tokenVal.t); }
return;
} else if (token == '&') {
token = AND; return;
} else if (token == '|') {
token = OR; return;
} else if (token == '^') {
token = XOR; return;
} else if (token == '!') {
token = NOT; return;
} else if (token == '(' || token == ')') {
return;
}
}
};
auto expr1 = [&](auto &self, int level) -> void {
if (token == ATOM) {
std::vector<std::vector<Pt>> npolys; npolys.reserve(polys.size() * 2);
for (auto poly : polys) {
auto [a, b] = hullCut(poly, tokenVal);
npolys.emplace_back(a);
if (!b.empty()) { npolys.emplace_back(b); }
}
std::swap(npolys, polys);
next();
} else if (token == '(') {
next();
self(self, ATOM);
next();
} else if (token == NOT) {
next();
self(self, NOT);
}
while (token >= level) {
if (token == AND) {
next(); self(self, NOT);
} else if (token == OR) {
next(); self(self, NOT);
} else if (token == XOR) {
next(); self(self, NOT);
} else if (token == NOT) {
next(); self(self, NOT);
}
}
};
next(); expr1(expr1, ATOM);
std::vector<bool> stk;
Pt ct;
auto expr2 = [&](auto &self, int level) -> void {
if (token == ATOM) {
stk.emplace_back(side(tokenVal.s, tokenVal.t, ct) >= 0);
next();
} else if (token == '(') {
next();
self(self, ATOM);
next();
} else if (token == NOT) {
next();
self(self, NOT);
stk.back() = !stk.back();
}
while (token >= level) {
if (token == AND) {
next(); self(self, NOT);
bool a = stk.back(); stk.pop_back();
bool b = stk.back(); stk.pop_back();
stk.emplace_back(a & b);
} else if (token == OR) {
next(); self(self, NOT);
bool a = stk.back(); stk.pop_back();
bool b = stk.back(); stk.pop_back();
stk.emplace_back(a | b);
} else if (token == XOR) {
next(); self(self, NOT);
bool a = stk.back(); stk.pop_back();
bool b = stk.back(); stk.pop_back();
stk.emplace_back(a ^ b);
}
}
};
db ret = 0;
for (auto poly : polys) {
ct = polyCenter(poly);
p = 0; next(); expr2(expr2, ATOM);
if (stk.back()) {
for (int i = poly.size() - 1, j = 0; j < poly.size(); i = j++) {
ret += det(poly[i], poly[j]);
}
}
stk.pop_back();
}
std::cout << ret / 2;
return 0;
}