#include <bits/stdc++.h>
#define int double
#define PI acos(-1)
using namespace std;
const double eps = 1e-12;

inline int diff(double lhs, double rhs) {
    if (lhs - eps < rhs && rhs < lhs + eps) return 0;
    return (lhs < rhs) ? -1 : 1;
}

inline bool is_between(double check, double a, double b) {
    if (a < b)
        return (a - eps < check && check < b + eps);
    else
        return (b - eps < check && check < a + eps);
}

struct Point {
    double x, y;
    bool operator==(const Point& rhs) const {
        return diff(x, rhs.x) == 0 && diff(y, rhs.y) == 0;
    }
    Point operator+(const Point& rhs) const {
        return Point{ x + rhs.x, y + rhs.y };
    }
    Point operator-(const Point& rhs) const {
        return Point{ x - rhs.x, y - rhs.y };
    }
    Point operator*(double t) const {
        return Point{ x * t, y * t };
    }
};

struct Circle {
    Point center;
    double r;
};

struct Line {
    Point pos, dir;
};

inline double inner(const Point& a, const Point& b) {
    return a.x * b.x + a.y * b.y;
}

inline double outer(const Point& a, const Point& b) {
    return a.x * b.y - a.y * b.x;
}

inline int ccw_line(const Line& line, const Point& point) {
    return diff(outer(line.dir, point - line.pos), 0);
}

inline int ccw(const Point& a, const Point& b, const Point& c) {
    return diff(outer(b - a, c - a), 0);
}

inline double dist(const Point& a, const Point& b) {
    return sqrt(inner(a - b, a - b));
}

inline double dist2(const Point &a, const Point &b) {
    return inner(a - b, a - b);
}

inline double dist(const Line& line, const Point& point, bool segment = false) {
    double c1 = inner(point - line.pos, line.dir);
    if (segment && diff(c1, 0) <= 0) return dist(line.pos, point);
    double c2 = inner(line.dir, line.dir);
    if (segment && diff(c2, c1) <= 0) return dist(line.pos + line.dir, point);
    return dist(line.pos + line.dir * (c1 / c2), point);
}

bool get_cross(const Line& a, const Line& b, Point& ret) {
    double mdet = outer(b.dir, a.dir);
    if (diff(mdet, 0) == 0) return false;
    double t2 = outer(a.dir, b.pos - a.pos) / mdet;
    ret = b.pos + b.dir * t2;
    return true;
}

bool get_segment_cross(const Line& a, const Line& b, Point& ret) {
    double mdet = outer(b.dir, a.dir);
    if (diff(mdet, 0) == 0) return false;
    double t1 = -outer(b.pos - a.pos, b.dir) / mdet;
    double t2 = outer(a.dir, b.pos - a.pos) / mdet;
    if (!is_between(t1, 0, 1) || !is_between(t2, 0, 1)) return false;
    ret = b.pos + b.dir * t2;
    return true;
}

Point inner_center(const Point &a, const Point &b, const Point &c) {
    double wa = dist(b, c), wb = dist(c, a), wc = dist(a, b);
    double w = wa + wb + wc;
    return Point{ (wa * a.x + wb * b.x + wc * c.x) / w, (wa * a.y + wb * b.y + wc * c.y) / w };
}

Point outer_center(const Point &a, const Point &b, const Point &c) {
    Point d1 = b - a, d2 = c - a;
    double area = outer(d1, d2);
    double dx = d1.x * d1.x * d2.y - d2.x * d2.x * d1.y
        + d1.y * d2.y * (d1.y - d2.y);
    double dy = d1.y * d1.y * d2.x - d2.y * d2.y * d1.x
        + d1.x * d2.x * (d1.x - d2.y);
    return Point{ a.x + dx / area / 2.0, a.y - dy / area / 2.0 };
}

vector<Point> circle_line(const Circle& circle, const Line& line) {
    vector<Point> result;
    double a = 2 * inner(line.dir, line.dir);
    double b = 2 * (line.dir.x * (line.pos.x - circle.center.x)
        + line.dir.y * (line.pos.y - circle.center.y));
    double c = inner(line.pos - circle.center, line.pos - circle.center)
        - circle.r * circle.r;
    double det = b * b - 2 * a * c;
    int pred = diff(det, 0);
    if (pred == 0)
        result.push_back(line.pos + line.dir * (-b / a));
    else if (pred > 0) {
        det = sqrt(det);
        result.push_back(line.pos + line.dir * ((-b + det) / a));
        result.push_back(line.pos + line.dir * ((-b - det) / a));
    }
    return result;
}

vector<Point> circle_circle(const Circle& a, const Circle& b) {
    vector<Point> result;
    double aa = a.center.x * a.center.x + a.center.y * a.center.y - a.r * a.r;
    double bb = b.center.x * b.center.x + b.center.y * b.center.y - b.r * b.r;
    double tmp = (bb - aa) / 2.0;
    Point cdiff = b.center - a.center;
    if (diff(cdiff.x, 0) == 0) {
        if (diff(cdiff.y, 0) == 0) {
            return result;
        }
        return circle_line(a, Line{ Point{ 0, tmp / cdiff.y }, Point{ 1, 0 } });
    }
    return circle_line(a,
        Line{ Point{ tmp / cdiff.x, 0 }, Point{ -cdiff.y, cdiff.x } });
}

Point ret;
Circle a, b;
signed main() {
    cin>>a.center.x>>a.center.y>>a.r;
    cin>>b.center.x>>b.center.y>>b.r;
    int pred = diff(dist(a.center, b.center), a.r + b.r);
    if (pred >= 0) return puts("0");
    auto r = circle_circle(a, b);
    if(dist(a.center, b.center && !r.size()) <= max(a.r - b.r, b.r - a.r))
        return printf("%.15f\n", min(a.r, b.r) * min(a.r, b.r) * PI) % 1;
    auto p = r.front(), q = r.back();
    double d = dist(p, q);
    double sa = asin(d / 2 / a.r) * 2;
    double sb = asin(d / 2 / b.r) * 2;
    assert(r.size() == 2);
    if(get_segment_cross(Line{a.center, b.center - a.center}, Line{p, q - p}, ret)){
        return printf("%.15f\n", a.r * a.r * sa / 2 + b.r * b.r * sb / 2 - a.r * a.r * sin(sa) / 2 - b.r * b.r * sin(sb) / 2) % 1;
    }
    if(dist(Line{p, q - p}, a.center, true) < dist(Line{p, q - p}, b.center, true))
        return printf("%.15f\n", a.r * a.r * (PI - sa / 2) + b.r * b.r * sb / 2 + a.r * a.r * sin(sa) / 2 - b.r * b.r * sin(sb) / 2) % 1;
    return printf("%.15f\n", a.r * a.r * sa / 2 + b.r * b.r * (PI - sb / 2) - a.r * a.r * sin(sa) / 2 + b.r * b.r * sin(sb) / 2) % 1;
}


#include <bits/stdc++.h>
#define PI acos(-1)
using namespace std;
const double eps = 1e-9;

inline int diff(double lhs, double rhs) {
    if (lhs - eps < rhs && rhs < lhs + eps) return 0;
    return (lhs < rhs) ? -1 : 1;
}

inline bool is_between(double check, double a, double b) {
    if (a < b)
        return (a - eps < check && check < b + eps);
    else
        return (b - eps < check && check < a + eps);
}

struct Point {
    double x, y;
    bool operator==(const Point& rhs) const {
        return diff(x, rhs.x) == 0 && diff(y, rhs.y) == 0;
    }
    Point operator+(const Point& rhs) const {
        return Point{ x + rhs.x, y + rhs.y };
    }
    Point operator-(const Point& rhs) const {
        return Point{ x - rhs.x, y - rhs.y };
    }
    Point operator*(double t) const {
        return Point{ x * t, y * t };
    }
};

struct Circle {
    Point center;
    double r;
};

struct Line {
    Point pos, dir;
};

inline double inner(const Point& a, const Point& b) {
    return a.x * b.x + a.y * b.y;
}

inline double outer(const Point& a, const Point& b) {
    return a.x * b.y - a.y * b.x;
}

inline int ccw_line(const Line& line, const Point& point) {
    return diff(outer(line.dir, point - line.pos), 0);
}

inline int ccw(const Point& a, const Point& b, const Point& c) {
    return diff(outer(b - a, c - a), 0);
}

inline double dist(const Point& a, const Point& b) {
    return sqrt(inner(a - b, a - b));
}

inline double dist2(const Point &a, const Point &b) {
    return inner(a - b, a - b);
}

inline double dist(const Line& line, const Point& point, bool segment = false) {
    double c1 = inner(point - line.pos, line.dir);
    if (segment && diff(c1, 0) <= 0) return dist(line.pos, point);
    double c2 = inner(line.dir, line.dir);
    if (segment && diff(c2, c1) <= 0) return dist(line.pos + line.dir, point);
    return dist(line.pos + line.dir * (c1 / c2), point);
}

bool get_cross(const Line& a, const Line& b, Point& ret) {
    double mdet = outer(b.dir, a.dir);
    if (diff(mdet, 0) == 0) return false;
    double t2 = outer(a.dir, b.pos - a.pos) / mdet;
    ret = b.pos + b.dir * t2;
    return true;
}

bool get_segment_cross(const Line& a, const Line& b, Point& ret) {
    double mdet = outer(b.dir, a.dir);
    if (diff(mdet, 0) == 0) return false;
    double t1 = -outer(b.pos - a.pos, b.dir) / mdet;
    double t2 = outer(a.dir, b.pos - a.pos) / mdet;
    if (!is_between(t1, 0, 1) || !is_between(t2, 0, 1)) return false;
    ret = b.pos + b.dir * t2;
    return true;
}

Point inner_center(const Point &a, const Point &b, const Point &c) {
    double wa = dist(b, c), wb = dist(c, a), wc = dist(a, b);
    double w = wa + wb + wc;
    return Point{ (wa * a.x + wb * b.x + wc * c.x) / w, (wa * a.y + wb * b.y + wc * c.y) / w };
}

Point outer_center(const Point &a, const Point &b, const Point &c) {
    Point d1 = b - a, d2 = c - a;
    double area = outer(d1, d2);
    double dx = d1.x * d1.x * d2.y - d2.x * d2.x * d1.y
        + d1.y * d2.y * (d1.y - d2.y);
    double dy = d1.y * d1.y * d2.x - d2.y * d2.y * d1.x
        + d1.x * d2.x * (d1.x - d2.y);
    return Point{ a.x + dx / area / 2.0, a.y - dy / area / 2.0 };
}

vector<Point> circle_line(const Circle& circle, const Line& line) {
    vector<Point> result;
    double a = 2 * inner(line.dir, line.dir);
    double b = 2 * (line.dir.x * (line.pos.x - circle.center.x)
        + line.dir.y * (line.pos.y - circle.center.y));
    double c = inner(line.pos - circle.center, line.pos - circle.center)
        - circle.r * circle.r;
    double det = b * b - 2 * a * c;
    int pred = diff(det, 0);
    if (pred == 0)
        result.push_back(line.pos + line.dir * (-b / a));
    else if (pred > 0) {
        det = sqrt(det);
        result.push_back(line.pos + line.dir * ((-b + det) / a));
        result.push_back(line.pos + line.dir * ((-b - det) / a));
    }
    return result;
}

vector<Point> circle_circle(const Circle& a, const Circle& b) {
    vector<Point> result;
    double aa = a.center.x * a.center.x + a.center.y * a.center.y - a.r * a.r;
    double bb = b.center.x * b.center.x + b.center.y * b.center.y - b.r * b.r;
    double tmp = (bb - aa) / 2.0;
    Point cdiff = b.center - a.center;
    if (diff(cdiff.x, 0) == 0) {
        if (diff(cdiff.y, 0) == 0) {
            return result;
        }
        return circle_line(a, Line{ Point{ 0, tmp / cdiff.y }, Point{ 1, 0 } });
    }
    return circle_line(a,
        Line{ Point{ tmp / cdiff.x, 0 }, Point{ -cdiff.y, cdiff.x } });
}

Point ret;
Circle a, b;
int main() {
    cin>>a.center.x>>a.center.y>>a.r;
    cin>>b.center.x>>b.center.y>>b.r;
    int pred = diff(dist(a.center, b.center), a.r + b.r);
    if (pred >= 0) return puts("0");
    auto r = circle_circle(a, b);
    if(dist(a.center, b.center) <= max(a.r - b.r, b.r - a.r)) return printf("%.15f\n", min(a.r, b.r) * min(a.r, b.r) * PI) % 1;
    auto p = r.front(), q = r.back();
    double d = dist(p, q);
    double sa = asin(d / 2 / a.r) * 2;
    double sb = asin(d / 2 / b.r) * 2;
    if(get_segment_cross(Line{a.center, b.center}, Line{p, q}, ret)) {
        return printf("%.15f\n", a.r * a.r * sa / 2 + b.r * b.r * sb / 2 - a.r * a.r * sin(sa) / 2 - b.r * b.r * sin(sb) / 2) % 1;
    }
    if(dist(Line{p, q}, a.center, true) < dist(Line{p, q}, b.center, true))
        return printf("%.15f\n", a.r * a.r * (PI - sa / 2) + b.r * b.r * sb / 2 - a.r * a.r * sin(sa) / 2 - b.r * b.r * sin(sb) / 2) % 1;
    return printf("%.15f\n", a.r * a.r * sa / 2 + b.r * b.r * (PI - sb / 2) - a.r * a.r * sin(sa) / 2 - b.r * b.r * sin(sb) / 2) % 1;
}


#include <bits/stdc++.h>
using namespace std;
#define PI acos(-1)
long long x1, y1, r1;
long long x2, y2, r2;
const double eps = 1e-15;

double dist(long long x1, long long y1, long long x2, long long y2) {
    return sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2));
}
int main() {
    cin>>x1>>y1>>r1;
    cin>>x2>>y2>>r2;

    double cd = dist(x1, y1, x2, y2);
    if(r1 + r2 - eps <= cd) return puts("0");
    if(cd + r2 - eps  <= r1) {
        return printf("%.15f",  r2 * r2 * PI) % 1;
    }
    if(cd + r1 - eps  <= r2) {
        return printf("%.15f",  r1 * r1 * PI) % 1;
    }
    double s = (cd + r1 + r2) / 2;
    double ts = sqrt(s) * sqrt(s - cd) * sqrt(s - r1) * sqrt(s - r2);
    double t1 = (-r2 * r2 + cd * cd + r1 * r1) / 2 / cd / r1;
    double t2 = (-r1 * r1 + cd * cd + r2 * r2) / 2 / cd / r2;
    return printf("%.15f", r1 * r1 * acos(t1) + r2 * r2 * acos(t2) - ts * 2) % 1;
}


#include <bits/stdc++.h>
#define PI acos(-1)
using namespace std;
const double eps = 1e-15;

bool xxx;
inline int diff(double lhs, double rhs) {
    if (lhs - eps < rhs && rhs < lhs + eps) return 0;
    return (lhs < rhs) ? -1 : 1;
}

