Problem: Greg the Dwarf has been really busy recently with excavations by the Neverland Mountain. However for the well-known reasons (as you probably remember he is a very unusual dwarf and he cannot stand sunlight) Greg can only excavate at night. And in the morning he should be in his crypt before the first sun ray strikes. That's why he wants to find the shortest route from the excavation point to his crypt. Greg has recollected how the Codeforces participants successfully solved the problem of transporting his coffin to a crypt. So, in some miraculous way Greg appeared in your bedroom and asks you to help him in a highly persuasive manner. As usual, you didn't feel like turning him down.

After some thought, you formalized the task as follows: as the Neverland mountain has a regular shape and ends with a rather sharp peak, it can be represented as a cone whose base radius equals r and whose height equals h. The graveyard where Greg is busy excavating and his crypt can be represented by two points on the cone's surface. All you've got to do is find the distance between points on the cone's surface. 

The task is complicated by the fact that the mountain's base on the ground level and even everything below the mountain has been dug through by gnome (one may wonder whether they've been looking for the same stuff as Greg...). So, one can consider the shortest way to pass not only along the side surface, but also along the cone's base (and in a specific case both points can lie on the cone's base — see the first sample test)

Greg will be satisfied with the problem solution represented as the length of the shortest path between two points — he can find his way pretty well on his own. He gave you two hours to solve the problem and the time is ticking!

Input

The first input line contains space-separated integers r and h (1 ≤ r, h ≤ 1000) — the base radius and the cone height correspondingly. The second and third lines contain coordinates of two points on the cone surface, groups of three space-separated real numbers. The coordinates of the points are given in the systems of coordinates where the origin of coordinates is located in the centre of the cone's base and its rotation axis matches the OZ axis. In this coordinate system the vertex of the cone is located at the point (0, 0, h), the base of the cone is a circle whose center is at the point (0, 0, 0), lying on the XOY plane, and all points on the cone surface have a non-negative coordinate z. It is guaranteed that the distances from the points to the cone surface do not exceed 10 - 12. All real numbers in the input have no more than 16 digits after decimal point.

Output

Print the length of the shortest path between the points given in the input, with absolute or relative error not exceeding 10 - 6.

Examples

Input

2 2
1.0 0.0 0.0
-1.0 0.0 0.0


Output

2.000000000

Input

2 2
1.0 0.0 0.0
1.0 0.0 1.0


Output

2.414213562

Input

2 2
1.0 0.0 1.0
-1.0 0.0 1.0


Output

2.534324263

Input

2 2
1.0 0.0 0.0
0.0 1.0 1.0


Output

3.254470198

Solution (in CPP):

