import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;

public class Euler966 {

    static final double K_PI = 3.141592653589793238462643383279502884;
    static final double K_EPS = 1e-12;

    static class Vec2 {
        double x, y;

        Vec2(double x, double y) {
            this.x = x;
            this.y = y;
        }

        Vec2 add(Vec2 o) {
            return new Vec2(x + o.x, y + o.y);
        }

        Vec2 sub(Vec2 o) {
            return new Vec2(x - o.x, y - o.y);
        }

        Vec2 mul(double s) {
            return new Vec2(x * s, y * s);
        }
    }

    static double dot(Vec2 a, Vec2 b) {
        return a.x * b.x + a.y * b.y;
    }

    static double cross(Vec2 a, Vec2 b) {
        return a.x * b.y - a.y * b.x;
    }

    static double norm2(Vec2 v) {
        return dot(v, v);
    }

    static double dist(Vec2 a, Vec2 b) {
        return Math.sqrt(norm2(a.sub(b)));
    }

    static class Triangle {
        Vec2 a, b, c;
        double area, radius, maxSide;

        Triangle(Vec2 a, Vec2 b, Vec2 c, double area, double radius, double maxSide) {
            this.a = a;
            this.b = b;
            this.c = c;
            this.area = area;
            this.radius = radius;
            this.maxSide = maxSide;
        }
    }

    static Triangle makeTriangle(int s1, int s2, int s3) {
        int[] sides = { s1, s2, s3 };
        Arrays.sort(sides);

        double a = sides[0];
        double b = sides[1];
        double c = sides[2];

        Vec2 A = new Vec2(0.0, 0.0);
        Vec2 B = new Vec2(c, 0.0);
        double x = (b * b + c * c - a * a) / (2.0 * c);
        double y2 = b * b - x * x;
        if (y2 < 0.0 && y2 > -1e-18) {
            y2 = 0.0;
        }
        Vec2 C = new Vec2(x, Math.sqrt(Math.max(0.0, y2)));

        double area = Math.abs(cross(B.sub(A), C.sub(A))) * 0.5;
        double radius = Math.sqrt(area / K_PI);
        double maxSide = Math.max(Math.max(dist(A, B), dist(B, C)), dist(C, A));

        return new Triangle(A, B, C, area, radius, maxSide);
    }

    static boolean pointInTriangle(Triangle tri, Vec2 p) {
        double c1 = cross(tri.b.sub(tri.a), p.sub(tri.a));
        double c2 = cross(tri.c.sub(tri.b), p.sub(tri.b));
        double c3 = cross(tri.a.sub(tri.c), p.sub(tri.c));
        return c1 >= -1e-14 && c2 >= -1e-14 && c3 >= -1e-14;
    }

    static Vec2 nearestOnSegment(Vec2 p, Vec2 u, Vec2 v) {
        Vec2 uv = v.sub(u);
        double d = norm2(uv);
        if (d <= 0.0)
            return u;
        double t = dot(p.sub(u), uv) / d;
        if (t < 0.0)
            t = 0.0;
        else if (t > 1.0)
            t = 1.0;
        return u.add(uv.mul(t));
    }

    static Vec2 projectToTriangle(Triangle tri, Vec2 p) {
        if (pointInTriangle(tri, p))
            return p;

        Vec2[] candidates = {
                tri.a, tri.b, tri.c,
                nearestOnSegment(p, tri.a, tri.b),
                nearestOnSegment(p, tri.b, tri.c),
                nearestOnSegment(p, tri.c, tri.a),
        };

        Vec2 best = candidates[0];
        double bestD = norm2(p.sub(best));
        for (int i = 1; i < 6; ++i) {
            double cur = norm2(p.sub(candidates[i]));
            if (cur < bestD) {
                bestD = cur;
                best = candidates[i];
            }
        }
        return best;
    }