inline bool is_between(double check, double a, double b) {
    if (a < b)
        return (a - eps < check && check < b + eps);
    else
        return (b - eps < check && check < a + eps);
}

struct Point {
    double x, y;
    bool operator==(const Point& rhs) const {
        return diff(x, rhs.x) == 0 && diff(y, rhs.y) == 0;
    }
    Point operator+(const Point& rhs) const {
        return Point{ x + rhs.x, y + rhs.y };
    }
    Point operator-(const Point& rhs) const {
        return Point{ x - rhs.x, y - rhs.y };
    }
    Point operator*(double t) const {
        return Point{ x * t, y * t };
    }
};

struct Circle {
    Point center;
    double r;
};

struct Line {
    Point pos, dir;
};

inline double inner(const Point& a, const Point& b) {
    return a.x * b.x + a.y * b.y;
}

inline double outer(const Point& a, const Point& b) {
    return a.x * b.y - a.y * b.x;
}

inline int ccw_line(const Line& line, const Point& point) {
    return diff(outer(line.dir, point - line.pos), 0);
}

inline int ccw(const Point& a, const Point& b, const Point& c) {
    return diff(outer(b - a, c - a), 0);
}

inline double dist(const Point& a, const Point& b) {
    return sqrt(inner(a - b, a - b));
}

inline double dist2(const Point &a, const Point &b) {
    return inner(a - b, a - b);
}

inline double dist(const Line& line, const Point& point, bool segment = false) {
    double c1 = inner(point - line.pos, line.dir);
    if (segment && diff(c1, 0) <= 0) return dist(line.pos, point);
    double c2 = inner(line.dir, line.dir);
    if (segment && diff(c2, c1) <= 0) return dist(line.pos + line.dir, point);
    return dist(line.pos + line.dir * (c1 / c2), point);
}

bool get_cross(const Line& a, const Line& b, Point& ret) {
    double mdet = outer(b.dir, a.dir);
    if (diff(mdet, 0) == 0) return false;
    double t2 = outer(a.dir, b.pos - a.pos) / mdet;
    ret = b.pos + b.dir * t2;
    return true;
}

bool get_segment_cross(const Line& a, const Line& b, Point& ret) {
    double mdet = outer(b.dir, a.dir);
    if (diff(mdet, 0) == 0) return false;
    double t1 = -outer(b.pos - a.pos, b.dir) / mdet;
    double t2 = outer(a.dir, b.pos - a.pos) / mdet;
    if (!is_between(t1, 0, 1) || !is_between(t2, 0, 1)) return false;
    ret = b.pos + b.dir * t2;
    return true;
}

Point inner_center(const Point &a, const Point &b, const Point &c) {
    double wa = dist(b, c), wb = dist(c, a), wc = dist(a, b);
    double w = wa + wb + wc;
    return Point{ (wa * a.x + wb * b.x + wc * c.x) / w, (wa * a.y + wb * b.y + wc * c.y) / w };
}

Point outer_center(const Point &a, const Point &b, const Point &c) {
    Point d1 = b - a, d2 = c - a;
    double area = outer(d1, d2);
    double dx = d1.x * d1.x * d2.y - d2.x * d2.x * d1.y
        + d1.y * d2.y * (d1.y - d2.y);
    double dy = d1.y * d1.y * d2.x - d2.y * d2.y * d1.x
        + d1.x * d2.x * (d1.x - d2.y);
    return Point{ a.x + dx / area / 2.0, a.y - dy / area / 2.0 };
}

vector<Point> circle_line(const Circle& circle, const Line& line) {
    vector<Point> result;
    double a = 2 * inner(line.dir, line.dir);
    double b = 2 * (line.dir.x * (line.pos.x - circle.center.x)
        + line.dir.y * (line.pos.y - circle.center.y));
    double c = inner(line.pos - circle.center, line.pos - circle.center)
        - circle.r * circle.r;
    double det = b * b - 2 * a * c;
    if (xxx) printf("%.15f %.15f\n", b * b, 2 * a * c);
    int pred = diff(det, 0);
    if (xxx) printf("%d %.15f\n", pred, det);
    if (xxx) printf("%.15f %.15f %.15f\n", a, b, c);
    if (pred == 0)
        result.push_back(line.pos + line.dir * (-b / a));
    else if (pred > 0) {
        det = sqrt(det);
        result.push_back(line.pos + line.dir * ((-b + det) / a));
        result.push_back(line.pos + line.dir * ((-b - det) / a));
    }
    return result;
}

vector<Point> circle_circle(const Circle& a, const Circle& b) {
    vector<Point> result;
    double aa = a.center.x * a.center.x + a.center.y * a.center.y - a.r * a.r;
    double bb = b.center.x * b.center.x + b.center.y * b.center.y - b.r * b.r;
    double tmp = (bb - aa) / 2.0;
    Point cdiff = b.center - a.center;
    if (diff(cdiff.x, 0) == 0) {
        if (diff(cdiff.y, 0) == 0) {
            return result;
        }
        return circle_line(a, Line{ Point{ 0, tmp / cdiff.y }, Point{ 1, 0 } });
    }
    auto p = Point{ -cdiff.y, cdiff.x };
    return circle_line(a,
        Line{ Point{ tmp / cdiff.x, 0 }, p * (1 / dist(p, Point{0, 0}))});
}

double cs(double r, double h) {
    return r * r * h;
}

double ts(double a, double b) {
    return sqrt(a + b / 2) * sqrt(a - b / 2) * b / 2;
}

Point ret;
Circle a, b;
signed main() {
    cin>>a.center.x>>a.center.y>>a.r;
    cin>>b.center.x>>b.center.y>>b.r;
    xxx = (a.center.x == 44721);
    double norm = 1e9;
    a.center.x /= norm;
    a.center.y /= norm;
    b.center.x /= norm;
    b.center.y /= norm;
    a.r /= norm;
    b.r /= norm;
    int pred = diff(dist(a.center, b.center), a.r + b.r);
    if (pred >= 0) return puts("0");
    auto r = circle_circle(a, b);
    double cc = dist(a.center, b.center);
    if (xxx) printf("1\n");
    if(cc <= max(a.r - b.r, b.r - a.r) || !r.size())
        return printf("%.15f\n", (min(a.r, b.r) * min(a.r, b.r) * PI) * norm * norm) % 1;
    if (xxx) printf("2\n");
    auto p = r.front(), q = r.back();
    double d = sqrt(abs(-cc + a.r - b.r)) * sqrt(abs(-cc - a.r + b.r)) * sqrt(-cc + a.r + b.r) * sqrt(cc + a.r + b.r) / cc;
    double sa = asin(d / 2 / a.r);
    double sb = asin(d / 2 / b.r);
    if (xxx) printf("3\n");
    if(get_segment_cross(Line{a.center, b.center - a.center}, Line{p, q - p}, ret)){
        return printf("%.15f\n", (cs(a.r, sa) + cs(b.r, sb) - ts(a.r, d) - ts(b.r, d)) * norm * norm) % 1;
    }
    if (xxx) printf("4\n");
    if(dist(Line{p, q - p}, a.center, true) < dist(Line{p, q - p}, b.center, true))
        return printf("%.15f\n", (cs(a.r, PI - sa) + cs(b.r, sb) + ts(a.r, d) - ts(b.r, d)) * norm * norm) % 1;
    if (xxx) printf("5\n");
    return printf("%.15f\n", (cs(a.r, sa) + cs(b.r, PI - sb) - ts(a.r, d) + ts(b.r, d)) * norm * norm) % 1;
}


#include <bits/stdc++.h>
#define int long long
#define PI acos(-1)
using namespace std;
const double eps = 1e-9;

inline int diff(double lhs, double rhs) {
    if (lhs - eps < rhs && rhs < lhs + eps) return 0;
    return (lhs < rhs) ? -1 : 1;
}

inline bool is_between(double check, double a, double b) {
    if (a < b)
        return (a - eps < check && check < b + eps);
    else
        return (b - eps < check && check < a + eps);
}

struct Point {
    double x, y;
    bool operator==(const Point& rhs) const {
        return diff(x, rhs.x) == 0 && diff(y, rhs.y) == 0;
    }
    Point operator+(const Point& rhs) const {
        return Point{ x + rhs.x, y + rhs.y };
    }
    Point operator-(const Point& rhs) const {
        return Point{ x - rhs.x, y - rhs.y };
    }
    Point operator*(double t) const {
        return Point{ x * t, y * t };
    }
};

struct Circle {
    Point center;
    double r;
};

struct Line {
    Point pos, dir;
};

inline double inner(const Point& a, const Point& b) {
    return a.x * b.x + a.y * b.y;
}

inline double outer(const Point& a, const Point& b) {
    return a.x * b.y - a.y * b.x;
}

inline int ccw_line(const Line& line, const Point& point) {
    return diff(outer(line.dir, point - line.pos), 0);
}

inline int ccw(const Point& a, const Point& b, const Point& c) {
    return diff(outer(b - a, c - a), 0);
}

inline double dist(const Point& a, const Point& b) {
    return sqrt(inner(a - b, a - b));
}

inline double dist2(const Point &a, const Point &b) {
    return inner(a - b, a - b);
}

inline double dist(const Line& line, const Point& point, bool segment = false) {
    double c1 = inner(point - line.pos, line.dir);
    if (segment && diff(c1, 0) <= 0) return dist(line.pos, point);
    double c2 = inner(line.dir, line.dir);
    if (segment && diff(c2, c1) <= 0) return dist(line.pos + line.dir, point);
    return dist(line.pos + line.dir * (c1 / c2), point);
}

bool get_cross(const Line& a, const Line& b, Point& ret) {
    double mdet = outer(b.dir, a.dir);
    if (diff(mdet, 0) == 0) return false;
    double t2 = outer(a.dir, b.pos - a.pos) / mdet;
    ret = b.pos + b.dir * t2;
    return true;
}

bool get_segment_cross(const Line& a, const Line& b, Point& ret) {
    double mdet = outer(b.dir, a.dir);
    if (diff(mdet, 0) == 0) return false;
    double t1 = -outer(b.pos - a.pos, b.dir) / mdet;
    double t2 = outer(a.dir, b.pos - a.pos) / mdet;
    if (!is_between(t1, 0, 1) || !is_between(t2, 0, 1)) return false;
    ret = b.pos + b.dir * t2;
    return true;
}

Point inner_center(const Point &a, const Point &b, const Point &c) {
    double wa = dist(b, c), wb = dist(c, a), wc = dist(a, b);
    double w = wa + wb + wc;
    return Point{ (wa * a.x + wb * b.x + wc * c.x) / w, (wa * a.y + wb * b.y + wc * c.y) / w };
}

Point outer_center(const Point &a, const Point &b, const Point &c) {
    Point d1 = b - a, d2 = c - a;
    double area = outer(d1, d2);
    double dx = d1.x * d1.x * d2.y - d2.x * d2.x * d1.y
        + d1.y * d2.y * (d1.y - d2.y);
    double dy = d1.y * d1.y * d2.x - d2.y * d2.y * d1.x
        + d1.x * d2.x * (d1.x - d2.y);
    return Point{ a.x + dx / area / 2.0, a.y - dy / area / 2.0 };
}

vector<Point> circle_line(const Circle& circle, const Line& line) {
    vector<Point> result;
    double a = 2 * inner(line.dir, line.dir);
    double b = 2 * (line.dir.x * (line.pos.x - circle.center.x)
        + line.dir.y * (line.pos.y - circle.center.y));
    double c = inner(line.pos - circle.center, line.pos - circle.center)
        - circle.r * circle.r;
    double det = b * b - 2 * a * c;
    int pred = diff(det, 0);
    if (pred == 0)
        result.push_back(line.pos + line.dir * (-b / a));
    else if (pred > 0) {
        det = sqrt(det);
        result.push_back(line.pos + line.dir * ((-b + det) / a));
        result.push_back(line.pos + line.dir * ((-b - det) / a));
    }
    return result;
}

vector<Point> circle_circle(const Circle& a, const Circle& b) {
    vector<Point> result;
    double aa = a.center.x * a.center.x + a.center.y * a.center.y - a.r * a.r;
    double bb = b.center.x * b.center.x + b.center.y * b.center.y - b.r * b.r;
    double tmp = (bb - aa) / 2.0;
    Point cdiff = b.center - a.center;
    if (diff(cdiff.x, 0) == 0) {
        if (diff(cdiff.y, 0) == 0) {
            return result;
        }
        return circle_line(a, Line{ Point{ 0, tmp / cdiff.y }, Point{ 1, 0 } });
    }
    return circle_line(a,
        Line{ Point{ tmp / cdiff.x, 0 }, Point{ -cdiff.y, cdiff.x } });
}

Point ret;
Circle a, b;
signed main() {
    cin>>a.center.x>>a.center.y>>a.r;
    cin>>b.center.x>>b.center.y>>b.r;
    int pred = diff(dist(a.center, b.center), a.r + b.r);
    if (pred >= 0) return puts("0");
    auto r = circle_circle(a, b);
    if(dist(a.center, b.center) <= max(a.r - b.r, b.r - a.r)) return printf("%.15f\n", min(a.r, b.r) * min(a.r, b.r) * PI) % 1;
    auto p = r.front(), q = r.back();
    double d = dist(p, q);
    double sa = asin(d / 2 / a.r) * 2;
    double sb = asin(d / 2 / b.r) * 2;
    if(get_segment_cross(Line{a.center, b.center - a.center}, Line{p, q - p}, ret))
        return printf("%.15f\n", a.r * a.r * sa / 2 + b.r * b.r * sb / 2 - a.r * a.r * sin(sa) / 2 - b.r * b.r * sin(sb) / 2) % 1;
    if(dist(Line{p, q - p}, a.center, true) < dist(Line{p, q - p}, b.center, true))
        return printf("%.15f\n", a.r * a.r * (PI - sa / 2) + b.r * b.r * sb / 2 + a.r * a.r * sin(sa) / 2 - b.r * b.r * sin(sb) / 2) % 1;
    return printf("%.15f\n", a.r * a.r * sa / 2 + b.r * b.r * (PI - sb / 2) - a.r * a.r * sin(sa) / 2 + b.r * b.r * sin(sb) / 2) % 1;
}


#include <bits/stdc++.h>
#define int long long
#define PI acos(-1)
using namespace std;
const double eps = 1e-12;

inline int diff(double lhs, double rhs) {
    if (lhs - eps < rhs && rhs < lhs + eps) return 0;
    return (lhs < rhs) ? -1 : 1;
}

inline bool is_between(double check, double a, double b) {
    if (a < b)
        return (a - eps < check && check < b + eps);
    else
        return (b - eps < check && check < a + eps);
}

struct Point {
    double x, y;
    bool operator==(const Point& rhs) const {
        return diff(x, rhs.x) == 0 && diff(y, rhs.y) == 0;
    }
    Point operator+(const Point& rhs) const {
        return Point{ x + rhs.x, y + rhs.y };
    }
    Point operator-(const Point& rhs) const {
        return Point{ x - rhs.x, y - rhs.y };
    }
    Point operator*(double t) const {
        return Point{ x * t, y * t };
    }
};

struct Circle {
    Point center;
    double r;
};

