#pragma GCC optimize("O3,unroll-loops")
#pragma GCC target("avx2,bmi,bmi2,lzcnt,popcnt")
#include <bits/stdc++.h>
using namespace std;
#define rep(a, b, c) for (int a = (b); a < (c); a++)
#define all(x) begin(x), end(x)
#define sz(x) int(size(x))
using vi = vector<int>;
using ll = long long;
using pii = pair<int, int>;
const double eps = 1e-9;
template<class T>
struct Point {
using P = Point;
T x, y;
explicit Point(T x=0, T y=0): x(x), y(y) {}
P operator+(P p) const { return P(x+p.x, y+p.y); }
P operator-(P p) const { return P(x-p.x, y-p.y); }
P operator*(T d) const { return P(x*d, y*d); }
P operator/(T d) const { return P(x/d, y/d); }
T dot(P p) const { return x*p.x + y*p.y; }
T cross(P p) const { return x*p.y - y*p.x; }
T cross(P a, P b) const { return (a-*this).cross(b-*this); }
};
template<class P>
pair<int, P> lineInter(P s1, P e1, P s2, P e2) {
auto d = (e1 - s1).cross(e2 - s2);
if (d == 0)
return {-(s1.cross(e1, s2) == 0), P(0, 0)};
auto p = s2.cross(e1, e2), q = s2.cross(e2, s1);
return {1, (s1 * p + e1 * q) / d};
}
typedef Point<double> P;
vector<P> polygonCut(const vector<P>& poly, P s, P e) {
vector<P> res;
rep (i, 0, sz(poly)) {
P cur = poly[i], prev = i ? poly[i-1] : poly.back();
bool side = s.cross(e, cur) < 0;
if (side != (s.cross(e, prev) < 0))
res.push_back(lineInter(s, e, cur, prev).second);
if (side) res.push_back(cur);
}
return res;
}
template<class T>
T polygonArea2(vector<Point<T>>& v) {
T a = v.back().cross(v[0]);
rep (i, 0, sz(v) - 1) a += v[i].cross(v[i+1]);
return a;
}
vector<pair<char, int>> stk;
int ptr = 0;
pair<char, int> pop() { return stk[ptr++]; }
pair<char, int> peek() { return stk[ptr]; }
map<tuple<int, int, int>, int> id;
vector<tuple<int, int, int>> lines;
const int GRPS = 301 * 301;
using bs = bitset<GRPS>;
vector<pair<vector<P>, vector<bool>>> polys;
bs parse() {
auto [c, li] = pop();
if (c == '(') {
if (peek().first == '!') {
pop();
auto x = parse();
assert(pop().first == ')');
return ~x;
}
auto x = parse();
auto op = pop().first;
auto y = parse();
assert(pop().first == ')');
if (op == '&') return x & y;
else if (op == '|') return x | y;
else if (op == '^') return x ^ y;
else assert(0);
}
assert(c == 0);
bs x;
rep (i, 0, sz(polys))
x[i] = polys[i].second[li];
return x;
}
void solve() {
ll xlo, xhi, ylo, yhi;
cin >> xlo >> xhi >> ylo >> yhi;
string in;
cin >> in;
for (int i = 0; i < sz(in); ) {
if (in[i] != '[') {
stk.emplace_back(in[i++], 0);
continue;
}
i++;
int k = 0;
while (in[i+k] != ',') k++;
int a = stoi(in.substr(i, k));
i += k + 1;
k = 0;
while (in[i+k] != ',') k++;
int b = stoi(in.substr(i, k));
i += k + 1;
k = 0;
while (in[i+k] != ']') k++;
int c = stoi(in.substr(i, k));
i += k + 1;
int idx = sz(lines);
lines.emplace_back(a, b, c);
id[lines[idx]] = idx;
stk.emplace_back(0, idx);
}
polys.push_back({{P(xlo, ylo), P(xhi, ylo), P(xhi, yhi), P(xlo, yhi)}, vector<bool>(sz(lines))});
rep (i, 0, sz(lines)) {
auto [a, b, c] = lines[i];
vector<pair<vector<P>, vector<bool>>> nxt;
P dir(b, -a), p0;
if (a != 0) p0 = P(double(-c) / a);
else p0 = P(0, double(-c) / b);
auto p1 = p0 + dir;
for (auto& [poly, sides] : polys) {
auto res = polygonCut(poly, p0, p1);
if (!res.empty()) {
nxt.push_back({res, sides});
nxt.back().second[i] = 0;
}
res = polygonCut(poly, p1, p0);
if (!res.empty()) {
nxt.push_back({res, sides});
nxt.back().second[i] = 1;
}
}
swap(polys, nxt);
}
auto res = parse();
double ans = 0;
rep (i, 0, sz(polys)) if (res[i])
ans += polygonArea2(polys[i].first);
ans /= 2;
cout << setprecision(15) << fixed << ans << "\n";
}
int main() {
cin.tie(0)->sync_with_stdio(0);
cin.exceptions(cin.failbit);
// int t; cin >> t; while (t--)
solve();
return 0;
}
/*
-5 10 -10 5
((!([1,2,-3]&[10,3,-2]))^([-2,3,1]|[5,-2,7]))
*/