Solution:
#include <bits/stdc++.h>
using namespace std;
double h, r;
double pi = 3.141592653589793;
bool isGreaterThan(double a, double b) { return a - b > 0.000001; }
bool isZero(double d) { return d < 0.000001 && d > -0.000001; }
pair<double, double> findCoordinatesOnPlane(double x, double y, double z) {
  double angleOnCircle, theta, sinTheta, cosTheta;
  double d, tmp;
  angleOnCircle = atan2(y, x);
  angleOnCircle += angleOnCircle < 0.0 ? pi + pi : 0.0;
  theta = angleOnCircle * r / sqrt(r * r + h * h);
  sinTheta = sin(theta);
  cosTheta = cos(theta);
  d = (h - z);
  d = (z ? sqrt(x * x + y * y + d * d) : sqrt(r * r + h * h));
  return make_pair(theta, d);
}
double euclideanDistance(double x1, double y1, double x2, double y2) {
  double tmp1 = x1 - x2, tmp2 = y1 - y2;
  return sqrt(tmp1 * tmp1 + tmp2 * tmp2);
}
double findConeSurfaceDistance(double x1, double y1, double z1, double x2,
                               double y2, double z2) {
  pair<double, double> a, b, tmp;
  double tmp1, tmp2, aTheta, bTheta, alpha;
  tmp = findCoordinatesOnPlane(x1, y1, z1);
  b = findCoordinatesOnPlane(x2, y2, z2);
  a = max(tmp, b);
  b = min(tmp, b);
  alpha = 2 * pi * r / sqrt(r * r + h * h);
  aTheta = a.first;
  bTheta = b.first;
  if (isGreaterThan((aTheta - bTheta), alpha / 2.0)) {
    aTheta = bTheta + (alpha - aTheta + bTheta);
  }
  return euclideanDistance(a.second * cos(aTheta), a.second * sin(aTheta),
                           b.second * cos(bTheta), b.second * sin(bTheta));
}
double sortaBinarySearch(double left, double right, double xHi, double yHi,
                         double zHi, double xLo, double yLo, double zLo) {
  double x, y, leftVal, rightVal, middle, midVal;
  x = r * cos(left);
  y = r * sin(left);
  leftVal = euclideanDistance(x, y, xLo, yLo) +
            findConeSurfaceDistance(xHi, yHi, zHi, x, y, 0.0);
  x = r * cos(right);
  y = r * sin(right);
  rightVal = euclideanDistance(x, y, xLo, yLo) +
             findConeSurfaceDistance(xHi, yHi, zHi, x, y, 0.0);
  while (!isZero(right - left)) {
    middle = (left + right) / 2.0;
    x = r * cos(middle);
    y = r * sin(middle);
    midVal = euclideanDistance(x, y, xLo, yLo) +
             findConeSurfaceDistance(xHi, yHi, zHi, x, y, 0.0);
    if (leftVal > rightVal) {
      leftVal = midVal;
      left = middle;
    } else {
      rightVal = midVal;
      right = middle;
    }
  }
  return min(leftVal, rightVal);
}
double findOptimalSingleBrinkPointDistance(double xHi, double yHi, double zHi,
                                           double xLo, double yLo, double zLo) {
  pair<double, double> tmpCoord;
  double minDist;
  double left = 0, right = 2 * pi, middle;
  double leftVal, rightVal, midVal, prevMinDegree;
  double curr;
  double x, y;
  double aDegree = pi / 180.0, twoDegrees = pi / 90.0;
  double minDegree, minVal;
  x = r * cos(left);
  y = r * sin(left);
  minVal = euclideanDistance(x, y, xLo, yLo) +
           findConeSurfaceDistance(xHi, yHi, zHi, x, y, 0.0);
  minDegree = left;
  for (left = aDegree; left < right; left += aDegree) {
    x = r * cos(left);
    y = r * sin(left);
    curr = euclideanDistance(x, y, xLo, yLo) +
           findConeSurfaceDistance(x, y, 0, xHi, yHi, zHi);
    if (curr < minVal) {
      prevMinDegree = minDegree;
      minVal = curr;
      minDegree = left;
    }
  }
  left = minDegree - aDegree * 2;
  right = minDegree + aDegree * 2;
  minVal = sortaBinarySearch(minDegree - aDegree, minDegree + aDegree, xHi, yHi,
                             zHi, xLo, yLo, zLo);
  minVal = min(minVal, sortaBinarySearch(minDegree - 2 * aDegree,
                                         minDegree + 2 * aDegree, xHi, yHi, zHi,
                                         xLo, yLo, zLo));
  return minVal;
}
double sortaBinarySearch2(double left, double right, double x1, double y1,
                          double z1, double x2, double y2, double z2) {
  double leftVal, rightVal, midVal, middle, x, y;
  x = r * cos(left);
  y = r * sin(left);
  leftVal = findConeSurfaceDistance(x1, y1, z1, x, y, 0.0) +
            findOptimalSingleBrinkPointDistance(x2, y2, z2, x, y, 0.0);
  x = r * cos(right);
  y = r * sin(right);
  rightVal = findConeSurfaceDistance(x1, y1, z1, x, y, 0.0) +
             findOptimalSingleBrinkPointDistance(x2, y2, z2, x, y, 0.0);
  while (!isZero(right - left)) {
    middle = (left + right) / 2.0;
    x = r * cos(middle);
    y = r * sin(middle);
    midVal = findConeSurfaceDistance(x1, y1, z1, x, y, 0.0);
    midVal += findOptimalSingleBrinkPointDistance(x2, y2, z2, x, y, 0.0);
    if (leftVal > rightVal) {
      leftVal = midVal;
      left = middle;
    } else {
      rightVal = midVal;
      right = middle;
    }
  }
  return min(leftVal, rightVal);
}
double findOptimalDoubleBrinkPointDistance(double x1, double y1, double z1,
                                           double x2, double y2, double z2) {
  double minDegree, minVal;
  double left = 0, right = 2 * pi, middle;
  double leftVal, rightVal, midVal;
  double curr;
  double x, y;
  double aDegree = pi / 180.0, twoDegrees = pi / 90.0;
  minDegree = atan2(y1, x1);
  minVal = sortaBinarySearch2(minDegree - aDegree, minDegree + aDegree, x1, y1,
                              z1, x2, y2, z2);
  minVal = min(minVal, sortaBinarySearch2(minDegree - 2 * aDegree,
                                          minDegree + 2 * aDegree, x1, y1, z1,
                                          x2, y2, z2));
  minVal = min(minVal, sortaBinarySearch2(minDegree - 3 * aDegree,
                                          minDegree + 3 * aDegree, x1, y1, z1,
                                          x2, y2, z2));
  minVal = min(minVal, sortaBinarySearch2(minDegree - 4 * aDegree,
                                          minDegree + 4 * aDegree, x1, y1, z1,
                                          x2, y2, z2));
  return minVal;
}
int main() {
  pair<double, double> a, b;
  double x1, y1, z1, x2, y2, z2;
  double tmp1, tmp2, res;
  bool pt1OnBase, pt2OnBase;
  cin >> r >> h;
  cin >> x1 >> y1 >> z1;
  cin >> x2 >> y2 >> z2;
  pt1OnBase = isZero(z1);
  pt2OnBase = isZero(z2);
  if (pt1OnBase) {
    if (pt2OnBase) {
      tmp1 = x1 - x2;
      tmp2 = y1 - y2;
      res = sqrt(tmp1 * tmp1 + tmp2 * tmp2);
    } else {
      res = findOptimalSingleBrinkPointDistance(x2, y2, z2, x1, y1, z1);
      if (isZero(x1 * x1 + y1 * y1 - r * r))
        res = min(res, findConeSurfaceDistance(x1, y1, z1, x2, y2, z2));
    }
  } else if (pt2OnBase) {
    res = findOptimalSingleBrinkPointDistance(x1, y1, z1, x2, y2, z2);
    if (isZero(x2 * x2 + y2 * y2 - r * r))
      res = min(res, findConeSurfaceDistance(x1, y1, z1, x2, y2, z2));
  } else {
    res = findConeSurfaceDistance(x1, y1, z1, x2, y2, z2);
    res = min(res, findOptimalDoubleBrinkPointDistance(x1, y1, z1, x2, y2, z2));
  }
  printf("%.9lf\n", res);
  return 0;
}