struct Line {
    Point pos, dir;
};

inline double inner(const Point& a, const Point& b) {
    return a.x * b.x + a.y * b.y;
}

inline double outer(const Point& a, const Point& b) {
    return a.x * b.y - a.y * b.x;
}

inline int ccw_line(const Line& line, const Point& point) {
    return diff(outer(line.dir, point - line.pos), 0);
}

inline int ccw(const Point& a, const Point& b, const Point& c) {
    return diff(outer(b - a, c - a), 0);
}

inline double dist(const Point& a, const Point& b) {
    return sqrt(inner(a - b, a - b));
}

inline double dist2(const Point &a, const Point &b) {
    return inner(a - b, a - b);
}

inline double dist(const Line& line, const Point& point, bool segment = false) {
    double c1 = inner(point - line.pos, line.dir);
    if (segment && diff(c1, 0) <= 0) return dist(line.pos, point);
    double c2 = inner(line.dir, line.dir);
    if (segment && diff(c2, c1) <= 0) return dist(line.pos + line.dir, point);
    return dist(line.pos + line.dir * (c1 / c2), point);
}

bool get_cross(const Line& a, const Line& b, Point& ret) {
    double mdet = outer(b.dir, a.dir);
    if (diff(mdet, 0) == 0) return false;
    double t2 = outer(a.dir, b.pos - a.pos) / mdet;
    ret = b.pos + b.dir * t2;
    return true;
}

bool get_segment_cross(const Line& a, const Line& b, Point& ret) {
    double mdet = outer(b.dir, a.dir);
    if (diff(mdet, 0) == 0) return false;
    double t1 = -outer(b.pos - a.pos, b.dir) / mdet;
    double t2 = outer(a.dir, b.pos - a.pos) / mdet;
    if (!is_between(t1, 0, 1) || !is_between(t2, 0, 1)) return false;
    ret = b.pos + b.dir * t2;
    return true;
}

Point inner_center(const Point &a, const Point &b, const Point &c) {
    double wa = dist(b, c), wb = dist(c, a), wc = dist(a, b);
    double w = wa + wb + wc;
    return Point{ (wa * a.x + wb * b.x + wc * c.x) / w, (wa * a.y + wb * b.y + wc * c.y) / w };
}

Point outer_center(const Point &a, const Point &b, const Point &c) {
    Point d1 = b - a, d2 = c - a;
    double area = outer(d1, d2);
    double dx = d1.x * d1.x * d2.y - d2.x * d2.x * d1.y
        + d1.y * d2.y * (d1.y - d2.y);
    double dy = d1.y * d1.y * d2.x - d2.y * d2.y * d1.x
        + d1.x * d2.x * (d1.x - d2.y);
    return Point{ a.x + dx / area / 2.0, a.y - dy / area / 2.0 };
}

vector<Point> circle_line(const Circle& circle, const Line& line) {
    vector<Point> result;
    double a = 2 * inner(line.dir, line.dir);
    double b = 2 * (line.dir.x * (line.pos.x - circle.center.x)
        + line.dir.y * (line.pos.y - circle.center.y));
    double c = inner(line.pos - circle.center, line.pos - circle.center)
        - circle.r * circle.r;
    double det = b * b - 2 * a * c;
    int pred = diff(det, 0);
    if (pred == 0)
        result.push_back(line.pos + line.dir * (-b / a));
    else if (pred > 0) {
        det = sqrt(det);
        result.push_back(line.pos + line.dir * ((-b + det) / a));
        result.push_back(line.pos + line.dir * ((-b - det) / a));
    }
    return result;
}

vector<Point> circle_circle(const Circle& a, const Circle& b) {
    vector<Point> result;
    double aa = a.center.x * a.center.x + a.center.y * a.center.y - a.r * a.r;
    double bb = b.center.x * b.center.x + b.center.y * b.center.y - b.r * b.r;
    double tmp = (bb - aa) / 2.0;
    Point cdiff = b.center - a.center;
    if (diff(cdiff.x, 0) == 0) {
        if (diff(cdiff.y, 0) == 0) {
            return result;
        }
        return circle_line(a, Line{ Point{ 0, tmp / cdiff.y }, Point{ 1, 0 } });
    }
    return circle_line(a,
        Line{ Point{ tmp / cdiff.x, 0 }, Point{ -cdiff.y, cdiff.x } });
}

Point ret;
Circle a, b;
signed main() {
    cin>>a.center.x>>a.center.y>>a.r;
    cin>>b.center.x>>b.center.y>>b.r;
    int pred = diff(dist(a.center, b.center), a.r + b.r);
    if (pred >= 0) return puts("0");
    auto r = circle_circle(a, b);
    if(dist(a.center, b.center) <= max(a.r - b.r, b.r - a.r)) return printf("%.15f\n", min(a.r, b.r) * min(a.r, b.r) * PI) % 1;
    auto p = r.front(), q = r.back();
    double d = dist(p, q);
    double sa = asin(d / 2 / a.r) * 2;
    double sb = asin(d / 2 / b.r) * 2;
    if(get_segment_cross(Line{a.center, b.center}, Line{p, q}, ret)) {
        return printf("%.15f\n", a.r * a.r * sa / 2 + b.r * b.r * sb / 2 - a.r * a.r * sin(sa) / 2 - b.r * b.r * sin(sb) / 2) % 1;
    }
    if(dist(Line{p, q}, a.center, true) < dist(Line{p, q}, b.center, true))
        return printf("%.15f\n", a.r * a.r * (PI - sa / 2) + b.r * b.r * sb / 2 - a.r * a.r * sin(sa) / 2 - b.r * b.r * sin(sb) / 2) % 1;
    return printf("%.15f\n", a.r * a.r * sa / 2 + b.r * b.r * (PI - sb / 2) - a.r * a.r * sin(sa) / 2 - b.r * b.r * sin(sb) / 2) % 1;
}


#include <bits/stdc++.h>
#define PI acos(-1)
using namespace std;
const double eps = 1e-9;

inline int diff(double lhs, double rhs) {
    if (lhs - eps < rhs && rhs < lhs + eps) return 0;
    return (lhs < rhs) ? -1 : 1;
}

inline bool is_between(double check, double a, double b) {
    if (a < b)
        return (a - eps < check && check < b + eps);
    else
        return (b - eps < check && check < a + eps);
}

struct Point {
    double x, y;
    bool operator==(const Point& rhs) const {
        return diff(x, rhs.x) == 0 && diff(y, rhs.y) == 0;
    }
    Point operator+(const Point& rhs) const {
        return Point{ x + rhs.x, y + rhs.y };
    }
    Point operator-(const Point& rhs) const {
        return Point{ x - rhs.x, y - rhs.y };
    }
    Point operator*(double t) const {
        return Point{ x * t, y * t };
    }
};

struct Circle {
    Point center;
    double r;
};

struct Line {
    Point pos, dir;
};

inline double inner(const Point& a, const Point& b) {
    return a.x * b.x + a.y * b.y;
}

inline double outer(const Point& a, const Point& b) {
    return a.x * b.y - a.y * b.x;
}

inline int ccw_line(const Line& line, const Point& point) {
    return diff(outer(line.dir, point - line.pos), 0);
}

inline int ccw(const Point& a, const Point& b, const Point& c) {
    return diff(outer(b - a, c - a), 0);
}

inline double dist(const Point& a, const Point& b) {
    return sqrt(inner(a - b, a - b));
}

inline double dist2(const Point &a, const Point &b) {
    return inner(a - b, a - b);
}

inline double dist(const Line& line, const Point& point, bool segment = false) {
    double c1 = inner(point - line.pos, line.dir);
    if (segment && diff(c1, 0) <= 0) return dist(line.pos, point);
    double c2 = inner(line.dir, line.dir);
    if (segment && diff(c2, c1) <= 0) return dist(line.pos + line.dir, point);
    return dist(line.pos + line.dir * (c1 / c2), point);
}

bool get_cross(const Line& a, const Line& b, Point& ret) {
    double mdet = outer(b.dir, a.dir);
    if (diff(mdet, 0) == 0) return false;
    double t2 = outer(a.dir, b.pos - a.pos) / mdet;
    ret = b.pos + b.dir * t2;
    return true;
}

bool get_segment_cross(const Line& a, const Line& b, Point& ret) {
    double mdet = outer(b.dir, a.dir);
    if (diff(mdet, 0) == 0) return false;
    double t1 = -outer(b.pos - a.pos, b.dir) / mdet;
    double t2 = outer(a.dir, b.pos - a.pos) / mdet;
    if (!is_between(t1, 0, 1) || !is_between(t2, 0, 1)) return false;
    ret = b.pos + b.dir * t2;
    return true;
}

Point inner_center(const Point &a, const Point &b, const Point &c) {
    double wa = dist(b, c), wb = dist(c, a), wc = dist(a, b);
    double w = wa + wb + wc;
    return Point{ (wa * a.x + wb * b.x + wc * c.x) / w, (wa * a.y + wb * b.y + wc * c.y) / w };
}

Point outer_center(const Point &a, const Point &b, const Point &c) {
    Point d1 = b - a, d2 = c - a;
    double area = outer(d1, d2);
    double dx = d1.x * d1.x * d2.y - d2.x * d2.x * d1.y
        + d1.y * d2.y * (d1.y - d2.y);
    double dy = d1.y * d1.y * d2.x - d2.y * d2.y * d1.x
        + d1.x * d2.x * (d1.x - d2.y);
    return Point{ a.x + dx / area / 2.0, a.y - dy / area / 2.0 };
}

vector<Point> circle_line(const Circle& circle, const Line& line) {
    vector<Point> result;
    double a = 2 * inner(line.dir, line.dir);
    double b = 2 * (line.dir.x * (line.pos.x - circle.center.x)
        + line.dir.y * (line.pos.y - circle.center.y));
    double c = inner(line.pos - circle.center, line.pos - circle.center)
        - circle.r * circle.r;
    double det = b * b - 2 * a * c;
    int pred = diff(det, 0);
    if (pred == 0)
        result.push_back(line.pos + line.dir * (-b / a));
    else if (pred > 0) {
        det = sqrt(det);
        result.push_back(line.pos + line.dir * ((-b + det) / a));
        result.push_back(line.pos + line.dir * ((-b - det) / a));
    }
    return result;
}

vector<Point> circle_circle(const Circle& a, const Circle& b) {
    vector<Point> result;
    int pred = diff(dist(a.center, b.center), a.r + b.r);
    if (pred >= 0) {
        result.push_back(Point {0, 0});
        result.push_back(Point {0, 0});
        result.push_back(Point {0, 0});
        return result;
    }
    double aa = a.center.x * a.center.x + a.center.y * a.center.y - a.r * a.r;
    double bb = b.center.x * b.center.x + b.center.y * b.center.y - b.r * b.r;
    double tmp = (bb - aa) / 2.0;
    Point cdiff = b.center - a.center;
    if (diff(cdiff.x, 0) == 0) {
        if (diff(cdiff.y, 0) == 0) {
            return result;
        }
        return circle_line(a, Line{ Point{ 0, tmp / cdiff.y }, Point{ 1, 0 } });
    }
    return circle_line(a,
        Line{ Point{ tmp / cdiff.x, 0 }, Point{ -cdiff.y, cdiff.x } });
}

Point ret;
Circle a, b;
int main() {
    cin>>a.center.x>>a.center.y>>a.r;
    cin>>b.center.x>>b.center.y>>b.r;
    auto r = circle_circle(a, b);
    int rs = (int) r.size();
    if(rs == 3) return puts("0");
    if(rs <= 1) return printf("%.15f\n", min(a.r, b.r) * min(a.r, b.r) * PI) % 1;
    auto p = r.front(), q = r.back();
    double d = dist(p, q);
    double sa = asin(d / 2 / a.r) * 2;
    double sb = asin(d / 2 / b.r) * 2;
    if(get_segment_cross(Line{a.center, b.center}, Line{p, q}, ret)) {
        return printf("%.15f\n", a.r * a.r * sa / 2 + b.r * b.r * sb / 2 - a.r * a.r * sin(sa) / 2 - b.r * b.r * sin(sb) / 2) % 1;
    }
    if(dist(Line{p, q}, a.center, true) < dist(Line{p, q}, b.center, true))
        return printf("%.15f\n", a.r * a.r * (PI - sa / 2) + b.r * b.r * sb / 2 - a.r * a.r * sin(sa) / 2 - b.r * b.r * sin(sb) / 2) % 1;
    return printf("%.15f\n", a.r * a.r * sa / 2 + b.r * b.r * (PI - sb / 2) - a.r * a.r * sin(sa) / 2 - b.r * b.r * sin(sb) / 2) % 1;
}


#include <bits/stdc++.h>
#define PI acos(-1)
using namespace std;
const double eps = 1e-9;

inline int diff(double lhs, double rhs) {
    if (lhs - eps < rhs && rhs < lhs + eps) return 0;
    return (lhs < rhs) ? -1 : 1;
}

inline bool is_between(double check, double a, double b) {
    if (a < b)
        return (a - eps < check && check < b + eps);
    else
        return (b - eps < check && check < a + eps);
}

struct Point {
    double x, y;
    bool operator==(const Point& rhs) const {
        return diff(x, rhs.x) == 0 && diff(y, rhs.y) == 0;
    }
    Point operator+(const Point& rhs) const {
        return Point{ x + rhs.x, y + rhs.y };
    }
    Point operator-(const Point& rhs) const {
        return Point{ x - rhs.x, y - rhs.y };
    }
    Point operator*(double t) const {
        return Point{ x * t, y * t };
    }
};

struct Circle {
    Point center;
    double r;
};

struct Line {
    Point pos, dir;
};

inline double inner(const Point& a, const Point& b) {
    return a.x * b.x + a.y * b.y;
}

inline double outer(const Point& a, const Point& b) {
    return a.x * b.y - a.y * b.x;
}

inline int ccw_line(const Line& line, const Point& point) {
    return diff(outer(line.dir, point - line.pos), 0);
}

inline int ccw(const Point& a, const Point& b, const Point& c) {
    return diff(outer(b - a, c - a), 0);
}

inline double dist(const Point& a, const Point& b) {
    return sqrt(inner(a - b, a - b));
}

inline double dist2(const Point &a, const Point &b) {
    return inner(a - b, a - b);
}

inline double dist(const Line& line, const Point& point, bool segment = false) {
    double c1 = inner(point - line.pos, line.dir);
    if (segment && diff(c1, 0) <= 0) return dist(line.pos, point);
    double c2 = inner(line.dir, line.dir);
    if (segment && diff(c2, c1) <= 0) return dist(line.pos + line.dir, point);
    return dist(line.pos + line.dir * (c1 / c2), point);
}

bool get_cross(const Line& a, const Line& b, Point& ret) {
    double mdet = outer(b.dir, a.dir);
    if (diff(mdet, 0) == 0) return false;
    double t2 = outer(a.dir, b.pos - a.pos) / mdet;
    ret = b.pos + b.dir * t2;
    return true;
}