    static double segmentContribution(Vec2 a, Vec2 b, double r2) {
        Vec2[] pts = new Vec2[4];
        int n = 0;
        pts[n++] = a;

        Vec2 d = b.sub(a);
        double qa = dot(d, d);
        double qb = 2.0 * dot(a, d);
        double qc = dot(a, a) - r2;
        double disc = qb * qb - 4.0 * qa * qc;

        if (disc > 1e-18) {
            double sdisc = Math.sqrt(disc);
            double t1 = (-qb - sdisc) / (2.0 * qa);
            double t2 = (-qb + sdisc) / (2.0 * qa);
            if (t1 > t2) {
                double tmp = t1;
                t1 = t2;
                t2 = tmp;
            }

            if (t1 > K_EPS && t1 < 1.0 - K_EPS) {
                pts[n++] = a.add(d.mul(t1));
            }
            if (t2 > K_EPS && t2 < 1.0 - K_EPS && Math.abs(t2 - t1) > 1e-12) {
                pts[n++] = a.add(d.mul(t2));
            }
        }

        pts[n++] = b;

        double acc = 0.0;
        for (int i = 0; i + 1 < n; ++i) {
            Vec2 p = pts[i];
            Vec2 q = pts[i + 1];
            Vec2 mid = new Vec2((p.x + q.x) * 0.5, (p.y + q.y) * 0.5);

            if (norm2(mid) <= r2 + 1e-13) {
                acc += 0.5 * cross(p, q);
            } else {
                acc += 0.5 * r2 * Math.atan2(cross(p, q), dot(p, q));
            }
        }
        return acc;
    }

    static double overlapArea(Triangle tri, Vec2 center) {
        double r = tri.radius;
        double r2 = r * r;

        Vec2 p0 = tri.a.sub(center);
        Vec2 p1 = tri.b.sub(center);
        Vec2 p2 = tri.c.sub(center);

        double area = 0.0;
        area += segmentContribution(p0, p1, r2);
        area += segmentContribution(p1, p2, r2);
        area += segmentContribution(p2, p0, r2);
        return Math.abs(area);
    }

    static class EvalPoint implements Comparable<EvalPoint> {
        Vec2 p;
        double v;

        EvalPoint(Vec2 p, double v) {
            this.p = p;
            this.v = v;
        }

        @Override
        public int compareTo(EvalPoint o) {
            return Double.compare(o.v, this.v);
        }
    }

    static EvalPoint nelderMead(Triangle tri, Vec2 start, double step, int iterations) {
        List<EvalPoint> simplex = new ArrayList<>(Arrays.asList(
                new EvalPoint(projectToTriangle(tri, start), overlapArea(tri, projectToTriangle(tri, start))),
                new EvalPoint(projectToTriangle(tri, new Vec2(start.x + step, start.y)),
                        overlapArea(tri, projectToTriangle(tri, new Vec2(start.x + step, start.y)))),
                new EvalPoint(projectToTriangle(tri, new Vec2(start.x, start.y + step)),
                        overlapArea(tri, projectToTriangle(tri, new Vec2(start.x, start.y + step))))));

        for (int it = 0; it < iterations; ++it) {
            Collections.sort(simplex);

            Vec2 centroid = new Vec2(
                    (simplex.get(0).p.x + simplex.get(1).p.x) * 0.5,
                    (simplex.get(0).p.y + simplex.get(1).p.y) * 0.5);

            Vec2 reflected = new Vec2(
                    centroid.x + (centroid.x - simplex.get(2).p.x),
                    centroid.y + (centroid.y - simplex.get(2).p.y));
            Vec2 pr = projectToTriangle(tri, reflected);
            EvalPoint er = new EvalPoint(pr, overlapArea(tri, pr));

            if (er.v > simplex.get(0).v) {
                Vec2 expanded = new Vec2(
                        centroid.x + 2.0 * (er.p.x - centroid.x),
                        centroid.y + 2.0 * (er.p.y - centroid.y));
                Vec2 pe = projectToTriangle(tri, expanded);
                EvalPoint ee = new EvalPoint(pe, overlapArea(tri, pe));
                simplex.set(2, ee.v > er.v ? ee : er);
                continue;
            }

            if (er.v > simplex.get(1).v) {
                simplex.set(2, er);
                continue;
            }

            Vec2 contracted = new Vec2(
                    centroid.x + 0.5 * (simplex.get(2).p.x - centroid.x),
                    centroid.y + 0.5 * (simplex.get(2).p.y - centroid.y));
            Vec2 pc = projectToTriangle(tri, contracted);
            EvalPoint ec = new EvalPoint(pc, overlapArea(tri, pc));
            if (ec.v > simplex.get(2).v) {
                simplex.set(2, ec);
                continue;
            }

            Vec2 p1 = new Vec2(
                    simplex.get(0).p.x + 0.5 * (simplex.get(1).p.x - simplex.get(0).p.x),
                    simplex.get(0).p.y + 0.5 * (simplex.get(1).p.y - simplex.get(0).p.y));
            Vec2 pp1 = projectToTriangle(tri, p1);
            simplex.set(1, new EvalPoint(pp1, overlapArea(tri, pp1)));

            Vec2 p2 = new Vec2(
                    simplex.get(0).p.x + 0.5 * (simplex.get(2).p.x - simplex.get(0).p.x),
                    simplex.get(0).p.y + 0.5 * (simplex.get(2).p.y - simplex.get(0).p.y));
            Vec2 pp2 = projectToTriangle(tri, p2);
            simplex.set(2, new EvalPoint(pp2, overlapArea(tri, pp2)));
        }

        Collections.sort(simplex);
        return simplex.get(0);
    }

