Problem: You are given two circles. Find the area of their intersection.

Input

The first line contains three integers x1, y1, r1 ( - 109 ≤ x1, y1 ≤ 109, 1 ≤ r1 ≤ 109) — the position of the center and the radius of the first circle.

The second line contains three integers x2, y2, r2 ( - 109 ≤ x2, y2 ≤ 109, 1 ≤ r2 ≤ 109) — the position of the center and the radius of the second circle.

Output

Print the area of the intersection of the circles. The answer will be considered correct if the absolute or relative error doesn't exceed 10 - 6.

Examples

Input

0 0 4
6 0 4


Output

7.25298806364175601379


Input

0 0 5
11 0 5


Output

0.00000000000000000000

Solution (in JAVA):

Solution:
import java.io.*;
import java.math.*;
import java.util.*;
import java.util.stream.*;

@SuppressWarnings("unchecked")
public class P600D {

  // contants
  final static int ITERS = 1_000;
  final static MathContext MC = MathContext.DECIMAL128;
//  final static MathContext MC = new MathContext(1000, RoundingMode.HALF_EVEN);
  final static BigDecimal EPS = BigDecimal.valueOf(1E-30);
  final static BigDecimal ONE = BigDecimal.ONE;
  final static BigDecimal TWO = ONE.add(ONE);
  final static BigDecimal ONE_HALF = ONE.divide(TWO, MC);
  final static BigDecimal PI = new BigDecimal("3.1415926535897932384626433832795028841971693993751");
  final static BigDecimal PI_2 = PI.divide(TWO, MC);
  final static BigDecimal ATAN1_2 = new BigDecimal("0.46364760900080611621425623146121440202853705428612");

  BigDecimal sqr(BigDecimal x) {
    return x.multiply(x, MC);
  }

  BigDecimal sqrt(BigDecimal x) {
    BigDecimal y = BigDecimal.valueOf(Math.sqrt(x.doubleValue())).add(EPS); // first approx
    for (int i = ITERS; i > 0; i--) { // Heron's iters
      y = y.add(x.divide(y, MC)).divide(TWO, MC);
    }

    return y;
  }

  BigDecimal acos(BigDecimal x) {
    if (x.subtract(ONE).abs().compareTo(EPS) <= 0) {
      return BigDecimal.ZERO;
    }

    return PI_2.subtract(atan(x.divide(sqrt(ONE.subtract(sqr(x), MC)), MC)), MC);
  }

  BigDecimal atan(BigDecimal x) {
    int sgn = x.signum();
    x = x.abs();
    BigDecimal add = BigDecimal.ZERO;

    if (x.compareTo(ONE) >= 0) {
      add = PI_2.divide(TWO);
      x = x.subtract(ONE).divide(x.add(ONE), MC);
    }

    if (x.compareTo(ONE_HALF) >= 0) {
      add = add.add(ATAN1_2);
      x = x.subtract(ONE_HALF).divide(x.divide(TWO, MC).add(ONE), MC);
    }

    BigDecimal n = ONE;
    BigDecimal y = x;
    BigDecimal x2 = sqr(x);

    for (int i = 0; i < ITERS; i++) {
      n = n.add(TWO);
      x = x.multiply(x2, MC);
      y = ((i & 1) == 0) ? y.subtract(x.divide(n, MC), MC) : y.add(x.divide(n, MC), MC);
    }

    return ((sgn >= 0) ? y.add(add) : y.add(add).negate());
  }

  BigDecimal area(BigDecimal r, BigDecimal d) {
    BigDecimal d_r = d.divide(r, MC);
    return r.multiply(r.multiply(acos(d_r)).subtract(d.multiply(sqrt(ONE.subtract(sqr(d_r))))));
  }