bool get_segment_cross(const Line& a, const Line& b, Point& ret) {
    double mdet = outer(b.dir, a.dir);
    if (diff(mdet, 0) == 0) return false;
    double t1 = -outer(b.pos - a.pos, b.dir) / mdet;
    double t2 = outer(a.dir, b.pos - a.pos) / mdet;
    if (!is_between(t1, 0, 1) || !is_between(t2, 0, 1)) return false;
    ret = b.pos + b.dir * t2;
    return true;
}

Point inner_center(const Point &a, const Point &b, const Point &c) {
    double wa = dist(b, c), wb = dist(c, a), wc = dist(a, b);
    double w = wa + wb + wc;
    return Point{ (wa * a.x + wb * b.x + wc * c.x) / w, (wa * a.y + wb * b.y + wc * c.y) / w };
}

Point outer_center(const Point &a, const Point &b, const Point &c) {
    Point d1 = b - a, d2 = c - a;
    double area = outer(d1, d2);
    double dx = d1.x * d1.x * d2.y - d2.x * d2.x * d1.y
        + d1.y * d2.y * (d1.y - d2.y);
    double dy = d1.y * d1.y * d2.x - d2.y * d2.y * d1.x
        + d1.x * d2.x * (d1.x - d2.y);
    return Point{ a.x + dx / area / 2.0, a.y - dy / area / 2.0 };
}

vector<Point> circle_line(const Circle& circle, const Line& line) {
    vector<Point> result;
    double a = 2 * inner(line.dir, line.dir);
    double b = 2 * (line.dir.x * (line.pos.x - circle.center.x)
        + line.dir.y * (line.pos.y - circle.center.y));
    double c = inner(line.pos - circle.center, line.pos - circle.center)
        - circle.r * circle.r;
    double det = b * b - 2 * a * c;
    int pred = diff(det, 0);
    if (pred == 0)
        result.push_back(line.pos + line.dir * (-b / a));
    else if (pred > 0) {
        det = sqrt(det);
        result.push_back(line.pos + line.dir * ((-b + det) / a));
        result.push_back(line.pos + line.dir * ((-b - det) / a));
    }
    return result;
}

vector<Point> circle_circle(const Circle& a, const Circle& b) {
    vector<Point> result;
    double aa = a.center.x * a.center.x + a.center.y * a.center.y - a.r * a.r;
    double bb = b.center.x * b.center.x + b.center.y * b.center.y - b.r * b.r;
    double tmp = (bb - aa) / 2.0;
    Point cdiff = b.center - a.center;
    if (diff(cdiff.x, 0) == 0) {
        if (diff(cdiff.y, 0) == 0) {
            return result;
        }
        return circle_line(a, Line{ Point{ 0, tmp / cdiff.y }, Point{ 1, 0 } });
    }
    return circle_line(a,
        Line{ Point{ tmp / cdiff.x, 0 }, Point{ -cdiff.y, cdiff.x } });
}

Point ret;
Circle a, b;

double cs(double r, double h) {
    return r * r * h;
}

double ts(double a, double b) {
    return sqrt(a + b / 2) * sqrt(a - b / 2) * b / 2;
}

signed main() {
    cin>>a.center.x>>a.center.y>>a.r;
    cin>>b.center.x>>b.center.y>>b.r;
    int pred = diff(dist(a.center, b.center), a.r + b.r);
    if (pred >= 0) return puts("0");
    auto r = circle_circle(a, b);
    double cc = dist(a.center, b.center);
    if (a.center.x == 44721) printf("%.15f %d\n", cc, (int) r.size());
    if(cc <= max(a.r - b.r, b.r - a.r) || !r.size())
        return printf("%.15f\n", min(a.r, b.r) * min(a.r, b.r) * PI) % 1;
    auto p = r.front(), q = r.back();
    double d = sqrt(abs(-cc + a.r - b.r)) * sqrt(abs(-cc - a.r + b.r)) * sqrt(-cc + a.r + b.r) * sqrt(cc + a.r + b.r) / cc;
    double sa = asin(d / 2 / a.r);
    double sb = asin(d / 2 / b.r);
    if (a.center.x == 44721) printf("%.15f %d\n", cc, (int) r.size());
    if(get_segment_cross(Line{a.center, b.center - a.center}, Line{p, q - p}, ret)){
        return printf("%.15f\n", cs(a.r, sa) + cs(b.r, sb) - ts(a.r, d) - ts(b.r, d)) % 1;
    }
    if (a.center.x == 44721) printf("%.15f %d\n", cc, (int) r.size());
    if(dist(Line{p, q - p}, a.center, true) < dist(Line{p, q - p}, b.center, true))
        return printf("%.15f\n", cs(a.r, PI - sa) + cs(b.r, sb) + ts(a.r, d) - ts(b.r, d)) % 1;
    if (a.center.x == 44721) printf("%.15f %d\n", cc, (int) r.size());
    return printf("%.15f\n", cs(a.r, sa) + cs(b.r, PI - sb) - ts(a.r, d) + ts(b.r, d)) % 1;
}


#include <bits/stdc++.h>
#define PI acos(-1)
using namespace std;
const double eps = 1e-15;

inline int diff(double lhs, double rhs) {
    if (lhs - eps < rhs && rhs < lhs + eps) return 0;
    return (lhs < rhs) ? -1 : 1;
}

inline bool is_between(double check, double a, double b) {
    if (a < b)
        return (a - eps < check && check < b + eps);
    else
        return (b - eps < check && check < a + eps);
}

struct Point {
    double x, y;
    bool operator==(const Point& rhs) const {
        return diff(x, rhs.x) == 0 && diff(y, rhs.y) == 0;
    }
    Point operator+(const Point& rhs) const {
        return Point{ x + rhs.x, y + rhs.y };
    }
    Point operator-(const Point& rhs) const {
        return Point{ x - rhs.x, y - rhs.y };
    }
    Point operator*(double t) const {
        return Point{ x * t, y * t };
    }
};

struct Circle {
    Point center;
    double r;
};

struct Line {
    Point pos, dir;
};

inline double inner(const Point& a, const Point& b) {
    return a.x * b.x + a.y * b.y;
}

inline double outer(const Point& a, const Point& b) {
    return a.x * b.y - a.y * b.x;
}

inline int ccw_line(const Line& line, const Point& point) {
    return diff(outer(line.dir, point - line.pos), 0);
}

inline int ccw(const Point& a, const Point& b, const Point& c) {
    return diff(outer(b - a, c - a), 0);
}

inline double dist(const Point& a, const Point& b) {
    return sqrt(inner(a - b, a - b));
}

inline double dist2(const Point &a, const Point &b) {
    return inner(a - b, a - b);
}

inline double dist(const Line& line, const Point& point, bool segment = false) {
    double c1 = inner(point - line.pos, line.dir);
    if (segment && diff(c1, 0) <= 0) return dist(line.pos, point);
    double c2 = inner(line.dir, line.dir);
    if (segment && diff(c2, c1) <= 0) return dist(line.pos + line.dir, point);
    return dist(line.pos + line.dir * (c1 / c2), point);
}

bool get_cross(const Line& a, const Line& b, Point& ret) {
    double mdet = outer(b.dir, a.dir);
    if (diff(mdet, 0) == 0) return false;
    double t2 = outer(a.dir, b.pos - a.pos) / mdet;
    ret = b.pos + b.dir * t2;
    return true;
}

bool get_segment_cross(const Line& a, const Line& b, Point& ret) {
    double mdet = outer(b.dir, a.dir);
    if (diff(mdet, 0) == 0) return false;
    double t1 = -outer(b.pos - a.pos, b.dir) / mdet;
    double t2 = outer(a.dir, b.pos - a.pos) / mdet;
    if (!is_between(t1, 0, 1) || !is_between(t2, 0, 1)) return false;
    ret = b.pos + b.dir * t2;
    return true;
}

Point inner_center(const Point &a, const Point &b, const Point &c) {
    double wa = dist(b, c), wb = dist(c, a), wc = dist(a, b);
    double w = wa + wb + wc;
    return Point{ (wa * a.x + wb * b.x + wc * c.x) / w, (wa * a.y + wb * b.y + wc * c.y) / w };
}

Point outer_center(const Point &a, const Point &b, const Point &c) {
    Point d1 = b - a, d2 = c - a;
    double area = outer(d1, d2);
    double dx = d1.x * d1.x * d2.y - d2.x * d2.x * d1.y
        + d1.y * d2.y * (d1.y - d2.y);
    double dy = d1.y * d1.y * d2.x - d2.y * d2.y * d1.x
        + d1.x * d2.x * (d1.x - d2.y);
    return Point{ a.x + dx / area / 2.0, a.y - dy / area / 2.0 };
}

vector<Point> circle_line(const Circle& circle, const Line& line) {
    vector<Point> result;
    double a = 2 * inner(line.dir, line.dir);
    double b = 2 * (line.dir.x * (line.pos.x - circle.center.x)
        + line.dir.y * (line.pos.y - circle.center.y));
    double c = inner(line.pos - circle.center, line.pos - circle.center)
        - circle.r * circle.r;
    double det = b * b - 2 * a * c;
    int pred = diff(det, 0);
    if (pred == 0)
        result.push_back(line.pos + line.dir * (-b / a));
    else if (pred > 0) {
        det = sqrt(det);
        result.push_back(line.pos + line.dir * ((-b + det) / a));
        result.push_back(line.pos + line.dir * ((-b - det) / a));
    }
    return result;
}

vector<Point> circle_circle(const Circle& a, const Circle& b) {
    vector<Point> result;
    double aa = a.center.x * a.center.x + a.center.y * a.center.y - a.r * a.r;
    double bb = b.center.x * b.center.x + b.center.y * b.center.y - b.r * b.r;
    double tmp = (bb - aa) / 2.0;
    Point cdiff = b.center - a.center;
    if (diff(cdiff.x, 0) == 0) {
        if (diff(cdiff.y, 0) == 0) {
            return result;
        }
        return circle_line(a, Line{ Point{ 0, tmp / cdiff.y }, Point{ 1, 0 } });
    }
    return circle_line(a,
        Line{ Point{ tmp / cdiff.x, 0 }, Point{ -cdiff.y, cdiff.x } });
}

Point ret;
Circle a, b;

double cs(double r, double h) {
    return r * r * h;
}

double ts(double a, double b) {
    return sqrt(a + b / 2) * sqrt(a - b / 2) * b / 2;
}

signed main() {
    cin>>a.center.x>>a.center.y>>a.r;
    cin>>b.center.x>>b.center.y>>b.r;
    int pred = diff(dist(a.center, b.center), a.r + b.r);
    if (pred >= 0) return puts("0");
    auto r = circle_circle(a, b);
    double cc = dist(a.center, b.center);
    if(cc <= max(a.r - b.r, b.r - a.r) || !r.size())
        return printf("%.15f\n", min(a.r, b.r) * min(a.r, b.r) * PI) % 1;
    auto p = r.front(), q = r.back();
    double d = sqrt(abs(-cc + a.r - b.r)) * sqrt(abs(-cc - a.r + b.r)) * sqrt(-cc + a.r + b.r) * sqrt(cc + a.r + b.r) / cc;
    double sa = asin(d / 2 / a.r);
    double sb = asin(d / 2 / b.r);
    if(get_segment_cross(Line{a.center, b.center - a.center}, Line{p, q - p}, ret)){
        return printf("%.15f\n", cs(a.r, sa) + cs(b.r, sb) - ts(a.r, d) - ts(b.r, d)) % 1;
    }
    if(dist(Line{p, q - p}, a.center, true) < dist(Line{p, q - p}, b.center, true))
        return printf("%.15f\n", cs(a.r, PI / 2 - sa) + cs(b.r, sb) + ts(a.r, d) - ts(b.r, d)) % 1;
    return printf("%.15f\n", cs(a.r, sa) + cs(b.r, PI / 2 - sb) - ts(a.r, d) + ts(b.r, d)) % 1;
}


#include <bits/stdc++.h>
#define int double
#define PI acos(-1)
using namespace std;
const double eps = 1e-12;

inline int diff(double lhs, double rhs) {
    if (lhs - eps < rhs && rhs < lhs + eps) return 0;
    return (lhs < rhs) ? -1 : 1;
}

inline bool is_between(double check, double a, double b) {
    if (a < b)
        return (a - eps < check && check < b + eps);
    else
        return (b - eps < check && check < a + eps);
}

struct Point {
    double x, y;
    bool operator==(const Point& rhs) const {
        return diff(x, rhs.x) == 0 && diff(y, rhs.y) == 0;
    }
    Point operator+(const Point& rhs) const {
        return Point{ x + rhs.x, y + rhs.y };
    }
    Point operator-(const Point& rhs) const {
        return Point{ x - rhs.x, y - rhs.y };
    }
    Point operator*(double t) const {
        return Point{ x * t, y * t };
    }
};

struct Circle {
    Point center;
    double r;
};

struct Line {
    Point pos, dir;
};

inline double inner(const Point& a, const Point& b) {
    return a.x * b.x + a.y * b.y;
}

inline double outer(const Point& a, const Point& b) {
    return a.x * b.y - a.y * b.x;
}

inline int ccw_line(const Line& line, const Point& point) {
    return diff(outer(line.dir, point - line.pos), 0);
}

inline int ccw(const Point& a, const Point& b, const Point& c) {
    return diff(outer(b - a, c - a), 0);
}

inline double dist(const Point& a, const Point& b) {
    return sqrt(inner(a - b, a - b));
}

inline double dist2(const Point &a, const Point &b) {
    return inner(a - b, a - b);
}

inline double dist(const Line& line, const Point& point, bool segment = false) {
    double c1 = inner(point - line.pos, line.dir);
    if (segment && diff(c1, 0) <= 0) return dist(line.pos, point);
    double c2 = inner(line.dir, line.dir);
    if (segment && diff(c2, c1) <= 0) return dist(line.pos + line.dir, point);
    return dist(line.pos + line.dir * (c1 / c2), point);
}

bool get_cross(const Line& a, const Line& b, Point& ret) {
    double mdet = outer(b.dir, a.dir);
    if (diff(mdet, 0) == 0) return false;
    double t2 = outer(a.dir, b.pos - a.pos) / mdet;
    ret = b.pos + b.dir * t2;
    return true;
}

bool get_segment_cross(const Line& a, const Line& b, Point& ret) {
    double mdet = outer(b.dir, a.dir);
    if (diff(mdet, 0) == 0) return false;
    double t1 = -outer(b.pos - a.pos, b.dir) / mdet;
    double t2 = outer(a.dir, b.pos - a.pos) / mdet;
    if (!is_between(t1, 0, 1) || !is_between(t2, 0, 1)) return false;
    ret = b.pos + b.dir * t2;
    return true;
}

Point inner_center(const Point &a, const Point &b, const Point &c) {
    double wa = dist(b, c), wb = dist(c, a), wc = dist(a, b);
    double w = wa + wb + wc;
    return Point{ (wa * a.x + wb * b.x + wc * c.x) / w, (wa * a.y + wb * b.y + wc * c.y) / w };
}