    static double maximizeOverlap(int s1, int s2, int s3) {
        Triangle tri = makeTriangle(s1, s2, s3);
        List<Vec2> seeds = new ArrayList<>();

        int grid = 5;
        for (int i = 0; i <= grid; ++i) {
            for (int j = 0; j + i <= grid; ++j) {
                double u = (double) i / grid;
                double v = (double) j / grid;
                double w = 1.0 - u - v;
                seeds.add(new Vec2(
                        u * tri.a.x + v * tri.b.x + w * tri.c.x,
                        u * tri.a.y + v * tri.b.y + w * tri.c.y));
            }
        }

        seeds.add(new Vec2(
                (tri.a.x + tri.b.x + tri.c.x) / 3.0,
                (tri.a.y + tri.b.y + tri.c.y) / 3.0));

        double sideA = dist(tri.b, tri.c);
        double sideB = dist(tri.c, tri.a);
        double sideC = dist(tri.a, tri.b);
        double ws = sideA + sideB + sideC;

        seeds.add(new Vec2(
                (sideA * tri.a.x + sideB * tri.b.x + sideC * tri.c.x) / ws,
                (sideA * tri.a.y + sideB * tri.b.y + sideC * tri.c.y) / ws));

        List<EvalPoint> evaluated = new ArrayList<>();
        for (Vec2 p : seeds) {
            Vec2 proj = projectToTriangle(tri, p);
            evaluated.add(new EvalPoint(proj, overlapArea(tri, proj)));
        }

        Collections.sort(evaluated);

        EvalPoint best = evaluated.get(0);
        int tries = Math.min(4, evaluated.size());
        double step = tri.maxSide * 0.18;

        for (int i = 0; i < tries; ++i) {
            EvalPoint cur = nelderMead(tri, evaluated.get(i).p, step, 90);
            if (cur.v > best.v) {
                best = cur;
            }
        }

        EvalPoint refined = nelderMead(tri, best.p, tri.maxSide * 0.05, 50);
        if (refined.v > best.v) {
            best = refined;
        }

        if (best.v < 0.0)
            return 0.0;
        if (best.v > tri.area)
            return tri.area;
        return best.v;
    }

    static boolean nearlyEqual(double x, double y, double eps) {
        return Math.abs(x - y) <= eps;
    }

    static List<int[]> enumerateTriangles() {
        List<int[]> all = new ArrayList<>();
        for (int a = 1; a <= 200; ++a) {
            for (int b = a; b <= 200 - a; ++b) {
                int maxC = 200 - a - b;
                for (int c = b; c <= maxC; ++c) {
                    if (a + b <= c)
                        continue;
                    all.add(new int[] { a, b, c });
                }
            }
        }
        return all;
    }

    public static String solve() {
        List<int[]> triangles = enumerateTriangles();

        double total = triangles.parallelStream()
                .mapToDouble(t -> maximizeOverlap(t[0], t[1], t[2]))
                .sum();

        total = Math.round(total * 100.0) / 100.0;
        return String.format(java.util.Locale.US, "%.2f", total);
    }

    public static void main(String[] args) {
        double i345 = maximizeOverlap(3, 4, 5);
        if (!nearlyEqual(i345, 4.593049, 2e-6)) {
            System.out.println("Validation failed");
            return;
        }

        double i346 = maximizeOverlap(3, 4, 6);
        if (!nearlyEqual(i346, 3.552564, 2e-6)) {
            System.out.println("Validation failed");
            return;
        }

        double iPerm = maximizeOverlap(5, 3, 4);
        if (!nearlyEqual(iPerm, i345, 1e-10)) {
            System.out.println("Validation failed");
            return;
        }

        System.out.println(solve());
    }
}