  public void run() throws Exception {
    BigDecimal x2 = BigDecimal.valueOf(nextDouble());
    BigDecimal y2 = BigDecimal.valueOf(nextDouble());
    BigDecimal r1 = BigDecimal.valueOf(nextDouble());
    x2 = sqrt(sqr(BigDecimal.valueOf(nextDouble()).subtract(x2)).add(sqr(BigDecimal.valueOf(nextDouble()).subtract(y2))));
    BigDecimal r2 = BigDecimal.valueOf(nextDouble());

    if (r2.compareTo(r1) > 0) {
      BigDecimal t = r1; r1 = r2; r2 = t;
    }

    // empty area
    if (x2.compareTo(r1.add(r2)) >= 0) {
      println("0");
      return;
    }

    // full "r2" area
    if (x2.add(r2).compareTo(r1) <= 0) {
      println("+" + PI.multiply(sqr(r2)));
      return;
    }

    BigDecimal x0 = sqr(x2).add(sqr(r1)).subtract(sqr(r2)).divide(x2, MC).divide(TWO, MC);

    println(area(r1, x0).add(area(r2, x2.subtract(x0))));
  }
  public static void main(String... args) throws Exception {
    br = new BufferedReader(new InputStreamReader(System.in));
    pw = new PrintWriter(new BufferedOutputStream(System.out));
    new P600D().run();
    br.close();
    pw.close();
    System.err.println("\n[Time : " + (System.currentTimeMillis() - startTime) + " ms]");
  }

  static long startTime = System.currentTimeMillis();
  static BufferedReader br;
  static PrintWriter pw;
  StringTokenizer stok;

  String nextToken() throws IOException {
    while (stok == null || !stok.hasMoreTokens()) {
      String s = br.readLine();
      if (s == null) { return null; }
      stok = new StringTokenizer(s);
    }
    return stok.nextToken();
  }

  void print(byte b) { print("" + b); }
  void print(int i) { print("" + i); }
  void print(long l) { print("" + l); }
  void print(double d) { print("" + d); }
  void print(char c) { print("" + c); }
  void print(Object o) {
    if (o instanceof int[]) { print(Arrays.toString((int [])o));
    } else if (o instanceof long[]) { print(Arrays.toString((long [])o));
    } else if (o instanceof char[]) { print(Arrays.toString((char [])o));
    } else if (o instanceof byte[]) { print(Arrays.toString((byte [])o));
    } else if (o instanceof short[]) { print(Arrays.toString((short [])o));
    } else if (o instanceof boolean[]) { print(Arrays.toString((boolean [])o));
    } else if (o instanceof float[]) { print(Arrays.toString((float [])o));
    } else if (o instanceof double[]) { print(Arrays.toString((double [])o));
    } else if (o instanceof Object[]) { print(Arrays.toString((Object [])o));
    } else { print("" + o); }
  }
  void print(String s) { pw.print(s); }
  void println() { println(""); }
  void println(byte b) { println("" + b); }
  void println(int i) { println("" + i); }
  void println(long l) { println("" + l); }
  void println(double d) { println("" + d); }
  void println(char c) { println("" + c); }
  void println(Object o) { print(o); println(); }
  void println(String s) { pw.println(s); }
  int nextInt() throws IOException { return Integer.parseInt(nextToken()); }
  long nextLong() throws IOException { return Long.parseLong(nextToken()); }
  double nextDouble() throws IOException { return Double.parseDouble(nextToken()); }
  char nextChar() throws IOException { return (char) (br.read()); }
  String next() throws IOException { return nextToken(); }
  String nextLine() throws IOException { return br.readLine(); }
  int [] readInt(int size) throws IOException {
    int [] array = new int [size];
    for (int i = 0; i < size; i++) { array[i] = nextInt(); }
    return array;
  }
  long [] readLong(int size) throws IOException {
    long [] array = new long [size];
    for (int i = 0; i < size; i++) { array[i] = nextLong(); }
    return array;
  }
  double [] readDouble(int size) throws IOException {
    double [] array = new double [size];
    for (int i = 0; i < size; i++) { array[i] = nextDouble(); }
    return array;
  }
  String [] readLines(int size) throws IOException {
    String [] array = new String [size];
    for (int i = 0; i < size; i++) { array[i] = nextLine(); }
    return array;
  }
}