Point outer_center(const Point &a, const Point &b, const Point &c) {
    Point d1 = b - a, d2 = c - a;
    double area = outer(d1, d2);
    double dx = d1.x * d1.x * d2.y - d2.x * d2.x * d1.y
        + d1.y * d2.y * (d1.y - d2.y);
    double dy = d1.y * d1.y * d2.x - d2.y * d2.y * d1.x
        + d1.x * d2.x * (d1.x - d2.y);
    return Point{ a.x + dx / area / 2.0, a.y - dy / area / 2.0 };
}

vector<Point> circle_line(const Circle& circle, const Line& line) {
    vector<Point> result;
    double a = 2 * inner(line.dir, line.dir);
    double b = 2 * (line.dir.x * (line.pos.x - circle.center.x)
        + line.dir.y * (line.pos.y - circle.center.y));
    double c = inner(line.pos - circle.center, line.pos - circle.center)
        - circle.r * circle.r;
    double det = b * b - 2 * a * c;
    int pred = diff(det, 0);
    if (pred == 0)
        result.push_back(line.pos + line.dir * (-b / a));
    else if (pred > 0) {
        det = sqrt(det);
        result.push_back(line.pos + line.dir * ((-b + det) / a));
        result.push_back(line.pos + line.dir * ((-b - det) / a));
    }
    return result;
}

vector<Point> circle_circle(const Circle& a, const Circle& b) {
    vector<Point> result;
    double aa = a.center.x * a.center.x + a.center.y * a.center.y - a.r * a.r;
    double bb = b.center.x * b.center.x + b.center.y * b.center.y - b.r * b.r;
    double tmp = (bb - aa) / 2.0;
    Point cdiff = b.center - a.center;
    if (diff(cdiff.x, 0) == 0) {
        if (diff(cdiff.y, 0) == 0) {
            return result;
        }
        return circle_line(a, Line{ Point{ 0, tmp / cdiff.y }, Point{ 1, 0 } });
    }
    return circle_line(a,
        Line{ Point{ tmp / cdiff.x, 0 }, Point{ -cdiff.y, cdiff.x } });
}

Point ret;
Circle a, b;
signed main() {
    cin>>a.center.x>>a.center.y>>a.r;
    cin>>b.center.x>>b.center.y>>b.r;
    int pred = diff(dist(a.center, b.center), a.r + b.r);
    if (pred >= 0) return puts("0");
    auto r = circle_circle(a, b);
    if(dist(a.center, b.center) <= max(a.r - b.r, b.r - a.r) && !r.size())
        return printf("%.15f\n", min(a.r, b.r) * min(a.r, b.r) * PI) % 1;
    auto p = r.front(), q = r.back();
    double d = dist(p, q);
    double sa = asin(d / 2 / a.r) * 2;
    double sb = asin(d / 2 / b.r) * 2;
    assert(r.size() == 2);
    if(get_segment_cross(Line{a.center, b.center - a.center}, Line{p, q - p}, ret)){
        return printf("%.15f\n", a.r * a.r * sa / 2 + b.r * b.r * sb / 2 - a.r * a.r * sin(sa) / 2 - b.r * b.r * sin(sb) / 2) % 1;
    }
    if(dist(Line{p, q - p}, a.center, true) < dist(Line{p, q - p}, b.center, true))
        return printf("%.15f\n", a.r * a.r * (PI - sa / 2) + b.r * b.r * sb / 2 + a.r * a.r * sin(sa) / 2 - b.r * b.r * sin(sb) / 2) % 1;
    return printf("%.15f\n", a.r * a.r * sa / 2 + b.r * b.r * (PI - sb / 2) - a.r * a.r * sin(sa) / 2 + b.r * b.r * sin(sb) / 2) % 1;
}


#include <bits/stdc++.h>
#define int double
#define PI acos(-1)
using namespace std;
const double eps = 1e-9;

inline int diff(double lhs, double rhs) {
    if (lhs - eps < rhs && rhs < lhs + eps) return 0;
    return (lhs < rhs) ? -1 : 1;
}

inline bool is_between(double check, double a, double b) {
    if (a < b)
        return (a - eps < check && check < b + eps);
    else
        return (b - eps < check && check < a + eps);
}

struct Point {
    double x, y;
    bool operator==(const Point& rhs) const {
        return diff(x, rhs.x) == 0 && diff(y, rhs.y) == 0;
    }
    Point operator+(const Point& rhs) const {
        return Point{ x + rhs.x, y + rhs.y };
    }
    Point operator-(const Point& rhs) const {
        return Point{ x - rhs.x, y - rhs.y };
    }
    Point operator*(double t) const {
        return Point{ x * t, y * t };
    }
};

struct Circle {
    Point center;
    double r;
};

struct Line {
    Point pos, dir;
};

inline double inner(const Point& a, const Point& b) {
    return a.x * b.x + a.y * b.y;
}

inline double outer(const Point& a, const Point& b) {
    return a.x * b.y - a.y * b.x;
}

inline int ccw_line(const Line& line, const Point& point) {
    return diff(outer(line.dir, point - line.pos), 0);
}

inline int ccw(const Point& a, const Point& b, const Point& c) {
    return diff(outer(b - a, c - a), 0);
}

inline double dist(const Point& a, const Point& b) {
    return sqrt(inner(a - b, a - b));
}

inline double dist2(const Point &a, const Point &b) {
    return inner(a - b, a - b);
}

inline double dist(const Line& line, const Point& point, bool segment = false) {
    double c1 = inner(point - line.pos, line.dir);
    if (segment && diff(c1, 0) <= 0) return dist(line.pos, point);
    double c2 = inner(line.dir, line.dir);
    if (segment && diff(c2, c1) <= 0) return dist(line.pos + line.dir, point);
    return dist(line.pos + line.dir * (c1 / c2), point);
}

bool get_cross(const Line& a, const Line& b, Point& ret) {
    double mdet = outer(b.dir, a.dir);
    if (diff(mdet, 0) == 0) return false;
    double t2 = outer(a.dir, b.pos - a.pos) / mdet;
    ret = b.pos + b.dir * t2;
    return true;
}

bool get_segment_cross(const Line& a, const Line& b, Point& ret) {
    double mdet = outer(b.dir, a.dir);
    if (diff(mdet, 0) == 0) return false;
    double t1 = -outer(b.pos - a.pos, b.dir) / mdet;
    double t2 = outer(a.dir, b.pos - a.pos) / mdet;
    if (!is_between(t1, 0, 1) || !is_between(t2, 0, 1)) return false;
    ret = b.pos + b.dir * t2;
    return true;
}

Point inner_center(const Point &a, const Point &b, const Point &c) {
    double wa = dist(b, c), wb = dist(c, a), wc = dist(a, b);
    double w = wa + wb + wc;
    return Point{ (wa * a.x + wb * b.x + wc * c.x) / w, (wa * a.y + wb * b.y + wc * c.y) / w };
}

Point outer_center(const Point &a, const Point &b, const Point &c) {
    Point d1 = b - a, d2 = c - a;
    double area = outer(d1, d2);
    double dx = d1.x * d1.x * d2.y - d2.x * d2.x * d1.y
        + d1.y * d2.y * (d1.y - d2.y);
    double dy = d1.y * d1.y * d2.x - d2.y * d2.y * d1.x
        + d1.x * d2.x * (d1.x - d2.y);
    return Point{ a.x + dx / area / 2.0, a.y - dy / area / 2.0 };
}

vector<Point> circle_line(const Circle& circle, const Line& line) {
    vector<Point> result;
    double a = 2 * inner(line.dir, line.dir);
    double b = 2 * (line.dir.x * (line.pos.x - circle.center.x)
        + line.dir.y * (line.pos.y - circle.center.y));
    double c = inner(line.pos - circle.center, line.pos - circle.center)
        - circle.r * circle.r;
    double det = b * b - 2 * a * c;
    int pred = diff(det, 0);
    if (pred == 0)
        result.push_back(line.pos + line.dir * (-b / a));
    else if (pred > 0) {
        det = sqrt(det);
        result.push_back(line.pos + line.dir * ((-b + det) / a));
        result.push_back(line.pos + line.dir * ((-b - det) / a));
    }
    return result;
}

vector<Point> circle_circle(const Circle& a, const Circle& b) {
    vector<Point> result;
    double aa = a.center.x * a.center.x + a.center.y * a.center.y - a.r * a.r;
    double bb = b.center.x * b.center.x + b.center.y * b.center.y - b.r * b.r;
    double tmp = (bb - aa) / 2.0;
    Point cdiff = b.center - a.center;
    if (diff(cdiff.x, 0) == 0) {
        if (diff(cdiff.y, 0) == 0) {
            return result;
        }
        return circle_line(a, Line{ Point{ 0, tmp / cdiff.y }, Point{ 1, 0 } });
    }
    return circle_line(a,
        Line{ Point{ tmp / cdiff.x, 0 }, Point{ -cdiff.y, cdiff.x } });
}

Point ret;
Circle a, b;
signed main() {
    cin>>a.center.x>>a.center.y>>a.r;
    cin>>b.center.x>>b.center.y>>b.r;
    int pred = diff(dist(a.center, b.center), a.r + b.r);
    if (pred >= 0) return puts("0");
    auto r = circle_circle(a, b);
    if(dist(a.center, b.center) <= max(a.r - b.r, b.r - a.r))
        return printf("%.15f\n", min(a.r, b.r) * min(a.r, b.r) * PI) % 1;
    auto p = r.front(), q = r.back();
    double d = dist(p, q);
    double sa = asin(d / 2 / a.r) * 2;
    double sb = asin(d / 2 / b.r) * 2;
    assert(r.size() == 2);
    if(get_segment_cross(Line{a.center, b.center - a.center}, Line{p, q - p}, ret)){
        return printf("%.15f\n", a.r * a.r * sa / 2 + b.r * b.r * sb / 2 - a.r * a.r * sin(sa) / 2 - b.r * b.r * sin(sb) / 2) % 1;
    }
    if(dist(Line{p, q - p}, a.center, true) < dist(Line{p, q - p}, b.center, true))
        return printf("%.15f\n", a.r * a.r * (PI - sa / 2) + b.r * b.r * sb / 2 + a.r * a.r * sin(sa) / 2 - b.r * b.r * sin(sb) / 2) % 1;
    return printf("%.15f\n", a.r * a.r * sa / 2 + b.r * b.r * (PI - sb / 2) - a.r * a.r * sin(sa) / 2 + b.r * b.r * sin(sb) / 2) % 1;
}


#include <bits/stdc++.h>
#define int long long
#define PI acos(-1)
using namespace std;
const double eps = 1e-12;

inline int diff(double lhs, double rhs) {
    if (lhs - eps < rhs && rhs < lhs + eps) return 0;
    return (lhs < rhs) ? -1 : 1;
}

inline bool is_between(double check, double a, double b) {
    if (a < b)
        return (a - eps < check && check < b + eps);
    else
        return (b - eps < check && check < a + eps);
}

struct Point {
    double x, y;
    bool operator==(const Point& rhs) const {
        return diff(x, rhs.x) == 0 && diff(y, rhs.y) == 0;
    }
    Point operator+(const Point& rhs) const {
        return Point{ x + rhs.x, y + rhs.y };
    }
    Point operator-(const Point& rhs) const {
        return Point{ x - rhs.x, y - rhs.y };
    }
    Point operator*(double t) const {
        return Point{ x * t, y * t };
    }
};

struct Circle {
    Point center;
    double r;
};

struct Line {
    Point pos, dir;
};

inline double inner(const Point& a, const Point& b) {
    return a.x * b.x + a.y * b.y;
}

inline double outer(const Point& a, const Point& b) {
    return a.x * b.y - a.y * b.x;
}

inline int ccw_line(const Line& line, const Point& point) {
    return diff(outer(line.dir, point - line.pos), 0);
}

inline int ccw(const Point& a, const Point& b, const Point& c) {
    return diff(outer(b - a, c - a), 0);
}

inline double dist(const Point& a, const Point& b) {
    return sqrt(inner(a - b, a - b));
}

inline double dist2(const Point &a, const Point &b) {
    return inner(a - b, a - b);
}

inline double dist(const Line& line, const Point& point, bool segment = false) {
    double c1 = inner(point - line.pos, line.dir);
    if (segment && diff(c1, 0) <= 0) return dist(line.pos, point);
    double c2 = inner(line.dir, line.dir);
    if (segment && diff(c2, c1) <= 0) return dist(line.pos + line.dir, point);
    return dist(line.pos + line.dir * (c1 / c2), point);
}

bool get_cross(const Line& a, const Line& b, Point& ret) {
    double mdet = outer(b.dir, a.dir);
    if (diff(mdet, 0) == 0) return false;
    double t2 = outer(a.dir, b.pos - a.pos) / mdet;
    ret = b.pos + b.dir * t2;
    return true;
}

bool get_segment_cross(const Line& a, const Line& b, Point& ret) {
    double mdet = outer(b.dir, a.dir);
    if (diff(mdet, 0) == 0) return false;
    double t1 = -outer(b.pos - a.pos, b.dir) / mdet;
    double t2 = outer(a.dir, b.pos - a.pos) / mdet;
    if (!is_between(t1, 0, 1) || !is_between(t2, 0, 1)) return false;
    ret = b.pos + b.dir * t2;
    return true;
}

Point inner_center(const Point &a, const Point &b, const Point &c) {
    double wa = dist(b, c), wb = dist(c, a), wc = dist(a, b);
    double w = wa + wb + wc;
    return Point{ (wa * a.x + wb * b.x + wc * c.x) / w, (wa * a.y + wb * b.y + wc * c.y) / w };
}

Point outer_center(const Point &a, const Point &b, const Point &c) {
    Point d1 = b - a, d2 = c - a;
    double area = outer(d1, d2);
    double dx = d1.x * d1.x * d2.y - d2.x * d2.x * d1.y
        + d1.y * d2.y * (d1.y - d2.y);
    double dy = d1.y * d1.y * d2.x - d2.y * d2.y * d1.x
        + d1.x * d2.x * (d1.x - d2.y);
    return Point{ a.x + dx / area / 2.0, a.y - dy / area / 2.0 };
}

vector<Point> circle_line(const Circle& circle, const Line& line) {
    vector<Point> result;
    double a = 2 * inner(line.dir, line.dir);
    double b = 2 * (line.dir.x * (line.pos.x - circle.center.x)
        + line.dir.y * (line.pos.y - circle.center.y));
    double c = inner(line.pos - circle.center, line.pos - circle.center)
        - circle.r * circle.r;
    double det = b * b - 2 * a * c;
    int pred = diff(det, 0);
    if (pred == 0)
        result.push_back(line.pos + line.dir * (-b / a));
    else if (pred > 0) {
        det = sqrt(det);
        result.push_back(line.pos + line.dir * ((-b + det) / a));
        result.push_back(line.pos + line.dir * ((-b - det) / a));
    }
    return result;
}

vector<Point> circle_circle(const Circle& a, const Circle& b) {
    vector<Point> result;
    double aa = a.center.x * a.center.x + a.center.y * a.center.y - a.r * a.r;
    double bb = b.center.x * b.center.x + b.center.y * b.center.y - b.r * b.r;
    double tmp = (bb - aa) / 2.0;
    Point cdiff = b.center - a.center;
    if (diff(cdiff.x, 0) == 0) {
        if (diff(cdiff.y, 0) == 0) {
            return result;
        }
        return circle_line(a, Line{ Point{ 0, tmp / cdiff.y }, Point{ 1, 0 } });
    }
    return circle_line(a,
        Line{ Point{ tmp / cdiff.x, 0 }, Point{ -cdiff.y, cdiff.x } });
}

Point ret;
Circle a, b;
signed main() {
    cin>>a.center.x>>a.center.y>>a.r;
    cin>>b.center.x>>b.center.y>>b.r;
    int pred = diff(dist(a.center, b.center), a.r + b.r);
    if (pred >= 0) return puts("0");
    auto r = circle_circle(a, b);
    if(dist(a.center, b.center) <= max(a.r - b.r, b.r - a.r)) return printf("%.15f\n", min(a.r, b.r) * min(a.r, b.r) * PI) % 1;
    auto p = r.front(), q = r.back();
    double d = dist(p, q);
    double sa = asin(d / 2 / a.r) * 2;
    double sb = asin(d / 2 / b.r) * 2;
    if(get_segment_cross(Line{a.center, b.center}, Line{p, q}, ret)) {
        return printf("%.15f\n", a.r * a.r * sa / 2 + b.r * b.r * sb / 2 - a.r * a.r * sin(sa) / 2 - b.r * b.r * sin(sb) / 2) % 1;
    }
    if(dist(Line{p, q}, a.center, true) < dist(Line{p, q}, b.center, true))
        return printf("%.15f\n", a.r * a.r * (PI - sa / 2) + b.r * b.r * sb / 2 + a.r * a.r * sin(sa) / 2 - b.r * b.r * sin(sb) / 2) % 1;
    return printf("%.15f\n", a.r * a.r * sa / 2 + b.r * b.r * (PI - sb / 2) - a.r * a.r * sin(sa) / 2 + b.r * b.r * sin(sb) / 2) % 1;
}


#include <bits/stdc++.h>
using namespace std;
#define int long long
#define R (long double) 1e9
#define PI (long double) acos(-1)
int x1, y1, r1;
int x2, y2, r2;

int pow(int x) { return x * x; }
int dist2(int x1, int y1, int x2, int y2) {
    return (x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2);
}

long double dist(int x1, int y1, int x2, int y2) {
    return sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2));
}
signed main() {
    cin>>x1>>y1>>r1;
    cin>>x2>>y2>>r2;

    int cd = dist2(x1, y1, x2, y2);
    if(pow(r1 + r2) <= cd) return puts("0");
    if(cd <= pow(r1 - r2)) {
        return printf("%.15Lf",  pow(min(r1, r2)) * PI) % 1;
    }
    long double t1 = acos((-pow(r2) / R + cd / R + pow(r1) / R) * R / (long double) sqrt(cd) / 2 / r1);
    long double t2 = acos((-pow(r1) / R + cd / R + pow(r2) / R) * R / (long double) sqrt(cd) / 2 / r2);
    if (t1 < 1e-8)
        return printf("%.15Lf", pow(r2) * t2) % 1;
    if (t2 < 1e-8)
        return printf("%.15Lf", pow(r1) * t1) % 1;
    printf("%.15Lf", -r1 * r2 * sin(t1 + t2) + pow(r1) * t1 + pow(r2) * t2) % 1;
}


#include <bits/stdc++.h>
#define PI acos(-1)
using namespace std;
const double eps = 1e-15;

inline int diff(double lhs, double rhs) {
    if (lhs - eps < rhs && rhs < lhs + eps) return 0;
    return (lhs < rhs) ? -1 : 1;
}

inline bool is_between(double check, double a, double b) {
    if (a < b)
        return (a - eps < check && check < b + eps);
    else
        return (b - eps < check && check < a + eps);
}

struct Point {
    double x, y;
    bool operator==(const Point& rhs) const {
        return diff(x, rhs.x) == 0 && diff(y, rhs.y) == 0;
    }
    Point operator+(const Point& rhs) const {
        return Point{ x + rhs.x, y + rhs.y };
    }
    Point operator-(const Point& rhs) const {
        return Point{ x - rhs.x, y - rhs.y };
    }
    Point operator*(double t) const {
        return Point{ x * t, y * t };
    }
};

struct Circle {
    Point center;
    double r;
};

struct Line {
    Point pos, dir;
};

inline double inner(const Point& a, const Point& b) {
    return a.x * b.x + a.y * b.y;
}

inline double outer(const Point& a, const Point& b) {
    return a.x * b.y - a.y * b.x;
}

inline int ccw_line(const Line& line, const Point& point) {
    return diff(outer(line.dir, point - line.pos), 0);
}

inline int ccw(const Point& a, const Point& b, const Point& c) {
    return diff(outer(b - a, c - a), 0);
}

inline double dist(const Point& a, const Point& b) {
    return sqrt(inner(a - b, a - b));
}

inline double dist2(const Point &a, const Point &b) {
    return inner(a - b, a - b);
}

inline double dist(const Line& line, const Point& point, bool segment = false) {
    double c1 = inner(point - line.pos, line.dir);
    if (segment && diff(c1, 0) <= 0) return dist(line.pos, point);
    double c2 = inner(line.dir, line.dir);
    if (segment && diff(c2, c1) <= 0) return dist(line.pos + line.dir, point);
    return dist(line.pos + line.dir * (c1 / c2), point);
}

bool get_cross(const Line& a, const Line& b, Point& ret) {
    double mdet = outer(b.dir, a.dir);
    if (diff(mdet, 0) == 0) return false;
    double t2 = outer(a.dir, b.pos - a.pos) / mdet;
    ret = b.pos + b.dir * t2;
    return true;
}

bool get_segment_cross(const Line& a, const Line& b, Point& ret) {
    double mdet = outer(b.dir, a.dir);
    if (diff(mdet, 0) == 0) return false;
    double t1 = -outer(b.pos - a.pos, b.dir) / mdet;
    double t2 = outer(a.dir, b.pos - a.pos) / mdet;
    if (!is_between(t1, 0, 1) || !is_between(t2, 0, 1)) return false;
    ret = b.pos + b.dir * t2;
    return true;
}

Point inner_center(const Point &a, const Point &b, const Point &c) {
    double wa = dist(b, c), wb = dist(c, a), wc = dist(a, b);
    double w = wa + wb + wc;
    return Point{ (wa * a.x + wb * b.x + wc * c.x) / w, (wa * a.y + wb * b.y + wc * c.y) / w };
}

Point outer_center(const Point &a, const Point &b, const Point &c) {
    Point d1 = b - a, d2 = c - a;
    double area = outer(d1, d2);
    double dx = d1.x * d1.x * d2.y - d2.x * d2.x * d1.y
        + d1.y * d2.y * (d1.y - d2.y);
    double dy = d1.y * d1.y * d2.x - d2.y * d2.y * d1.x
        + d1.x * d2.x * (d1.x - d2.y);
    return Point{ a.x + dx / area / 2.0, a.y - dy / area / 2.0 };
}

vector<Point> circle_line(const Circle& circle, const Line& line) {
    vector<Point> result;
    double a = 2 * inner(line.dir, line.dir);
    double b = 2 * (line.dir.x * (line.pos.x - circle.center.x)
        + line.dir.y * (line.pos.y - circle.center.y));
    double c = inner(line.pos - circle.center, line.pos - circle.center)
        - circle.r * circle.r;
    double det = b * b - 2 * a * c;
    int pred = diff(det, 0);
    if (pred == 0)
        result.push_back(line.pos + line.dir * (-b / a));
    else if (pred > 0) {
        det = sqrt(det);
        result.push_back(line.pos + line.dir * ((-b + det) / a));
        result.push_back(line.pos + line.dir * ((-b - det) / a));
    }
    return result;
}

vector<Point> circle_circle(const Circle& a, const Circle& b) {
    vector<Point> result;
    double aa = a.center.x * a.center.x + a.center.y * a.center.y - a.r * a.r;
    double bb = b.center.x * b.center.x + b.center.y * b.center.y - b.r * b.r;
    double tmp = (bb - aa) / 2.0;
    Point cdiff = b.center - a.center;
    if (diff(cdiff.x, 0) == 0) {
        if (diff(cdiff.y, 0) == 0) {
            return result;
        }
        return circle_line(a, Line{ Point{ 0, tmp / cdiff.y }, Point{ 1, 0 } });
    }
    return circle_line(a,
        Line{ Point{ tmp / cdiff.x, 0 }, Point{ -cdiff.y, cdiff.x } });
}

Point ret;
Circle a, b;

double cs(double r, double h) {
    return r * r * h;
}

double ts(double a, double b) {
    return sqrt(a + b / 2) * sqrt(a - b / 2) * b / 2;
}

signed main() {
    cin>>a.center.x>>a.center.y>>a.r;
    cin>>b.center.x>>b.center.y>>b.r;
    int pred = diff(dist(a.center, b.center), a.r + b.r);
    if (pred >= 0) return puts("0");
    auto r = circle_circle(a, b);
    double cc = dist(a.center, b.center);
    if (a.center.x == 44721) printf("0 ");
    if(cc <= max(a.r - b.r, b.r - a.r) || !r.size())
        return printf("%.15f\n", min(a.r, b.r) * min(a.r, b.r) * PI) % 1;
    auto p = r.front(), q = r.back();
    double d = sqrt(abs(-cc + a.r - b.r)) * sqrt(abs(-cc - a.r + b.r)) * sqrt(-cc + a.r + b.r) * sqrt(cc + a.r + b.r) / cc;
    double sa = asin(d / 2 / a.r);
    double sb = asin(d / 2 / b.r);
    if (a.center.x == 44721) printf("1 ");
    if(get_segment_cross(Line{a.center, b.center - a.center}, Line{p, q - p}, ret)){
        return printf("%.15f\n", cs(a.r, sa) + cs(b.r, sb) - ts(a.r, d) - ts(b.r, d)) % 1;
    }
    if (a.center.x == 44721) printf("2 ");
    if(dist(Line{p, q - p}, a.center, true) < dist(Line{p, q - p}, b.center, true))
        return printf("%.15f\n", cs(a.r, PI - sa) + cs(b.r, sb) + ts(a.r, d) - ts(b.r, d)) % 1;
    if (a.center.x == 44721) printf("3 ");
    return printf("%.15f\n", cs(a.r, sa) + cs(b.r, PI - sb) - ts(a.r, d) + ts(b.r, d)) % 1;
}


#include <bits/stdc++.h>
#define int long long
#define PI acos(-1)
using namespace std;
const double eps = 1e-12;

inline int diff(double lhs, double rhs) {
    if (lhs - eps < rhs && rhs < lhs + eps) return 0;
    return (lhs < rhs) ? -1 : 1;
}

inline bool is_between(double check, double a, double b) {
    if (a < b)
        return (a - eps < check && check < b + eps);
    else
        return (b - eps < check && check < a + eps);
}

struct Point {
    double x, y;
    bool operator==(const Point& rhs) const {
        return diff(x, rhs.x) == 0 && diff(y, rhs.y) == 0;
    }
    Point operator+(const Point& rhs) const {
        return Point{ x + rhs.x, y + rhs.y };
    }
    Point operator-(const Point& rhs) const {
        return Point{ x - rhs.x, y - rhs.y };
    }
    Point operator*(double t) const {
        return Point{ x * t, y * t };
    }
};

struct Circle {
    Point center;
    double r;
};

struct Line {
    Point pos, dir;
};

inline double inner(const Point& a, const Point& b) {
    return a.x * b.x + a.y * b.y;
}

inline double outer(const Point& a, const Point& b) {
    return a.x * b.y - a.y * b.x;
}

inline int ccw_line(const Line& line, const Point& point) {
    return diff(outer(line.dir, point - line.pos), 0);
}

inline int ccw(const Point& a, const Point& b, const Point& c) {
    return diff(outer(b - a, c - a), 0);
}

inline double dist(const Point& a, const Point& b) {
    return sqrt(inner(a - b, a - b));
}

inline double dist2(const Point &a, const Point &b) {
    return inner(a - b, a - b);
}

inline double dist(const Line& line, const Point& point, bool segment = false) {
    double c1 = inner(point - line.pos, line.dir);
    if (segment && diff(c1, 0) <= 0) return dist(line.pos, point);
    double c2 = inner(line.dir, line.dir);
    if (segment && diff(c2, c1) <= 0) return dist(line.pos + line.dir, point);
    return dist(line.pos + line.dir * (c1 / c2), point);
}

bool get_cross(const Line& a, const Line& b, Point& ret) {
    double mdet = outer(b.dir, a.dir);
    if (diff(mdet, 0) == 0) return false;
    double t2 = outer(a.dir, b.pos - a.pos) / mdet;
    ret = b.pos + b.dir * t2;
    return true;
}

bool get_segment_cross(const Line& a, const Line& b, Point& ret) {
    double mdet = outer(b.dir, a.dir);
    if (diff(mdet, 0) == 0) return false;
    double t1 = -outer(b.pos - a.pos, b.dir) / mdet;
    double t2 = outer(a.dir, b.pos - a.pos) / mdet;
    if (!is_between(t1, 0, 1) || !is_between(t2, 0, 1)) return false;
    ret = b.pos + b.dir * t2;
    return true;
}

Point inner_center(const Point &a, const Point &b, const Point &c) {
    double wa = dist(b, c), wb = dist(c, a), wc = dist(a, b);
    double w = wa + wb + wc;
    return Point{ (wa * a.x + wb * b.x + wc * c.x) / w, (wa * a.y + wb * b.y + wc * c.y) / w };
}

Point outer_center(const Point &a, const Point &b, const Point &c) {
    Point d1 = b - a, d2 = c - a;
    double area = outer(d1, d2);
    double dx = d1.x * d1.x * d2.y - d2.x * d2.x * d1.y
        + d1.y * d2.y * (d1.y - d2.y);
    double dy = d1.y * d1.y * d2.x - d2.y * d2.y * d1.x
        + d1.x * d2.x * (d1.x - d2.y);
    return Point{ a.x + dx / area / 2.0, a.y - dy / area / 2.0 };
}

vector<Point> circle_line(const Circle& circle, const Line& line) {
    vector<Point> result;
    double a = 2 * inner(line.dir, line.dir);
    double b = 2 * (line.dir.x * (line.pos.x - circle.center.x)
        + line.dir.y * (line.pos.y - circle.center.y));
    double c = inner(line.pos - circle.center, line.pos - circle.center)
        - circle.r * circle.r;
    double det = b * b - 2 * a * c;
    int pred = diff(det, 0);
    if (pred == 0)
        result.push_back(line.pos + line.dir * (-b / a));
    else if (pred > 0) {
        det = sqrt(det);
        result.push_back(line.pos + line.dir * ((-b + det) / a));
        result.push_back(line.pos + line.dir * ((-b - det) / a));
    }
    return result;
}

vector<Point> circle_circle(const Circle& a, const Circle& b) {
    vector<Point> result;
    double aa = a.center.x * a.center.x + a.center.y * a.center.y - a.r * a.r;
    double bb = b.center.x * b.center.x + b.center.y * b.center.y - b.r * b.r;
    double tmp = (bb - aa) / 2.0;
    Point cdiff = b.center - a.center;
    if (diff(cdiff.x, 0) == 0) {
        if (diff(cdiff.y, 0) == 0) {
            return result;
        }
        return circle_line(a, Line{ Point{ 0, tmp / cdiff.y }, Point{ 1, 0 } });
    }
    return circle_line(a,
        Line{ Point{ tmp / cdiff.x, 0 }, Point{ -cdiff.y, cdiff.x } });
}

Point ret;
Circle a, b;
signed main() {
    cin>>a.center.x>>a.center.y>>a.r;
    cin>>b.center.x>>b.center.y>>b.r;
    int pred = diff(dist(a.center, b.center), a.r + b.r);
    if (pred >= 0) return puts("0");
    auto r = circle_circle(a, b);
    if(dist(a.center, b.center) <= max(a.r - b.r, b.r - a.r)) return printf("%.15f\n", min(a.r, b.r) * min(a.r, b.r) * PI) % 1;
    auto p = r.front(), q = r.back();
    assert(r.size() == 2);
    double d = dist(p, q);
    double sa = asin(d / 2 / a.r) * 2;
    double sb = asin(d / 2 / b.r) * 2;
    if(get_segment_cross(Line{a.center, b.center}, Line{p, q}, ret)) {
        return printf("%.15f\n", a.r * a.r * sa / 2 + b.r * b.r * sb / 2 - a.r * a.r * sin(sa) / 2 - b.r * b.r * sin(sb) / 2) % 1;
    }
    if(dist(Line{p, q}, a.center, true) < dist(Line{p, q}, b.center, true))
        return printf("%.15f\n", a.r * a.r * (PI - sa / 2) + b.r * b.r * sb / 2 - a.r * a.r * sin(sa) / 2 - b.r * b.r * sin(sb) / 2) % 1;
    return printf("%.15f\n", a.r * a.r * sa / 2 + b.r * b.r * (PI - sb / 2) - a.r * a.r * sin(sa) / 2 - b.r * b.r * sin(sb) / 2) % 1;
}


#include <bits/stdc++.h>
#define PI acos(-1)
using namespace std;
const double eps = 1e-9;

inline int diff(double lhs, double rhs) {
    if (lhs - eps < rhs && rhs < lhs + eps) return 0;
    return (lhs < rhs) ? -1 : 1;
}

inline bool is_between(double check, double a, double b) {
    if (a < b)
        return (a - eps < check && check < b + eps);
    else
        return (b - eps < check && check < a + eps);
}

struct Point {
    double x, y;
    bool operator==(const Point& rhs) const {
        return diff(x, rhs.x) == 0 && diff(y, rhs.y) == 0;
    }
    Point operator+(const Point& rhs) const {
        return Point{ x + rhs.x, y + rhs.y };
    }
    Point operator-(const Point& rhs) const {
        return Point{ x - rhs.x, y - rhs.y };
    }
    Point operator*(double t) const {
        return Point{ x * t, y * t };
    }
};

struct Circle {
    Point center;
    double r;
};

struct Line {
    Point pos, dir;
};

inline double inner(const Point& a, const Point& b) {
    return a.x * b.x + a.y * b.y;
}

inline double outer(const Point& a, const Point& b) {
    return a.x * b.y - a.y * b.x;
}

inline int ccw_line(const Line& line, const Point& point) {
    return diff(outer(line.dir, point - line.pos), 0);
}

inline int ccw(const Point& a, const Point& b, const Point& c) {
    return diff(outer(b - a, c - a), 0);
}

inline double dist(const Point& a, const Point& b) {
    return sqrt(inner(a - b, a - b));
}

inline double dist2(const Point &a, const Point &b) {
    return inner(a - b, a - b);
}

inline double dist(const Line& line, const Point& point, bool segment = false) {
    double c1 = inner(point - line.pos, line.dir);
    if (segment && diff(c1, 0) <= 0) return dist(line.pos, point);
    double c2 = inner(line.dir, line.dir);
    if (segment && diff(c2, c1) <= 0) return dist(line.pos + line.dir, point);
    return dist(line.pos + line.dir * (c1 / c2), point);
}

bool get_cross(const Line& a, const Line& b, Point& ret) {
    double mdet = outer(b.dir, a.dir);
    if (diff(mdet, 0) == 0) return false;
    double t2 = outer(a.dir, b.pos - a.pos) / mdet;
    ret = b.pos + b.dir * t2;
    return true;
}

bool get_segment_cross(const Line& a, const Line& b, Point& ret) {
    double mdet = outer(b.dir, a.dir);
    if (diff(mdet, 0) == 0) return false;
    double t1 = -outer(b.pos - a.pos, b.dir) / mdet;
    double t2 = outer(a.dir, b.pos - a.pos) / mdet;
    if (!is_between(t1, 0, 1) || !is_between(t2, 0, 1)) return false;
    ret = b.pos + b.dir * t2;
    return true;
}

Point inner_center(const Point &a, const Point &b, const Point &c) {
    double wa = dist(b, c), wb = dist(c, a), wc = dist(a, b);
    double w = wa + wb + wc;
    return Point{ (wa * a.x + wb * b.x + wc * c.x) / w, (wa * a.y + wb * b.y + wc * c.y) / w };
}

Point outer_center(const Point &a, const Point &b, const Point &c) {
    Point d1 = b - a, d2 = c - a;
    double area = outer(d1, d2);
    double dx = d1.x * d1.x * d2.y - d2.x * d2.x * d1.y
        + d1.y * d2.y * (d1.y - d2.y);
    double dy = d1.y * d1.y * d2.x - d2.y * d2.y * d1.x
        + d1.x * d2.x * (d1.x - d2.y);
    return Point{ a.x + dx / area / 2.0, a.y - dy / area / 2.0 };
}

vector<Point> circle_line(const Circle& circle, const Line& line) {
    vector<Point> result;
    double a = 2 * inner(line.dir, line.dir);
    double b = 2 * (line.dir.x * (line.pos.x - circle.center.x)
        + line.dir.y * (line.pos.y - circle.center.y));
    double c = inner(line.pos - circle.center, line.pos - circle.center)
        - circle.r * circle.r;
    double det = b * b - 2 * a * c;
    int pred = diff(det, 0);
    if (pred == 0)
        result.push_back(line.pos + line.dir * (-b / a));
    else if (pred > 0) {
        det = sqrt(det);
        result.push_back(line.pos + line.dir * ((-b + det) / a));
        result.push_back(line.pos + line.dir * ((-b - det) / a));
    }
    return result;
}

vector<Point> circle_circle(const Circle& a, const Circle& b) {
    vector<Point> result;
    int pred = diff(dist(a.center, b.center), a.r + b.r);
    if (pred >= 0) {
        result.push_back(Point {0, 0});
        return result;
    }
    double aa = a.center.x * a.center.x + a.center.y * a.center.y - a.r * a.r;
    double bb = b.center.x * b.center.x + b.center.y * b.center.y - b.r * b.r;
    double tmp = (bb - aa) / 2.0;
    Point cdiff = b.center - a.center;
    if (diff(cdiff.x, 0) == 0) {
        if (diff(cdiff.y, 0) == 0) {
            return result;
        }
        return circle_line(a, Line{ Point{ 0, tmp / cdiff.y }, Point{ 1, 0 } });
    }
    return circle_line(a,
        Line{ Point{ tmp / cdiff.x, 0 }, Point{ -cdiff.y, cdiff.x } });
}

Point ret;
Circle a, b;
int main() {
    cin>>a.center.x>>a.center.y>>a.r;
    cin>>b.center.x>>b.center.y>>b.r;
    auto r = circle_circle(a, b);
    int rs = (int) r.size();
    if(rs == 1) return puts("0");
    if(rs == 0) return printf("%.15f\n", min(a.r, b.r) * min(a.r, b.r) * PI) % 1;
    auto p = r.front(), q = r.back();
    double d = dist(p, q);
    double sa = asin(d / 2 / a.r) * 2;
    double sb = asin(d / 2 / b.r) * 2;
    if(get_segment_cross(Line{a.center, b.center}, Line{p, q}, ret)) {
        return printf("%.15f\n", a.r * a.r * sa / 2 + b.r * b.r * sb / 2 - a.r * a.r * sin(sa) / 2 - b.r * b.r * sin(sb) / 2) % 1;
    }
    if(dist(Line{p, q}, a.center, true) < dist(Line{p, q}, b.center, true))
        return printf("%.15f\n", a.r * a.r * (PI - sa / 2) + b.r * b.r * sb / 2 - a.r * a.r * sin(sa) / 2 - b.r * b.r * sin(sb) / 2) % 1;
    return printf("%.15f\n", a.r * a.r * sa / 2 + b.r * b.r * (PI - sb / 2) - a.r * a.r * sin(sa) / 2 - b.r * b.r * sin(sb) / 2) % 1;
}


#include <bits/stdc++.h>
#define int double
#define PI acos(-1)
using namespace std;
const double eps = 1e-12;

inline int diff(double lhs, double rhs) {
    if (lhs - eps < rhs && rhs < lhs + eps) return 0;
    return (lhs < rhs) ? -1 : 1;
}

inline bool is_between(double check, double a, double b) {
    if (a < b)
        return (a - eps < check && check < b + eps);
    else
        return (b - eps < check && check < a + eps);
}

struct Point {
    double x, y;
    bool operator==(const Point& rhs) const {
        return diff(x, rhs.x) == 0 && diff(y, rhs.y) == 0;
    }
    Point operator+(const Point& rhs) const {
        return Point{ x + rhs.x, y + rhs.y };
    }
    Point operator-(const Point& rhs) const {
        return Point{ x - rhs.x, y - rhs.y };
    }
    Point operator*(double t) const {
        return Point{ x * t, y * t };
    }
};

struct Circle {
    Point center;
    double r;
};

struct Line {
    Point pos, dir;
};

inline double inner(const Point& a, const Point& b) {
    return a.x * b.x + a.y * b.y;
}

inline double outer(const Point& a, const Point& b) {
    return a.x * b.y - a.y * b.x;
}

inline int ccw_line(const Line& line, const Point& point) {
    return diff(outer(line.dir, point - line.pos), 0);
}

inline int ccw(const Point& a, const Point& b, const Point& c) {
    return diff(outer(b - a, c - a), 0);
}

inline double dist(const Point& a, const Point& b) {
    return sqrt(inner(a - b, a - b));
}

inline double dist2(const Point &a, const Point &b) {
    return inner(a - b, a - b);
}

inline double dist(const Line& line, const Point& point, bool segment = false) {
    double c1 = inner(point - line.pos, line.dir);
    if (segment && diff(c1, 0) <= 0) return dist(line.pos, point);
    double c2 = inner(line.dir, line.dir);
    if (segment && diff(c2, c1) <= 0) return dist(line.pos + line.dir, point);
    return dist(line.pos + line.dir * (c1 / c2), point);
}

bool get_cross(const Line& a, const Line& b, Point& ret) {
    double mdet = outer(b.dir, a.dir);
    if (diff(mdet, 0) == 0) return false;
    double t2 = outer(a.dir, b.pos - a.pos) / mdet;
    ret = b.pos + b.dir * t2;
    return true;
}

bool get_segment_cross(const Line& a, const Line& b, Point& ret) {
    double mdet = outer(b.dir, a.dir);
    if (diff(mdet, 0) == 0) return false;
    double t1 = -outer(b.pos - a.pos, b.dir) / mdet;
    double t2 = outer(a.dir, b.pos - a.pos) / mdet;
    if (!is_between(t1, 0, 1) || !is_between(t2, 0, 1)) return false;
    ret = b.pos + b.dir * t2;
    return true;
}

Point inner_center(const Point &a, const Point &b, const Point &c) {
    double wa = dist(b, c), wb = dist(c, a), wc = dist(a, b);
    double w = wa + wb + wc;
    return Point{ (wa * a.x + wb * b.x + wc * c.x) / w, (wa * a.y + wb * b.y + wc * c.y) / w };
}

Point outer_center(const Point &a, const Point &b, const Point &c) {
    Point d1 = b - a, d2 = c - a;
    double area = outer(d1, d2);
    double dx = d1.x * d1.x * d2.y - d2.x * d2.x * d1.y
        + d1.y * d2.y * (d1.y - d2.y);
    double dy = d1.y * d1.y * d2.x - d2.y * d2.y * d1.x
        + d1.x * d2.x * (d1.x - d2.y);
    return Point{ a.x + dx / area / 2.0, a.y - dy / area / 2.0 };
}

vector<Point> circle_line(const Circle& circle, const Line& line) {
    vector<Point> result;
    double a = 2 * inner(line.dir, line.dir);
    double b = 2 * (line.dir.x * (line.pos.x - circle.center.x)
        + line.dir.y * (line.pos.y - circle.center.y));
    double c = inner(line.pos - circle.center, line.pos - circle.center)
        - circle.r * circle.r;
    double det = b * b - 2 * a * c;
    int pred = diff(det, 0);
    if (pred == 0)
        result.push_back(line.pos + line.dir * (-b / a));
    else if (pred > 0) {
        det = sqrt(det);
        result.push_back(line.pos + line.dir * ((-b + det) / a));
        result.push_back(line.pos + line.dir * ((-b - det) / a));
    }
    return result;
}

vector<Point> circle_circle(const Circle& a, const Circle& b) {
    vector<Point> result;
    double aa = a.center.x * a.center.x + a.center.y * a.center.y - a.r * a.r;
    double bb = b.center.x * b.center.x + b.center.y * b.center.y - b.r * b.r;
    double tmp = (bb - aa) / 2.0;
    Point cdiff = b.center - a.center;
    if (diff(cdiff.x, 0) == 0) {
        if (diff(cdiff.y, 0) == 0) {
            return result;
        }
        return circle_line(a, Line{ Point{ 0, tmp / cdiff.y }, Point{ 1, 0 } });
    }
    return circle_line(a,
        Line{ Point{ tmp / cdiff.x, 0 }, Point{ -cdiff.y, cdiff.x } });
}

Point ret;
Circle a, b;
signed main() {
    cin>>a.center.x>>a.center.y>>a.r;
    cin>>b.center.x>>b.center.y>>b.r;
    int pred = diff(dist(a.center, b.center), a.r + b.r);
    if (pred >= 0) return puts("0");
    auto r = circle_circle(a, b);
    if(dist(a.center, b.center) <= max(a.r - b.r, b.r - a.r) || !r.size())
        return printf("%.15f\n", min(a.r, b.r) * min(a.r, b.r) * PI) % 1;
    auto p = r.front(), q = r.back();
    double d = dist(p, q);
    double sa = asin(d / 2 / a.r) * 2;
    double sb = asin(d / 2 / b.r) * 2;
    assert(r.size() == 2);
    if(get_segment_cross(Line{a.center, b.center - a.center}, Line{p, q - p}, ret)){
        return printf("%.15f\n", a.r * a.r * sa / 2 + b.r * b.r * sb / 2 - a.r * a.r * sin(sa) / 2 - b.r * b.r * sin(sb) / 2) % 1;
    }
    if(dist(Line{p, q - p}, a.center, true) < dist(Line{p, q - p}, b.center, true))
        return printf("%.15f\n", a.r * a.r * (PI - sa / 2) + b.r * b.r * sb / 2 + a.r * a.r * sin(sa) / 2 - b.r * b.r * sin(sb) / 2) % 1;
    return printf("%.15f\n", a.r * a.r * sa / 2 + b.r * b.r * (PI - sb / 2) - a.r * a.r * sin(sa) / 2 + b.r * b.r * sin(sb) / 2) % 1;
}


#include <bits/stdc++.h>
using namespace std;
#define int double
#define PI acos(-1)
int x1, y1, r1;
int x2, y2, r2;
const double eps = 1e-15;

double dist(int x1, int y1, int x2, int y2) {
    return sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2));
}
signed main() {
    cin>>x1>>y1>>r1;
    cin>>x2>>y2>>r2;

    double cd = dist(x1, y1, x2, y2);
    if(r1 + r2 - eps <= cd) return puts("0");
    if(cd + r2 - eps  <= r1) {
        return printf("%.15f",  r2 * r2 * PI) % 1;
    }
    if(cd + r1 - eps  <= r2) {
        return printf("%.15f",  r1 * r1 * PI) % 1;
    }
    double s = (cd + r1 + r2) / 2;
    double ts = sqrt(s) * sqrt(s - cd) * sqrt(s - r1) * sqrt(s - r2);
    double t1 = (-r2 * r2 + cd * cd + r1 * r1) / 2 / cd / r1;
    double t2 = (-r1 * r1 + cd * cd + r2 * r2) / 2 / cd / r2;
    return printf("%.15f", r1 * r1 * acos(t1) + r2 * r2 * acos(t2) - ts * 2) % 1;
}


#include <bits/stdc++.h>
using namespace std;
#define int long long
#define R (long double) 1e9
#define PI (long double) acos(-1)
int x1, y1, r1;
int x2, y2, r2;

int pow(int x) { return x * x; }
int dist2(int x1, int y1, int x2, int y2) {
    return (x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2);
}

long double dist(int x1, int y1, int x2, int y2) {
    return sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2));
}
signed main() {
    cin>>x1>>y1>>r1;
    cin>>x2>>y2>>r2;

    int cd = dist2(x1, y1, x2, y2);
    if(pow(r1 + r2) <= cd) return puts("0");
    if(cd <= pow(r1 - r2)) {
        return printf("%.15Lf",  pow(min(r1, r2)) * PI) % 1;
    }
    long double t1 = acos((-pow(rr2) / R + rcd / R + pow(rr1) / R) * R / (long double) sqrt(rcd) / 2 / rr1);
    long double t2 = acos((-pow(rr1) / R + rcd / R + pow(rr2) / R) * R / (long double) sqrt(rcd) / 2 / rr2);
    if (t1 < 1e-8)
        return printf("%.15Lf", pow(r2) * t2) % 1;
    if (t2 < 1e-8)
        return printf("%.15Lf", pow(r1) * t1) % 1;
    printf("%.15Lf", -r1 * r2 * sin(t1 + t2) + pow(r1) * t1 + pow(r2) * t2) % 1;
}


#include <bits/stdc++.h>
using namespace std;
#define int long long
#define PI (long double) acos(-1)
int x1, y1, r1;
int x2, y2, r2;

int pow(int x) { return x * x; }
int dist2(int x1, int y1, int x2, int y2) {
    return (x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2);
}

long double dist(int x1, int y1, int x2, int y2) {
    return sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2));
}
signed main() {
    cin>>x1>>y1>>r1;
    cin>>x2>>y2>>r2;

    int cd = dist2(x1, y1, x2, y2);
    if(pow(r1 + r2) <= cd) return puts("0");
    if(cd <= pow(r1 - r2)) {
        return printf("%.15Lf",  pow(min(r1, r2)) * PI) % 1;
    }
	long double rr1 = r1 / (long double) 1e9;
	long double rr2 = r2 / (long double) 1e9;
	long double rcd = cd / (long double) 1e18;
    long double t1 = acos((-pow(rr2) + rcd + pow(rr1)) / (long double) sqrt(rcd) / 2 / rr1);
    long double t2 = acos((-pow(rr1) + rcd + pow(rr2)) / (long double) sqrt(rcd) / 2 / rr2);
    if (t1 < 1e-8)
        return printf("%.15Lf", pow(r2) * t2) % 1;
    if (t2 < 1e-8)
        return printf("%.15Lf", pow(r1) * t1) % 1;
    printf("%.15Lf", -r1 * r2 * sin(t1 + t2) + pow(r1) * t1 + pow(r2) * t2) % 1;
}


#include <bits/stdc++.h>
using namespace std;
#define int long long
#define PI (long double) acos(-1)
int x1, y1, r1;
int x2, y2, r2;

int pow(int x) { return x * x; }
int dist2(int x1, int y1, int x2, int y2) {
    return (x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2);
}

long double dist(int x1, int y1, int x2, int y2) {
    return sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2));
}
signed main() {
    cin>>x1>>y1>>r1;
    cin>>x2>>y2>>r2;

    int cd = dist2(x1, y1, x2, y2);
    if(pow(r1 + r2) <= cd) return puts("0");
    if(cd <= pow(r1 - r2)) {
        return printf("%.15Lf",  pow(min(r1, r2)) * PI) % 1;
    }
	long double rr1 = r1 / (long double) 1e6;
	long double rr2 = r2 / (long double) 1e6;
	long double rcd = cd / (long double) 1e12;
    long double t1 = acos((-pow(rr2) + rcd + pow(rr1)) / (long double) sqrt(rcd) / 2 / rr1);
    long double t2 = acos((-pow(rr1) + rcd + pow(rr2)) / (long double) sqrt(rcd) / 2 / rr2);
    if (t1 < 1e-8)
        return printf("%.15Lf", pow(r2) * t2) % 1;
    if (t2 < 1e-8)
        return printf("%.15Lf", pow(r1) * t1) % 1;
    printf("%.15Lf", -r1 * r2 * sin(t1 + t2) + pow(r1) * t1 + pow(r2) * t2) % 1;
}


#include <bits/stdc++.h>
using namespace std;
#define int long long
#define PI (long double) acos(-1)
int x1, y1, r1;
int x2, y2, r2;

int pow(int x) { return x * x; }
int dist2(int x1, int y1, int x2, int y2) {
    return (x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2);
}

long double dist(int x1, int y1, int x2, int y2) {
    return sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2));
}
signed main() {
    cin>>x1>>y1>>r1;
    cin>>x2>>y2>>r2;

    int cd = dist2(x1, y1, x2, y2);
    if(pow(r1 + r2) <= cd) return puts("0");
    if(cd <= pow(r1 - r2)) {
        return printf("%.15Lf",  pow(min(r1, r2)) * PI) % 1;
    }
	long double rr1 = r1 / (long double) 1e9;
	long double rr2 = r2 / (long double) 1e9;
	long double rcd = cd / (long double) 1e9;
    long double t1 = acos((-pow(rr2) + rcd + pow(rr1)) / (long double) sqrt(rcd) / 2 / rr1);
    long double t2 = acos((-pow(rr1) + rcd + pow(rr2)) / (long double) sqrt(rcd) / 2 / rr2);
    if (t1 < 1e-8)
        return printf("%.15Lf", pow(r2) * t2) % 1;
    if (t2 < 1e-8)
        return printf("%.15Lf", pow(r1) * t1) % 1;
    printf("%.15Lf", -r1 * r2 * sin(t1 + t2) + pow(r1) * t1 + pow(r2) * t2) % 1;
}


#include <bits/stdc++.h>
#define PI acos(-1)
using namespace std;
const double eps = 1e-15;

bool xxx;
inline int diff(double lhs, double rhs) {
    if (lhs - eps < rhs && rhs < lhs + eps) return 0;
    return (lhs < rhs) ? -1 : 1;
}

inline bool is_between(double check, double a, double b) {
    if (a < b)
        return (a - eps < check && check < b + eps);
    else
        return (b - eps < check && check < a + eps);
}

struct Point {
    double x, y;
    bool operator==(const Point& rhs) const {
        return diff(x, rhs.x) == 0 && diff(y, rhs.y) == 0;
    }
    Point operator+(const Point& rhs) const {
        return Point{ x + rhs.x, y + rhs.y };
    }
    Point operator-(const Point& rhs) const {
        return Point{ x - rhs.x, y - rhs.y };
    }
    Point operator*(double t) const {
        return Point{ x * t, y * t };
    }
};

struct Circle {
    Point center;
    double r;
};

struct Line {
    Point pos, dir;
};

inline double inner(const Point& a, const Point& b) {
    return a.x * b.x + a.y * b.y;
}

inline double outer(const Point& a, const Point& b) {
    return a.x * b.y - a.y * b.x;
}

inline int ccw_line(const Line& line, const Point& point) {
    return diff(outer(line.dir, point - line.pos), 0);
}

inline int ccw(const Point& a, const Point& b, const Point& c) {
    return diff(outer(b - a, c - a), 0);
}

inline double dist(const Point& a, const Point& b) {
    return sqrt(inner(a - b, a - b));
}

inline double dist2(const Point &a, const Point &b) {
    return inner(a - b, a - b);
}

inline double dist(const Line& line, const Point& point, bool segment = false) {
    double c1 = inner(point - line.pos, line.dir);
    if (segment && diff(c1, 0) <= 0) return dist(line.pos, point);
    double c2 = inner(line.dir, line.dir);
    if (segment && diff(c2, c1) <= 0) return dist(line.pos + line.dir, point);
    return dist(line.pos + line.dir * (c1 / c2), point);
}

bool get_cross(const Line& a, const Line& b, Point& ret) {
    double mdet = outer(b.dir, a.dir);
    if (diff(mdet, 0) == 0) return false;
    double t2 = outer(a.dir, b.pos - a.pos) / mdet;
    ret = b.pos + b.dir * t2;
    return true;
}

bool get_segment_cross(const Line& a, const Line& b, Point& ret) {
    double mdet = outer(b.dir, a.dir);
    if (diff(mdet, 0) == 0) return false;
    double t1 = -outer(b.pos - a.pos, b.dir) / mdet;
    double t2 = outer(a.dir, b.pos - a.pos) / mdet;
    if (!is_between(t1, 0, 1) || !is_between(t2, 0, 1)) return false;
    ret = b.pos + b.dir * t2;
    return true;
}

Point inner_center(const Point &a, const Point &b, const Point &c) {
    double wa = dist(b, c), wb = dist(c, a), wc = dist(a, b);
    double w = wa + wb + wc;
    return Point{ (wa * a.x + wb * b.x + wc * c.x) / w, (wa * a.y + wb * b.y + wc * c.y) / w };
}

Point outer_center(const Point &a, const Point &b, const Point &c) {
    Point d1 = b - a, d2 = c - a;
    double area = outer(d1, d2);
    double dx = d1.x * d1.x * d2.y - d2.x * d2.x * d1.y
        + d1.y * d2.y * (d1.y - d2.y);
    double dy = d1.y * d1.y * d2.x - d2.y * d2.y * d1.x
        + d1.x * d2.x * (d1.x - d2.y);
    return Point{ a.x + dx / area / 2.0, a.y - dy / area / 2.0 };
}

vector<Point> circle_line(const Circle& circle, const Line& line) {
    vector<Point> result;
    double a = 2 * inner(line.dir, line.dir);
    double b = 2 * (line.dir.x * (line.pos.x - circle.center.x)
        + line.dir.y * (line.pos.y - circle.center.y));
    double c = inner(line.pos - circle.center, line.pos - circle.center)
        - circle.r * circle.r;
    double det = b * b - 2 * a * c;
    int pred = diff(det, 0);
    if (xxx) printf("%d %.15f\n", pred, det);
    if (xxx) printf("%.15f %.15f %.15f\n", a, b, c);
    if (pred == 0)
        result.push_back(line.pos + line.dir * (-b / a));
    else if (pred > 0) {
        det = sqrt(det);
        result.push_back(line.pos + line.dir * ((-b + det) / a));
        result.push_back(line.pos + line.dir * ((-b - det) / a));
    }
    return result;
}

vector<Point> circle_circle(const Circle& a, const Circle& b) {
    vector<Point> result;
    double aa = a.center.x * a.center.x + a.center.y * a.center.y - a.r * a.r;
    double bb = b.center.x * b.center.x + b.center.y * b.center.y - b.r * b.r;
    double tmp = (bb - aa) / 2.0;
    Point cdiff = b.center - a.center;
    if (diff(cdiff.x, 0) == 0) {
        if (diff(cdiff.y, 0) == 0) {
            return result;
        }
        return circle_line(a, Line{ Point{ 0, tmp / cdiff.y }, Point{ 1, 0 } });
    }
    if (a.center.x == 44721) printf("!\n");
    return circle_line(a,
        Line{ Point{ tmp / cdiff.x, 0 }, Point{ -cdiff.y, cdiff.x } });
}

double cs(double r, double h) {
    return r * r * h;
}

double ts(double a, double b) {
    return sqrt(a + b / 2) * sqrt(a - b / 2) * b / 2;
}

Point ret;
Circle a, b;
signed main() {
    cin>>a.center.x>>a.center.y>>a.r;
    cin>>b.center.x>>b.center.y>>b.r;
    xxx = (a.center.x == 44721);
    int pred = diff(dist(a.center, b.center), a.r + b.r);
    if (pred >= 0) return puts("0");
    auto r = circle_circle(a, b);
    double cc = dist(a.center, b.center);
    if (a.center.x == 44721) printf("%.15f %d\n", cc, (int) r.size());
    if(cc <= max(a.r - b.r, b.r - a.r) || !r.size())
        return printf("%.15f\n", min(a.r, b.r) * min(a.r, b.r) * PI) % 1;
    auto p = r.front(), q = r.back();
    double d = sqrt(abs(-cc + a.r - b.r)) * sqrt(abs(-cc - a.r + b.r)) * sqrt(-cc + a.r + b.r) * sqrt(cc + a.r + b.r) / cc;
    double sa = asin(d / 2 / a.r);
    double sb = asin(d / 2 / b.r);
    if (a.center.x == 44721) printf("%.15f %d\n", cc, (int) r.size());
    if(get_segment_cross(Line{a.center, b.center - a.center}, Line{p, q - p}, ret)){
        return printf("%.15f\n", cs(a.r, sa) + cs(b.r, sb) - ts(a.r, d) - ts(b.r, d)) % 1;
    }
    if (a.center.x == 44721) printf("%.15f %d\n", cc, (int) r.size());
    if(dist(Line{p, q - p}, a.center, true) < dist(Line{p, q - p}, b.center, true))
        return printf("%.15f\n", cs(a.r, PI - sa) + cs(b.r, sb) + ts(a.r, d) - ts(b.r, d)) % 1;
    if (a.center.x == 44721) printf("%.15f %d\n", cc, (int) r.size());
    return printf("%.15f\n", cs(a.r, sa) + cs(b.r, PI - sb) - ts(a.r, d) + ts(b.r, d)) % 1;
}