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!

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.

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

#include<iostream>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<stdio.h>
using namespace std;
const double eps=1e-9,inf=1e9+9,pi=acos(-1.0),dtheta=pi/4.;
double ans,r,h,xa,ya,za,xb,yb,zb,la,ra,mxa,mya,lb,rb,mxb,myb,lv,rv,lz,rz;
double dist(double x1,double y1,double z1,double x2,double y2,double z2)
{
	return sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2)+(z1-z2)*(z1-z2));
}
void norm(double &theta)
{
	while(theta<-eps)
	   theta+=2*pi;
    while(theta>2*pi-eps)
       theta-=2*pi;
}
double solve(double x1,double y1,double z1,double x2,double y2,double z2)
{
	double l1,l2,l,cj,alpha,dj,theta,res;
	if(fabs(z1)<eps&&fabs(z2)<eps)
	    return dist(x1,y1,z1,x2,y2,z2);
	l1=dist(x1,y1,z1,0,0,h);
	l2=dist(x2,y2,z2,0,0,h);
	alpha=atan2(y2,x2)-atan2(y1,x1);
	norm(alpha);
	if(alpha>pi)
	   alpha=2*pi-alpha;
	l=alpha*r;
	cj=sqrt(r*r+h*h);
	theta=l/cj;
	double u1,v1,u2,v2;
	u1=0;
	v1=l1;
	u2=l2*sin(theta);
	v2=l2*cos(theta);
	res=sqrt((u1-u2)*(u1-u2)+(v1-v2)*(v1-v2));
    theta=2*pi-theta;
  	u1=0;
	v1=l1;
	u2=l2*sin(theta);
	v2=l2*cos(theta);
	res=min(res,sqrt((u1-u2)*(u1-u2)+(v1-v2)*(v1-v2)));
    return res;
}
int main()
{
	int i,j,s,p,q,it1,it2;
	scanf("%lf%lf",&r,&h);
	scanf("%lf%lf%lf%lf%lf%lf",&xa,&ya,&za,&xb,&yb,&zb);
	ans=inf;
	if(fabs(za)>eps&&fabs(zb)>eps)
	   ans=min(ans,solve(xa,ya,za,xb,yb,zb));
	if(fabs(za)<eps&&fabs(zb)<eps)
	   ans=min(ans,dist(xa,ya,za,xb,yb,zb));
	if(fabs(zb)<eps)
	{
	    swap(xa,xb);
	    swap(ya,yb);
	    swap(za,zb);
	}
	la=0;
	ra=2*pi;
	for(it1=0;it1<1000;it1++)
	{
		mxa=(29.*la+ra)/30.;
		mya=(la+29.*ra)/30.;
	    lv=solve(xa,ya,za,r*cos(mxa),r*sin(mxa),0)+solve(xb,yb,zb,r*cos(mxa),r*sin(mxa),0);
        rv=solve(xa,ya,za,r*cos(mya),r*sin(mya),0)+solve(xb,yb,zb,r*cos(mya),r*sin(mya),0);
        ans=min(ans,lv);
        ans=min(ans,rv);
    	if(lv>rv)
           la=mxa;
        else
           ra=mya;
	}
    la=0;
    ra=2*pi;
	for(it1=0;it1<600;it1++)
    {
    	 mxa=(49.*la+ra)/50.;
   	     mya=(la+49.*ra)/50.;
   	     lb=0;
   	     rb=2*pi;
   	     for(it2=0;it2<600;it2++)
   	     {
     	    mxb=(49.0*lb+rb)/50.;
     	    myb=(lb+49.0*rb)/50.;
     	    lv=solve(xa,ya,za,r*cos(mxa),r*sin(mxa),0)+solve(xb,yb,zb,r*cos(mxb),r*sin(mxb),0)+dist(r*cos(mxa),r*sin(mxa),0,r*cos(mxb),r*sin(mxb),0);
     	    rv=solve(xa,ya,za,r*cos(mxa),r*sin(mxa),0)+solve(xb,yb,zb,r*cos(myb),r*sin(myb),0)+dist(r*cos(mxa),r*sin(mxa),0,r*cos(myb),r*sin(myb),0);
			 if(lv>rv)
     	       lb=mxb;
  	        else
  	           rb=myb;
		  }
		  mxb=0.5*(lb+rb);
		  lz=solve(xa,ya,za,r*cos(mxa),r*sin(mxa),0)+solve(xb,yb,zb,r*cos(mxb),r*sin(mxb),0)+dist(r*cos(mxa),r*sin(mxa),0,r*cos(mxb),r*sin(mxb),0);
          lb=0;
   	      rb=2*pi;
		  for(it2=0;it2<600;it2++)
          {
          	   	mxb=(49.*lb+rb)/50.;
     	     	myb=(lb+49.*rb)/50.;
     	        lv=solve(xa,ya,za,r*cos(mya),r*sin(mya),0)+solve(xb,yb,zb,r*cos(mxb),r*sin(mxb),0)+dist(r*cos(mya),r*sin(mya),0,r*cos(mxb),r*sin(mxb),0);
     	        rv=solve(xa,ya,za,r*cos(mya),r*sin(mya),0)+solve(xb,yb,zb,r*cos(myb),r*sin(myb),0)+dist(r*cos(mya),r*sin(mya),0,r*cos(myb),r*sin(myb),0);
     	        ans=min(ans,lv);
     	        ans=min(ans,rv);
			    if(lv>rv)
     	           lb=mxb;
  	            else
  	               rb=myb;
          }
          mxb=0.5*(lb+rb);
          rz=solve(xa,ya,za,r*cos(mya),r*sin(mya),0)+solve(xb,yb,zb,r*cos(mxb),r*sin(mxb),0)+dist(r*cos(mya),r*sin(mya),0,r*cos(mxb),r*sin(mxb),0);
          if(lz>rz)
             la=mxa;
          else
             ra=mya;
    }
    printf("%.20f\n",ans);
	return 0;
}

#include<iostream>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<stdio.h>
using namespace std;
const int bound=50;
const double eps=1e-9,inf=1e9+9,pi=acos(-1.0);
double ans,r,h,xa,ya,za,xb,yb,zb,la,ra,mxa,mya,lb,rb,mxb,myb,lv,rv,lz,rz;
double dtheta;
double dist(double x1,double y1,double z1,double x2,double y2,double z2)
{
	return sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2)+(z1-z2)*(z1-z2));
}
void norm(double &theta)
{
	while(theta<-eps)
	   theta+=2*pi;
    while(theta>2*pi-eps)
       theta-=2*pi;
}
double solve(double x1,double y1,double z1,double x2,double y2,double z2)
{
	double l1,l2,l,cj,alpha,dj,theta,res;
	if(fabs(z1)<eps&&fabs(z2)<eps)
	    return dist(x1,y1,z1,x2,y2,z2);
	l1=dist(x1,y1,z1,0,0,h);
	l2=dist(x2,y2,z2,0,0,h);
	alpha=atan2(y2,x2)-atan2(y1,x1);
	norm(alpha);
	if(alpha>pi)
	   alpha=2*pi-alpha;
	l=alpha*r;
	cj=sqrt(r*r+h*h);
	theta=l/cj;
	double u1,v1,u2,v2;
	u1=0;
	v1=l1;
	u2=l2*sin(theta);
	v2=l2*cos(theta);
	res=sqrt((u1-u2)*(u1-u2)+(v1-v2)*(v1-v2));
    theta=2*pi-theta;
  	u1=0;
	v1=l1;
	u2=l2*sin(theta);
	v2=l2*cos(theta);
	res=min(res,sqrt((u1-u2)*(u1-u2)+(v1-v2)*(v1-v2)));
    return res;
}
double compute(double alpha,double beta)
{
	return solve(xa,ya,za,r*cos(alpha),r*sin(alpha),0)+solve(xb,yb,zb,r*cos(beta),r*sin(beta),0)+dist(r*cos(alpha),r*sin(alpha),0,r*cos(beta),r*sin(beta),0);
}
double compute(double alpha)
{
	double theta,vl,ch,ret=inf;
	for(theta=0;theta<2*pi;theta+=dtheta)
	{
		vl=compute(alpha,theta);
		if(ret>vl)
		{
			ret=vl;
			ch=theta;
		}
	}
	lb=max(0.,ch-dtheta);
	rb=min(2*pi,ch+dtheta);
	while(lb<rb)
	{
		mxb=(2*lb+rb)/3;
		myb=(lb+2*rb)/3;
		if(compute(alpha,mxb)>compute(alpha,myb))
		    lb=mxb+eps;
        else
            rb=myb-eps;
	}
	vl=compute(alpha,0.5*(lb+rb));
	if(ret>vl)
	   ret=vl;
    return ret;
}
int main()
{
	int i,j,s,p,q,it1,it2;
	scanf("%lf%lf",&r,&h);
	scanf("%lf%lf%lf%lf%lf%lf",&xa,&ya,&za,&xb,&yb,&zb);
	ans=inf;
	if(fabs(za)>eps&&fabs(zb)>eps)
	   ans=min(ans,solve(xa,ya,za,xb,yb,zb));
	if(fabs(za)<eps&&fabs(zb)<eps)
	   ans=min(ans,dist(xa,ya,za,xb,yb,zb));
	if(fabs(zb)<eps)
	{
	    swap(xa,xb);
	    swap(ya,yb);
	    swap(za,zb);
	}
	double theta,vl,ch,mi=inf;
	dtheta=2*pi/bound;
	mi=inf;
	for(theta=0;theta<2*pi;theta+=dtheta)
	{
		vl=solve(xa,ya,za,r*cos(theta),r*sin(theta),0)+solve(xb,yb,zb,r*cos(theta),r*sin(theta),0);
		if(mi>vl)
		{
			mi=vl;
			ch=theta;
		}
		if(ans>vl)
		   ans=vl;
	}
	la=max(0.,ch-dtheta);
	ra=min(2*pi,ch+dtheta);
	while(la<ra)
	{
		mxa=(2*la+ra)/3;
		mya=(la+2*ra)/3;
		lv=solve(xa,ya,za,r*cos(mxa),r*sin(mxa),0)+solve(xb,yb,zb,r*cos(mxa),r*sin(mxa),0);
        rv=solve(xa,ya,za,r*cos(mya),r*sin(mya),0)+solve(xb,yb,zb,r*cos(mya),r*sin(mya),0);
    	if(lv>rv)
           la=mxa+eps;
        else
           ra=mya-eps;
	}
	vl=solve(xa,ya,za,r*cos(0.5*(la+ra)),r*sin(0.5*(la+ra)),0)+solve(xb,yb,zb,r*cos(0.5*(la+ra)),r*sin(0.5*(la+ra)),0);
	if(ans>vl)
	   ans=vl;
	mi=inf;
	for(theta=0;theta<2*pi;theta+=dtheta)
	{
		vl=compute(theta);
		if(mi>vl)
        {
        	mi=vl;
        	ch=theta;
        }
        if(ans>vl)
           ans=vl;
	}
    la=max(0.,ch-dtheta);
    ra=min(2*pi,ch+dtheta);
    while(la<ra)
    {
    	mxa=(2*la+ra)/3;
    	mya=(la+2*ra)/3;
    	if(compute(mxa)>compute(mya))
    	    la=mxa+eps;
	    else
	        ra=mya-eps;
    }
    vl=compute(0.5*(la+ra));
    if(ans>vl)
       ans=vl;
	/*
	la=0;
	ra=2*pi;
	for(it1=0;it1<1000;it1++)
	{
		mxa=(29.*la+ra)/30.;
		mya=(la+29.*ra)/30.;
	    lv=solve(xa,ya,za,r*cos(mxa),r*sin(mxa),0)+solve(xb,yb,zb,r*cos(mxa),r*sin(mxa),0);
        rv=solve(xa,ya,za,r*cos(mya),r*sin(mya),0)+solve(xb,yb,zb,r*cos(mya),r*sin(mya),0);
        ans=min(ans,lv);
        ans=min(ans,rv);
    	if(lv>rv)
           la=mxa;
        else
           ra=mya;
	}
	*/
	/*
    la=0;
    ra=2*pi;
	for(it1=0;it1<600;it1++)
    {
    	 mxa=(49.*la+ra)/50.;
   	     mya=(la+49.*ra)/50.;
   	     lb=0;
   	     rb=2*pi;
   	     for(it2=0;it2<600;it2++)
   	     {
     	    mxb=(49.0*lb+rb)/50.;
     	    myb=(lb+49.0*rb)/50.;
     	    lv=solve(xa,ya,za,r*cos(mxa),r*sin(mxa),0)+solve(xb,yb,zb,r*cos(mxb),r*sin(mxb),0)+dist(r*cos(mxa),r*sin(mxa),0,r*cos(mxb),r*sin(mxb),0);
     	    rv=solve(xa,ya,za,r*cos(mxa),r*sin(mxa),0)+solve(xb,yb,zb,r*cos(myb),r*sin(myb),0)+dist(r*cos(mxa),r*sin(mxa),0,r*cos(myb),r*sin(myb),0);
			 if(lv>rv)
     	       lb=mxb;
  	        else
  	           rb=myb;
		  }
		  mxb=0.5*(lb+rb);
		  lz=solve(xa,ya,za,r*cos(mxa),r*sin(mxa),0)+solve(xb,yb,zb,r*cos(mxb),r*sin(mxb),0)+dist(r*cos(mxa),r*sin(mxa),0,r*cos(mxb),r*sin(mxb),0);
          lb=0;
   	      rb=2*pi;
		  for(it2=0;it2<600;it2++)
          {
          	   	mxb=(49.*lb+rb)/50.;
     	     	myb=(lb+49.*rb)/50.;
     	        lv=solve(xa,ya,za,r*cos(mya),r*sin(mya),0)+solve(xb,yb,zb,r*cos(mxb),r*sin(mxb),0)+dist(r*cos(mya),r*sin(mya),0,r*cos(mxb),r*sin(mxb),0);
     	        rv=solve(xa,ya,za,r*cos(mya),r*sin(mya),0)+solve(xb,yb,zb,r*cos(myb),r*sin(myb),0)+dist(r*cos(mya),r*sin(mya),0,r*cos(myb),r*sin(myb),0);
     	        ans=min(ans,lv);
     	        ans=min(ans,rv);
			    if(lv>rv)
     	           lb=mxb;
  	            else
  	               rb=myb;
          }
          mxb=0.5*(lb+rb);
          rz=solve(xa,ya,za,r*cos(mya),r*sin(mya),0)+solve(xb,yb,zb,r*cos(mxb),r*sin(mxb),0)+dist(r*cos(mya),r*sin(mya),0,r*cos(mxb),r*sin(mxb),0);
          if(lz>rz)
             la=mxa;
          else
             ra=mya;
    }
    */
    printf("%.20f\n",ans);
	return 0;
}

#include<iostream>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<stdio.h>
using namespace std;
const int bound=100;
const double eps=1e-9,inf=1e9+9,pi=acos(-1.0);
double ans,r,h,xa,ya,za,xb,yb,zb,la,ra,mxa,mya,lb,rb,mxb,myb,lv,rv,lz,rz;
double dtheta;
double dist(double x1,double y1,double z1,double x2,double y2,double z2)
{
	return sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2)+(z1-z2)*(z1-z2));
}
void norm(double &theta)
{
	while(theta<-eps)
	   theta+=2*pi;
    while(theta>2*pi-eps)
       theta-=2*pi;
}
double solve(double x1,double y1,double z1,double x2,double y2,double z2)
{
	double l1,l2,l,cj,alpha,dj,theta,res;
	if(fabs(z1)<eps&&fabs(z2)<eps)
	    return dist(x1,y1,z1,x2,y2,z2);
	l1=dist(x1,y1,z1,0,0,h);
	l2=dist(x2,y2,z2,0,0,h);
	alpha=atan2(y2,x2)-atan2(y1,x1);
	norm(alpha);
	if(alpha>pi)
	   alpha=2*pi-alpha;
	l=alpha*r;
	cj=sqrt(r*r+h*h);
	theta=l/cj;
	double u1,v1,u2,v2;
	u1=0;
	v1=l1;
	u2=l2*sin(theta);
	v2=l2*cos(theta);
	res=sqrt((u1-u2)*(u1-u2)+(v1-v2)*(v1-v2));
    theta=2*pi-theta;
  	u1=0;
	v1=l1;
	u2=l2*sin(theta);
	v2=l2*cos(theta);
	res=min(res,sqrt((u1-u2)*(u1-u2)+(v1-v2)*(v1-v2)));
    return res;
}
double compute(double alpha,double beta)
{
	return solve(xa,ya,za,r*cos(alpha),r*sin(alpha),0)+solve(xb,yb,zb,r*cos(beta),r*sin(beta),0)+dist(r*cos(alpha),r*sin(alpha),0,r*cos(beta),r*sin(beta),0);
}
double compute(double alpha)
{
	double theta,vl,ch,ret=inf;
	for(theta=0;theta<2*pi;theta+=dtheta)
	{
		vl=compute(alpha,theta);
		if(ret>vl)
		{
			ret=vl;
			ch=theta;
		}
	}
	lb=max(0.,ch-dtheta);
	rb=min(2*pi,ch+dtheta);
	while(lb<rb)
	{
		mxb=0.5*(lb+rb);
		myb=mxb+eps;
		if(compute(alpha,mxb)>compute(alpha,myb))
		    lb=mxb+eps;
        else
            rb=mxb-eps;
	}
	vl=compute(alpha,0.5*(lb+rb));
	if(ret>vl)
	   ret=vl;
    return ret;
}
int main()
{
	int i,j,s,p,q,it1,it2;
	scanf("%lf%lf",&r,&h);
	scanf("%lf%lf%lf%lf%lf%lf",&xa,&ya,&za,&xb,&yb,&zb);
	ans=inf;
	if(fabs(za)>eps&&fabs(zb)>eps)
	   ans=min(ans,solve(xa,ya,za,xb,yb,zb));
	if(fabs(za)<eps&&fabs(zb)<eps)
	   ans=min(ans,dist(xa,ya,za,xb,yb,zb));
	if(fabs(zb)<eps)
	{
	    swap(xa,xb);
	    swap(ya,yb);
	    swap(za,zb);
	}
	double theta,vl,ch,mi=inf;
	dtheta=2*pi/bound;
	mi=inf;
	for(theta=0;theta<2*pi;theta+=dtheta)
	{
		vl=solve(xa,ya,za,r*cos(theta),r*sin(theta),0)+solve(xb,yb,zb,r*cos(theta),r*sin(theta),0);
		if(mi>vl)
		{
			mi=vl;
			ch=theta;
		}
		if(ans>vl)
		   ans=vl;
	}
	la=max(0.,ch-dtheta);
	ra=min(2*pi,ch+dtheta);
	while(la<ra)
	{
		mxa=0.5*(la+ra);
		mya=mxa+eps;
		lv=solve(xa,ya,za,r*cos(mxa),r*sin(mxa),0)+solve(xb,yb,zb,r*cos(mxa),r*sin(mxa),0);
        rv=solve(xa,ya,za,r*cos(mya),r*sin(mya),0)+solve(xb,yb,zb,r*cos(mya),r*sin(mya),0);
		if(lv>rv)
		   la=mxa+eps;
		else
		   ra=mxa-eps;
	}
	vl=solve(xa,ya,za,r*cos(0.5*(la+ra)),r*sin(0.5*(la+ra)),0)+solve(xb,yb,zb,r*cos(0.5*(la+ra)),r*sin(0.5*(la+ra)),0);
	if(ans>vl)
	   ans=vl;
	mi=inf;
	for(theta=0;theta<2*pi;theta+=dtheta)
	{
		vl=compute(theta);
		if(mi>vl)
        {
        	mi=vl;
        	ch=theta;
        }
        if(ans>vl)
           ans=vl;
	}
    la=max(0.,ch-dtheta);
    ra=min(2*pi,ch+dtheta);
    while(la<ra)
    {
        mxa=0.5*(la+ra);
        mya=mxa+eps;
		if(compute(mxa)>compute(mya))
    	    la=mxa+eps;
	    else
	        ra=mxa-eps;
    }
    vl=compute(0.5*(la+ra));
    if(ans>vl)
       ans=vl;
    printf("%.20f\n",ans);
	return 0;
}

#include<iostream>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<stdio.h>
using namespace std;
const int bound=40;
const double eps=1e-6,inf=1e9+9,pi=acos(-1.0);
double ans,r,h,xa,ya,za,xb,yb,zb,la,ra,mxa,mya,lb,rb,mxb,myb,lv,rv,lz,rz;
double dtheta;
double dist(double x1,double y1,double z1,double x2,double y2,double z2)
{
	return sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2)+(z1-z2)*(z1-z2));
}
void norm(double &theta)
{
	while(theta<-eps)
	   theta+=2*pi;
    while(theta>2*pi-eps)
       theta-=2*pi;
}
double solve(double x1,double y1,double z1,double x2,double y2,double z2)
{
	double l1,l2,l,cj,alpha,dj,theta,res;
	if(fabs(z1)<eps&&fabs(z2)<eps)
	    return dist(x1,y1,z1,x2,y2,z2);
	l1=dist(x1,y1,z1,0,0,h);
	l2=dist(x2,y2,z2,0,0,h);
	alpha=atan2(y2,x2)-atan2(y1,x1);
	norm(alpha);
	if(alpha>pi)
	   alpha=2*pi-alpha;
	l=alpha*r;
	cj=sqrt(r*r+h*h);
	theta=l/cj;
	double u1,v1,u2,v2;
	u1=0;
	v1=l1;
	u2=l2*sin(theta);
	v2=l2*cos(theta);
	res=sqrt((u1-u2)*(u1-u2)+(v1-v2)*(v1-v2));
    theta=2*pi-theta;
  	u1=0;
	v1=l1;
	u2=l2*sin(theta);
	v2=l2*cos(theta);
	res=min(res,sqrt((u1-u2)*(u1-u2)+(v1-v2)*(v1-v2)));
    return res;
}
double compute(double alpha,double beta)
{
	return solve(xa,ya,za,r*cos(alpha),r*sin(alpha),0)+solve(xb,yb,zb,r*cos(beta),r*sin(beta),0)+dist(r*cos(alpha),r*sin(alpha),0,r*cos(beta),r*sin(beta),0);
}
double compute(double alpha)
{
	double theta,vl,ch,ret=inf;
	for(theta=0;theta<2*pi;theta+=dtheta)
	{
		vl=compute(alpha,theta);
		if(ret>vl)
		{
			ret=vl;
			ch=theta;
		}
	}
	lb=max(0.,ch-dtheta);
	rb=min(2*pi,ch+dtheta);
	while(lb<rb)
	{
		mxb=(2*lb+rb)/3;
		myb=(lb+2*rb)/3;
		if(compute(alpha,mxb)>compute(alpha,myb))
		    lb=mxb+eps;
        else
            rb=myb-eps;
	}
	vl=compute(alpha,0.5*(lb+rb));
	if(ret>vl)
	   ret=vl;
    return ret;
}
int main()
{
	int i,j,s,p,q,it1,it2;
	scanf("%lf%lf",&r,&h);
	scanf("%lf%lf%lf%lf%lf%lf",&xa,&ya,&za,&xb,&yb,&zb);
	ans=inf;
	if(fabs(za)>eps&&fabs(zb)>eps)
	   ans=min(ans,solve(xa,ya,za,xb,yb,zb));
	if(fabs(za)<eps&&fabs(zb)<eps)
	   ans=min(ans,dist(xa,ya,za,xb,yb,zb));
	if(fabs(zb)<eps)
	{
	    swap(xa,xb);
	    swap(ya,yb);
	    swap(za,zb);
	}
	double theta,vl,ch,mi=inf;
	dtheta=2*pi/bound;
	mi=inf;
	for(theta=0;theta<2*pi;theta+=dtheta)
	{
		vl=solve(xa,ya,za,r*cos(theta),r*sin(theta),0)+solve(xb,yb,zb,r*cos(theta),r*sin(theta),0);
		if(mi>vl)
		{
			mi=vl;
			ch=theta;
		}
		if(ans>vl)
		   ans=vl;
	}
	la=max(0.,ch-dtheta);
	ra=min(2*pi,ch+dtheta);
	while(la<ra)
	{
		mxa=(2*la+ra)/3;
		mya=(la+2*ra)/3;
		lv=solve(xa,ya,za,r*cos(mxa),r*sin(mxa),0)+solve(xb,yb,zb,r*cos(mxa),r*sin(mxa),0);
        rv=solve(xa,ya,za,r*cos(mya),r*sin(mya),0)+solve(xb,yb,zb,r*cos(mya),r*sin(mya),0);
    	if(lv>rv)
           la=mxa+eps;
        else
           ra=mya-eps;
	}
	vl=solve(xa,ya,za,r*cos(0.5*(la+ra)),r*sin(0.5*(la+ra)),0)+solve(xb,yb,zb,r*cos(0.5*(la+ra)),r*sin(0.5*(la+ra)),0);
	if(ans>vl)
	   ans=vl;
	mi=inf;
	for(theta=0;theta<2*pi;theta+=dtheta)
	{
		vl=compute(theta);
		if(mi>vl)
        {
        	mi=vl;
        	ch=theta;
        }
        if(ans>vl)
           ans=vl;
	}
    la=max(0.,ch-dtheta);
    ra=min(2*pi,ch+dtheta);
    while(la<ra)
    {
    	mxa=(2*la+ra)/3;
    	mya=(la+2*ra)/3;
    	if(compute(mxa)>compute(mya))
    	    la=mxa+eps;
	    else
	        ra=mya-eps;
    }
    vl=compute(0.5*(la+ra));
    if(ans>vl)
       ans=vl;
    printf("%.20f\n",ans);
	return 0;
}

#include<iostream>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<stdio.h>
using namespace std;
const int bound=40;
const double eps=1e-9,eps2=1e-9,inf=1e9+9,pi=acos(-1.0);
double ans,r,h,xa,ya,za,xb,yb,zb,la,ra,mxa,mya,lb,rb,mxb,myb,lv,rv,lz,rz;
double dtheta;
double dist(double x1,double y1,double z1,double x2,double y2,double z2)
{
	return sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2)+(z1-z2)*(z1-z2));
}
void norm(double &theta)
{
	while(theta<-eps)
	   theta+=2*pi;
    while(theta>2*pi-eps)
       theta-=2*pi;
}
double solve(double x1,double y1,double z1,double x2,double y2,double z2)
{
	double l1,l2,l,cj,alpha,dj,theta,res;
	if(fabs(z1)<eps&&fabs(z2)<eps)
	    return dist(x1,y1,z1,x2,y2,z2);
	l1=dist(x1,y1,z1,0,0,h);
	l2=dist(x2,y2,z2,0,0,h);
	alpha=atan2(y2,x2)-atan2(y1,x1);
	norm(alpha);
	if(alpha>pi)
	   alpha=2*pi-alpha;
	l=alpha*r;
	cj=sqrt(r*r+h*h);
	theta=l/cj;
	double u1,v1,u2,v2;
	u1=0;
	v1=l1;
	u2=l2*sin(theta);
	v2=l2*cos(theta);
	res=sqrt((u1-u2)*(u1-u2)+(v1-v2)*(v1-v2));
    theta=2*pi-theta;
  	u1=0;
	v1=l1;
	u2=l2*sin(theta);
	v2=l2*cos(theta);
	res=min(res,sqrt((u1-u2)*(u1-u2)+(v1-v2)*(v1-v2)));
    return res;
}
double compute(double alpha,double beta)
{
	return solve(xa,ya,za,r*cos(alpha),r*sin(alpha),0)+solve(xb,yb,zb,r*cos(beta),r*sin(beta),0)+dist(r*cos(alpha),r*sin(alpha),0,r*cos(beta),r*sin(beta),0);
}
double compute(double alpha)
{
	double theta,vl,ch,ret=inf;
	for(theta=0;theta<2*pi;theta+=dtheta)
	{
		vl=compute(alpha,theta);
		if(ret>vl)
		{
			ret=vl;
			ch=theta;
		}
	}
	lb=max(0.,ch-dtheta);
	rb=min(2*pi,ch+dtheta);
	while(lb<rb)
	{
	//	mxb=(2*lb+rb)/3;
	//	myb=(lb+2*rb)/3;
		mxb=0.5*(lb+rb);
		myb=mxb+eps2;
		if(compute(alpha,mxb)>compute(alpha,myb))
		    lb=mxb+eps;
        else
            rb=mxb-eps;
	}
	vl=compute(alpha,0.5*(lb+rb));
	if(ret>vl)
	   ret=vl;
    return ret;
}
int main()
{
	int i,j,s,p,q,it1,it2;
	scanf("%lf%lf",&r,&h);
	scanf("%lf%lf%lf%lf%lf%lf",&xa,&ya,&za,&xb,&yb,&zb);
	ans=inf;
	if(fabs(za)>eps&&fabs(zb)>eps)
	   ans=min(ans,solve(xa,ya,za,xb,yb,zb));
	if(fabs(za)<eps&&fabs(zb)<eps)
	   ans=min(ans,dist(xa,ya,za,xb,yb,zb));
	if(fabs(zb)<eps)
	{
	    swap(xa,xb);
	    swap(ya,yb);
	    swap(za,zb);
	}
	double theta,vl,ch,mi=inf;
	dtheta=2*pi/bound;
	mi=inf;
	for(theta=0;theta<2*pi;theta+=dtheta)
	{
		vl=solve(xa,ya,za,r*cos(theta),r*sin(theta),0)+solve(xb,yb,zb,r*cos(theta),r*sin(theta),0);
		if(mi>vl)
		{
			mi=vl;
			ch=theta;
		}
		if(ans>vl)
		   ans=vl;
	}
	la=max(0.,ch-dtheta);
	ra=min(2*pi,ch+dtheta);
	while(la<ra)
	{
		mxa=0.5*(la+ra);
		mya=mxa+eps2;
		lv=solve(xa,ya,za,r*cos(mxa),r*sin(mxa),0)+solve(xb,yb,zb,r*cos(mxa),r*sin(mxa),0);
        rv=solve(xa,ya,za,r*cos(mya),r*sin(mya),0)+solve(xb,yb,zb,r*cos(mya),r*sin(mya),0);
		if(lv>rv)
		   la=mxa+eps;
		else
		   ra=mxa-eps;
	}
	vl=solve(xa,ya,za,r*cos(0.5*(la+ra)),r*sin(0.5*(la+ra)),0)+solve(xb,yb,zb,r*cos(0.5*(la+ra)),r*sin(0.5*(la+ra)),0);
	if(ans>vl)
	   ans=vl;
	mi=inf;
	for(theta=0;theta<2*pi;theta+=dtheta)
	{
		vl=compute(theta);
		if(mi>vl)
        {
        	mi=vl;
        	ch=theta;
        }
        if(ans>vl)
           ans=vl;
	}
    la=max(0.,ch-dtheta);
    ra=min(2*pi,ch+dtheta);
    while(la<ra)
    {
    //	mxa=(2*la+ra)/3;
    //	mya=(la+2*ra)/3;
        mxa=0.5*(la+ra);
        mya=mxa+eps2;
		if(compute(mxa)>compute(mya))
    	    la=mxa+eps;
	    else
	        ra=mxa-eps;
    }
    vl=compute(0.5*(la+ra));
    if(ans>vl)
       ans=vl;
    printf("%.20f\n",ans);
	return 0;
}

#include<iostream>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<stdio.h>
using namespace std;
const int bound=40;
const double eps=1e-9,inf=1e9+9,pi=acos(-1.0);
double ans,r,h,xa,ya,za,xb,yb,zb,la,ra,mxa,mya,lb,rb,mxb,myb,lv,rv,lz,rz;
double dtheta;
double dist(double x1,double y1,double z1,double x2,double y2,double z2)
{
	return sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2)+(z1-z2)*(z1-z2));
}
void norm(double &theta)
{
	while(theta<-eps)
	   theta+=2*pi;
    while(theta>2*pi-eps)
       theta-=2*pi;
}
double solve(double x1,double y1,double z1,double x2,double y2,double z2)
{
	double l1,l2,l,cj,alpha,dj,theta,res;
	if(fabs(z1)<eps&&fabs(z2)<eps)
	    return dist(x1,y1,z1,x2,y2,z2);
	l1=dist(x1,y1,z1,0,0,h);
	l2=dist(x2,y2,z2,0,0,h);
	alpha=atan2(y2,x2)-atan2(y1,x1);
	norm(alpha);
	if(alpha>pi)
	   alpha=2*pi-alpha;
	l=alpha*r;
	cj=sqrt(r*r+h*h);
	theta=l/cj;
	double u1,v1,u2,v2;
	u1=0;
	v1=l1;
	u2=l2*sin(theta);
	v2=l2*cos(theta);
	res=sqrt((u1-u2)*(u1-u2)+(v1-v2)*(v1-v2));
    theta=2*pi-theta;
  	u1=0;
	v1=l1;
	u2=l2*sin(theta);
	v2=l2*cos(theta);
	res=min(res,sqrt((u1-u2)*(u1-u2)+(v1-v2)*(v1-v2)));
    return res;
}
double compute(double alpha,double beta)
{
	return solve(xa,ya,za,r*cos(alpha),r*sin(alpha),0)+solve(xb,yb,zb,r*cos(beta),r*sin(beta),0)+dist(r*cos(alpha),r*sin(alpha),0,r*cos(beta),r*sin(beta),0);
}
double compute(double alpha)
{
	double theta,vl,ch,ret=inf;
	for(theta=0;theta<2*pi;theta+=dtheta)
	{
		vl=compute(alpha,theta);
		if(ret>vl)
		{
			ret=vl;
			ch=theta;
		}
	}
	lb=max(0.,ch-dtheta);
	rb=min(2*pi,ch+dtheta);
	while(lb<rb)
	{
		mxb=0.5*(lb+rb);
		myb=mxb+eps;
		if(compute(alpha,mxb)>compute(alpha,myb))
		    lb=mxb+eps;
        else
            rb=mxb-eps;
	}
	vl=compute(alpha,0.5*(lb+rb));
	if(ret>vl)
	   ret=vl;
    return ret;
}
int main()
{
	int i,j,s,p,q,it1,it2;
	scanf("%lf%lf",&r,&h);
	scanf("%lf%lf%lf%lf%lf%lf",&xa,&ya,&za,&xb,&yb,&zb);
	ans=inf;
	if(fabs(za)>eps&&fabs(zb)>eps)
	   ans=min(ans,solve(xa,ya,za,xb,yb,zb));
	if(fabs(za)<eps&&fabs(zb)<eps)
	   ans=min(ans,dist(xa,ya,za,xb,yb,zb));
	if(fabs(zb)<eps)
	{
	    swap(xa,xb);
	    swap(ya,yb);
	    swap(za,zb);
	}
	double theta,vl,ch,mi=inf;
	dtheta=2*pi/bound;
	mi=inf;
	for(theta=0;theta<2*pi;theta+=dtheta)
	{
		vl=solve(xa,ya,za,r*cos(theta),r*sin(theta),0)+solve(xb,yb,zb,r*cos(theta),r*sin(theta),0);
		if(mi>vl)
		{
			mi=vl;
			ch=theta;
		}
		if(ans>vl)
		   ans=vl;
	}
	la=max(0.,ch-dtheta);
	ra=min(2*pi,ch+dtheta);
	while(la<ra)
	{
		mxa=0.5*(la+ra);
		mya=mxa+eps;
		lv=solve(xa,ya,za,r*cos(mxa),r*sin(mxa),0)+solve(xb,yb,zb,r*cos(mxa),r*sin(mxa),0);
        rv=solve(xa,ya,za,r*cos(mya),r*sin(mya),0)+solve(xb,yb,zb,r*cos(mya),r*sin(mya),0);
		if(lv>rv)
		   la=mxa+eps;
		else
		   ra=mxa-eps;
	}
	vl=solve(xa,ya,za,r*cos(0.5*(la+ra)),r*sin(0.5*(la+ra)),0)+solve(xb,yb,zb,r*cos(0.5*(la+ra)),r*sin(0.5*(la+ra)),0);
	if(ans>vl)
	   ans=vl;
	mi=inf;
	for(theta=0;theta<2*pi;theta+=dtheta)
	{
		vl=compute(theta);
		if(mi>vl)
        {
        	mi=vl;
        	ch=theta;
        }
        if(ans>vl)
           ans=vl;
	}
    la=max(0.,ch-dtheta);
    ra=min(2*pi,ch+dtheta);
    while(la<ra)
    {
        mxa=0.5*(la+ra);
        mya=mxa+eps;
		if(compute(mxa)>compute(mya))
    	    la=mxa+eps;
	    else
	        ra=mxa-eps;
    }
    vl=compute(0.5*(la+ra));
    if(ans>vl)
       ans=vl;
    printf("%.20f\n",ans);
	return 0;
}

#include <iostream>
#include <cstdio>
#include <vector>
#include <algorithm>
#include <cstring>
#include <string>
#include <queue>
#include <set>
#include <map>
#include <bitset>
#include <cmath>
#include <ctime>
#pragma comment (linker, "/STACK:256000000")

using namespace std;

const double eps = 1e-9;
const double pi = 2.0 * acos(0.0);
double r, h;

double dist(double x1, double y1, double z1, double x2, double y2, double z2) {
	double dx = x1 - x2;
	double dy = y1 - y2;
	double dz = z1 - z2;
	return sqrt(dx * dx + dy * dy + dz * dz);
}

double dist(double x1, double y1, double x2, double y2) {
	double dx = x1 - x2;
	double dy = y1 - y2;
	return sqrt(dx * dx + dy * dy);
}

double solve(double x1, double y1, double z1, double x2, double y2, double z2) {
	if (fabs(z1) < eps && fabs(z2) < eps) {
		return dist(x1, y1, z1, x2, y2, z2);
	}

	double l1 = dist(x1, y1, z1, 0, 0, h);
	double l2 = dist(x2, y2, z2, 0, 0, h);

	if (fabs(l1) < eps || fabs(l2) < eps) {
		return l1 + l2;
	}

	double coef = l2 / l1;
	double xn = x1 * coef;
	double yn = y1 * coef;
	double zn = h + (z1 - h) * coef;
	double cr = sqrt(l2 * l2 - (h - z2) * (h - z2));
	double ang = acos((xn * x2 + yn * y2) / (cr * cr));

	double length = ang * r;
	double alpha = length / sqrt(r * r + h * h);

	double u1 = l1, v1 = 0.0;
	double u2 = l2 * cos(alpha), v2 = l2 * sin(alpha);

	return dist(u1, v1, u2, v2);
}

double calc(double xa, double ya, double za, double xb, double yb, double zb, double x0, double y0, double z0, double L, double R) {
	double res = 1e20;
	double d = solve(xa, ya, za, x0, y0, z0);
	for (int i = 0; i < 30; ++i) {
		double x = (2.0 * L + R) / 3.0;
		double y = (L + 2.0 * R) / 3.0;

		double x1 = r * cos(x), y1 = r * sin(x);
		double x2 = r * cos(y), y2 = r * sin(y);

		double A = solve(x0, y0, z0, x1, y1, 0.0) + solve(x1, y1, 0.0, xb, yb, zb);
		double B = solve(x0, y0, z0, x2, y2, 0.0) + solve(x2, y2, 0.0, xb, yb, zb);
		res = min(res, d + A);
		res = min(res, d + B);
		if (A < B) {
			R = y;
		} else {
			L = x;
		}
	}
	return res;
}

int main() {
	//freopen("input.txt", "r", stdin);
	//freopen("output.txt", "w", stdout);

	cin >> r >> h;
	double xa, ya, za;
	double xb, yb, zb;
	cin >> xa >> ya >> za;
	cin >> xb >> yb >> zb;

	double res = 1e20;
	if (fabs(za) > eps && fabs(zb) > eps) {
		res = min(res, solve(xa, ya, za, xb, yb, zb));
	}
	if (fabs(za) < eps && fabs(zb) < eps) {
		res = min(res, dist(xa, ya, za, xb, yb, zb));
	}

	double angle = 2.0 * pi / 100;
	for (int step = 0; step < 100; ++step) {
		double left_bound = (double)(step) * angle;
		double right_bound = (double)(step + 1) * angle;

		for (int i = 0; i < 60; ++i) {
			double L = (2.0 * left_bound + right_bound) / 3.0;
			double R = (left_bound + 2.0 * right_bound) / 3.0;

			double valueL = solve(xa, ya, za, r * cos(L), r * sin(L), 0) + solve(r * cos(L), r * sin(L), 0, xb, yb, zb);
			double valueR = solve(xa, ya, za, r * cos(R), r * sin(R), 0) + solve(r * cos(R), r * sin(R), 0, xb, yb, zb);
			res = min(res, valueL);
			res = min(res, valueR);
			if (valueL < valueR) {
				right_bound = R;
			} else {
				left_bound = L;
			}
		}
	}
	//printf("%.12lf\n", res);
	int cnt = 8;
	angle = 2.0 * pi / (double)(cnt);
	for (int stepA = 0; stepA < cnt; ++stepA) {
		for (int stepB = 0; stepB < cnt; ++stepB) {
			double left_bound = (double)(stepA) * angle;
			double right_bound = (double)(stepA + 1) * angle;

			double lB = (double)(stepB) * angle;
			double rB = (double)(stepB + 1) * angle;
			for (int i = 0; i < 30; ++i) {
				double L = (2.0 * left_bound + right_bound) / 3.0;
				double R = (left_bound + 2.0 * right_bound) / 3.0;

				double valueL = calc(xa, ya, za, xb, yb, zb, r * cos(L), r * sin(L), 0.0, lB, rB);
				double valueR = calc(xa, ya, za, xb, yb, zb, r * cos(R), r * sin(R), 0.0, lB, rB);
				res = min(res, valueL);
				res = min(res, valueR);
				if (valueL < valueR) {
					right_bound = R;
				} else {
					left_bound = L;
				}
			}
		}
	}

	printf("%.12lf\n", res);

	return 0;
}

#include <iostream>
#include <cstdio>
#include <vector>
#include <algorithm>
#include <cstring>
#include <string>
#include <queue>
#include <set>
#include <map>
#include <bitset>
#include <cmath>
#include <ctime>
#pragma comment (linker, "/STACK:256000000")

using namespace std;

const double eps = 1e-9;
const double pi = 2.0 * acos(0.0);
double r, h;

double dist(double x1, double y1, double z1, double x2, double y2, double z2) {
	double dx = x1 - x2;
	double dy = y1 - y2;
	double dz = z1 - z2;
	return sqrt(dx * dx + dy * dy + dz * dz);
}

double dist(double x1, double y1, double x2, double y2) {
	double dx = x1 - x2;
	double dy = y1 - y2;
	return sqrt(dx * dx + dy * dy);
}

double solve(double x1, double y1, double z1, double x2, double y2, double z2) {
	if (fabs(z1) < eps && fabs(z2) < eps) {
		return dist(x1, y1, z1, x2, y2, z2);
	}

	double l1 = dist(x1, y1, z1, 0, 0, h);
	double l2 = dist(x2, y2, z2, 0, 0, h);

	if (fabs(l1) < eps || fabs(l2) < eps) {
		return l1 + l2;
	}

	double coef = l2 / l1;
	double xn = x1 * coef;
	double yn = y1 * coef;
	double zn = h + (z1 - h) * coef;
	double cr = sqrt(l2 * l2 - (h - z2) * (h - z2));
	double ang = acos((xn * x2 + yn * y2) / (cr * cr));

	double length = ang * r;
	double alpha = length / sqrt(r * r + h * h);

	double u1 = l1, v1 = 0.0;
	double u2 = l2 * cos(alpha), v2 = l2 * sin(alpha);

	return dist(u1, v1, u2, v2);
}

double calc(double xa, double ya, double za, double xb, double yb, double zb, double x0, double y0, double z0, double L, double R) {
	double res = 1e20;
	double d = solve(xa, ya, za, x0, y0, z0);
	for (int i = 0; i < 40; ++i) {
		double x = (2.0 * L + R) / 3.0;
		double y = (L + 2.0 * R) / 3.0;

		double x1 = r * cos(x), y1 = r * sin(x);
		double x2 = r * cos(y), y2 = r * sin(y);

		double A = solve(x0, y0, z0, x1, y1, 0.0) + solve(x1, y1, 0.0, xb, yb, zb);
		double B = solve(x0, y0, z0, x2, y2, 0.0) + solve(x2, y2, 0.0, xb, yb, zb);
		res = min(res, d + A);
		res = min(res, d + B);
		if (A < B) {
			R = y;
		} else {
			L = x;
		}
	}
	return res;
}

int main() {
	//freopen("input.txt", "r", stdin);
	//freopen("output.txt", "w", stdout);

	cin >> r >> h;
	double xa, ya, za;
	double xb, yb, zb;
	cin >> xa >> ya >> za;
	cin >> xb >> yb >> zb;

	double res = 1e20;
	if (fabs(za) > eps && fabs(zb) > eps) {
		res = min(res, solve(xa, ya, za, xb, yb, zb));
	}
	if (fabs(za) < eps && fabs(zb) < eps) {
		res = min(res, dist(xa, ya, za, xb, yb, zb));
	}

	double angle = 2.0 * pi / 200;
	for (int step = 0; step < 200; ++step) {
		double left_bound = (double)(step) * angle;
		double right_bound = (double)(step + 1) * angle;

		for (int i = 0; i < 200; ++i) {
			double L = (2.0 * left_bound + right_bound) / 3.0;
			double R = (left_bound + 2.0 * right_bound) / 3.0;

			double valueL = solve(xa, ya, za, r * cos(L), r * sin(L), 0) + solve(r * cos(L), r * sin(L), 0, xb, yb, zb);
			double valueR = solve(xa, ya, za, r * cos(R), r * sin(R), 0) + solve(r * cos(R), r * sin(R), 0, xb, yb, zb);
			res = min(res, valueL);
			res = min(res, valueR);
			if (valueL < valueR) {
				right_bound = R;
			} else {
				left_bound = L;
			}
		}
	}
	//printf("%.12lf\n", res);
	int cnt = 8;
	angle = 2.0 * pi / (double)(cnt);
	for (int stepA = 0; stepA < cnt; ++stepA) {
		for (int stepB = 0; stepB < cnt; ++stepB) {
			double left_bound = (double)(stepA) * angle;
			double right_bound = (double)(stepA + 1) * angle;

			double lB = (double)(stepB) * angle;
			double rB = (double)(stepB + 1) * angle;
			for (int i = 0; i < 40; ++i) {
				double L = (2.0 * left_bound + right_bound) / 3.0;
				double R = (left_bound + 2.0 * right_bound) / 3.0;

				double valueL = calc(xa, ya, za, xb, yb, zb, r * cos(L), r * sin(L), 0.0, lB, rB);
				double valueR = calc(xa, ya, za, xb, yb, zb, r * cos(R), r * sin(R), 0.0, lB, rB);
				res = min(res, valueL);
				res = min(res, valueR);
				if (valueL < valueR) {
					right_bound = R;
				} else {
					left_bound = L;
				}
			}
		}
	}

	printf("%.12lf\n", res);

	return 0;
}

#include <iostream>
#include <cstdio>
#include <vector>
#include <algorithm>
#include <cstring>
#include <string>
#include <queue>
#include <set>
#include <map>
#include <bitset>
#include <cmath>
#include <ctime>
#pragma comment (linker, "/STACK:256000000")

using namespace std;

const double eps = 1e-9;
const double pi = 2.0 * acos(0.0);
double r, h;

double dist(double x1, double y1, double z1, double x2, double y2, double z2) {
	double dx = x1 - x2;
	double dy = y1 - y2;
	double dz = z1 - z2;
	return sqrt(dx * dx + dy * dy + dz * dz);
}

double dist(double x1, double y1, double x2, double y2) {
	double dx = x1 - x2;
	double dy = y1 - y2;
	return sqrt(dx * dx + dy * dy);
}

double solve(double x1, double y1, double z1, double x2, double y2, double z2) {
	if (fabs(z1) < eps && fabs(z2) < eps) {
		return dist(x1, y1, z1, x2, y2, z2);
	}

	double l1 = dist(x1, y1, z1, 0, 0, h);
	double l2 = dist(x2, y2, z2, 0, 0, h);

	if (fabs(l1) < eps || fabs(l2) < eps) {
		return l1 + l2;
	}

	double coef = l2 / l1;
	double xn = x1 * coef;
	double yn = y1 * coef;
	double zn = h + (z1 - h) * coef;
	double cr = sqrt(l2 * l2 - (h - z2) * (h - z2));
	double ang = acos((xn * x2 + yn * y2) / (cr * cr));

	double length = ang * r;
	double alpha = length / sqrt(r * r + h * h);

	double u1 = l1, v1 = 0.0;
	double u2 = l2 * cos(alpha), v2 = l2 * sin(alpha);

	return dist(u1, v1, u2, v2);
}

/*double solve(double x1, double y1, double z1, double x2, double y2, double z2) {
	double A = solve1(x1, y1, z1, x2, y2, z2);
	double B = solve1(x2, y2, z2, x1, y1, z1);

	if (fabs(A - B) > eps) {
		int t = 0;
		solve1(x1, y1, z1, x2, y2, z2);
		solve1(x2, y2, z2, x1, y1, z1);
	}
	return min(A, B);
}*/

double calc(double xa, double ya, double za, double xb, double yb, double zb, double x0, double y0, double z0, double L, double R) {
	double res = 1e20;
	double d = solve(xa, ya, za, x0, y0, z0);
	for (int i = 0; i < 60; ++i) {
		double x = (2.0 * L + R) / 3.0;
		double y = (L + 2.0 * R) / 3.0;

		double x1 = r * cos(x), y1 = r * sin(x);
		double x2 = r * cos(y), y2 = r * sin(y);

		double A = solve(x0, y0, z0, x1, y1, 0.0) + solve(x1, y1, 0.0, xb, yb, zb);
		double B = solve(x0, y0, z0, x2, y2, 0.0) + solve(x2, y2, 0.0, xb, yb, zb);
		res = min(res, d + A);
		res = min(res, d + B);
		if (A < B) {
			R = y;
		} else {
			L = x;
		}
	}
	return res;
}

int main() {
	//freopen("input.txt", "r", stdin);
	//freopen("output.txt", "w", stdout);

	cin >> r >> h;
	double xa, ya, za;
	double xb, yb, zb;
	cin >> xa >> ya >> za;
	cin >> xb >> yb >> zb;

	double res = 1e20;
	if (fabs(za) > eps && fabs(zb) > eps) {
		res = min(res, solve(xa, ya, za, xb, yb, zb));
	}
	if (fabs(za) < eps && fabs(zb) < eps) {
		res = min(res, dist(xa, ya, za, xb, yb, zb));
	}

	double angle = 2.0 * pi / 1000;
	for (int step = 0; step < 1000; ++step) {
		double left_bound = (double)(step) * angle;
		double right_bound = (double)(step + 1) * angle;

		for (int i = 0; i < 200; ++i) {
			double L = (2.0 * left_bound + right_bound) / 3.0;
			double R = (left_bound + 2.0 * right_bound) / 3.0;

			double valueL = solve(xa, ya, za, r * cos(L), r * sin(L), 0) + solve(r * cos(L), r * sin(L), 0, xb, yb, zb);
			double valueR = solve(xa, ya, za, r * cos(R), r * sin(R), 0) + solve(r * cos(R), r * sin(R), 0, xb, yb, zb);
			res = min(res, valueL);
			res = min(res, valueR);
			if (valueL < valueR) {
				right_bound = R;
			} else {
				left_bound = L;
			}
		}
	}
	//printf("%.12lf\n", res);
	int cnt = 5;
	angle = 2.0 * pi / (double)(cnt);
	for (int stepA = 0; stepA < cnt; ++stepA) {
		for (int stepB = 0; stepB < cnt; ++stepB) {
			double left_bound = (double)(stepA) * angle;
			double right_bound = (double)(stepA + 1) * angle;

			double lB = (double)(stepB) * angle;
			double rB = (double)(stepB + 1) * angle;
			for (int i = 0; i < 60; ++i) {
				double L = (2.0 * left_bound + right_bound) / 3.0;
				double R = (left_bound + 2.0 * right_bound) / 3.0;

				double valueL = calc(xa, ya, za, xb, yb, zb, r * cos(L), r * sin(L), 0.0, lB, rB);
				double valueR = calc(xa, ya, za, xb, yb, zb, r * cos(R), r * sin(R), 0.0, lB, rB);
				res = min(res, valueL);
				res = min(res, valueR);
				if (valueL < valueR) {
					right_bound = R;
				} else {
					left_bound = L;
				}
			}
		}
	}

	printf("%.12lf\n", res);

	return 0;
}

#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <string>
#include <set>
#include <vector>
#include <cmath>
#include <cassert>
#include <cstdlib>
#include <map>
#include <queue>
#include <deque>
#include <bitset>

#define y0 y63475625
#define y1 y28435
#define j0 jfd0sf
#define j1 je90ue0
#define sqr(x) ((x)*(x))
#define fi first
#define se second
#define pb push_back
#define mp make_pair
#define re return
#define sz(x) ((int)(x).size())
#define all(x) (x).begin(), (x).end()
#define rep(i, n) for (int i = 0; i < (n); i++)
#define rrep(i, n) for (int i = (n) - 1; i >= 0; i--)
#define sqrt(x) (sqrt(abs(x)))
#define fill(a, x) memset(a, x, sizeof(a))

using namespace std;

typedef vector <int> vi;
typedef vector <vi> vvi;
typedef long long ll;
typedef long double ld;
typedef pair <int, int> ii;
typedef vector <ii> vii;
typedef double D;
typedef pair <ll, ll> pll;
typedef vector <string> vs;

template <class T> T abs(const T a) {
    return a > 0 ? a : -a;
}

const double PI = 2.0 * acos(1.0);

const ld eps = 1e-12;

ld alpha;

int n;
int m;

ld dist(ld ra, ld rb, ld angle) {
    if (abs(ra) < eps) {
        re rb * alpha;
    }
    if (abs(rb) < eps) {
        re ra * alpha;
    }
    if (fabs(angle) < eps)
        re abs(rb - ra) * alpha;
    ld co = rb * sin(angle / alpha);
    ld si = (ra - rb * cos(angle / alpha));
    ld q = sqrt(sqr(co) + sqr(si));
    co /= q; si /= q;
    //ld f0 = alpha * atan2(si, co);
    ld tmp = tan(angle / alpha), tg = si / co;
    re abs(alpha * ra * (co * (tmp - tg) / (1.0 + tmp * tg) + si));
}

int main()
{
    ld r, h;
    cin >> r >> h;
    ld xa, ya, za, xb, yb, zb;
    cin >> xa >> ya >> za;
    cin >> xb >> yb >> zb;
    if (abs(zb) < eps && abs(za) < eps) {
        printf("%.10lf\n", (D)sqrt(sqr(xb - xa) + sqr(yb - ya)));
        re 0;
    }
    if (abs(zb) < eps) {
        swap(xa, xb);
        swap(ya, yb);
        swap(za, zb);
    }

    alpha = sqrt(1.0 + sqr(h / r));
    if (abs(za) > eps && abs(zb) > eps) {
        ld ra = sqrt(sqr(xa) + sqr(ya));
        ld rb = sqrt(sqr(xb) + sqr(yb));
        ld angle = -1.0;
        if (abs(ra) > eps && abs(rb) > eps)
            angle = acos((xa * xb + ya * yb) / ra / rb);
        ld ans = dist(ra, rb, angle);
        ld fans1 = -1, fans2 = -1;
        rep(i, 1) {
            ld L1 = -M_PI / 20, R1 = M_PI / 20.0;
            ld L2 = -M_PI / 20, R2 = M_PI / 20.0;
            n = 1780;
            rep(j, n) {
                ld f1 = L1 + (R1 - L1) * j / (ld)n;
                rep(k, n) {
                    ld f2 = L2 + (R2 - L2) * k / (ld)n;
                    ld tmp = r * sqrt(2.0 - 2.0 * cos(angle + f1 - f2)) + dist(r, ra, f1) + dist(r, rb, f2);
                    if (tmp < ans) {
                        ans = tmp;
                        fans1 = f1;
                        fans2 = f2;
                    }
                }
            }
            ld d = R1 - L1;
            L1 = fans1 - d / 2.0 * 0.99;
            L2 = fans2 - d / 2.0 * 0.99;
            R1 = fans1 + d / 2.0 * 0.99;
            R2 = fans2 + d / 2.0 * 0.99;
        }
        printf("%.10lf\n", (D)ans);
        re 0;
    } else {
        //todo
        ld L = 0.0, R = 2.0 * M_PI;
        ld ans = 1e20;
        ld fans = -1;
        ld rb = sqrt(sqr(xb) + sqr(yb));
        rep(i, 200) {
            rep(j, 1000) {
                double f = L + (R - L) / 100.0 * j;
                ld x = r * cos(f);
                ld y = r * sin(f);
                ld angle = -1.0;
                if (abs(rb) > eps)
                    angle = acos((x * xb + y * yb) / rb / r);
                ld tmp = sqrt(sqr(xa - x) + sqr(ya - y)) + dist(r, rb, angle);
                if (tmp < ans) {
                    ans = tmp;
                    fans = f;
                }
            }
            ld d = R - L;
            L = fans - d / 2.0 * 0.9;
            R = fans + d / 2.0 * 0.9;
        }
        printf("%.10lf\n", (D)ans);
    }
    return 0;
}

//ÒÛ ÍÀÐÊÎÌÀÍ ×ÒÎ ËÈ ×ÈÒÀÒÜ ÝÒÎ

#include <algorithm>
#include <functional>
#include <numeric>
#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <ctime>
#include <cstring>
#include <cassert>
#include <vector>
#include <list>
#include <map>
#include <set>
#include <deque>
#include <queue>
#include <bitset>
#include <sstream>

using namespace std;

#define forn(i, n) for(int i = 0; i < int(n); ++i)
#define for1(i, n) for(int i = 1; i <= int(n); ++i)
#define ford(i, n) for(int i = int(n) - 1; i >= 0; --i)
#define fore(i, l, r) for(int i = int(l); i < int(r); ++i)
#define sz(v) int((v).size())
#define all(v) (v).begin(), (v).end()
#define pb push_back
#define X first
#define Y second

typedef long long li;
typedef long double ld;
typedef pair<ld, ld> pt;

template<typename T> T abs(T a) { return a < 0 ? -a : a; }
template<typename T> T sqr(T a) { return a*a; }

const int INF = (int)1e9;
const ld EPS = 1e-13;
const ld PI = 3.1415926535897932384626433832795;

const int MAGIC = 10;
const int ITER = 50;

struct pt3{
    ld X, Y, Z;

    pt3(){ X = Y = Z = 0; }
    pt3(const ld& X, const ld& Y, const ld& Z) : X(X), Y(Y), Z(Z){}
};

inline ld dist(const pt3& a, const pt3& b){
    return sqrtl(sqr(a.X - b.X) + sqr(a.Y - b.Y) + sqr(a.Z - b.Z));
}

inline ld dist2(const pt3& a, const pt3& b){
    return (sqr(a.X - b.X) + sqr(a.Y - b.Y) + sqr(a.Z - b.Z));
}

inline ld leng(const pt3& a){
    return sqrtl(a.X*a.X + a.Y*a.Y + a.Z*a.Z);
}

inline pt3 operator - (const pt3& a, const pt3& b){
    return pt3(a.X - b.X, a.Y - b.Y, a.Z - b.Z);
}

inline pt3 norm(const pt3& a, const ld& nln){
    ld ln = leng(a);
    return pt3(a.X * (nln / ln), a.Y * (nln / ln), a.Z * (nln / ln));
}

inline ld distAng(const ld& a, const ld& b){
    if(a > b)
        return min(a - b, b + 2*PI - a);
    else
        return min(b - a, a + 2*PI - b);
}

ld h, r;
pt3 a, b, ap, bp, t;
ld aa, ba, ard, brd, ad, bd, ar, br, trd;

inline pt3 getPoint(const ld& ang){
    return pt3(r*cos(ang), r*sin(ang), 0);
}

inline pt3 project(const pt3& a){
    pt3 v = norm(a - t, sqrtl(sqr(a.Z) + dist2(a, t) - sqr(h - a.Z)));
    return pt3(a.X + v.X, a.Y + v.Y, a.Z + v.Z);
}

inline ld distCon(const ld& z1, const ld& z2, ld ang){
    /*
    if(z1 > z2)
        return distCon(z2, z1, ang);

    if(abs(z2 - h) < EPS){
        return trd * (h - z1) / h;
    }
    */

    while(ang < 0)
        ang += 2*PI;
    while(ang > 2*PI)
        ang -= 2*PI;
    ang *= r / trd;

    pt a(trd * (h - z1) / h, 0);
    ld r2 = trd * (h - z2) / h;
    pt b(r2 * cos(ang), r2 * sin(ang));

    return sqrtl(sqr(a.X - b.X) + sqr(a.Y - b.Y));
}

inline ld distCon(const pt3& a, const pt3& b){
    ld dif = atan2(a.Y, a.X) - atan2(b.Y, b.X);
    while(dif < 0)
        dif += 2*PI;
    while(dif > 2*PI)
        dif -= 2*PI;

    //cerr << dif << " " << dif * nang << endl;

    return min(distCon(a.Z, b.Z, dif), distCon(a.Z, b.Z, (2*PI - dif)));
}

ld solve2(const pt3& ca){
    if(abs(b.Z) < EPS)
        return dist(ca, b);

    int curMagic = (a.Z < EPS) ? (MAGIC * MAGIC) : (MAGIC);

    ld d = 2*PI / curMagic;

    ld ans = 1e100;

    forn(i, curMagic){
        ld lf = i*d;
        ld rg = i*d + d;

        forn(j, ITER){
            ld d = (rg - lf) / 3;
            ld ml = lf + d;
            ld mr = rg - d;

            pt3 pl = getPoint(ml), pr = getPoint(mr);

            if(dist(ca, pl) + min(distCon(0, b.Z, ml - ba), distCon(0, b.Z, ba - ml)) > dist(ca, pr) + min(distCon(0, b.Z, mr - ba), distCon(0, b.Z, ba - mr))){
                lf = ml;
            }else{
                rg = mr;
            }
        }

        ans = min(ans, dist(ca, getPoint(lf)) + min(distCon(0, b.Z, lf - ba), distCon(0, b.Z, ba - lf)));
    }

    return ans;
}

ld solve1(){
    if(abs(a.Z) < EPS)
        return solve2(a);

    ld d = 2*PI / MAGIC;

    ld ans = 1e100;

    forn(i, MAGIC){
        ld lf = i*d;
        ld rg = i*d + d;

        forn(j, ITER){
            ld d = (rg - lf) / 3;
            ld ml = lf + d;
            ld mr = rg - d;

            pt3 pl = getPoint(ml), pr = getPoint(mr);

            if(min(distCon(0, a.Z, ml - aa), distCon(0, a.Z, aa - ml)) + solve2(pl) > min(distCon(0, a.Z, mr - aa), distCon(0, a.Z, aa - mr)) + solve2(pr)){
                lf = ml;
            }else{
                rg = mr;
            }
        }

        ans = min(ans, min(distCon(0, a.Z, lf - aa), distCon(0, a.Z, aa - lf)) + solve2(getPoint(lf)));
    }

    return ans;
}

int main(){
    #ifndef ONLINE_JUDGE
        freopen("input.txt", "rt", stdin);
        //freopen("output.txt", "wt", stdout);
    #endif

    cout.precision(10);
    cout << fixed;

    cin >> r >> h >> a.X >> a.Y >> a.Z >> b.X >> b.Y >> b.Z;

    if(b.Z < EPS)
        swap(a, b);

    t = pt3(0, 0, h);
    trd = sqrtl(r*r + h*h);

    if(a.Z < EPS && b.Z < EPS){
        cout << dist(a, b) << endl;
        return 0;
    }

    if(a.X < EPS && a.Y < EPS && abs(a.Z - h) < EPS){
        if(b.Z < EPS){
            cout << trd + r - dist(b, pt3(0, 0, 0)) << endl;
        }else{
            cout << dist(a, b) << endl;
        }

        return 0;
    }

    if(b.X < EPS && b.Y < EPS && abs(b.Z - h) < EPS){
        if(a.Z < EPS){
            cout << trd + r - dist(a, pt3(0, 0, 0)) << endl;
        }else{
            cout << dist(a, b) << endl;
        }
        return 0;
    }

    if(abs(a.Z) > EPS){
        ap = project(a);
        ad = dist(a, ap);
        ard = sqrtl(r*r + h*h) / h * (h - a.Z);
        aa = atan2(ap.Y, ap.X);
        while(aa < 0)
            aa += 2*PI;
        ar = sqrtl(dist2(a, t) - sqr(h - a.Z));
    }

    if(abs(b.Z) > EPS){
        bp = project(b);
        bd = dist(b, ap);
        brd = sqrtl(r*r + h*h) / h * (h - b.Z);
        ba = atan2(bp.Y, bp.X);
        while(ba < 0)
            ba += 2*PI;
        br = sqrtl(dist2(b, t) - sqr(h - b.Z));
    }

    ld conDist = 1e100;

    if(abs(a.Z) > EPS && abs(b.Z) > EPS){
        conDist = distCon(a, b);
    }

    //cerr << clock() << endl;

    cout << min(conDist,solve1()) << endl;

    cerr << clock() << endl;

    return 0;
}

#include<stdio.h>
#include<math.h>
#include<algorithm>
#include<stdlib.h>
#include<string.h>
#include<string>
using namespace std;
typedef double db;
const db pi=acos(-1),eps=0.2;
struct p{
    db x,y,z;
}a,b,c,v;
void set(p&a,db x,db y,db z){
    a.x=x;a.y=y;a.z=z;
}
void swap(db&a,db&b){
    db c=a;a=b;b=c;
}
db sqr(db a){
    return a*a;
}
void swap(p&a,p&b){
    p c=a;a=b;b=c;
}
db r,h,l,z;
db dis(p a,p b){
    return sqrt(sqr(a.x-b.x)+sqr(a.y-b.y)+sqr(a.z-b.z));
}
db abs(db x){
    if(x<0)return -x;
    return x;
}
db cc(db a,db b,db z){
    return sqrt(sqr(a)+sqr(b)-2*cos(z)*a*b);
}
db aa(p a){
    return atan2(a.y,a.x);
}
db zt(p a,p b){
    db z=abs(aa(a)-aa(b));
    return min(z,2*pi-z);
}
db zt(db z){
    return z*r/l;
}
db diss(p a,p b){
    return cc(dis(a,v),dis(b,v),zt(zt(a,b)));
}
p rp(db z){
    p o;
    set(o,r*cos(z),r*sin(z),0);
    return o;
}
db ff(p a,p b,db z){
    p o=rp(z);
    return diss(b,o)+dis(a,o);
}
db fff(p a,p b,db z){
    p o=rp(z);
    db ll=aa(b)-eps,rr=aa(b)+eps,m1,m2;
    for(int i=200;i;i--){
        m1=ll+(rr-ll)*0.49;
        m2=ll+(rr-ll)*0.51;
        if(ff(o,b,m1)<ff(o,b,m2))rr=m2;else ll=m1;
    }
    return diss(a,o)+ff(o,b,ll);
}
int main(){
    scanf("%lf%lf",&r,&h);
    scanf("%lf%lf%lf",&a.x,&a.y,&a.z);
    scanf("%lf%lf%lf",&b.x,&b.y,&b.z);
    if(a.z==0&&b.z==0){
        printf("%.15lf\n",dis(a,b));
        return 0;
    }
    set(v,0,0,h);
    l=sqrt(sqr(r)+sqr(h));
    if(a.z> 0&&b.z> 0){
        db lll=aa(a)-eps,rrr=aa(a)+eps,m1,m2;
        for(int i=200;i;i--){
            m1=lll+(rrr-lll)*0.49;
            m2=lll+(rrr-lll)*0.51;
            if(fff(a,b,m1)<fff(a,b,m2))rrr=m2;else lll=m1;
        }
//        printf("%.15lf\n\n",dis(a,rp(aa(a)))+dis(b,rp(aa(b)))+dis(rp(aa(a)),rp(aa(b))));
//        printf("%.15lf\n%.15lf\n\n",sqrt(sqr(a.x)+sqr(a.y)),sqrt(sqr(b.x)+sqr(b.y)));
//        printf("%.15lf\n%.15lf\n\n",diss(a,b),fff(a,b,lll));
        printf("%.15lf\n",min(diss(a,b),fff(a,b,lll)));
        return 0;
    }
    if(b.z==0)swap(a,b);
    db l1,ll=aa(b)-eps,rr=aa(b)+eps,m1,m2;
    for(int i=200;i;i--){
        m1=ll+(rr-ll)*0.49;
        m2=ll+(rr-ll)*0.51;
        if(ff(a,b,m1)<ff(a,b,m2))rr=m2;else ll=m1;
    }
    l1=ll,ll=aa(a)-eps,rr=aa(a)+eps;
    for(int i=200;i;i--){
        m1=ll+(rr-ll)*0.49;
        m2=ll+(rr-ll)*0.51;
        if(ff(a,b,m1)<ff(a,b,m2))rr=m2;else ll=m1;
    }
    if(ff(a,b,ll)<ff(a,b,l1))l1=ll;
    ll=-pi,rr=pi;
    for(int i=200;i;i--){
        m1=ll+(rr-ll)*0.49;
        m2=ll+(rr-ll)*0.51;
        if(ff(a,b,m1)<ff(a,b,m2))rr=m2;else ll=m1;
    }
    printf("%.15lf\n",min(ff(a,b,ll),ff(a,b,l1)));
	return 0;
}

#pragma comment(linker, "/STACK:65777216")

#include <algorithm>
#include <iostream>
#include <string>
#include<sstream>
#include<string.h>
#include <cstdio>
#include <vector>
#include <bitset>
#include <cmath>
#include <queue>
#include<stack>
#include <set>
#include <map>
#include<ctime>

using namespace std;

typedef long long ll;
typedef vector<int> vi;
typedef pair<int,int> pii;
typedef pair<double,double> pdd;
typedef unsigned long long ull;

#define FOR(i,a,b) for (int i(a); i < (b); i++)
#define REP(i,n) FOR(i,0,n)
#define SORT(v) sort((v).begin(),(v).end())
#define UN(v) sort((v).begin(),(v).end()),v.erase(unique(v.begin(),v.end()),v.end())
#define CL(a,b) memset(a,b,sizeof(a))
#define pb push_back

typedef long double ld;
const ld pi = acosl(-1.);
const ld eps = 1e-11;

int r,h;

ld getAngle(ld x,ld y, ld z){
	ld H = h - z;
	if(H<eps) return 0;
	ld R = r * H / h;
	ld X = 0;
	ld Y = R;
	ld d = sqrtl((x-X)*(x-X)+(y-Y)*(y-Y));
	ld a = asinl(d/2/R)*2;
	ld l = a * R / sqrtl(R*R+H*H);
	if(x>0) l=-l;
	return l;
}

ld conDist(ld z,ld Z,ld a){
	ld r1 = sqrtl(h*h+r*r+0.)/h*(h-z);
	ld r2 = sqrtl(h*h+r*r+0.)/h*(h-Z);
	ld x = r1;
	ld y = 0;
	ld X = cosl(a)*r2;
	ld Y = sinl(a)*r2;

	//cout<<x<<' '<<y<<' '<<X<<' '<<Y<<' '<<r1<<' '<<r2<<' '<<a<<endl;
	return sqrtl((x-X)*(x-X)+(y-Y)*(y-Y));
}

ld getOnConus(ld x,ld y,ld z,ld X, ld Y,ld Z){
	ld a1 = getAngle(x,y,z);
	ld a2 = getAngle(X,Y,Z);
	ld a = fabsl(a2-a1);
	ld A = r / sqrtl(h*h+r*r+0.) * 2 * pi;
	//cout<<a<<' '<<A<<endl;
	return min(conDist(z,Z,a),conDist(z,Z,A-a));
}

ld getOnConus(ld x,ld y,ld z,ld X, ld Y){
	if(z>eps) return getOnConus(x,y,z,X,Y,0);
	return sqrtl((x-X)*(x-X)+(y-Y)*(y-Y));
}

ld getD(ld x,ld y,ld z,ld X, ld Y,ld Z,ld XX,ld YY,ld XXX,ld YYY){
	ld res = sqrtl((XX-XXX)*(XX-XXX)+(YY-YYY)*(YY-YYY));
	//cout<<res<<' '<<x<<' '<<y<<' '<<z<<' '<<XXX<<' '<<YYY<<endl;
	res += getOnConus(x,y,z,XX,YY);
	//cout<<res<<endl;
	res += getOnConus(X,Y,Z,XXX,YYY);
	//cout<<res<<endl;
	if(0)if(res<1.6)
	{
		cout<<x<<' '<<y<<' '<<z<<" -> "<<XX<<' '<<YY<<" = "<<getOnConus(x,y,z,XX,YY,0)<<endl;
		cout<<X<<' '<<Y<<' '<<Z<<" -> "<<XXX<<' '<<YYY<<" = "<<getOnConus(X,Y,Z,XXX,YYY,0)<<endl;
		cout<<res<<": "<<sqrt((XX-XXX)*(XX-XXX)+(YY-YYY)*(YY-YYY))<<' '<<endl;
	}
	return res;
}

ld getD(ld x,ld y,ld z,ld X, ld Y,ld Z,ld XX,ld YY){
	ld res = 1e100;
	REP(i,6){
		ld a = 2*pi/3*i;
		ld b = a + pi;
		REP(j,50){
			ld s1 = (a*2+b)/3;
			ld s2 = (a+2*b)/3;
			ld d1 = getD(x,y,z,X,Y,Z,XX,YY,cosl(s1)*r,sinl(s1)*r);
			ld d2 = getD(x,y,z,X,Y,Z,XX,YY,cosl(s2)*r,sinl(s2)*r);
			res = min(res,d1);
			res = min(res,d2);
			if(d1<d2) b = s2;
			else a = s1;
		}
	}
	return res;
}

ld go(ld x,ld y,ld z,ld X, ld Y,ld Z){
	ld res = getOnConus(x,y,z,X,Y,Z);
	if(z<eps || Z<eps) res = 1e100;
	REP(i,6){
		ld a = 2*pi/3*i;
		ld b = a + pi;
		REP(j,50){
			ld s1 = (a*2+b)/3;
			ld s2 = (a+2*b)/3;
			ld d1 = getD(x,y,z,X,Y,Z,cosl(s1)*r,sinl(s1)*r);
			ld d2 = getD(x,y,z,X,Y,Z,cosl(s2)*r,sinl(s2)*r);
			res = min(res,d1);
			res = min(res,d2);
			if(d1<d2) b = s2;
			else a = s1;
		}
	}
	return res;
}

int main(){
#ifdef LocalHost
    freopen("input.txt","r",stdin);
//    freopen("output.txt","w",stdout);
#endif

	cin>>r>>h;
	long double x,y,z,X,Y,Z;
	cin>>x>>y>>z>>X>>Y>>Z;
	if(z<eps && Z<eps)
		printf("%.10lf\n",(double)sqrt((x-X)*(x-X)+(y-Y)*(y-Y)));
	else printf("%.10lf\n",(double)go(x,y,z,X,Y,Z));
	//printf("%.10lf\n",(double)getD(x,y,z,X,Y,Z,1,0,1,0));
	//printf("%.10lf\n",(double)getOnConus(x,y,z,1,0,0));

#ifdef LocalHost
	cout<<endl<<endl<<"TIME: "<<clock()<<endl;
#endif
    return 0;
}

#pragma comment(linker, "/STACK:65777216")

#include <algorithm>
#include <iostream>
#include <string>
#include<sstream>
#include<string.h>
#include <cstdio>
#include <vector>
#include <bitset>
#include <cmath>
#include <queue>
#include<stack>
#include <set>
#include <map>
#include<ctime>

using namespace std;

typedef long long ll;
typedef vector<int> vi;
typedef pair<int,int> pii;
typedef pair<double,double> pdd;
typedef unsigned long long ull;

#define FOR(i,a,b) for (int i(a); i < (b); i++)
#define REP(i,n) FOR(i,0,n)
#define SORT(v) sort((v).begin(),(v).end())
#define UN(v) sort((v).begin(),(v).end()),v.erase(unique(v.begin(),v.end()),v.end())
#define CL(a,b) memset(a,b,sizeof(a))
#define pb push_back

typedef long double ld;
const ld pi = acosl(-1.);
const ld eps = 1e-17;

int r,h;

ld getAngle(ld x,ld y, ld z){
	ld H = h - z;
	if(H<eps) return 0;
	ld R = r * H / h;
	ld X = 0;
	ld Y = R;
	ld d = sqrtl((x-X)*(x-X)+(y-Y)*(y-Y));
	ld a = asinl(d/2/R)*2;
	ld l = a * R / sqrtl(R*R+H*H);
	if(x>0) l=-l;
	return l;
}

ld conDist(ld z,ld Z,ld a){
	ld r1 = sqrtl(h*h+r*r+0.)/h*(h-z);
	ld r2 = sqrtl(h*h+r*r+0.)/h*(h-Z);
	ld x = r1;
	ld y = 0;
	ld X = cosl(a)*r2;
	ld Y = sinl(a)*r2;
	return sqrtl((x-X)*(x-X)+(y-Y)*(y-Y));
}

ld getOnConus(ld x,ld y,ld z,ld X, ld Y,ld Z){
	ld a1 = getAngle(x,y,z);
	ld a2 = getAngle(X,Y,Z);
	ld a = fabsl(a2-a1);
	ld A = r / sqrtl(h*h+r*r+0.) * 2 * pi;
	return min(conDist(z,Z,a),conDist(z,Z,A-a));
}

ld getOnConus(ld x,ld y,ld z,ld X, ld Y){
	if(z>eps) return getOnConus(x,y,z,X,Y,0);
	return sqrtl((x-X)*(x-X)+(y-Y)*(y-Y));
}

ld getD(ld x,ld y,ld z,ld X, ld Y,ld Z,ld XX,ld YY,ld XXX,ld YYY){
	ld res = sqrtl((XX-XXX)*(XX-XXX)+(YY-YYY)*(YY-YYY));
	res += getOnConus(x,y,z,XX,YY);
	res += getOnConus(X,Y,Z,XXX,YYY);
	return res;
}

ld getD(ld x,ld y,ld z,ld X, ld Y,ld Z,ld XX,ld YY){
	ld res = 1e100;
	REP(i,6){
		ld a = 2*pi/3*i;
		ld b = a + pi;
		REP(j,40){
			ld s1 = (a*2+b)/3;
			ld s2 = (a+2*b)/3;
			ld d1 = getD(x,y,z,X,Y,Z,XX,YY,cosl(s1)*r,sinl(s1)*r);
			ld d2 = getD(x,y,z,X,Y,Z,XX,YY,cosl(s2)*r,sinl(s2)*r);
			res = min(res,min(d1,d2));
			if(d1<d2) b = s2;
			else a = s1;
		}
	}
	return res;
}

ld go(ld x,ld y,ld z,ld X, ld Y,ld Z){
	ld res = getOnConus(x,y,z,X,Y,Z);
	if(z<eps || Z<eps) res = 1e100;
	REP(i,6){
		ld a = 2*pi/3*i;
		ld b = a + pi;
		REP(j,40){
			ld s1 = (a*2+b)/3;
			ld s2 = (a+2*b)/3;
			ld d1 = getD(x,y,z,X,Y,Z,cosl(s1)*r,sinl(s1)*r);
			ld d2 = getD(x,y,z,X,Y,Z,cosl(s2)*r,sinl(s2)*r);
			res = min(res,min(d1,d2));
			if(d1<d2) b = s2;
			else a = s1;
		}
	}
	return res;
}

int main(){
#ifdef LocalHost
    freopen("input.txt","r",stdin);
//    freopen("output.txt","w",stdout);
#endif

	cin>>r>>h;
	long double x,y,z,X,Y,Z;
	cin>>x>>y>>z>>X>>Y>>Z;
	if(z<eps && Z<eps)
		printf("%.10lf\n",(double)sqrt((x-X)*(x-X)+(y-Y)*(y-Y)));
	else printf("%.10lf\n",(double)go(x,y,z,X,Y,Z));

#ifdef LocalHost
	cout<<endl<<endl<<"TIME: "<<clock()<<endl;
#endif
    return 0;
}

#pragma comment(linker, "/STACK:65777216")

#include <algorithm>
#include <iostream>
#include <string>
#include<sstream>
#include<string.h>
#include <cstdio>
#include <vector>
#include <bitset>
#include <cmath>
#include <queue>
#include<stack>
#include <set>
#include <map>
#include<ctime>

using namespace std;

typedef long long ll;
typedef vector<int> vi;
typedef pair<int,int> pii;
typedef pair<double,double> pdd;
typedef unsigned long long ull;

#define FOR(i,a,b) for (int i(a); i < (b); i++)
#define REP(i,n) FOR(i,0,n)
#define SORT(v) sort((v).begin(),(v).end())
#define UN(v) sort((v).begin(),(v).end()),v.erase(unique(v.begin(),v.end()),v.end())
#define CL(a,b) memset(a,b,sizeof(a))
#define pb push_back

typedef long double ld;
const ld pi = acosl(-1.);
const ld eps = 1e-17;

int r,h;

ld getAngle(ld x,ld y, ld z){
	ld H = h - z;
	if(H<eps) return 0;
	ld R = r * H / h;
	ld X = 0;
	ld Y = R;
	ld d = sqrtl((x-X)*(x-X)+(y-Y)*(y-Y));
	ld a = asinl(d/2/R)*2;
	ld l = a * R / sqrtl(R*R+H*H);
	if(x>0) l=-l;
	return l;
}

ld conDist(ld z,ld Z,ld a){
	ld r1 = sqrtl(h*h+r*r+0.)/h*(h-z);
	ld r2 = sqrtl(h*h+r*r+0.)/h*(h-Z);
	ld x = r1;
	ld y = 0;
	ld X = cosl(a)*r2;
	ld Y = sinl(a)*r2;
	return sqrtl((x-X)*(x-X)+(y-Y)*(y-Y));
}

ld getOnConus(ld x,ld y,ld z,ld X, ld Y,ld Z){
	ld a1 = getAngle(x,y,z);
	ld a2 = getAngle(X,Y,Z);
	ld a = fabsl(a2-a1);
	ld A = r / sqrtl(h*h+r*r+0.) * 2 * pi;
	return min(conDist(z,Z,a),conDist(z,Z,A-a));
}

ld getOnConus(ld x,ld y,ld z,ld X, ld Y){
	if(z>eps) return getOnConus(x,y,z,X,Y,0);
	return sqrtl((x-X)*(x-X)+(y-Y)*(y-Y));
}

ld getD(ld x,ld y,ld z,ld X, ld Y,ld Z,ld XX,ld YY,ld XXX,ld YYY){
	ld res = sqrtl((XX-XXX)*(XX-XXX)+(YY-YYY)*(YY-YYY));
	res += getOnConus(x,y,z,XX,YY);
	res += getOnConus(X,Y,Z,XXX,YYY);
	return res;
}

ld getD(ld x,ld y,ld z,ld X, ld Y,ld Z,ld XX,ld YY){
	ld res = 1e100;
	REP(i,6){
		ld a = 2*pi/3*i;
		ld b = a + pi;
		REP(j,50){
			ld s1 = (a*2+b)/3;
			ld s2 = (a+2*b)/3;
			ld d1 = getD(x,y,z,X,Y,Z,XX,YY,cosl(s1)*r,sinl(s1)*r);
			ld d2 = getD(x,y,z,X,Y,Z,XX,YY,cosl(s2)*r,sinl(s2)*r);
			res = min(res,min(d1,d2));
			if(d1<d2) b = s2;
			else a = s1;
		}
	}
	return res;
}

ld go(ld x,ld y,ld z,ld X, ld Y,ld Z){
	ld res = getOnConus(x,y,z,X,Y,Z);
	if(z<eps || Z<eps) res = 1e100;
	REP(i,6){
		ld a = 2*pi/3*i;
		ld b = a + pi;
		REP(j,50){
			ld s1 = (a*2+b)/3;
			ld s2 = (a+2*b)/3;
			ld d1 = getD(x,y,z,X,Y,Z,cosl(s1)*r,sinl(s1)*r);
			ld d2 = getD(x,y,z,X,Y,Z,cosl(s2)*r,sinl(s2)*r);
			res = min(res,min(d1,d2));
			if(d1<d2) b = s2;
			else a = s1;
		}
	}
	return res;
}

int main(){
#ifdef LocalHost
    freopen("input.txt","r",stdin);
//    freopen("output.txt","w",stdout);
#endif

	cin>>r>>h;
	long double x,y,z,X,Y,Z;
	cin>>x>>y>>z>>X>>Y>>Z;
	if(z<eps && Z<eps)
		printf("%.10lf\n",(double)sqrt((x-X)*(x-X)+(y-Y)*(y-Y)));
	else printf("%.10lf\n",(double)go(x,y,z,X,Y,Z));

#ifdef LocalHost
	cout<<endl<<endl<<"TIME: "<<clock()<<endl;
#endif
    return 0;
}

#include <bits/stdc++.h>

#define eps 1e-12

using namespace std;

typedef long double DO;

template<class T> inline void smin(T &a, T b) {if (a>b) a=b;}

struct point {

	DO x, y, z;

	point (DO x=0, DO y=0, DO z=0) : x(x), y(y), z(z){}

	point operator - (point a) {return point(x-a.x, y-a.y, z-a.z);}

	point operator + (point a) {return point(x+a.x, y+a.y, z+a.z);}

	DO operator * (point a) {return x*a.x+y*a.y+z*a.z;}

	DO nor() {return sqrtl(*this**this);}

	DO al() {return atan2l(y, x);}

	void input() {cin>>x>>y>>z;}

};

DO r, h, L;

const DO pi = acosl(-1);

void print(DO a) {

	printf("%.18lf\n", (double)a);

}

DO ALPHA;

DO calc_1(point a, DO al) {

	DO ans=0;

	DO be=fabsl(a.al()-al);

	if (be>2*pi) be-=2*pi;

	DO aa=(point(0, 0, h)-a).nor();

	return sqrtl(aa*aa+L*L-2*aa*L*cosl(min(be, 2*pi-be)*r/L));

}

point a, b;

DO calc1(DO al) {

	point pp=point(cosl(al)*r, sinl(al)*r, 0);

	return (pp-a).nor()+calc_1(b, al);

}

DO calc2(DO al, DO be) {

	DO alpha=fabsl(al-be);

	if (alpha>2*pi) alpha-=2*pi;

	return calc_1(a, al)+calc_1(b, be)+2*sinl(min(2*pi-alpha, alpha)/2)*r;

}

DO calc(DO al) {

	DO ans=1e200;

	for (int i=0; i<6; i++) {

		DO st=pi/3*i, ed=st+pi/2, x1, x2, y1, y2;

		for (int j=0; j<50; j++) {

			x1=(st*2+ed)/3, x2=(st+ed*2)/3;

			smin(ans, y2=calc2(al, x2));

			smin(ans, y1=calc2(al, x1));

			if (y1>y2) st=x1;

			else ed=x2;

		}

		smin(ans, calc2(al, ed));

	}

	return ans;

}

int main() {

	cin>>r>>h;

	a.input(), b.input();

	L=sqrtl(r*r+h*h);

	DO ALPHA=r*2*pi/L;

	if (a.z<eps && b.z<eps) {

		print((a-b).nor());

		return 0;

	}

	if (a.z>eps && b.z>eps) {

		DO al=a.al(), be=b.al();

		point pp=point(0, 0, h);

		DO ans=sqrtl((pp-a)*(pp-a)+(pp-b)*(pp-b)-2*(pp-a).nor()*(pp-b).nor()*cosl(min(fabsl(al-be), 2*pi-fabsl(al-be))*r/L));

		for (int i=0; i<6; i++) {

			DO st=pi/3*i, ed=st+pi/2, x1, x2;

			for (int j=0; j<50; j++) {

				x1=(st*2+ed)/3, x2=(st+ed*2)/3;

				if (calc(x1)>calc(x2)) st=x1;

				else ed=x2;

			}

			smin(ans, calc(ed));

		}

		print(ans);

		return 0;

	}

	if (a.z>eps) swap(a, b);

	DO ans=1e200;

	for (int i=0; i<6; i++) {

		DO st=pi/3*i, ed=st+pi/2, x1, x2;

		for (int j=0; j<50; j++) {

			x1=(st*2+ed)/3, x2=(st+ed*2)/3;

			if (calc1(x1)>calc1(x2)) st=x1;

			else ed=x2;

		}

		smin(ans, calc1(ed));

	}

	print(ans);

	return 0;

}

#include<bits/stdc++.h>
using namespace std;

typedef long double DB;
const DB PI = acos(DB(-1));
const DB INF = 1e10;
const DB EPS = 1e-12;

inline DB sqr(DB x) {
	return x * x;
}

struct PT {
	DB x, y;

	PT() {}
	PT(DB x, DB y) : x(x), y(y) {}
	void in() {
		double _x, _y;
		scanf("%lf%lf", &_x, &_y);
		x = _x, y = _y;
	}
};

bool operator<(const PT& p1, const PT& p2) {
	if (fabs(p1.x - p2.x) > EPS) return p1.x < p2.x;
	return p1.y + EPS < p2.y;
}

bool operator==(const PT& p1, const PT& p2) {
	return fabs(p1.x - p2.x) < EPS && fabs(p1.y - p2.y) < EPS;
}

PT operator+(PT p1, PT p2) {
	return PT(p1.x + p2.x, p1.y + p2.y);
}

PT operator-(PT p1, PT p2) {
	return PT(p1.x - p2.x, p1.y - p2.y);
}

PT operator*(PT p, DB c) {
	return PT(p.x * c, p.y * c);
}

PT operator/(PT p, DB c) {
	return PT(p.x / c, p.y / c);
}

DB dis(PT p) {
	return sqrt(sqr(p.x) + sqr(p.y));
}

DB dis2(PT p) {
	return sqr(p.x) + sqr(p.y);
}

DB dis2(PT p1, PT p2) {
	return sqr(p1.x - p2.x) + sqr(p1.y - p2.y);
}

DB dis(PT p1, PT p2) {
	return sqrt(dis2(p1, p2));
}

DB vect(PT p1, PT p2) {
	return p1.x * p2.y - p2.x * p1.y;
}

DB scal(PT p1, PT p2) {
	return p1.x * p2.x + p1.y * p2.y;
}

DB getAngle(PT p) {
	return atan2(p.y, p.x);
}

DB vect(PT p, PT p1, PT p2) {
	return vect(p1 - p, p2 - p);
}

DB scal(PT p, PT p1, PT p2) {
	return scal(p1 - p, p2 - p);
}

DB getAngle(PT p, PT p1, PT p2) {
	return getAngle(p2 - p) - getAngle(p1 - p);
}

DB getAngle180(PT p, PT p1, PT p2) {
	return acos(scal(p, p1, p2) / dis(p, p1) / dis(p, p2));
}

DB disToLine(PT p, PT p1, PT p2) {
	return fabs(vect(p, p1, p2)) / dis(p1, p2);
}

DB disToSeg(PT p, PT p1, PT p2) {
	if (scal(p1, p, p2) < 0) return dis(p, p1);
	if (scal(p2, p, p1) < 0) return dis(p, p2);
	return disToLine(p, p1, p2);
}

bool onLine(PT p, PT p1, PT p2) {
	return fabs(vect(p1 - p, p2 - p)) < EPS;
}

bool onSeg(PT p, PT p1, PT p2) {
	if (!onLine(p, p1, p2)) return 0;
	return (p1.x - p.x) * (p2.x - p.x) < EPS && (p1.y - p.y) * (p2.y - p.y) < EPS;
}

PT projection(PT a, PT b, PT p) {
	return a + (a - b) * scal(p - a, a - b) / dis2(a - b);
}

int posLineLine(PT p1, PT p2, PT p3, PT p4, PT& p) {
	DB s1 = vect(p1, p2, p3), s2 = vect(p1, p2, p4);
	if (fabs(s1 - s2) < EPS) {
		if (fabs(s1) < EPS) return 2;
		return 0;
	}
	p = p3 + (p4 - p3) * s1 / (s1 - s2);
	return 1;
}

int posCirLine(PT p, DB r, PT p1, PT p2, PT *q) {
	DB a, b, c, d2, d;
	a = dis2(p1, p2);
	b = scal(p1, p, p2);
	c = dis2(p, p1) - sqr(r);
	d2 = sqr(b) - a * c;
	if (d2 < -EPS) return 0;
	d = sqrt(fabs(d2));
	q[0] = p1 + (p2 - p1) * (b + d) / a;
	if (d2 < EPS) return 1;
	q[1] = p1 + (p2 - p1) * (b - d) / a;
	return 2;
}

int posCirCir(PT p1, DB r1, PT p2, DB r2, PT *q) {
	DB dx, dy, d, e, f2, f;
	dx = p2.x - p1.x, dy = p2.y - p1.y;
	d = dis(p1, p2);
	e = (sqr(r1) - sqr(r2) + sqr(d)) / 2 / d;
	f2 = sqr(r1) - sqr(e);
	if (f2 < -EPS) return 0;
	f = sqrt(fabs(f2));
	q[0] = PT(p1.x + (e * dx - f * dy) / d, p1.y + (e * dy + f * dx) / d);
	if (f2 < EPS) return 1;
	q[1] = PT(p1.x + (e * dx + f * dy) / d, p1.y + (e * dy - f * dx) / d);
	return 2;
}

DB calcArea(PT *p, int n) {
	DB rlt = 0;
	for (int i = 0; i < n; i++) rlt += vect(p[i], p[(i + 1) % n]);
	return rlt / 2;
}

int inPolygon(PT p, PT *q, int m) {
	PT p1, p2;
	int k = 0;
	for (int i = 0; i < m; i++) {
		p1 = q[i], p2 = q[(i + 1) % m];
		if (onSeg(p, p1, p2)) return 2;
		if (p1.y > p2.y) swap(p1, p2);
		if (p1.y < p.y + EPS && p.y + EPS < p2.y && vect(p, p1, p2) > 0) k++;
	}
	return k % 2;
}

int convex_hull(PT *p, int n, PT *q) {
	sort(p, p + n);
	n = unique(p, p + n) - p;
	if (n == 1) {
		q[0] = p[0];
		return 1;
	}
	int m = 0;
	for (int i = 0; i < n; i++) {
		while (m > 1 && vect(q[m - 2], q[m - 1], p[i]) < EPS) m--;
		q[m++] = p[i];
	}
	int k = m;
	for (int i = n - 2; i >= 0; i--) {
		while (m > k && vect(q[m - 2], q[m - 1], p[i]) < EPS) m--;
		q[m++] = p[i];
	}
	return --m;
}

PT P[2];
DB r, h, z[2];

DB calc(PT A, PT B, DB a, DB b) {
	DB d1 = sqrt(dis2(A) + sqr(h - a));
	DB d2 = sqrt(dis2(B) + sqr(h - b));
	DB ang = getAngle(A) - getAngle(B);
	while (ang < 0) ang += 2 * PI;
	while (ang > 2 * PI) ang -= 2 * PI;
	if (ang > PI) ang = 2 * PI - ang;
	ang = ang * r / sqrt(sqr(r) + sqr(h));
	return sqrt(sqr(d1) + sqr(d2) - 2 * cos(ang) * d1 * d2);
}

DB calc(PT A, PT B, DB a, DB b, DB ang) {
	PT C = PT(r * cos(ang), r * sin(ang));
	return calc(B, C, b, 0) + dis(C, A);
}

DB calc1(PT A, PT B, DB a, DB b) {
	DB step = PI / 100;
	DB ma = INF, which;
	for (DB now = -PI; now < PI - EPS; now += step) {
		DB ret = calc(A, B, a, b, now);
		if (ma > ret) {
			ma = ret;
			which = now;
		}
	}
	DB st = which - PI / 50, en = which + PI / 50;
	for (int times = 0; times < 200; times++) {
		DB md1 = (st + st + en) / 3, md2 = (st + en + en) / 3;
		if (calc(A, B, a, b, md1) < calc(A, B, a, b, md2)) en = md2;
		else st = md1;
	}
	return calc(A, B, a, b, st);
}

DB calc1(PT A, PT B, DB a, DB b, DB ang) {
	PT C = PT(r * cos(ang), r * sin(ang));
	return calc(A, C, a, 0) + calc1(C, B, 0, b);
}

DB calc2(PT A, PT B, DB a, DB b) {
	DB step = PI / 100;
	DB ma = INF, which;
	for (DB now = -PI; now < PI - EPS; now += step) {
		DB ret = calc1(A, B, a, b, now);
		if (ma > ret) {
			ma = ret;
			which = now;
		}
	}
	DB st = which - PI / 50, en = which + PI / 50;
	for (int times = 0; times < 200; times++) {
		DB md1 = (st + st + en) / 3, md2 = (st + en + en) / 3;
		if (calc1(A, B, a, b, md1) < calc1(A, B, a, b, md2)) en = md2;
		else st = md1;
	}
	return calc1(A, B, a, b, st);
}

int main() {
//	freopen("in.txt", "r", stdin);
	double _r, _h; scanf("%lf%lf", &_r, &_h);
	r = _r, h = _h;
	for (int i = 0; i < 2; i++) {
		double _z;
		P[i].in();
		scanf("%lf", &_z);
		z[i] = _z;
	}
	if (z[0] > z[1]) swap(P[0], P[1]), swap(z[0], z[1]);
	if (z[1] < EPS) return printf("%.20lf\n", (double)dis(P[0], P[1])), 0;
	if (z[0] > EPS) return printf("%.20lf\n", (double)min(calc(P[0], P[1], z[0], z[1]), calc2(P[0], P[1], z[0], z[1]))), 0;
	printf("%.20lf\n", (double)calc1(P[0], P[1], z[0], z[1]));
}

#include <set>
#include <map>
#include <queue>
#include <deque>
#include <cmath>
#include <ctime>
#include <bitset>
#include <vector>
#include <string>
#include <cstdio>
#include <cassert>
#include <cstring>
#include <iostream>
#include <algorithm>
#define For(i,x,y)  for(int i=(int)(x);i<=(int)(y);i++)
#define Forn(i,x,y) for(int i=(int)(x);i>=(int)(y);i--)
#define Rep(i,x,y)  for(int i=(int)(x);i< (int)(y);i++)
#define mk make_pair
#define pb push_back
#define fi first
#define se second
using namespace std;
typedef long double db;
typedef long long ll;
typedef pair<int,int> PII;
const int N=200005;
const int inf=1e9;
const ll Inf=1e10;
const int P=1000000007;
const db  pi=acos(-1);

db r,h,Sqr,l;
db X1,X2,Y1,Y2,Z1,Z2;

void read(db &x){
	double z;
	scanf("%lf",&z);
	x=z;
}

db sqr(db x){return x*x;}

db Fbb(db A,db B,db D,db E){
	return sqrt(sqr(A-D)+sqr(B-E));
}

db Faa(db A,db B,db C,db D,db E,db F){
	if(fabs(C-h)<1e-6) return sqrt(D*D+E*E+sqr(F-h));
	if(fabs(F-h)<1e-6) return sqrt(A*A+B*B+sqr(C-h));
	db X3=A*h/(h-C),Y3=B*h/(h-C),X4=D*h/(h-F),Y4=E*h/(h-F);
	db u=Sqr*2-sqr(X3-X4)-sqr(Y3-Y4);
	u/=2*Sqr;
	db the=acos(u);
	db phi=the*r/l;
	db D1=sqr(A)+sqr(B)+sqr(C-h),D2=sqr(D)+sqr(E)+sqr(F-h);
	return sqrt(D1+D2-2*sqrt(D1)*sqrt(D2)*cos(phi));
}

db Fab(db X,db Y,db Z,db E,db F,db the){
	db X3=r*cos(the),Y3=r*sin(the);
	return Faa(X,Y,Z,X3,Y3,0)+Fbb(E,F,X3,Y3);
}

db Al=0,Ar=0;
db Fab2(db the){
	db X3=cos(the)*r,Y3=sin(the)*r;
	db l=Al,r=Ar,T1,T2;
	For(i,1,400){
		db md1=(9*l+r)/10.,md2=(l+9*r)/10.;
		T1=Fab(X2,Y2,Z2,X3,Y3,md1);
		T2=Fab(X2,Y2,Z2,X3,Y3,md2);
		if(T1>T2) l=md1;else r=md2;
	}
	return T1+Faa(X1,Y1,Z1,X3,Y3,0);
}

int main(){
	read(r);read(h);Sqr=r*r;
	l=sqrt(r*r+h*h);
	read(X1);read(Y1);read(Z1);
	read(X2);read(Y2);read(Z2);

	if(Z1==0&&Z2==0){
		printf("%.16lf\n",double(Fbb(X1,Y1,X2,Y2)));
		return 0;
	}
	if(Z1!=0&&Z2!=0){
		Al=atan2(Y1,X1);
		Ar=atan2(Y2,X2);
		if(fabs(Ar-Al)>pi){
			X1=-X1,Y1=-Y1,X2=-X2,Y2=-Y2;
			Al=atan2(Y1,X1);
			Ar=atan2(Y2,X2);
		}
		if(Al>Ar) swap(Al,Ar);
		db ans=Faa(X1,Y1,Z1,X2,Y2,Z2);
		db l=Al,r=Ar,T1,T2;
		For(i,1,300){
			db md1=(9*l+r)/10.,md2=(l+9*r)/10.;
			T1=Fab2(md1);
			T2=Fab2(md2);
			if(T1>T2) l=md1;else r=md2;
		}
		ans=min(ans,T1);
		printf("%.16lf\n",double(ans));
		return 0;
	}
	if(Z1==0){
		swap(X1,X2);
		swap(Y1,Y2);
		swap(Z1,Z2);
	}
	db l=0,r=2*pi,T1,T2;
	For(i,1,500){
		db md1=(29*l+r)/30.,md2=(l+29*r)/30.;
		if((T1=Fab(X1,Y1,Z1,X2,Y2,md1))>(T2=Fab(X1,Y1,Z1,X2,Y2,md2))) l=md1;else r=md2;
	}
	printf("%.16lf\n",double(T1));
	return 0;
}

#include"bits/stdc++.h"
#define eps 1e-6

typedef double DO;
using namespace std;
template<typename A, typename B> inline void smin(A &a, const B &b) {if(a>b) a=b;}

struct point {
	DO x, y, z;
	inline point(DO x=0, DO y=0, DO z=0) : x(x), y(y), z(z) {}
	inline point operator - (point a) {return point(x-a.x, y-a.y, z-a.z);}
	inline DO al() {return atan2(y, x);}
	inline DO nor2() {return *this**this;}
	inline DO nor() {return sqrt(*this**this);}
	inline DO operator * (point a) {return x*a.x+y*a.y+z*a.z;}
	inline void input() {scanf("%lf %lf %lf", &x, &y, &z);}
	inline void print() {printf("%lf %lf %lf\n", x, y, z);}
} A, B, A_, B_, F;

DO r, h, R;
DO all=6.283185307179586476925286766559;
DO _120=2.0943951023931954923084289221863;
DO _150=2.2689280275926284500007979990352;

inline DO dist(point a, point b) {
	DO al=fabs(a.al()-b.al()); smin(al, all-al);
	DO da=(a-F).nor2(), db=(b-F).nor2();
	return sqrt(da+db-2*sqrt(da*db)*cos(r*al/R));
}

inline DO calc_A() {
	DO ans=1e100;
	for(DO st_=0; st_<all; st_+=_120) {
		DO st=st_, ed=st+_120+0.1;
		while(ed-st>eps) {
			DO a=(st+st+ed)/3; B_={r*cos(a), r*sin(a)}; DO val_a=(A_-B_).nor()+dist(B, B_);
			DO b=(st+ed+ed)/3; B_={r*cos(b), r*sin(b)}; DO val_b=(A_-B_).nor()+dist(B, B_);
			if(val_a<val_b) ed=b;
			else st=a;
		}
		DO al=(st+ed)/2; B_={r*cos(al), r*sin(al)}; smin(ans, (A_-B_).nor()+dist(B, B_));
	}
	return ans;
}

main() {
#ifndef ONLINE_JUDGE
	freopen("in.in", "r", stdin);
	freopen("out.out", "w", stdout);
#endif

	scanf("%lf %lf", &r, &h);
	F=point(0, 0, h);
	R=sqrt(r*r+h*h);

	A.input(), B.input();
	if(A.z>B.z) swap(A, B);

	DO ans;
	if(B.z<eps) ans=(A-B).nor();
	else if(A.z<eps) A_=A, ans=calc_A();
	else {
		ans=dist(A, B);
		for(DO st_=0; st_<all; st_+=_120) {
			DO st=st_, ed=st+_120+0.1;
			while(ed-st>eps) {
				DO a=(st+st+ed)/3; A_={r*cos(a), r*sin(a)}; DO val_a=dist(A, A_)+calc_A();
				DO b=(st+ed+ed)/3; A_={r*cos(b), r*sin(b)}; DO val_b=dist(A, A_)+calc_A();
				if(val_a<val_b) ed=b;
				else st=a;
			}
			DO al=(st+ed)/2; A_={r*cos(al), r*sin(al)}; smin(ans, dist(A, A_)+calc_A());
		}
	}
	printf("%.6lf", ans);
}

// eddy1021
#include <bits/stdc++.h>
using namespace std;
typedef double D;
typedef long double LD;
typedef long long ll;
typedef long long LL;
typedef pair<int,int> PII;
typedef pair<LL,LL> PLL;
// typedef pair<LD,LD> Pt;
typedef tuple<int,int,int> tiii;
typedef tuple<LL,LL,LL> tlll;
#define mod9 1000000009ll
#define mod7 1000000007ll
#define INF  1023456789ll
#define INF16 10000000000000000ll
#define FI first
#define SE second
// #define X FI
// #define Y SE
#define PB push_back
#define MP make_pair
#define MT make_tuple
#define eps 1e-9
#define SZ(x) (int)(x).size()
#define ALL(x) (x).begin(), (x).end()
#ifndef ONLINE_JUDGE
#define debug(...) printf(__VA_ARGS__)
#else
#define debug(...)
#endif
inline ll getint(){
  ll _x=0,_tmp=1; char _tc=getchar();
  while( (_tc<'0'||_tc>'9')&&_tc!='-' ) _tc=getchar();
  if( _tc == '-' ) _tc=getchar() , _tmp = -1;
  while(_tc>='0'&&_tc<='9') _x*=10,_x+=(_tc-'0'),_tc=getchar();
  return _x*_tmp;
}
inline ll add( ll _x , ll _y , ll _mod = mod7 ){
  ll _ = _x + _y;
  if( _ >= _mod ) _ -= _mod;
  return _;
}
inline ll sub( ll _x , ll _y , ll _mod = mod7 ){
  ll _ = _x - _y;
  if( _ < 0 ) _ += _mod;
  return _;
}
inline ll mul( ll _x , ll _y , ll _mod = mod7 ){
  ll _ = _x * _y;
  if( _ >= _mod ) _ %= _mod;
  return _;
}
ll mypow( ll _a , ll _x , ll _mod ){
  if( _x == 0 ) return 1ll;
  ll _tmp = mypow( _a , _x / 2 , _mod );
  _tmp = mul( _tmp , _tmp , _mod );
  if( _x & 1 ) _tmp = mul( _tmp , _a , _mod );
  return _tmp;
}
ll mymul( ll _a , ll _x , ll _mod ){
  if( _x == 0 ) return 0ll;
  ll _tmp = mymul( _a , _x / 2 , _mod );
  _tmp = add( _tmp , _tmp , _mod );
  if( _x & 1 ) _tmp = add( _tmp , _a , _mod );
  return _tmp;
}
inline bool equal( LD _x ,  LD _y ){
  return _x > _y - eps && _x < _y + eps;
}
int __ = 1 , _cs;
/*********default*********/
inline LD getLD(){
  D _; scanf( "%lf" , &_ );
  return _;
}
typedef tuple<LD,LD,LD> Pt;
#define X(U) get<0>(U)
#define Y(U) get<1>(U)
#define Z(U) get<2>(U)
inline void scan( Pt& tp ){
  X( tp ) = getLD();
  Y( tp ) = getLD();
  Z( tp ) = getLD();
}
inline void print( const Pt& tp ){
  printf( "(%.6f,%.6f,%.6f)\n" , (D)X( tp ) , (D)Y( tp ) , (D)Z( tp ) );
}
inline bool onbase( const Pt& tp ){
  return equal( Z( tp ) , 0.0 );
}
inline LD sqr( const LD& x ){ return x * x; }
LD r , h , ans , rr;
Pt p[ 2 ];
const LD pi = acosl( -1.0 );
const LD pi2 = 2.0 * acosl( -1.0 );
void build(){
}
void init(){
  r = getLD();
  h = getLD();
  rr = sqrtl( sqr( r ) + sqr( h ) );
  scan( p[ 0 ] );
  scan( p[ 1 ] );
}
inline LD dist( const Pt& x , const Pt&y ){
  return sqrtl( sqr( X( x ) - X( y ) ) +
                sqr( Y( x ) - Y( y ) ) +
                sqr( Z( x ) - Z( y ) ) );
}
inline LD dist_oncone( const Pt& x , const Pt& y ){
  LD ang1 = atan2( Y( x ) , X( x ) );
  LD ang2 = atan2( Y( y ) , X( y ) );
  LD dang = fabsl( ang1 - ang2 );
  dang *= r / rr;
  LD r1 = rr * ( 1.0 - Z( x ) / h );
  LD r2 = rr * ( 1.0 - Z( y ) / h );
  Pt p1 = MT( r1 , 0.0 , 0.0 );
  Pt p2 = MT( cosl( dang ) * r2 , sinl( dang ) * r2 , 0.0 );
  dang = r / rr * pi2 - dang;
  Pt p3 = MT( r1 , 0.0 , 0.0 );
  Pt p4 = MT( cosl( dang ) * r2 , sinl( dang ) * r2 , 0.0 );
  return min( dist( p1 , p2 ) , dist( p3 , p4 ) );
}
inline void cal1(){
  ans = min( ans , dist( p[ 0 ] , p[ 1 ] ) );
}
#define XX 10
#define KK 60
#define K 60
inline void cal2(){
  for( int y = 0 ; y < XX ; y ++ ){
    LD bans = 1e40 , bl = pi2 / XX * y , br = pi2 / XX * ( y + 1 ) , m1 , m2;
    for( int i = 0 ; i < K ; i ++ ){
      m1 = bl + ( br - bl ) / 3;
      m2 = br - ( br - bl ) / 3;
      Pt tmp1 = MT( cosl( m1 ) * r , sinl( m1 ) * r , 0.0 );
      Pt tmp2 = MT( cosl( m2 ) * r , sinl( m2 ) * r , 0.0 );
      LD tans1 = dist_oncone( p[ 1 ] , tmp1 ) + dist( tmp1 , p[ 0 ] );
      LD tans2 = dist_oncone( p[ 1 ] , tmp2 ) + dist( tmp2 , p[ 0 ] );
      if( tans1 < tans2 ){
        bans = min( bans , tans1 );
        br = m2;
      }else{
        bans = min( bans , tans2 );
        bl = m1;
      }
    }
    ans = min( ans , bans );
  }
}
inline LD cal4( const Pt& p1 , const Pt& p2 ){
  LD bbans = 1e40;
  for( int y = 0 ; y < XX ; y ++ ){
    LD bans = 1e40 , bl = pi2 / XX * y , br = pi2 / XX * ( y + 1 ) , m1 , m2;
    for( int i = 0 ; i < KK ; i ++ ){
      m1 = bl + ( br - bl ) / 3;
      m2 = br - ( br - bl ) / 3;
      Pt tmp1 = MT( cosl( m1 ) * r , sinl( m1 ) * r , 0.0 );
      Pt tmp2 = MT( cosl( m2 ) * r , sinl( m2 ) * r , 0.0 );
      LD tans1 = dist_oncone( p2 , tmp1 ) + dist( p1 , tmp1 );
      LD tans2 = dist_oncone( p2 , tmp2 ) + dist( p1 , tmp2 );
      if( tans1 < tans2 ){
        bans = min( bans , tans1 );
        br = m2;
      }else{
        bans = min( bans , tans2 );
        bl = m1;
      }
    }
    bbans = min( bbans , bans );
  }
  return bbans;
}
inline void cal3(){
  ans = min( ans , dist_oncone( p[ 0 ] , p[ 1 ] ) );
  for( int y = 0 ; y < XX ; y ++ ){
    LD bans = 1e40 , bl = pi2 / XX * y , br = pi2 / XX * ( y + 1 ) , m1 , m2;
    for( int i = 0 ; i < KK ; i ++ ){
      m1 = bl + ( br - bl ) / 3;
      m2 = br - ( br - bl ) / 3;
      Pt tmp1 = MT( cosl( m1 ) * r , sinl( m1 ) * r , 0.0 );
      Pt tmp2 = MT( cosl( m2 ) * r , sinl( m2 ) * r , 0.0 );
      LD tans1 = dist_oncone( p[ 0 ] , tmp1 ) + cal4( tmp1 , p[ 1 ] );
      LD tans2 = dist_oncone( p[ 0 ] , tmp2 ) + cal4( tmp2 , p[ 1 ] );
      if( tans1 < tans2 ){
        bans = min( bans , tans1 );
        br = m2;
      }else{
        bans = min( bans , tans2 );
        bl = m1;
      }
    }
    ans = min( ans , bans );
  }
}
void solve(){
  ans = 1e40;
  if( onbase( p[ 0 ] ) && onbase( p[ 1 ] ) ) cal1();
  else if( onbase( p[ 0 ] ) || onbase( p[ 1 ] ) ){
    if( onbase( p[ 1 ] ) ) swap( p[ 0 ] , p[ 1 ] );
    cal2();
  }else cal3();
  printf( "%.12f\n" , (D)ans );
}
int main(){
  build();
  //__ = getint();
  while( __ -- ){
    init();
    solve();
  }
}

// eddy1021
#include <bits/stdc++.h>
using namespace std;
typedef double D;
typedef long double LD;
typedef long long ll;
typedef long long LL;
typedef pair<int,int> PII;
typedef pair<LL,LL> PLL;
// typedef pair<LD,LD> Pt;
typedef tuple<int,int,int> tiii;
typedef tuple<LL,LL,LL> tlll;
#define mod9 1000000009ll
#define mod7 1000000007ll
#define INF  1023456789ll
#define INF16 10000000000000000ll
#define FI first
#define SE second
// #define X FI
// #define Y SE
#define PB push_back
#define MP make_pair
#define MT make_tuple
#define eps 1e-9
#define SZ(x) (int)(x).size()
#define ALL(x) (x).begin(), (x).end()
#ifndef ONLINE_JUDGE
#define debug(...) printf(__VA_ARGS__)
#else
#define debug(...)
#endif
inline ll getint(){
  ll _x=0,_tmp=1; char _tc=getchar();
  while( (_tc<'0'||_tc>'9')&&_tc!='-' ) _tc=getchar();
  if( _tc == '-' ) _tc=getchar() , _tmp = -1;
  while(_tc>='0'&&_tc<='9') _x*=10,_x+=(_tc-'0'),_tc=getchar();
  return _x*_tmp;
}
inline ll add( ll _x , ll _y , ll _mod = mod7 ){
  ll _ = _x + _y;
  if( _ >= _mod ) _ -= _mod;
  return _;
}
inline ll sub( ll _x , ll _y , ll _mod = mod7 ){
  ll _ = _x - _y;
  if( _ < 0 ) _ += _mod;
  return _;
}
inline ll mul( ll _x , ll _y , ll _mod = mod7 ){
  ll _ = _x * _y;
  if( _ >= _mod ) _ %= _mod;
  return _;
}
ll mypow( ll _a , ll _x , ll _mod ){
  if( _x == 0 ) return 1ll;
  ll _tmp = mypow( _a , _x / 2 , _mod );
  _tmp = mul( _tmp , _tmp , _mod );
  if( _x & 1 ) _tmp = mul( _tmp , _a , _mod );
  return _tmp;
}
ll mymul( ll _a , ll _x , ll _mod ){
  if( _x == 0 ) return 0ll;
  ll _tmp = mymul( _a , _x / 2 , _mod );
  _tmp = add( _tmp , _tmp , _mod );
  if( _x & 1 ) _tmp = add( _tmp , _a , _mod );
  return _tmp;
}
inline bool equal( LD _x ,  LD _y ){
  return _x > _y - eps && _x < _y + eps;
}
int __ = 1 , _cs;
/*********default*********/
inline LD getLD(){
  D _; scanf( "%lf" , &_ );
  return _;
}
typedef tuple<LD,LD,LD> Pt;
#define X(U) get<0>(U)
#define Y(U) get<1>(U)
#define Z(U) get<2>(U)
inline void scan( Pt& tp ){
  X( tp ) = getLD();
  Y( tp ) = getLD();
  Z( tp ) = getLD();
}
inline void print( const Pt& tp ){
  printf( "(%.6f,%.6f,%.6f)\n" , (D)X( tp ) , (D)Y( tp ) , (D)Z( tp ) );
}
inline bool onbase( const Pt& tp ){
  return equal( Z( tp ) , 0.0 );
}
inline LD sqr( const LD& x ){ return x * x; }
LD r , h , ans , rr;
Pt p[ 2 ];
const LD pi = acosl( -1.0 );
const LD pi2 = 2.0 * acosl( -1.0 );
void build(){
}
void init(){
  r = getLD();
  h = getLD();
  rr = sqrtl( sqr( r ) + sqr( h ) );
  scan( p[ 0 ] );
  scan( p[ 1 ] );
}
inline LD dist( const Pt& x , const Pt&y ){
  return sqrtl( sqr( X( x ) - X( y ) ) +
                sqr( Y( x ) - Y( y ) ) +
                sqr( Z( x ) - Z( y ) ) );
}
inline LD dist_oncone( const Pt& x , const Pt& y ){
  LD ang1 = atan2( Y( x ) , X( x ) );
  LD ang2 = atan2( Y( y ) , X( y ) );
  LD dang = fabsl( ang1 - ang2 );
  dang *= r / rr;
  LD r1 = rr * ( 1.0 - Z( x ) / h );
  LD r2 = rr * ( 1.0 - Z( y ) / h );
  Pt p1 = MT( r1 , 0.0 , 0.0 );
  Pt p2 = MT( cosl( dang ) * r2 , sinl( dang ) * r2 , 0.0 );
  dang = r / rr * pi2 - dang;
  Pt p3 = MT( r1 , 0.0 , 0.0 );
  Pt p4 = MT( cosl( dang ) * r2 , sinl( dang ) * r2 , 0.0 );
  return min( dist( p1 , p2 ) , dist( p3 , p4 ) );
}
inline void cal1(){
  ans = min( ans , dist( p[ 0 ] , p[ 1 ] ) );
}
#define XX 10
#define KK 80
#define K 120
inline void cal2(){
  for( int y = 0 ; y < XX ; y ++ ){
    LD bans = 1e40 , bl = pi2 / XX * y , br = pi2 / XX * ( y + 1 ) , m1 , m2;
    for( int i = 0 ; i < K ; i ++ ){
      m1 = bl + ( br - bl ) / 3;
      m2 = br - ( br - bl ) / 3;
      Pt tmp1 = MT( cosl( m1 ) * r , sinl( m1 ) * r , 0.0 );
      Pt tmp2 = MT( cosl( m2 ) * r , sinl( m2 ) * r , 0.0 );
      LD tans1 = dist_oncone( p[ 1 ] , tmp1 ) + dist( tmp1 , p[ 0 ] );
      LD tans2 = dist_oncone( p[ 1 ] , tmp2 ) + dist( tmp2 , p[ 0 ] );
      if( tans1 < tans2 ){
        bans = min( bans , tans1 );
        br = m2;
      }else{
        bans = min( bans , tans2 );
        bl = m1;
      }
    }
    ans = min( ans , bans );
  }
}
inline LD cal4( const Pt& p1 , const Pt& p2 ){
  LD bbans = 1e40;
  for( int y = 0 ; y < XX ; y ++ ){
    LD bans = 1e40 , bl = pi2 / XX * y , br = pi2 / XX * ( y + 1 ) , m1 , m2;
    for( int i = 0 ; i < KK ; i ++ ){
      m1 = bl + ( br - bl ) / 3;
      m2 = br - ( br - bl ) / 3;
      Pt tmp1 = MT( cosl( m1 ) * r , sinl( m1 ) * r , 0.0 );
      Pt tmp2 = MT( cosl( m2 ) * r , sinl( m2 ) * r , 0.0 );
      LD tans1 = dist_oncone( p2 , tmp1 ) + dist( p1 , tmp1 );
      LD tans2 = dist_oncone( p2 , tmp2 ) + dist( p1 , tmp2 );
      if( tans1 < tans2 ){
        bans = min( bans , tans1 );
        br = m2;
      }else{
        bans = min( bans , tans2 );
        bl = m1;
      }
    }
    bbans = min( bbans , bans );
  }
  return bbans;
}
inline void cal3(){
  ans = min( ans , dist_oncone( p[ 0 ] , p[ 1 ] ) );
  for( int y = 0 ; y < XX ; y ++ ){
    LD bans = 1e40 , bl = pi2 / XX * y , br = pi2 / XX * ( y + 1 ) , m1 , m2;
    for( int i = 0 ; i < KK ; i ++ ){
      m1 = bl + ( br - bl ) / 3;
      m2 = br - ( br - bl ) / 3;
      Pt tmp1 = MT( cosl( m1 ) * r , sinl( m1 ) * r , 0.0 );
      Pt tmp2 = MT( cosl( m2 ) * r , sinl( m2 ) * r , 0.0 );
      LD tans1 = dist_oncone( p[ 0 ] , tmp1 ) + cal4( tmp1 , p[ 1 ] );
      LD tans2 = dist_oncone( p[ 0 ] , tmp2 ) + cal4( tmp2 , p[ 1 ] );
      if( tans1 < tans2 ){
        bans = min( bans , tans1 );
        br = m2;
      }else{
        bans = min( bans , tans2 );
        bl = m1;
      }
    }
    ans = min( ans , bans );
  }
}
void solve(){
  ans = 1e40;
  if( onbase( p[ 0 ] ) && onbase( p[ 1 ] ) ) cal1();
  else if( onbase( p[ 0 ] ) || onbase( p[ 1 ] ) ){
    if( onbase( p[ 1 ] ) ) swap( p[ 0 ] , p[ 1 ] );
    cal2();
  }else cal3();
  printf( "%.12f\n" , (D)ans );
}
int main(){
  build();
  //__ = getint();
  while( __ -- ){
    init();
    solve();
  }
}

//lxrtxdy!
#include"bits/stdc++.h"
#define eps 1e-6

typedef double DO;
using namespace std;
template<typename A, typename B> inline void smin(A &a, const B &b) {if(a>b) a=b;}

struct point {
	DO x, y, z;
	inline point(DO x=0, DO y=0, DO z=0) : x(x), y(y), z(z) {}
	inline point operator - (point a) {return point(x-a.x, y-a.y, z-a.z);}
	inline DO al() {return atan2(y, x);}
	inline DO nor2() {return *this**this;}
	inline DO nor() {return sqrt(*this**this);}
	inline DO operator * (point a) {return x*a.x+y*a.y+z*a.z;}
	inline void input() {scanf("%lf %lf %lf", &x, &y, &z);}
	inline void print() {printf("%lf %lf %lf\n", x, y, z);}
} A, B, A_, B_, F;

DO r, h, R;
DO all=6.283185307179586476925286766559;
DO _120=2.0943951023931954923084289221863;
DO _150=2.2689280275926284500007979990352;

inline DO dist(point a, point b) {
	DO al=fabs(a.al()-b.al()); smin(al, all-al);
	DO da=(a-F).nor2(), db=(b-F).nor2();
	return sqrt(da+db-2*sqrt(da*db)*cos(r*al/R));
}

inline DO calc_A() {
	DO ans=1e100;
	for(DO st_=0; st_<all; st_+=_120) {
		DO st=st_, ed=st+_120+0.1;
		while(ed-st>eps) {
			DO a=(st+st+ed)/3; B_={r*cos(a), r*sin(a)}; DO val_a=(A_-B_).nor()+dist(B, B_);
			DO b=(st+ed+ed)/3; B_={r*cos(b), r*sin(b)}; DO val_b=(A_-B_).nor()+dist(B, B_);
			if(val_a<val_b) ed=b;
			else st=a;
		}
		DO al=(st+ed)/2; B_={r*cos(al), r*sin(al)}; smin(ans, (A_-B_).nor()+dist(B, B_));
	}
	return ans;
}

main() {
#ifndef ONLINE_JUDGE
	freopen("in.in", "r", stdin);
	freopen("out.out", "w", stdout);
#endif

	scanf("%lf %lf", &r, &h);
	F=point(0, 0, h);
	R=sqrt(r*r+h*h);

	A.input(), B.input();
	if(A.z>B.z) swap(A, B);

	DO ans;
	if(B.z<eps) ans=(A-B).nor();
	else if(A.z<eps) A_=A, ans=calc_A();
	else {
		ans=dist(A, B);
		for(DO st_=0; st_<all; st_+=_120) {
			DO st=st_, ed=st+_120+0.1;
			while(ed-st>eps) {
				DO a=(st+st+ed)/3; A_={r*cos(a), r*sin(a)}; DO val_a=dist(A, A_)+calc_A();
				DO b=(st+ed+ed)/3; A_={r*cos(b), r*sin(b)}; DO val_b=dist(A, A_)+calc_A();
				if(val_a<val_b) ed=b;
				else st=a;
			}
			DO al=(st+ed)/2; A_={r*cos(al), r*sin(al)}; smin(ans, dist(A, A_)+calc_A());
		}
	}
	printf("%.6lf", ans);
}
//hellobig_tq
//orzlxr!

#include"bits/stdc++.h"
#define eps 1e-6

typedef double DO;
using namespace std;
template<typename A, typename B> inline void smin(A &a, const B &b) {if(a>b) a=b;}

struct point {
	DO x, y, z;
	inline point(DO x=0, DO y=0, DO z=0) : x(x), y(y), z(z) {}
	inline point operator - (point a) {return point(x-a.x, y-a.y, z-a.z);}
	inline DO al() {return atan2(y, x);}
	inline DO nor2() {return *this**this;}
	inline DO nor() {return sqrt(*this**this);}
	inline DO operator * (point a) {return x*a.x+y*a.y+z*a.z;}
	inline void input() {scanf("%lf %lf %lf", &x, &y, &z);}
	inline void print() {printf("%lf %lf %lf\n", x, y, z);}
} A, B, A_, B_, F;

DO r, h, R;
DO all=6.283185307179586476925286766559;
DO _120=2.0943951023931954923084289221863;
DO _150=2.2689280275926284500007979990352;

inline DO dist(point a, point b) {
	DO al=fabs(a.al()-b.al()); smin(al, all-al);
	DO da=(a-F).nor2(), db=(b-F).nor2();
	return sqrt(da+db-2*sqrt(da*db)*cos(r*al/R));
}

inline DO calc_A() {
	DO ans=1e100;
	for(DO st_=0; st_<all; st_+=_120) {
		DO st=st_, ed=st+_120+0.1;
		while(ed-st>eps) {
			DO a=(st+st+ed)/3; B_={r*cos(a), r*sin(a)}; DO val_a=(A_-B_).nor()+dist(B, B_);
			DO b=(st+ed+ed)/3; B_={r*cos(b), r*sin(b)}; DO val_b=(A_-B_).nor()+dist(B, B_);
			if(val_a<val_b) ed=b;
			else st=a;
		}
		DO al=(st+ed)/2; B_={r*cos(al), r*sin(al)}; smin(ans, (A_-B_).nor()+dist(B, B_));
	}
	return ans;
}

main() {
#ifndef ONLINE_JUDGE
	freopen("in.in", "r", stdin);
	freopen("out.out", "w", stdout);
#endif

	scanf("%lf %lf", &r, &h);
	F=point(0, 0, h);
	R=sqrt(r*r+h*h);

	A.input(), B.input();
	if(A.z>B.z) swap(A, B);

	DO ans;
	if(B.z<eps) ans=(A-B).nor();
	else if(A.z<eps) A_=A, ans=calc_A();
	else {
		ans=dist(A, B);
		for(DO st_=0; st_<all; st_+=_120) {
			DO st=st_, ed=st+_120+0.1;
			while(ed-st>eps) {
				DO a=(st+st+ed)/3; A_={r*cos(a), r*sin(a)}; DO val_a=dist(A, A_)+calc_A();
				DO b=(st+ed+ed)/3; A_={r*cos(b), r*sin(b)}; DO val_b=dist(A, A_)+calc_A();
				if(val_a<val_b) ed=b;
				else st=a;
			}
			DO al=(st+ed)/2; A_={r*cos(al), r*sin(al)}; smin(ans, dist(A, A_)+calc_A());
		}
	}
	printf("%.6lf", ans);
}
//hellobig_tq

#include <bits/stdc++.h>

#define inf 0x3f3f3f3f

#define MOD 1000000007

#define pb push_back

#define sq(x) ((x)*(x))

#define x first

#define y second

#define eps 1e-12

#define bpt(x) (__builtin_popcount(x))

#define bptl(x) (__builtin_popcountll(x))

#define bit(x, y) (((x)>>(y))&1)

#define bclz(x) (__builtin_clz(x))

#define bclzl(x) (__builtin_clzll(x))

#define bctz(x) (__builtin_ctz(x))

#define bctzl(x) (__builtin_ctzll(x))

#define sgn(x) (((x)>eps)-((x)<-eps))

#define PQ priority_queue<pii, vector<pii>, greater<pii> >

using namespace std;

typedef long long INT;

typedef vector<int> VI;

typedef pair<int, int> pii;

typedef pair<pii, int> pi3;

typedef long double DO;

template<typename T, typename U> inline void smin(T &a, U b) {if (a>b) a=b;}

template<typename T, typename U> inline void smax(T &a, U b) {if (a<b) a=b;}

template<class T>inline void gn(T &x) {char c, sg=0; while (c=getchar(), (c>'9' || c<'0') && c!='-');for((c=='-'?sg=1, c=getchar():0), x=0; c>='0' && c<='9'; c=getchar()) x=(x<<1)+(x<<3)+c-'0';if (sg) x=-x;}

template<class T, class T1>inline void gn(T &x, T1 &y) {gn(x); gn(y);}

template<class T, class T1, class T2>inline void gn(T &x, T1 &y, T2 &z) {gn(x); gn(y); gn(z);}

template<class T>inline void print(T x) {if (x<0) {putchar('-');return print(-x);}if (x<10) {putchar('0'+x);return;} print(x/10);putchar(x%10+'0');}

template<class T>inline void printsp(T x) {print(x); putchar(' ');}

template<class T>inline void println(T x) {print(x); putchar('\n');}

template<class T, class U>inline void print(T x, U y) {printsp(x); println(y);}

template<class T, class U, class V>inline void print(T x, U y, V z) {printsp(x); printsp(y); println(z);}

int power(int a, int b, int m, int ans=1) {

	for (; b; b>>=1, a=1LL*a*a%m) if (b&1) ans=1LL*ans*a%m;

	return ans;

}

struct point {

	DO x, y, z;

	point (DO x=0, DO y=0, DO z=0) : x(x), y(y), z(z) {}

	point operator - (point a) {return point(x-a.x, y-a.y, z-a.z);}

	point operator + (point a) {return point(x+a.x, y+a.y, z+a.z);}

	point operator * (DO a) {return point(x*a, y*a, z*a);}

	point operator / (DO a) {return point(x/a, y/a, z/a);}

	point operator ^ (point a) {return point(y*a.z-z*a.y, -(x*a.z-z*a.x), x*a.y-y*a.x);}

	DO    operator * (point a) {return x*a.x+y*a.y+z*a.z;}

	point norm() {DO s=nor(); if (s<eps) return *this; return point(x/s, y/s, z/s);}

	DO nor() {return sqrtl(*this**this);}

	bool operator < (const point &a) const {

		if (fabsl(x-a.x)>eps) return x<a.x;

		if (fabsl(y-a.y)>eps) return y<a.y;

		return z<a.z-eps;

	}

	bool operator > (const point &a) const {

		if (fabsl(x-a.x)>eps) return x>a.x;

		if (fabsl(y-a.y)>eps) return y>a.y;

		return z>a.z-eps;

	}

	bool operator == (const point &a) const {

		if (fabsl(x-a.x)>eps) return 0;

		if (fabsl(y-a.y)>eps) return 0;

		return fabs(z-a.z)<eps;

	}

	void input() {cin>>x>>y>>z;}

	void print() {printf("%lf %lf %lf\n", (double)x, (double)y, (double)z);}

};

void print_ans(DO x) {

	cout<<fixed<<setprecision(15)<<x<<endl;

	exit(0);

}

DO pi=acosl(-1.0);

DO r, h, L;

point a, b, H;

DO calc3(point a, DO al) {

	DO be=atan2l(a.y, a.x);

	DO delta=fabsl(be-al);

	if (delta>2*pi) delta-=2*pi;

	smin(delta, 2*pi-delta);

	return sqrtl(L*L+(H-a)*(H-a)-(H-a).nor()*2*L*cosl(delta*r/L));

}

DO calc2(DO al, DO be) {

	return calc3(a, al)+calc3(b, be)+(point(cosl(al), sinl(al))-point(cosl(be), sinl(be))).nor()*r;

}

DO calc1(DO al) {

	DO ans=1e100;

	for (int j=0; j<6; j++) {

		DO st=pi/3*j, ed=st+pi/2;

		for (int i=0; i<50; i++) {

			DO x1=(st*2+ed)/3, x2=(st+ed*2)/3;

			DO y1=calc2(al, x1), y2=calc2(al, x2);

			if (y1<y2) ed=x2;

			else st=x1;

		}

		smin(ans, calc2(al, st));

	}

	return ans;

}

DO calc(DO al) {

	return calc3(b, al)+(a-point(cosl(al)*r, sinl(al)*r)).nor();

}

int main() {

#ifndef ONLINE_JUDGE

	freopen("in.in", "r", stdin);

	freopen("out.out", "w", stdout);

#endif

	cin>>r>>h;

	a.input(); b.input();

	H=point(0, 0, h);

	L=sqrtl(r*r+h*h);

	if (a.z<eps && b.z<eps) print_ans((a-b).nor());

	if (a.z>eps && b.z>eps) {

		DO la=(H-a).nor(), lb=(H-b).nor();

		DO delta=fabsl(atan2l(a.y, a.x)-atan2l(b.y, b.x));

		smin(delta, 2*pi-delta);

		DO ans=sqrtl((H-a)*(H-a)+(H-b)*(H-b)-2*la*lb*cosl(delta*r/L));

		for (int i=0; i<6; i++) {

			DO st=pi/3*i, ed=st+pi/2;

			for (int j=0; j<50; j++) {

				DO x1=(st*2+ed)/3, x2=(st+ed*2)/3;

				DO y1=calc1(x1), y2=calc1(x2);

				smin(ans, y1); smin(ans, y2);

				if (y1<y2) ed=x2;

				else st=x1;

			}

			smin(ans, calc1(st));

		}

		print_ans(ans);

	}

	if (b.z<eps) swap(a, b);

	DO ans=1e100;

	for (int i=0; i<6; i++) {

		DO st=pi/3*i, ed=st+pi/2;

		for (int j=0; j<100; j++) {

			DO x1=(st*2+ed)/3, x2=(st+ed*2)/3;

			DO y1=calc(x1), y2=calc(x2);

			smin(ans, y1); smin(ans, y2);

			if (y1<y2) ed=x2;

			else st=x1;

		}

		smin(ans, calc(st));

	}

	print_ans(ans);

	return 0;

}

#include <malloc.h>

#include <vector>
#include <set>
#include <map>
#include <algorithm>
#include <numeric>
#include <cmath>
#include <deque>
#include <list>
#include <string>
#include <cstdlib>
#include <queue>
#include <cstdio>
#include <iostream>
#include <sstream>
#include <cstring>
#include <assert.h>
#include <stack>
#include <bitset>

//#define debug
//#define ONLINE_JUDGE

#ifdef ONLINE_JUDGE
#define trace(a) void()
#define tracearr(a, b) void()
#else
#include "/home/victor/Dropbox/Public/trace.cpp"
#endif
using namespace std;
#define elif else if
#define sqr(a) ((a)*(a))
#define forn(i,j) for(int i=0;i<int(j);i++)
#define ford(i,j) for(int i=int(j)-1;i>=0;i--)
#define mp make_pair
#define pb push_back
#define fs first
#define sc second
#define all(a) a.begin(),a.end()
#define forin(i,c) for(typeof((c).begin()) i=(c).begin();i!=(c).end();i++)
#define fill_zero(a) memset(a,0,sizeof(a))
#define count botva
#define y1 botven

typedef long double ld;

const ld pi = 3.141592653589793238462643;
const ld e = 1e-9;

ld R, H;
ld x1, y1, h1, x2, y2, h2;

ld dist (ld a, ld h1, ld h2) {
        ld l = sqrt(sqr(H) + sqr(R));
        h1 = (H - h1) * l / H;
        h2 = (H - h2) * l / H;
        a *= R / l;
        ld x, y;
        x = h1 * sin(a);
        y = h1 * cos(a) - h2;
        return sqrt(sqr(x) + sqr(y));
}

bool getdata () {
        return cin >> R >> H >> x1 >> y1 >> h1 >> x2 >> y2 >> h2;
}

ld final(ld a, ld a1, ld a2, ld h1, ld h2) {
        return dist(a1, h1, 0) + 2 * R * sin((a2 - a1) / 2) + dist(a - a2, 0, h2);
}

ld search2 (ld a, ld a1, ld h1, ld h2) {
        ld l = a1, r = a;
        forn(qwe, 300) {
                ld ml = (l * 6 + r) / 7, mr = (r * 6 + l) / 7;
                if (final(a, a1, ml, h1, h2) < final(a, a1, mr, h1, h2))
                        r = mr;
                else
                        l = ml;
        }
        return final(a, a1, (l + r) / 2, h1, h2);
}

ld search1 (ld a, ld h1, ld h2) {
        ld l = 0, r = a;
        forn(qwr, 300) {
                ld ml = (l * 6 + r) / 7, mr = (r * 6 + l) / 7;
                if (search2(a, ml, h1, h2) < search2(a, mr, h1, h2))
                        r = mr;
                else
                        l = ml;
        }
        return search2(a, (l + r) / 2, h1, h2);
}

ld res (ld a, ld a1, ld h1, ld r2) {
        return dist(a1, h1, 0.) + sqrt(sqr(R * cos(a - a1) - r2) + sqr(R * sin(a - a1)));
}

ld search3 (ld a, ld h1, ld r2) {
        ld l = 0. * a, r  = a;
        forn(sdf, 500) {
                ld ml = (l * 9 + r) / 10, mr = (l + r * 9) / 10;
                // cerr << l << ' ' << ml << " (" << res(a, ml, h1, r2) << ") " << mr << " (" << res(a, mr, h1, r2) << ") " << r << endl;
                if (res(a, ml, h1, r2) < res(a, mr, h1, r2))
                        r = mr;
                else
                        l = ml;
        }
        return res(a, (l + r) / 2, h1, r2);
}

bool solve () {
        cerr << '#' << endl;
        ld a1 = atan2l(y1, x1), a2 = atan2l(y2, x2);
        ld a = fabsl(a1 - a2);
        if (a > pi)
                a = 2 * pi - a;
        if (h1 > e && h2 > e) {
                ld ans = dist(a, h1, h2);
                ld ans2 = search1(a, h1, h2);
                if (ans2 < ans)
                        ans = ans2;
                printf("%0.9lf\n", (double)ans);
        } else if (h1 < e && h2 < e) {
                printf("%0.9lf\n", (double)sqrtl(sqr(x1 - x2) + sqr(y1 - y2)));
        } else {
                if (h1 < e) {
                        cerr << '!' << endl;
                        swap(h1, h2);
                        swap(x1, x2);
                        swap(y1, y2);
                }
                ld ans = search3(a, h1, sqrt(sqr(x2) + sqr(y2)));
                printf("%0.9lf\n", (double)ans);
        }
        return 1;
}

int main ()
{
#ifndef ONLINE_JUDGE
        freopen("input.txt", "rt", stdin);
        freopen("output.txt", "wt", stdout);
        while (getdata())
                solve();
#else
        getdata();
        solve();
#endif
        return 0;
}

#include <malloc.h>
#include <vector>
#include <set>
#include <map>
#include <algorithm>
#include <numeric>
#include <cmath>
#include <deque>
#include <list>
#include <string>
#include <cstdlib>
#include <queue>
#include <cstdio>
#include <iostream>
#include <sstream>
#include <cstring>
#include <assert.h>
#include <stack>
#include <bitset>
#ifdef ONLINE_JUDGE
#define trace(a) void()
#define tracearr(a, b) void()
#else
#include "/home/victor/Dropbox/Public/trace.cpp"
#endif
using namespace std;
#define elif else if
#define sqr(a) ((a)*(a))
#define forn(i,j) for(int i=0;i<int(j);i++)
#define ford(i,j) for(int i=int(j)-1;i>=0;i--)
#define mp make_pair
#define pb push_back
#define fs first
#define sc second
#define all(a) a.begin(),a.end()
#define forin(i,c) for(typeof((c).begin()) i=(c).begin();i!=(c).end();i++)
#define fill_zero(a) memset(a,0,sizeof(a))
#define count botva
#define y1 botven

typedef long double ld;

const ld pi = 3.141592653589793238462643;
const ld e = 1e-9;

ld R, H;
ld x1, y1, h1, x2, y2, h2;

ld dist (ld a, ld h1, ld h2) {
        ld l = sqrt(sqr(H) + sqr(R));
        h1 = (H - h1) * l / H;
        h2 = (H - h2) * l / H;
        a *= R / l;
        ld x, y;
        x = h1 * sin(a);
        y = h1 * cos(a) - h2;
        return sqrt(sqr(x) + sqr(y));
}

bool getdata () {
        return cin >> R >> H >> x1 >> y1 >> h1 >> x2 >> y2 >> h2;
}

ld final(ld a, ld a1, ld a2, ld h1, ld h2) {
        return dist(a1, h1, 0) + 2 * R * sin((a2 - a1) / 2) + dist(a - a2, 0, h2);
}

ld search2 (ld a, ld a1, ld h1, ld h2) {
        ld l = a1, r = a;
        forn(qwe, 300) {
                ld ml = (l * 6 + r) / 7, mr = (r * 6 + l) / 7;
                if (final(a, a1, ml, h1, h2) < final(a, a1, mr, h1, h2))
                        r = mr;
                else
                        l = ml;
        }
        return final(a, a1, (l + r) / 2, h1, h2);
}

ld search1 (ld a, ld h1, ld h2) {
        ld l = 0, r = a;
        forn(qwr, 300) {
                ld ml = (l * 6 + r) / 7, mr = (r * 6 + l) / 7;
                if (search2(a, ml, h1, h2) < search2(a, mr, h1, h2))
                        r = mr;
                else
                        l = ml;
        }
        return search2(a, (l + r) / 2, h1, h2);
}

ld res (ld a, ld a1, ld h1, ld r2) {
        return dist(a1, h1, 0.) + sqrt(sqr(R * cos(a - a1) - r2) + sqr(R * sin(a - a1)));
}

ld search3 (ld a, ld h1, ld r2) {
        ld l = 0. * a, r  = a;
        forn(sdf, 500) {
                ld ml = (l * 9 + r) / 10, mr = (l + r * 9) / 10;

                if (res(a, ml, h1, r2) < res(a, mr, h1, r2))
                        r = mr;
                else
                        l = ml;
        }
        return res(a, (l + r) / 2, h1, r2);
}

bool solve () {
        cerr << '#' << endl;
        ld a1 = atan2l(y1, x1), a2 = atan2l(y2, x2);
        ld a = fabsl(a1 - a2);
        if (a > pi)
                a = 2 * pi - a;
        if (h1 > e && h2 > e) {
                ld ans = dist(a, h1, h2);
                ld ans2 = search1(a, h1, h2);
                if (ans2 < ans)
                        ans = ans2;
                printf("%0.9lf\n", (double)ans);
        } else if (h1 < e && h2 < e) {
                printf("%0.9lf\n", (double)sqrtl(sqr(x1 - x2) + sqr(y1 - y2)));
        } else {
                if (h1 < e) {
                        cerr << '!' << endl;
                        swap(h1, h2);
                        swap(x1, x2);
                        swap(y1, y2);
                }
                ld ans = search3(a, h1, sqrt(sqr(x2) + sqr(y2)));
                printf("%0.9lf\n", (double)ans);
        }
        return 1;
}

int main ()
{
#ifndef ONLINE_JUDGE
        freopen("input.txt", "rt", stdin);
        freopen("output.txt", "wt", stdout);
        while (getdata())
                solve();
#else
        getdata();
        solve();
#endif
        return 0;
}

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <climits>
#include <cstring>
#include <string>
#include <vector>
#include <stack>
#include <queue>
#include <set>
#include <map>
#include <algorithm>

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;
/*    printf("aTheta=%.9lf\n", aTheta * 180.0 / pi);
    printf("bTheta=%.9lf\n", bTheta * 180.0 / pi);
    printf("alpha=%.9lf\n", alpha * 180.0 / pi);
*/
    if(isGreaterThan((aTheta - bTheta), alpha / 2.0))
    {
        // find mirror and do shieat
        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;

//    minDegree = atan2(yHi, xHi);
    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);
//        printf("middle=%.9lf - left=%.9lf - right=%.9lf\n", middle * 180.0 / pi, left * 180.0/pi, right * 180.0/ pi);
//        printf("x=%.9lf - y=%.9lf\n", x, y);
//        cout << "leftVal=" << leftVal << " - rightVal=" << rightVal << " - midVal=" << midVal << endl;
        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));
    minVal = min(minVal, sortaBinarySearch2(minDegree - 8 * aDegree, minDegree + 8 * aDegree, x1, y1, z1, x2, y2, z2));
    minVal = min(minVal, sortaBinarySearch2(minDegree - 16 * aDegree, minDegree + 16 * aDegree, x1, y1, z1, x2, y2, z2));
    minVal = min(minVal, sortaBinarySearch2(minDegree - 32 * aDegree, minDegree + 32 * aDegree, x1, y1, z1, x2, y2, z2));
    minVal = min(minVal, sortaBinarySearch2(minDegree - 64 * aDegree, minDegree + 64 * aDegree, x1, y1, z1, x2, y2, z2));
    minVal = min(minVal, sortaBinarySearch2(minDegree - 128 * aDegree, minDegree + 128 * 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;
}

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <climits>
#include <cstring>
#include <string>
#include <vector>
#include <stack>
#include <queue>
#include <set>
#include <map>
#include <algorithm>

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;
/*    printf("aTheta=%.9lf\n", aTheta * 180.0 / pi);
    printf("bTheta=%.9lf\n", bTheta * 180.0 / pi);
    printf("alpha=%.9lf\n", alpha * 180.0 / pi);
*/
    if(isGreaterThan((aTheta - bTheta), alpha / 2.0))
    {
        // find mirror and do shieat
        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;

//    minDegree = atan2(yHi, xHi);
    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);
//        printf("middle=%.9lf - left=%.9lf - right=%.9lf\n", middle * 180.0 / pi, left * 180.0/pi, right * 180.0/ pi);
//        printf("x=%.9lf - y=%.9lf\n", x, y);
//        cout << "leftVal=" << leftVal << " - rightVal=" << rightVal << " - midVal=" << midVal << endl;
        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));
    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;
}

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <climits>
#include <cstring>
#include <string>
#include <vector>
#include <stack>
#include <queue>
#include <set>
#include <map>
#include <algorithm>

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;
/*    printf("aTheta=%.9lf\n", aTheta * 180.0 / pi);
    printf("bTheta=%.9lf\n", bTheta * 180.0 / pi);
    printf("alpha=%.9lf\n", alpha * 180.0 / pi);
*/
    if(isGreaterThan((aTheta - bTheta), alpha / 2.0))
    {
        // find mirror and do shieat
        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;

//    minDegree = atan2(yHi, xHi);
    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);
//        printf("middle=%.9lf - left=%.9lf - right=%.9lf\n", middle * 180.0 / pi, left * 180.0/pi, right * 180.0/ pi);
//        printf("x=%.9lf - y=%.9lf\n", x, y);
//        cout << "leftVal=" << leftVal << " - rightVal=" << rightVal << " - midVal=" << midVal << endl;
        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;
}

#pragma comment(linker, "/STACK:65777216")

#include <algorithm>
#include <iostream>
#include <string>
#include<sstream>
#include<string.h>
#include <cstdio>
#include <vector>
#include <bitset>
#include <cmath>
#include <queue>
#include<stack>
#include <set>
#include <map>
#include<ctime>

using namespace std;

typedef long long ll;
typedef vector<int> vi;
typedef pair<int,int> pii;
typedef pair<double,double> pdd;
typedef unsigned long long ull;

#define FOR(i,a,b) for (int i(a); i < (b); i++)
#define REP(i,n) FOR(i,0,n)
#define SORT(v) sort((v).begin(),(v).end())
#define UN(v) sort((v).begin(),(v).end()),v.erase(unique(v.begin(),v.end()),v.end())
#define CL(a,b) memset(a,b,sizeof(a))
#define pb push_back

typedef long double ld;
const ld pi = acosl(-1.);
const ld eps = 1e-17;

int r,h;

ld getAngle(ld x,ld y, ld z){
	ld H = h - z;
	if(H<eps) return 0;
	ld R = r * H / h;
	ld X = 0;
	ld Y = R;
	ld d = sqrtl((x-X)*(x-X)+(y-Y)*(y-Y));
	ld a = asinl(d/2/R)*2;
	ld l = a * R / sqrtl(R*R+H*H);
	if(x>0) l=-l;
	return l;
}

ld conDist(ld z,ld Z,ld a){
	ld r1 = sqrtl(h*h+r*r+0.)/h*(h-z);
	ld r2 = sqrtl(h*h+r*r+0.)/h*(h-Z);
	ld x = r1;
	ld y = 0;
	ld X = cosl(a)*r2;
	ld Y = sinl(a)*r2;
	return sqrtl((x-X)*(x-X)+(y-Y)*(y-Y));
}

ld getOnConus(ld x,ld y,ld z,ld X, ld Y,ld Z){
	ld a1 = getAngle(x,y,z);
	ld a2 = getAngle(X,Y,Z);
	ld a = fabsl(a2-a1);
	ld A = r / sqrtl(h*h+r*r+0.) * 2 * pi;
	return min(conDist(z,Z,a),conDist(z,Z,A-a));
}

ld getOnConus(ld x,ld y,ld z,ld X, ld Y){
	if(z>eps) return getOnConus(x,y,z,X,Y,0);
	return sqrtl((x-X)*(x-X)+(y-Y)*(y-Y));
}

ld getD(ld x,ld y,ld z,ld X, ld Y,ld Z,ld XX,ld YY,ld XXX,ld YYY){
	ld res = sqrtl((XX-XXX)*(XX-XXX)+(YY-YYY)*(YY-YYY));
	res += getOnConus(x,y,z,XX,YY);
	res += getOnConus(X,Y,Z,XXX,YYY);
	return res;
}

ld getD(ld x,ld y,ld z,ld X, ld Y,ld Z,ld XX,ld YY){
	ld res = 1e100;
	REP(i,6){
		ld a = 2*pi/3*i;
		ld b = a + pi;
		REP(j,40){
			ld s1 = (a*2+b)/3;
			ld s2 = (a+2*b)/3;
			ld d1 = getD(x,y,z,X,Y,Z,XX,YY,cosl(s1)*r,sinl(s1)*r);
			ld d2 = getD(x,y,z,X,Y,Z,XX,YY,cosl(s2)*r,sinl(s2)*r);
			res = min(res,min(d1,d2));
			if(d1<d2) b = s2;
			else a = s1;
		}
	}
	return res;
}

ld go(ld x,ld y,ld z,ld X, ld Y,ld Z){
	ld res = getOnConus(x,y,z,X,Y,Z);
	if(z<eps || Z<eps) res = 1e100;
	REP(i,6){
		ld a = 2*pi/3*i;
		ld b = a + pi;
		REP(j,40){
			ld s1 = (a*2+b)/3;
			ld s2 = (a+2*b)/3;
			ld d1 = getD(x,y,z,X,Y,Z,cosl(s1)*r,sinl(s1)*r);
			ld d2 = getD(x,y,z,X,Y,Z,cosl(s2)*r,sinl(s2)*r);
			res = min(res,min(d1,d2));
			if(d1<d2) b = s2;
			else a = s1;
		}
	}
	return res;
}

int main(){
#ifdef LocalHost
    freopen("input.txt","r",stdin);
//    freopen("output.txt","w",stdout);
#endif

	cin>>r>>h;
	long double x,y,z,X,Y,Z;
	cin>>x>>y>>z>>X>>Y>>Z;
	if(z<eps && Z<eps)
		printf("%.10lf\n",(double)sqrt((x-X)*(x-X)+(y-Y)*(y-Y)));
	else printf("%.10lf\n",(double)go(x,y,z,X,Y,Z));

#ifdef LocalHost
	cout<<endl<<endl<<"TIME: "<<clock()<<endl;
#endif
    return 0;
}

#include<stdio.h>
#include<math.h>
#include<algorithm>
#include<stdlib.h>
#include<string.h>
#include<string>
using namespace std;
typedef double db;
const db pi=acos(-1),eps=0.2;
struct p{
    db x,y,z;
}a,b,c,v;
void set(p&a,db x,db y,db z){
    a.x=x;a.y=y;a.z=z;
}
void swap(db&a,db&b){
    db c=a;a=b;b=c;
}
db sqr(db a){
    return a*a;
}
void swap(p&a,p&b){
    p c=a;a=b;b=c;
}
db r,h,l,z;
db dis(p a,p b){
    return sqrt(sqr(a.x-b.x)+sqr(a.y-b.y)+sqr(a.z-b.z));
}
db abs(db x){
    if(x<0)return -x;
    return x;
}
db cc(db a,db b,db z){
    return sqrt(sqr(a)+sqr(b)-2*cos(z)*a*b);
}
db aa(p a){
    return atan2(a.y,a.x);
}
db zt(p a,p b){
    db z=abs(aa(a)-aa(b));
    return min(z,2*pi-z);
}
db zt(db z){
    return z*r/l;
}
db diss(p a,p b){
    return cc(dis(a,v),dis(b,v),zt(zt(a,b)));
}
p rp(db z){
    p o;
    set(o,r*cos(z),r*sin(z),0);
    return o;
}
db ff(p a,p b,db z){
    p o=rp(z);
    return diss(b,o)+dis(a,o);
}
db fff(p a,p b,db z){
    p o=rp(z);
    db ll=aa(b)-eps,rr=aa(b)+eps,m1,m2;
    for(int i=200;i;i--){
        m1=ll+(rr-ll)*0.49;
        m2=ll+(rr-ll)*0.51;
        if(ff(o,b,m1)<ff(o,b,m2))rr=m2;else ll=m1;
    }
    return diss(a,o)+ff(o,b,ll);
}
int main(){
    scanf("%lf%lf",&r,&h);
    scanf("%lf%lf%lf",&a.x,&a.y,&a.z);
    scanf("%lf%lf%lf",&b.x,&b.y,&b.z);
    if(a.z==0&&b.z==0){
        printf("%.15lf\n",dis(a,b));
        return 0;
    }
    set(v,0,0,h);
    l=sqrt(sqr(r)+sqr(h));
    if(a.z> 0&&b.z> 0){
        db lll=aa(a)-eps,rrr=aa(a)+eps,m1,m2;
        for(int i=200;i;i--){
            m1=lll+(rrr-lll)*0.49;
            m2=lll+(rrr-lll)*0.51;
            if(fff(a,b,m1)<fff(a,b,m2))rrr=m2;else lll=m1;
        }
        printf("%.15lf\n",min(diss(a,b),fff(a,b,lll)));
        return 0;
    }
    if(b.z==0)swap(a,b);
    db l1,ll=aa(b)-eps,rr=aa(b)+eps,m1,m2;
    for(int i=200;i;i--){
        m1=ll+(rr-ll)*0.49;
        m2=ll+(rr-ll)*0.51;
        if(ff(a,b,m1)<ff(a,b,m2))rr=m2;else ll=m1;
    }
    l1=ll,ll=aa(a)-eps,rr=aa(a)+eps;
    for(int i=200;i;i--){
        m1=ll+(rr-ll)*0.49;
        m2=ll+(rr-ll)*0.51;
        if(ff(a,b,m1)<ff(a,b,m2))rr=m2;else ll=m1;
    }
    if(ff(a,b,ll)<ff(a,b,l1))l1=ll;
    ll=-pi,rr=pi;
    for(int i=200;i;i--){
        m1=ll+(rr-ll)*0.49;
        m2=ll+(rr-ll)*0.51;
        if(ff(a,b,m1)<ff(a,b,m2))rr=m2;else ll=m1;
    }
    printf("%.15lf\n",min(ff(a,b,ll),ff(a,b,l1)));
	return 0;
}

#include <iostream>
#include <cmath>
#include <cstdlib>

using namespace std;

double error=1e-9;

double r,h,lado,perimetro;

struct point {
  double x,y,z;
  point() {
  }
  point(double inx,double iny,double inz) {
    x=inx;y=iny;z=inz;
  }
};

point operator-(point p1,point p2)
{
  p1.x-=p2.x;
  p1.y-=p2.y;
  p1.z-=p2.z;
  return p1;
}

point rotar(point p,double a)
{
  point nextp=p;
  nextp.x=p.x*cos(a)-p.y*sin(a);
  nextp.y=p.x*sin(a)+p.y*cos(a);
  return nextp;
}

double cuad(double x)
{
  return x*x;
}

double abs(point p)
{
  return sqrt(cuad(p.x)+cuad(p.y)+cuad(p.z));
}

point p1,pp1;
point p2,pp2;

point obtenpp(double a)
{
  double arg=a*r/lado;
  return point(lado*cos(arg),lado*sin(arg),0);
}

double distap1(double a)
{
  return abs(pp1-obtenpp(a));
}

double distap2(double a)
{
  return abs(pp2-obtenpp(a));
}

int divisor=500;

double buscar1(double a1,double a2)
{
  if (abs(a1-a2)<error) return distap1(a1)+abs(p2-point(r*cos(a1),r*sin(a1),0));
  int imin=0;
  double solmin=distap1(a1)+abs(p2-point(r*cos(a1),r*sin(a1),0));
  for (int i=0;i<=divisor;i++) {
    double a=(a1*(divisor-i)+a2*i)/divisor;
    double solact=distap1(a)+abs(p2-point(r*cos(a),r*sin(a),0));
    if (solact<solmin) {
      imin=i;
      solmin=solact;
    }
  }
  int i1=max(0,imin-1);
  int i2=min(divisor,imin+1);
  return buscar1((a1*(divisor-i1)+a2*i1)/divisor,
		 (a1*(divisor-i2)+a2*i2)/divisor);
  //return solmin;
  /*
  int iinf=max(imin-1,0);
  int isup=min(imin+1,100);
  return buscar1(p2,a1*(100-iinf)+a2*iinf,a1*(100-isup),a2*isup);
  */
}

double buscar2(double a1inf,double a1sup,double a2inf,double a2sup)
{
  int imin=0,jmin=0;
  double solmin=distap1(a1inf)+distap2(a2inf)+
     abs(point(r*cos(a1inf),r*sin(a1inf),0)-point(r*cos(a2inf),r*sin(a2inf),0));
  if (abs(a1inf-a1sup)<error and abs(a2inf-a2sup)<error)
    return solmin;
  for (int i=0;i<=divisor;i++) {
    for (int j=0;j<=divisor;j++) {
      double aa1=(a1inf*(divisor-i)+a1sup*i)/divisor;
      double aa2=(a2inf*(divisor-j)+a2sup*j)/divisor;
      if (aa1<=aa2) {
	double solact=distap1(aa1)+distap2(aa2)+
	  abs(point(r*cos(aa1),r*sin(aa1),0)-point(r*cos(aa2),r*sin(aa2),0));
	if (solact<solmin) {
	  imin=i;
	  jmin=j;
	  solmin=solact;
	}
      }
    }
  }
  int i1=max(0,imin-1);
  int i2=min(divisor,imin+1);
  int j1=max(0,jmin-1);
  int j2=min(divisor,jmin+1);
  return buscar2((a1inf*(divisor-i1)+a1sup*i1)/divisor,
		 (a1inf*(divisor-i2)+a1sup*i2)/divisor,
		 (a2inf*(divisor-j1)+a2sup*j1)/divisor,
		 (a2inf*(divisor-j2)+a2sup*j2)/divisor);
  //return solmin;
}

int main()
{
  cout.setf(ios::fixed);
  cout.precision(10);
  cin>>r>>h>>p1.x>>p1.y>>p1.z>>p2.x>>p2.y>>p2.z;
  lado=sqrt(cuad(r)+cuad(h));
  perimetro=2*M_PI*r;
  if (p1.z<error and p2.z<error) {
    cout<<abs(p1-p2)<<endl;
    exit(0);
  }
  if (p1.z<p2.z) swap(p1,p2);
  if (p1.z>h-error) {
    if (p2.z<error)
      cout<<r-sqrt(cuad(p2.x)+cuad(p2.y))+abs(p1-point(r,0,0))<<endl;
    else
      cout<<abs(p1-p2)<<endl;
    exit(0);
  }
  double a=atan2(p1.y,p1.x);
  p1=rotar(p1,-a);
  p2=rotar(p2,-a);
  if (p2.y<0) p2.y=-p2.y;
  double a1=0;
  if (abs(p2-point(0,0,0))<error) {
    cout<<r+abs(p1-point(r,0,0))<<endl;
    exit(0);
  }
  double a2=atan2(p2.y,p2.x);
  if (a2<0) a2=-a2;
  pp1=point(abs(point(0,0,h)-p1),0,0);
  double lenp2=abs(point(0,0,h)-p2);
  double aa2=a2*r/lado;
  pp2=point(lenp2*cos(aa2),lenp2*sin(aa2),0);
  if (pp2.y<0) pp2.y=-pp2.y;
  double sol;
  if (p2.z<error) {
    sol=buscar1(a1,a2);
  } else {
    sol=min(abs(pp1-pp2),buscar2(a1,a2,a1,a2));
  }
  cout<<sol<<endl;
}

#include<iostream>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<stdio.h>
using namespace std;
const int bound=40;
const double eps=1e-9,inf=1e9+9,pi=acos(-1.0);
double ans,r,h,xa,ya,za,xb,yb,zb,la,ra,mxa,mya,lb,rb,mxb,myb,lv,rv,lz,rz;
double dtheta;
double dist(double x1,double y1,double z1,double x2,double y2,double z2)
{
	return sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2)+(z1-z2)*(z1-z2));
}
void norm(double &theta)
{
	while(theta<-eps)
	   theta+=2*pi;
    while(theta>2*pi-eps)
       theta-=2*pi;
}
double solve(double x1,double y1,double z1,double x2,double y2,double z2)
{
	double l1,l2,l,cj,alpha,dj,theta,res;
	if(fabs(z1)<eps&&fabs(z2)<eps)
	    return dist(x1,y1,z1,x2,y2,z2);
	l1=dist(x1,y1,z1,0,0,h);
	l2=dist(x2,y2,z2,0,0,h);
	alpha=atan2(y2,x2)-atan2(y1,x1);
	norm(alpha);
	if(alpha>pi)
	   alpha=2*pi-alpha;
	l=alpha*r;
	cj=sqrt(r*r+h*h);
	theta=l/cj;
	double u1,v1,u2,v2;
	u1=0;
	v1=l1;
	u2=l2*sin(theta);
	v2=l2*cos(theta);
	res=sqrt((u1-u2)*(u1-u2)+(v1-v2)*(v1-v2));
    theta=2*pi-theta;
  	u1=0;
	v1=l1;
	u2=l2*sin(theta);
	v2=l2*cos(theta);
	res=min(res,sqrt((u1-u2)*(u1-u2)+(v1-v2)*(v1-v2)));
    return res;
}
double compute(double alpha,double beta)
{
	return solve(xa,ya,za,r*cos(alpha),r*sin(alpha),0)+solve(xb,yb,zb,r*cos(beta),r*sin(beta),0)+dist(r*cos(alpha),r*sin(alpha),0,r*cos(beta),r*sin(beta),0);
}
double compute(double alpha)
{
	double theta,vl,ch,ret=inf;
	for(theta=0;theta<2*pi;theta+=dtheta)
	{
		vl=compute(alpha,theta);
		if(ret>vl)
		{
			ret=vl;
			ch=theta;
		}
	}
	lb=max(0.,ch-dtheta);
	rb=min(2*pi,ch+dtheta);
	while(lb<rb)
	{
		mxb=0.5*(lb+rb);
		myb=mxb+eps;
		if(compute(alpha,mxb)>compute(alpha,myb))
		    lb=mxb+eps;
        else
            rb=mxb-eps;
	}
	vl=compute(alpha,0.5*(lb+rb));
	if(ret>vl)
	   ret=vl;
    return ret;
}
int main()
{
	int i,j,s,p,q,it1,it2;
	scanf("%lf%lf",&r,&h);
	scanf("%lf%lf%lf%lf%lf%lf",&xa,&ya,&za,&xb,&yb,&zb);
	ans=inf;
	if(fabs(za)>eps&&fabs(zb)>eps)
	   ans=min(ans,solve(xa,ya,za,xb,yb,zb));
	if(fabs(za)<eps&&fabs(zb)<eps)
	   ans=min(ans,dist(xa,ya,za,xb,yb,zb));
	if(fabs(zb)<eps)
	{
	    swap(xa,xb);
	    swap(ya,yb);
	    swap(za,zb);
	}
	double theta,vl,ch,mi=inf;
	dtheta=2*pi/bound;
	mi=inf;
	for(theta=0;theta<2*pi;theta+=dtheta)
	{
		vl=solve(xa,ya,za,r*cos(theta),r*sin(theta),0)+solve(xb,yb,zb,r*cos(theta),r*sin(theta),0);
		if(mi>vl)
		{
			mi=vl;
			ch=theta;
		}
		if(ans>vl)
		   ans=vl;
	}
	la=max(0.,ch-dtheta);
	ra=min(2*pi,ch+dtheta);
	while(la<ra)
	{
		mxa=0.5*(la+ra);
		mya=mxa+eps;
		lv=solve(xa,ya,za,r*cos(mxa),r*sin(mxa),0)+solve(xb,yb,zb,r*cos(mxa),r*sin(mxa),0);
        rv=solve(xa,ya,za,r*cos(mya),r*sin(mya),0)+solve(xb,yb,zb,r*cos(mya),r*sin(mya),0);
		if(lv>rv)
		   la=mxa+eps;
		else
		   ra=mxa-eps;
	}
	vl=solve(xa,ya,za,r*cos(0.5*(la+ra)),r*sin(0.5*(la+ra)),0)+solve(xb,yb,zb,r*cos(0.5*(la+ra)),r*sin(0.5*(la+ra)),0);
	if(ans>vl)
	   ans=vl;
	mi=inf;
	for(theta=0;theta<2*pi;theta+=dtheta)
	{
		vl=compute(theta);
		if(mi>vl)
        {
        	mi=vl;
        	ch=theta;
        }
        if(ans>vl)
           ans=vl;
	}
    la=max(0.,ch-dtheta);
    ra=min(2*pi,ch+dtheta);
    while(la<ra)
    {
        mxa=0.5*(la+ra);
        mya=mxa+eps;
		if(compute(mxa)>compute(mya))
    	    la=mxa+eps;
	    else
	        ra=mxa-eps;
    }
    vl=compute(0.5*(la+ra));
    if(ans>vl)
       ans=vl;
    printf("%.20f\n",ans);
	return 0;
}

#include<iostream>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<stdio.h>
using namespace std;
const int bound=40;
const double eps=1e-6,inf=1e9+9,pi=acos(-1.0);
double ans,r,h,xa,ya,za,xb,yb,zb,la,ra,mxa,mya,lb,rb,mxb,myb,lv,rv,lz,rz;
double dtheta;
double dist(double x1,double y1,double z1,double x2,double y2,double z2)
{
	return sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2)+(z1-z2)*(z1-z2));
}
void norm(double &theta)
{
	while(theta<-eps)
	   theta+=2*pi;
    while(theta>2*pi-eps)
       theta-=2*pi;
}
double solve(double x1,double y1,double z1,double x2,double y2,double z2)
{
	double l1,l2,l,cj,alpha,dj,theta,res;
	if(fabs(z1)<eps&&fabs(z2)<eps)
	    return dist(x1,y1,z1,x2,y2,z2);
	l1=dist(x1,y1,z1,0,0,h);
	l2=dist(x2,y2,z2,0,0,h);
	alpha=atan2(y2,x2)-atan2(y1,x1);
	norm(alpha);
	if(alpha>pi)
	   alpha=2*pi-alpha;
	l=alpha*r;
	cj=sqrt(r*r+h*h);
	theta=l/cj;
	double u1,v1,u2,v2;
	u1=0;
	v1=l1;
	u2=l2*sin(theta);
	v2=l2*cos(theta);
	res=sqrt((u1-u2)*(u1-u2)+(v1-v2)*(v1-v2));
    theta=2*pi-theta;
  	u1=0;
	v1=l1;
	u2=l2*sin(theta);
	v2=l2*cos(theta);
	res=min(res,sqrt((u1-u2)*(u1-u2)+(v1-v2)*(v1-v2)));
    return res;
}
double compute(double alpha,double beta)
{
	return solve(xa,ya,za,r*cos(alpha),r*sin(alpha),0)+solve(xb,yb,zb,r*cos(beta),r*sin(beta),0)+dist(r*cos(alpha),r*sin(alpha),0,r*cos(beta),r*sin(beta),0);
}
double compute(double alpha)
{
	double theta,vl,ch,ret=inf;
	for(theta=0;theta<2*pi;theta+=dtheta)
	{
		vl=compute(alpha,theta);
		if(ret>vl)
		{
			ret=vl;
			ch=theta;
		}
	}
	lb=max(0.,ch-dtheta);
	rb=min(2*pi,ch+dtheta);
	while(lb<rb)
	{
		mxb=(2*lb+rb)/3;
		myb=(lb+2*rb)/3;
		if(compute(alpha,mxb)>compute(alpha,myb))
		    lb=mxb+eps;
        else
            rb=myb-eps;
	}
	vl=compute(alpha,0.5*(lb+rb));
	if(ret>vl)
	   ret=vl;
    return ret;
}
int main()
{
	int i,j,s,p,q,it1,it2;
	scanf("%lf%lf",&r,&h);
	scanf("%lf%lf%lf%lf%lf%lf",&xa,&ya,&za,&xb,&yb,&zb);
	ans=inf;
	if(fabs(za)>eps&&fabs(zb)>eps)
	   ans=min(ans,solve(xa,ya,za,xb,yb,zb));
	if(fabs(za)<eps&&fabs(zb)<eps)
	   ans=min(ans,dist(xa,ya,za,xb,yb,zb));
	if(fabs(zb)<eps)
	{
	    swap(xa,xb);
	    swap(ya,yb);
	    swap(za,zb);
	}
	double theta,vl,ch,mi=inf;
	dtheta=2*pi/bound;
	mi=inf;
	for(theta=0;theta<2*pi;theta+=dtheta)
	{
		vl=solve(xa,ya,za,r*cos(theta),r*sin(theta),0)+solve(xb,yb,zb,r*cos(theta),r*sin(theta),0);
		if(mi>vl)
		{
			mi=vl;
			ch=theta;
		}
		if(ans>vl)
		   ans=vl;
	}
	la=max(0.,ch-dtheta);
	ra=min(2*pi,ch+dtheta);
	while(la<ra)
	{
		mxa=(2*la+ra)/3;
		mya=(la+2*ra)/3;
		lv=solve(xa,ya,za,r*cos(mxa),r*sin(mxa),0)+solve(xb,yb,zb,r*cos(mxa),r*sin(mxa),0);
        rv=solve(xa,ya,za,r*cos(mya),r*sin(mya),0)+solve(xb,yb,zb,r*cos(mya),r*sin(mya),0);
    	if(lv>rv)
           la=mxa+eps;
        else
           ra=mya-eps;
	}
	vl=solve(xa,ya,za,r*cos(0.5*(la+ra)),r*sin(0.5*(la+ra)),0)+solve(xb,yb,zb,r*cos(0.5*(la+ra)),r*sin(0.5*(la+ra)),0);
	if(ans>vl)
	   ans=vl;
	mi=inf;
	for(theta=0;theta<2*pi;theta+=dtheta)
	{
		vl=compute(theta);
		if(mi>vl)
        {
        	mi=vl;
        	ch=theta;
        }
        if(ans>vl)
           ans=vl;
	}
    la=max(0.,ch-dtheta);
    ra=min(2*pi,ch+dtheta);
    while(la<ra)
    {
    	mxa=(2*la+ra)/3;
    	mya=(la+2*ra)/3;
    	if(compute(mxa)>compute(mya))
    	    la=mxa+eps;
	    else
	        ra=mya-eps;
    }
    vl=compute(0.5*(la+ra));
    if(ans>vl)
       ans=vl;
    printf("%.20f\n",ans);
	return 0;
}

#include<iostream>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<stdio.h>
using namespace std;
const int bound=40;
const double eps=1e-7,eps2=1e-7,inf=1e9+9,pi=acos(-1.0);
double ans,r,h,xa,ya,za,xb,yb,zb,la,ra,mxa,mya,lb,rb,mxb,myb,lv,rv,lz,rz;
double dtheta;
double dist(double x1,double y1,double z1,double x2,double y2,double z2)
{
	return sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2)+(z1-z2)*(z1-z2));
}
void norm(double &theta)
{
	while(theta<-eps)
	   theta+=2*pi;
    while(theta>2*pi-eps)
       theta-=2*pi;
}
double solve(double x1,double y1,double z1,double x2,double y2,double z2)
{
	double l1,l2,l,cj,alpha,dj,theta,res;
	if(fabs(z1)<eps&&fabs(z2)<eps)
	    return dist(x1,y1,z1,x2,y2,z2);
	l1=dist(x1,y1,z1,0,0,h);
	l2=dist(x2,y2,z2,0,0,h);
	alpha=atan2(y2,x2)-atan2(y1,x1);
	norm(alpha);
	if(alpha>pi)
	   alpha=2*pi-alpha;
	l=alpha*r;
	cj=sqrt(r*r+h*h);
	theta=l/cj;
	double u1,v1,u2,v2;
	u1=0;
	v1=l1;
	u2=l2*sin(theta);
	v2=l2*cos(theta);
	res=sqrt((u1-u2)*(u1-u2)+(v1-v2)*(v1-v2));
    theta=2*pi-theta;
  	u1=0;
	v1=l1;
	u2=l2*sin(theta);
	v2=l2*cos(theta);
	res=min(res,sqrt((u1-u2)*(u1-u2)+(v1-v2)*(v1-v2)));
    return res;
}
double compute(double alpha,double beta)
{
	return solve(xa,ya,za,r*cos(alpha),r*sin(alpha),0)+solve(xb,yb,zb,r*cos(beta),r*sin(beta),0)+dist(r*cos(alpha),r*sin(alpha),0,r*cos(beta),r*sin(beta),0);
}
double compute(double alpha)
{
	double theta,vl,ch,ret=inf;
	for(theta=0;theta<2*pi;theta+=dtheta)
	{
		vl=compute(alpha,theta);
		if(ret>vl)
		{
			ret=vl;
			ch=theta;
		}
	}
	lb=max(0.,ch-dtheta);
	rb=min(2*pi,ch+dtheta);
	while(lb<rb)
	{
		mxb=0.5*(lb+rb);
		myb=mxb+eps2;
		if(compute(alpha,mxb)>compute(alpha,myb))
		    lb=mxb+eps;
        else
            rb=mxb-eps;
	}
	vl=compute(alpha,0.5*(lb+rb));
	if(ret>vl)
	   ret=vl;
    return ret;
}
int main()
{
	int i,j,s,p,q,it1,it2;
	scanf("%lf%lf",&r,&h);
	scanf("%lf%lf%lf%lf%lf%lf",&xa,&ya,&za,&xb,&yb,&zb);
	ans=inf;
	if(fabs(za)>eps&&fabs(zb)>eps)
	   ans=min(ans,solve(xa,ya,za,xb,yb,zb));
	if(fabs(za)<eps&&fabs(zb)<eps)
	   ans=min(ans,dist(xa,ya,za,xb,yb,zb));
	if(fabs(zb)<eps)
	{
	    swap(xa,xb);
	    swap(ya,yb);
	    swap(za,zb);
	}
	double theta,vl,ch,mi=inf;
	dtheta=2*pi/bound;
	mi=inf;
	for(theta=0;theta<2*pi;theta+=dtheta)
	{
		vl=solve(xa,ya,za,r*cos(theta),r*sin(theta),0)+solve(xb,yb,zb,r*cos(theta),r*sin(theta),0);
		if(mi>vl)
		{
			mi=vl;
			ch=theta;
		}
		if(ans>vl)
		   ans=vl;
	}
	la=max(0.,ch-dtheta);
	ra=min(2*pi,ch+dtheta);
	while(la<ra)
	{
		mxa=0.5*(la+ra);
		mya=mxa+eps2;
		lv=solve(xa,ya,za,r*cos(mxa),r*sin(mxa),0)+solve(xb,yb,zb,r*cos(mxa),r*sin(mxa),0);
        rv=solve(xa,ya,za,r*cos(mya),r*sin(mya),0)+solve(xb,yb,zb,r*cos(mya),r*sin(mya),0);
		if(lv>rv)
		   la=mxa+eps;
		else
		   ra=mxa-eps;
	}
	vl=solve(xa,ya,za,r*cos(0.5*(la+ra)),r*sin(0.5*(la+ra)),0)+solve(xb,yb,zb,r*cos(0.5*(la+ra)),r*sin(0.5*(la+ra)),0);
	if(ans>vl)
	   ans=vl;
	mi=inf;
	for(theta=0;theta<2*pi;theta+=dtheta)
	{
		vl=compute(theta);
		if(mi>vl)
        {
        	mi=vl;
        	ch=theta;
        }
        if(ans>vl)
           ans=vl;
	}
    la=max(0.,ch-dtheta);
    ra=min(2*pi,ch+dtheta);
    while(la<ra)
    {
    //	mxa=(2*la+ra)/3;
    //	mya=(la+2*ra)/3;
        mxa=0.5*(la+ra);
        mya=mxa+eps2;
		if(compute(mxa)>compute(mya))
    	    la=mxa+eps;
	    else
	        ra=mxa-eps;
    }
    vl=compute(0.5*(la+ra));
    if(ans>vl)
       ans=vl;
    printf("%.20f\n",ans);
	return 0;
}

#include<iostream>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<stdio.h>
using namespace std;
const int bound=50;
const double eps=1e-9,inf=1e9+9,pi=acos(-1.0);
double ans,r,h,xa,ya,za,xb,yb,zb,la,ra,mxa,mya,lb,rb,mxb,myb,lv,rv,lz,rz;
double dtheta;
double dist(double x1,double y1,double z1,double x2,double y2,double z2)
{
	return sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2)+(z1-z2)*(z1-z2));
}
void norm(double &theta)
{
	while(theta<-eps)
	   theta+=2*pi;
    while(theta>2*pi-eps)
       theta-=2*pi;
}
double solve(double x1,double y1,double z1,double x2,double y2,double z2)
{
	double l1,l2,l,cj,alpha,dj,theta,res;
	if(fabs(z1)<eps&&fabs(z2)<eps)
	    return dist(x1,y1,z1,x2,y2,z2);
	l1=dist(x1,y1,z1,0,0,h);
	l2=dist(x2,y2,z2,0,0,h);
	alpha=atan2(y2,x2)-atan2(y1,x1);
	norm(alpha);
	if(alpha>pi)
	   alpha=2*pi-alpha;
	l=alpha*r;
	cj=sqrt(r*r+h*h);
	theta=l/cj;
	double u1,v1,u2,v2;
	u1=0;
	v1=l1;
	u2=l2*sin(theta);
	v2=l2*cos(theta);
	res=sqrt((u1-u2)*(u1-u2)+(v1-v2)*(v1-v2));
    theta=2*pi-theta;
  	u1=0;
	v1=l1;
	u2=l2*sin(theta);
	v2=l2*cos(theta);
	res=min(res,sqrt((u1-u2)*(u1-u2)+(v1-v2)*(v1-v2)));
    return res;
}
double compute(double alpha,double beta)
{
	return solve(xa,ya,za,r*cos(alpha),r*sin(alpha),0)+solve(xb,yb,zb,r*cos(beta),r*sin(beta),0)+dist(r*cos(alpha),r*sin(alpha),0,r*cos(beta),r*sin(beta),0);
}
double compute(double alpha)
{
	double theta,vl,ch,ret=inf;
	for(theta=0;theta<2*pi;theta+=dtheta)
	{
		vl=compute(alpha,theta);
		if(ret>vl)
		{
			ret=vl;
			ch=theta;
		}
	}
	lb=max(0.,ch-dtheta);
	rb=min(2*pi,ch+dtheta);
	while(lb<rb)
	{
		mxb=(2*lb+rb)/3;
		myb=(lb+2*rb)/3;
		if(compute(alpha,mxb)>compute(alpha,myb))
		    lb=mxb+eps;
        else
            rb=myb-eps;
	}
	vl=compute(alpha,0.5*(lb+rb));
	if(ret>vl)
	   ret=vl;
    return ret;
}
int main()
{
	int i,j,s,p,q,it1,it2;
	scanf("%lf%lf",&r,&h);
	scanf("%lf%lf%lf%lf%lf%lf",&xa,&ya,&za,&xb,&yb,&zb);
	ans=inf;
	if(fabs(za)>eps&&fabs(zb)>eps)
	   ans=min(ans,solve(xa,ya,za,xb,yb,zb));
	if(fabs(za)<eps&&fabs(zb)<eps)
	   ans=min(ans,dist(xa,ya,za,xb,yb,zb));
	if(fabs(zb)<eps)
	{
	    swap(xa,xb);
	    swap(ya,yb);
	    swap(za,zb);
	}
	double theta,vl,ch,mi=inf;
	dtheta=2*pi/bound;
	mi=inf;
	for(theta=0;theta<2*pi;theta+=dtheta)
	{
		vl=solve(xa,ya,za,r*cos(theta),r*sin(theta),0)+solve(xb,yb,zb,r*cos(theta),r*sin(theta),0);
		if(mi>vl)
		{
			mi=vl;
			ch=theta;
		}
		if(ans>vl)
		   ans=vl;
	}
	la=max(0.,ch-dtheta);
	ra=min(2*pi,ch+dtheta);
	while(la<ra)
	{
		mxa=(2*la+ra)/3;
		mya=(la+2*ra)/3;
		lv=solve(xa,ya,za,r*cos(mxa),r*sin(mxa),0)+solve(xb,yb,zb,r*cos(mxa),r*sin(mxa),0);
        rv=solve(xa,ya,za,r*cos(mya),r*sin(mya),0)+solve(xb,yb,zb,r*cos(mya),r*sin(mya),0);
    	if(lv>rv)
           la=mxa+eps;
        else
           ra=mya-eps;
	}
	vl=solve(xa,ya,za,r*cos(0.5*(la+ra)),r*sin(0.5*(la+ra)),0)+solve(xb,yb,zb,r*cos(0.5*(la+ra)),r*sin(0.5*(la+ra)),0);
	if(ans>vl)
	   ans=vl;
	mi=inf;
	for(theta=0;theta<2*pi;theta+=dtheta)
	{
		vl=compute(theta);
		if(mi>vl)
        {
        	mi=vl;
        	ch=theta;
        }
        if(ans>vl)
           ans=vl;
	}
    la=max(0.,ch-dtheta);
    ra=min(2*pi,ch+dtheta);
    while(la<ra)
    {
    	mxa=(2*la+ra)/3;
    	mya=(la+2*ra)/3;
    	if(compute(mxa)>compute(mya))
    	    la=mxa+eps;
	    else
	        ra=mya-eps;
    }
    vl=compute(0.5*(la+ra));
    if(ans>vl)
       ans=vl;
    printf("%.20f\n",ans);
	return 0;
}

#define pi 3.1415926535897932384626433832795

#include<bits/stdc++.h>

#define eps 1e-7

typedef double DO;

using namespace std;

template<typename T, typename U> inline void smin(T &a, const U &b) {if(a>b) a=b;}

struct point {

	DO x, y, z;

	inline DO al() {return atan2(y, x);}

	inline DO nor() {return sqrt(nor2());}

	inline DO nor2() {return *this**this;}

	inline point(DO x=0, DO y=0, DO z=0) : x(x), y(y), z(z) {}

	inline DO operator * (point a) {return x*a.x+y*a.y+z*a.z;}

	inline point operator - (point a) {return point(x-a.x, y-a.y, z-a.z);}

	inline point norm() {DO s=nor(); if(s<eps) return *this; return point(x/s, y/s, z/s);}

	inline void input() {scanf("%lf %lf %lf", &x, &y, &z);}

};

DO whole=2*pi, step=whole/3;

DO r, h, R;

point A, AA, B;

inline DO calc_laterals(point a, point b) {

	DO al=fabs(a.al()-b.al()); smin(al, whole-al);

	DO dada=(a-point(0, 0, h)).nor2(), da=sqrt(dada);

	DO dbdb=(b-point(0, 0, h)).nor2(), db=sqrt(dbdb);

	return sqrt(dada+dbdb-2*da*db*cos(r*al/R));

}

inline DO solve() {

	DO ans=1e13;

	for(DO sst=0; sst<whole; sst+=step) {

		DO st=sst, ed=st+step+0.1;

		while(ed-st>eps) {

			DO a=(st+st+ed)/3, b=(st+ed+ed)/3;

			point aa=point(r*cos(a), r*sin(a)); DO sa=(AA-aa).nor()+calc_laterals(aa, B);

			point bb=point(r*cos(b), r*sin(b)); DO sb=(AA-bb).nor()+calc_laterals(bb, B);

			if(sa>sb) st=a;

			else ed=b;

		}

		point aa=point(r*cos(st), r*sin(st)); smin(ans, (AA-aa).nor()+calc_laterals(aa, B));

	}

	return ans;

}

main() {

	scanf("%lf %lf", &r, &h);

	R=sqrt(r*r+h*h);

	A.input(), B.input();

	if(B.z<eps) swap(A, B);

	DO ans;

	if(A.z<eps) {

		if(B.z<eps) ans=(A-B).nor();

		else AA=A, ans=solve();

	}

	else {

		ans=calc_laterals(A, B);

		for(DO sst=0; sst<whole; sst+=step) {

			DO st=sst, ed=st+step+0.1;

			while(ed-st>eps) {

				DO a=(st+st+ed)/3, b=(st+ed+ed)/3;

				AA=point(r*cos(a), r*sin(a)); DO sa=calc_laterals(A, AA)+solve();

				AA=point(r*cos(b), r*sin(b)); DO sb=calc_laterals(A, AA)+solve();

				if(sa>sb) st=a;

				else ed=b;

			}

			AA=point(r*cos(st), r*sin(st)); smin(ans, calc_laterals(A, AA)+solve());

		}

	}

	printf("%.7lf", ans);

}

#define pi 3.1415926535897932384626433832795

#include<bits/stdc++.h>

#define eps 1e-8

using namespace std;

typedef double DO;

template<typename T, typename U> inline void smin(T &a, const U &b) {if(a>b) a=b;}

struct point {

	DO x, y, z;

	inline DO al() {return atan2(y, x);}

	inline DO nor() {return sqrt(nor2());}

	inline DO nor2() {return *this**this;}

	inline point(DO x=0, DO y=0, DO z=0) : x(x), y(y), z(z) {}

	inline DO operator * (point a) {return x*a.x+y*a.y+z*a.z;}

	inline point operator - (point a) {return point(x-a.x, y-a.y, z-a.z);}

	inline point norm() {DO s=nor(); if(s<eps) return *this; return point(x/s, y/s, z/s);}

	inline void input() {scanf("%lf %lf %lf", &x, &y, &z);}

};

DO whole=2*pi, step=whole/3;

DO r, h, R;

point A, AA, B;

inline DO calc_laterals(point a, point b) {

	DO al=fabs(a.al()-b.al()); smin(al, whole-al);

	DO dada=(a-point(0, 0, h)).nor2(), da=sqrt(dada);

	DO dbdb=(b-point(0, 0, h)).nor2(), db=sqrt(dbdb);

	return sqrt(dada+dbdb-2*da*db*cos(r*al/R));

}

inline DO solve() {

	DO ans=1e13;

	for(DO sst=0; sst<whole; sst+=step) {

		DO st=sst, ed=st+step+0.1;

		while(ed-st>eps) {

			DO a=(st+st+ed)/3, b=(st+ed+ed)/3;

			point aa=point(r*cos(a), r*sin(a)); DO sa=(AA-aa).nor()+calc_laterals(aa, B);

			point bb=point(r*cos(b), r*sin(b)); DO sb=(AA-bb).nor()+calc_laterals(bb, B);

			if(sa>sb) st=a;

			else ed=b;

		}

		point aa=point(r*cos(st), r*sin(st)); smin(ans, (AA-aa).nor()+calc_laterals(aa, B));

	}

	return ans;

}

main() {

	scanf("%lf %lf", &r, &h);

	R=sqrt(r*r+h*h);

	A.input(), B.input();

	if(B.z<eps) swap(A, B);

	DO ans;

	if(A.z<eps) {

		if(B.z<eps) ans=(A-B).nor();

		else AA=A, ans=solve();

	}

	else {

		ans=calc_laterals(A, B);

		for(DO sst=0; sst<whole; sst+=step) {

			DO st=sst, ed=st+step+0.1;

			while(ed-st>eps) {

				DO a=(st+st+ed)/3, b=(st+ed+ed)/3;

				AA=point(r*cos(a), r*sin(a)); DO sa=calc_laterals(A, AA)+solve();

				AA=point(r*cos(b), r*sin(b)); DO sb=calc_laterals(A, AA)+solve();

				if(sa>sb) st=a;

				else ed=b;

			}

			AA=point(r*cos(st), r*sin(st)); smin(ans, calc_laterals(A, AA)+solve());

		}

	}

	printf("%.7lf", ans);

}

#include <bits/stdc++.h>

using namespace std;

typedef long long INT;

typedef long double DO;

typedef pair<int, int> pii;

typedef vector<int> VI;

#define eps 1e-10

const DO pi = acosl(-1.0);

struct point {

    DO x, y, z;

    point (DO x=0, DO y=0, DO z=0) : x(x), y(y), z(z) {}

    point operator + (const point &a) {return point(a.x+x, a.y+y, z+a.z);}

    point operator - (const point &a) {return point(a.x-x, a.y-y, z-a.z);}

    DO operator * (const point &a) {return x*a.x+y*a.y+z*a.z;}

    DO nor() {return sqrtl(*this**this);}

    DO al() {return atan2l(y, x);}

    void input() {

        cin>>x>>y>>z;

    }

};

point p, q, H;

DO r, L;

DO calc_dst(point p, point q) {

    DO al=p.al(), be=q.al();

    al=min(fabs(al-be), 2*pi-fabs(al-be));

    return sqrtl((H-p)*(H-p)+(H-q)*(H-q)-2.0*(H-p).nor()*(H-q).nor()*cosl(al*r/L));

}

DO calc2(DO al) {

    point a = point(cosl(al)*r, sinl(al)*r, 0);

    return calc_dst(q, a)+(a-p).nor();

}

DO calc1(DO al, DO be) {

    point a=point(cosl(al)*r, sinl(al)*r, 0);

    point b=point(cosl(be)*r, sinl(be)*r, 0);

    return calc_dst(p, a)+calc_dst(b, q)+(a-b).nor();

}

DO calc(DO al) {

    DO ans=1e100;

    for (int i=0; i<6; i++) {

        DO st=pi/3*i, ed=st+pi/2;

        for (int j=0; j<100; j++) {

            DO x1=(st+st+ed)/3, x2=(st+ed+ed)/3;

            if (calc1(al, x1)<calc1(al, x2)) ed=x2;

            else st=x1;

        }

        ans=min(ans, calc1(al, st));

    }

    return ans;

}

int main() {

#ifndef ONLINE_JUDGE

    freopen("in.in", "r", stdin);

    freopen("out.out", "w", stdout);

#endif

    DO h;

    cin>>r>>h;

    p.input(); q.input();

    H = point(0, 0, h);

    L = sqrtl(h*h+r*r);

    DO ans=1e100;

    if (p.z<eps && q.z<eps) {

        ans=(p-q).nor();

    } else if (p.z>eps && q.z>eps) {

        ans=calc_dst(p, q);

        for (int i=0; i<6; i++) {

            DO st=pi/3*i, ed=st+pi/2;

            for (int j=0; j<100; j++) {

                DO x1=(st+st+ed)/3, x2=(st+ed+ed)/3;

                if (calc(x1)<calc(x2)) ed=x2;

                else st=x1;

            }

            ans=min(ans, calc(st));

        }

    } else {

        if (p.z>eps) swap(p, q);

        for (int i=0; i<6; i++) {

            DO st=pi/3*i, ed=st+pi/2;

            for (int j=0; j<100; j++) {

                DO x1=(st+st+ed)/3, x2=(st+ed+ed)/3;

                if (calc2(x1)<calc2(x2)) ed=x2;

                else st=x1;

            }

            ans=min(ans, calc2(st));

        }

    }

    cout << setprecision(20) << fixed << ans << endl;

    return 0;

}

#include"bits/stdc++.h"
#define eps 1e-6

typedef double DO;
using namespace std;
template<typename A, typename B> inline void smin(A &a, const B &b) {if(a>b) a=b;}

struct point {
	DO x, y, z;
	inline point(DO x=0, DO y=0, DO z=0) : x(x), y(y), z(z) {}
	inline point operator - (point a) {return point(x-a.x, y-a.y, z-a.z);}
	inline DO al() {return atan2(y, x);}
	inline DO nor2() {return *this**this;}
	inline DO nor() {return sqrt(*this**this);}
	inline DO operator * (point a) {return x*a.x+y*a.y+z*a.z;}
	inline void input() {scanf("%lf %lf %lf", &x, &y, &z);}
	inline void print() {printf("%lf %lf %lf\n", x, y, z);}
} A, B, A_, B_, F;

DO r, h, R;
DO all=6.283185307179586476925286766559;
DO _120=2.0943951023931954923084289221863;
DO _150=2.2689280275926284500007979990352;

inline DO dist(point a, point b) {
	DO al=fabs(a.al()-b.al()); smin(al, all-al);
	DO da=(a-F).nor2(), db=(b-F).nor2();
	return sqrt(da+db-2*sqrt(da*db)*cos(r*al/R));
}

inline DO calc_A() {
	DO ans=1e100;
	for(DO st_=0; st_<all; st_+=_120) {
		DO st=st_, ed=st+_120+0.1;
		while(ed-st>eps) {
			DO a=(st+st+ed)/3; B_={r*cos(a), r*sin(a)}; DO val_a=(A_-B_).nor()+dist(B, B_);
			DO b=(st+ed+ed)/3; B_={r*cos(b), r*sin(b)}; DO val_b=(A_-B_).nor()+dist(B, B_);
			if(val_a<val_b) ed=b;
			else st=a;
		}
		DO al=(st+ed)/2; B_={r*cos(al), r*sin(al)}; smin(ans, (A_-B_).nor()+dist(B, B_));
	}
	return ans;
}

main() {
#ifndef ONLINE_JUDGE
	freopen("in.in", "r", stdin);
	freopen("out.out", "w", stdout);
#endif

	scanf("%lf %lf", &r, &h);
	F=point(0, 0, h);
	R=sqrt(r*r+h*h);

	A.input(), B.input();
	if(A.z>B.z) swap(A, B);

	DO ans;
	if(B.z<eps) ans=(A-B).nor();
	else if(A.z<eps) A_=A, ans=calc_A();
	else {
		ans=dist(A, B);
		for(DO st_=0; st_<all; st_+=_120) {
			DO st=st_, ed=st+_120+0.1;
			while(ed-st>eps) {
				DO a=(st+st+ed)/3; A_={r*cos(a), r*sin(a)}; DO val_a=dist(A, A_)+calc_A();
				DO b=(st+ed+ed)/3; A_={r*cos(b), r*sin(b)}; DO val_b=dist(A, A_)+calc_A();
				if(val_a<val_b) ed=b;
				else st=a;
			}
			DO al=(st+ed)/2; A_={r*cos(al), r*sin(al)}; smin(ans, dist(A, A_)+calc_A());
		}
	}
	printf("%.6lf", ans);
}

#include "bits/stdc++.h"
#define x first
#define y second
#define sq(_) ((_)*(_))
using namespace std;
using DO = long double;
using pdd = pair<DO, DO>;
pdd operator + (const pdd &a, const pdd &b) {return {a.x+b.x, a.y+b.y};}
pdd operator - (const pdd &a, const pdd &b) {return {a.x-b.x, a.y-b.y};}
pdd operator * (const pdd &a, const DO &b) {return {a.x*b, a.y*b};}
pdd operator / (const pdd &a, const DO &b) {return {a.x/b, a.y/b};}
DO  operator * (const pdd &a, const pdd &b) {return a.x*b.x+a.y*b.y;}
DO  operator ^ (const pdd &a, const pdd &b) {return a.x*b.y-a.y*b.x;}
DO len(const pdd &a) {return sqrtl(a*a);}
pdd rot(const pdd &a, const DO &alp) {
  return {a.x*cosl(alp)-a.y*sinl(alp), a.x*sinl(alp)+a.y*cosl(alp)};
}
DO alp(const pdd &a) {
  return atan2l(a.y, a.x);
}

const DO pi = acosl(-1);
const DO eps = 1e-10;
int sgn(const DO &a) {
  return a<-eps ? -1 : a>eps;
}

DO h, r, R;

pdd get(DO ax, DO ay) {
  pdd p = {ax, ay};
  DO len = ::len(p);
  if(sgn(len) == 0) {
    return {r, 0};
  }else {
    return p*(r/len);
  }
}

DO f(DO ax, DO ay, DO az, DO bx, DO by, DO bz) {
  pdd p, q;
  p = get(ax, ay);
  q = get(bx, by);
  DO ap = alp(p);
  DO aq = alp(q);
  DO al = aq-ap;
  while(al<-eps) al+=pi*2;
  while(al>pi*2+eps) al-=pi*2;
  if(al>pi+eps) {
    al=pi*2-al;
  }
  al=al*(r/R);
  DO a = sqrtl(sq(ax)+sq(ay)+sq(h-az));
  DO b = sqrtl(sq(bx)+sq(by)+sq(h-bz));
  DO c=sq(a)+sq(b)-2*a*b*cosl(al);
  c=max((DO)0, c);
  return sqrtl(c);
}

DO f1(DO ax, DO ay, DO bx, DO by, DO bz, DO ag=0) {
  pdd p = get(ax, ay);
  pdd p1, p2;
  int step = 100;
  DO st=0, ed=pi*2, md1, md2, v1, v2;
  while(step--) {
    md1=(st+st+ed)/3;
    md2=(st+ed+ed)/3;
    p1=rot(p, md1+ag);
    p2=rot(p, md2+ag);
    v1=len(pdd(ax, ay)-p1)+f(p1.x, p1.y, 0, bx, by, bz);
    v2=len(pdd(ax, ay)-p2)+f(p2.x, p2.y, 0, bx, by, bz);
    if(v1<v2) {
      ed=md2;
    }else {
      st=md1;
    }
  }
  p1=rot(p, st+ag);
  v1=len(pdd(ax, ay)-p1)+f(p1.x, p1.y, 0, bx, by, bz);
  return v1;
}

DO f2(DO ax, DO ay, DO bx, DO by, DO bz) {
  DO ans = f1(ax, ay, bx, by, bz);
  ans = min(ans, f1(ax, ay, bx, by, bz, pi*2/3));
  ans = min(ans, f1(ax, ay, bx, by, bz, pi*4/3));
  return ans;
}

DO f3(DO ax, DO ay, DO az, DO bx, DO by, DO bz, DO ag=0) {
  DO ans = f(ax, ay, az, bx, by, bz);
  pdd p = get(ax, ay);
  int step = 100;
  DO st=0, ed=pi*2, md1, md2, v1, v2;
  pdd p1, p2;
  while(step--) {
    md1=(st+st+ed)/3;
    md2=(st+ed+ed)/3;
    p1=rot(p, md1+ag);
    p2=rot(p, md2+ag);
    v1=f(p1.x, p1.y, 0, ax, ay, az)+f2(p1.x, p1.y, bx, by, bz);
    v2=f(p2.x, p2.y, 0, ax, ay, az)+f2(p2.x, p2.y, bx, by, bz);
    if(v1 < v2) {
      ed=md2;
    }else {
      st=md1;
    }
  }
  p1=rot(p, st+ag);
  v1=f(p1.x, p1.y, 0, ax, ay, az)+f2(p1.x, p1.y, bx, by, bz);
  ans=min(ans, v1);
  return ans;
}

DO f4(DO ax, DO ay, DO az, DO bx, DO by, DO bz) {
  DO ans=f3(ax, ay, az, bx, by, bz);
  ans=min(ans, f3(ax, ay, az, bx, by, bz, pi*2/3));
  ans=min(ans, f3(ax, ay, az, bx, by, bz, pi*4/3));
  return ans;
}

int main() {
#ifndef ONLINE_JUDGE
  freopen("in.in", "r", stdin);
  freopen("out.out", "w", stdout);
#endif
  cout<<fixed<<setprecision(10);
  cin>>r>>h;
  R = sqrtl(sq(r)+sq(h));
  DO ax, ay, az, bx, by, bz;
  cin>>ax>>ay>>az>>bx>>by>>bz;
  if(sgn(az) == 0 && sgn(bz) == 0) {
    cout<<len(pdd(ax-bx, ay-by))<<endl;
    return 0;
  }
  if(sgn(az) == 0) {
    cout<<f2(ax, ay, bx, by, bz)<<endl;
    return 0;
  }
  if(sgn(bz) == 0) {
    cout<<f2(bx, by, ax, ay, az)<<endl;
    return 0;
  }
  DO ans=f4(ax, ay, az, bx, by, bz);
  cout<<ans<<endl;
  return 0;
}

#define pi 3.1415926535897932384626433832795

#include<bits/stdc++.h>

#define eps 1e-10

using namespace std;

typedef long double DO;

template<typename T, typename U> inline void smin(T &a, const U &b) {if(a>b) a=b;}

struct point {

	DO x, y, z;

	inline point(DO x=0, DO y=0, DO z=0) : x(x), y(y), z(z) {}

	inline point operator - (point a) {return point(x-a.x, y-a.y, z-a.z);}

	inline point operator + (point a) {return point(x+a.x, y+a.y, z+a.z);}

	inline point operator * (DO a) {return point(x*a, y*a, z*a);}

	inline point operator / (DO a) {return point(x/a, y/a, z/a);}

	inline DO operator * (point a) {return x*a.x+y*a.y+z*a.z;}

	inline point norm() {DO s=nor(); if(s<eps) return *this; return point(x/s, y/s, z/s);}

	inline DO nor() {return sqrtl(nor2());}

	inline DO nor2() {return *this**this;}

	inline DO al() {return atan2l(y, x);}

	inline void input() {cin>>x>>y>>z;}

};

DO whole=2*pi, step=whole/3;

DO r, h, R;

point A, AA, B;

inline DO calc_laterals(point a, point b) {

	DO al=fabsl(a.al()-b.al()); smin(al, whole-al);

	DO dada=(a-point(0, 0, h)).nor2(), da=sqrtl(dada);

	DO dbdb=(b-point(0, 0, h)).nor2(), db=sqrtl(dbdb);

	return sqrtl(dada+dbdb-2*da*db*cosl(r*al/R));

}

inline DO solve() {

	DO ans=1e13;

	for(DO sst=0; sst<whole; sst+=step) {

		DO st=sst, ed=st+step+0.1;

		while(ed-st>eps) {

			DO a=(st+st+ed)/3, b=(st+ed+ed)/3;

			point aa=point(r*cosl(a), r*sinl(a)); DO sa=(AA-aa).nor()+calc_laterals(aa, B);

			point bb=point(r*cosl(b), r*sinl(b)); DO sb=(AA-bb).nor()+calc_laterals(bb, B);

			if(sa>sb) st=a;

			else ed=b;

		}

		point aa=point(r*cosl(st), r*sinl(st)); smin(ans, (AA-aa).nor()+calc_laterals(aa, B));

	}

	return ans;

}

main() {

#ifndef	ONLINE_JUDGE

	freopen("in.in", "r", stdin);

	freopen("out.out", "w", stdout);

#endif

	cin>>r>>h;

	R=sqrtl(r*r+h*h);

	A.input(), B.input();

	if(B.z<eps) swap(A, B);

	DO ans;

	if(A.z<eps) {

		if(B.z<eps) ans=(A-B).nor();

		else AA=A, ans=solve();

	}

	else {

		ans=calc_laterals(A, B);

		for(DO sst=0; sst<whole; sst+=step) {

			DO st=sst, ed=st+step+0.1;

			while(ed-st>eps) {

				DO a=(st+st+ed)/3, b=(st+ed+ed)/3;

				AA=point(r*cosl(a), r*sinl(a)); DO sa=calc_laterals(A, AA)+solve();

				AA=point(r*cosl(b), r*sinl(b)); DO sb=calc_laterals(A, AA)+solve();

				if(sa>sb) st=a;

				else ed=b;

			}

			AA=point(r*cosl(st), r*sinl(st)); smin(ans, calc_laterals(A, AA)+solve());

		}

	}

	printf("%.7lf", (double)ans);

}

#define pi 3.1415926535897932384626433832795

#include<bits/stdc++.h>

#define eps 1e-13

using namespace std;

typedef long double DO;

template<typename T, typename U> inline void smin(T &a, const U &b) {if(a>b) a=b;}

struct point {

	DO x, y, z;

	inline point(DO x=0, DO y=0, DO z=0) : x(x), y(y), z(z) {}

	inline point operator - (point a) {return point(x-a.x, y-a.y, z-a.z);}

	inline point operator + (point a) {return point(x+a.x, y+a.y, z+a.z);}

	inline point operator * (DO a) {return point(x*a, y*a, z*a);}

	inline point operator / (DO a) {return point(x/a, y/a, z/a);}

	inline DO operator * (point a) {return x*a.x+y*a.y+z*a.z;}

	inline point norm() {DO s=nor(); if(s<eps) return *this; return point(x/s, y/s, z/s);}

	inline DO nor() {return sqrtl(nor2());}

	inline DO nor2() {return *this**this;}

	inline DO al() {return atan2l(y, x);}

	inline void input() {cin>>x>>y>>z;}

};

DO whole=2*pi, step=whole/3;

DO r, h, R;

point A, AA, B;

inline DO calc_laterals(point a, point b) {

	DO al=fabsl(a.al()-b.al()); smin(al, whole-al);

	DO dada=(a-point(0, 0, h)).nor2(), da=sqrtl(dada);

	DO dbdb=(b-point(0, 0, h)).nor2(), db=sqrtl(dbdb);

	return sqrtl(dada+dbdb-2*da*db*cosl(r*al/R));

}

inline DO solve() {

	DO ans=1e13;

	for(DO sst=0; sst<whole; sst+=step) {

		DO st=sst, ed=st+step+0.3;

		while(ed-st>eps) {

			DO a=(st+st+ed)/3, b=(st+ed+ed)/3;

			point aa=point(r*cosl(a), r*sinl(a)); DO sa=(AA-aa).nor()+calc_laterals(aa, B);

			point bb=point(r*cosl(b), r*sinl(b)); DO sb=(AA-bb).nor()+calc_laterals(bb, B);

			if(sa>sb) st=a;

			else ed=b;

		}

		point aa=point(r*cosl(st), r*sinl(st)); smin(ans, (AA-aa).nor()+calc_laterals(aa, B));

		point bb=point(r*cosl(ed), r*sinl(ed)); smin(ans, (AA-bb).nor()+calc_laterals(bb, B));

	}

	return ans;

}

main() {

#ifndef	ONLINE_JUDGE

	freopen("in.in", "r", stdin);

	freopen("out.out", "w", stdout);

#endif

	cin>>r>>h;

	R=sqrtl(r*r+h*h);

	A.input(), B.input();

	if(B.z<eps) swap(A, B);

	DO ans;

	if(A.z<eps) {

		if(B.z<eps) ans=(A-B).nor();

		else AA=A, ans=solve();

	}

	else {

		ans=calc_laterals(A, B);

		for(DO sst=0; sst<whole; sst+=step) {

			DO st=sst, ed=st+step+0.3;

			while(ed-st>eps) {

				DO a=(st+st+ed)/3, b=(st+ed+ed)/3;

				AA=point(r*cosl(a), r*sinl(a)); DO sa=calc_laterals(A, AA)+solve();

				AA=point(r*cosl(b), r*sinl(b)); DO sb=calc_laterals(A, AA)+solve();

				if(sa>sb) st=a;

				else ed=b;

			}

			AA=point(r*cosl(st), r*sinl(st)); smin(ans, calc_laterals(A, AA)+solve());

			AA=point(r*cosl(ed), r*sinl(ed)); smin(ans, calc_laterals(A, AA)+solve());

		}

	}

	printf("%.10lf", (double)ans);

}

#define pi 3.1415926535897932384626433832795

#include<bits/stdc++.h>

#define eps 1e-7

typedef double DO;

using namespace std;

template<typename T, typename U> inline void smin(T &a, const U &b) {if(a>b) a=b;}

struct point {

 DO x, y, z;

 inline DO al() {return atan2(y, x);}

 inline DO nor() {return sqrt(nor2());}

 inline DO nor2() {return *this**this;}

 inline point(DO x=0, DO y=0, DO z=0) : x(x), y(y), z(z) {}

 inline DO operator * (point a) {return x*a.x+y*a.y+z*a.z;}

 inline point operator - (point a) {return point(x-a.x, y-a.y, z-a.z);}

 inline point norm() {DO s=nor(); if(s<eps) return *this; return point(x/s, y/s, z/s);}

 inline void input() {scanf("%lf %lf %lf", &x, &y, &z);}

};

DO whole=2*pi, step=whole/3;

DO r, h, R;

point A, AA, B;

inline DO calc_laterals(point a, point b) {

 DO al=fabs(a.al()-b.al()); smin(al, whole-al);

 DO dada=(a-point(0, 0, h)).nor2(), da=sqrt(dada);

 DO dbdb=(b-point(0, 0, h)).nor2(), db=sqrt(dbdb);

 return sqrt(dada+dbdb-2*da*db*cos(r*al/R));

}

inline DO solve() {

 DO ans=1e13;

 for(DO sst=0; sst<whole; sst+=step) {

  DO st=sst, ed=st+step+0.1;

  while(ed-st>eps) {

   DO a=(st+st+ed)/3, b=(st+ed+ed)/3;

   point aa=point(r*cos(a), r*sin(a)); DO sa=(AA-aa).nor()+calc_laterals(aa, B);

   point bb=point(r*cos(b), r*sin(b)); DO sb=(AA-bb).nor()+calc_laterals(bb, B);

   if(sa>sb) st=a;

   else ed=b;

  }

  point aa=point(r*cos(st), r*sin(st)); smin(ans, (AA-aa).nor()+calc_laterals(aa, B));

 }

 return ans;

}

main() {

 scanf("%lf %lf", &r, &h);

 R=sqrt(r*r+h*h);

 A.input(), B.input();

 if(B.z<eps) swap(A, B);

 DO ans;

 if(A.z<eps) {

  if(B.z<eps) ans=(A-B).nor();

  else AA=A, ans=solve();

 }

 else {

  ans=calc_laterals(A, B);

  for(DO sst=0; sst<whole; sst+=step) {

   DO st=sst, ed=st+step+0.1;

   while(ed-st>eps) {

    DO a=(st+st+ed)/3, b=(st+ed+ed)/3;

    AA=point(r*cos(a), r*sin(a)); DO sa=calc_laterals(A, AA)+solve();

    AA=point(r*cos(b), r*sin(b)); DO sb=calc_laterals(A, AA)+solve();

    if(sa>sb) st=a;

    else ed=b;

   }

   AA=point(r*cos(st), r*sin(st)); smin(ans, calc_laterals(A, AA)+solve());

  }

 }

 printf("%.7lf", ans);

}

#include<iostream>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<stdio.h>
using namespace std;
const int bound=40;
const double eps=1e-7,eps2=1e-7,inf=1e9+9,pi=acos(-1.0);
double ans,r,h,xa,ya,za,xb,yb,zb,la,ra,mxa,mya,lb,rb,mxb,myb,lv,rv,lz,rz;
double dtheta;
double dist(double x1,double y1,double z1,double x2,double y2,double z2)
{
	return sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2)+(z1-z2)*(z1-z2));
}
void norm(double &theta)
{
	while(theta<-eps)
	   theta+=2*pi;
    while(theta>2*pi-eps)
       theta-=2*pi;
}
double solve(double x1,double y1,double z1,double x2,double y2,double z2)
{
	double l1,l2,l,cj,alpha,dj,theta,res;
	if(fabs(z1)<eps&&fabs(z2)<eps)
	    return dist(x1,y1,z1,x2,y2,z2);
	l1=dist(x1,y1,z1,0,0,h);
	l2=dist(x2,y2,z2,0,0,h);
	alpha=atan2(y2,x2)-atan2(y1,x1);
	norm(alpha);
	if(alpha>pi)
	   alpha=2*pi-alpha;
	l=alpha*r;
	cj=sqrt(r*r+h*h);
	theta=l/cj;
	double u1,v1,u2,v2;
	u1=0;
	v1=l1;
	u2=l2*sin(theta);
	v2=l2*cos(theta);
	res=sqrt((u1-u2)*(u1-u2)+(v1-v2)*(v1-v2));
    theta=2*pi-theta;
  	u1=0;
	v1=l1;
	u2=l2*sin(theta);
	v2=l2*cos(theta);
	res=min(res,sqrt((u1-u2)*(u1-u2)+(v1-v2)*(v1-v2)));
    return res;
}
double compute(double alpha,double beta)
{
	return solve(xa,ya,za,r*cos(alpha),r*sin(alpha),0)+solve(xb,yb,zb,r*cos(beta),r*sin(beta),0)+dist(r*cos(alpha),r*sin(alpha),0,r*cos(beta),r*sin(beta),0);
}
double compute(double alpha)
{
	double theta,vl,ch,ret=inf;
	for(theta=0;theta<2*pi;theta+=dtheta)
	{
		vl=compute(alpha,theta);
		if(ret>vl)
		{
			ret=vl;
			ch=theta;
		}
	}
	lb=max(0.,ch-dtheta);
	rb=min(2*pi,ch+dtheta);
	while(lb<rb)
	{
		mxb=0.5*(lb+rb);
		myb=mxb+eps2;
		if(compute(alpha,mxb)>compute(alpha,myb))
		    lb=mxb+eps;
        else
            rb=mxb-eps;
	}
	vl=compute(alpha,0.5*(lb+rb));
	if(ret>vl)
	   ret=vl;
    return ret;
}
int main()
{
	int i,j,s,p,q,it1,it2;
	scanf("%lf%lf",&r,&h);
	scanf("%lf%lf%lf%lf%lf%lf",&xa,&ya,&za,&xb,&yb,&zb);
	ans=inf;
	if(fabs(za)>eps&&fabs(zb)>eps)
	   ans=min(ans,solve(xa,ya,za,xb,yb,zb));
	if(fabs(za)<eps&&fabs(zb)<eps)
	   ans=min(ans,dist(xa,ya,za,xb,yb,zb));
	if(fabs(zb)<eps)
	{
	    swap(xa,xb);
	    swap(ya,yb);
	    swap(za,zb);
	}
	double theta,vl,ch,mi=inf;
	dtheta=2*pi/bound;
	mi=inf;
	for(theta=0;theta<2*pi;theta+=dtheta)
	{
		vl=solve(xa,ya,za,r*cos(theta),r*sin(theta),0)+solve(xb,yb,zb,r*cos(theta),r*sin(theta),0);
		if(mi>vl)
		{
			mi=vl;
			ch=theta;
		}
		if(ans>vl)
		   ans=vl;
	}
	la=max(0.,ch-dtheta);
	ra=min(2*pi,ch+dtheta);
	while(la<ra)
	{
		mxa=0.5*(la+ra);
		mya=mxa+eps2;
		lv=solve(xa,ya,za,r*cos(mxa),r*sin(mxa),0)+solve(xb,yb,zb,r*cos(mxa),r*sin(mxa),0);
        rv=solve(xa,ya,za,r*cos(mya),r*sin(mya),0)+solve(xb,yb,zb,r*cos(mya),r*sin(mya),0);
		if(lv>rv)
		   la=mxa+eps;
		else
		   ra=mxa-eps;
	}
	vl=solve(xa,ya,za,r*cos(0.5*(la+ra)),r*sin(0.5*(la+ra)),0)+solve(xb,yb,zb,r*cos(0.5*(la+ra)),r*sin(0.5*(la+ra)),0);
	if(ans>vl)
	   ans=vl;
	mi=inf;
	for(theta=0;theta<2*pi;theta+=dtheta)
	{
		vl=compute(theta);
		if(mi>vl)
        {
        	mi=vl;
        	ch=theta;
        }
        if(ans>vl)
           ans=vl;
	}
    la=max(0.,ch-dtheta);
    ra=min(2*pi,ch+dtheta);
    while(la<ra)
    {
        mxa=0.5*(la+ra);
        mya=mxa+eps2;
		if(compute(mxa)>compute(mya))
    	    la=mxa+eps;
	    else
	        ra=mxa-eps;
    }
    vl=compute(0.5*(la+ra));
    if(ans>vl)
       ans=vl;
    printf("%.20f\n",ans);
	return 0;
}

#include<iostream>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<stdio.h>
using namespace std;
const int bound=50;
const double eps=1e-6,inf=1e9+9,pi=acos(-1.0);
double ans,r,h,xa,ya,za,xb,yb,zb,la,ra,mxa,mya,lb,rb,mxb,myb,lv,rv,lz,rz;
double dtheta;
double dist(double x1,double y1,double z1,double x2,double y2,double z2)
{
	return sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2)+(z1-z2)*(z1-z2));
}
void norm(double &theta)
{
	while(theta<-eps)
	   theta+=2*pi;
    while(theta>2*pi-eps)
       theta-=2*pi;
}
double solve(double x1,double y1,double z1,double x2,double y2,double z2)
{
	double l1,l2,l,cj,alpha,dj,theta,res;
	if(fabs(z1)<eps&&fabs(z2)<eps)
	    return dist(x1,y1,z1,x2,y2,z2);
	l1=dist(x1,y1,z1,0,0,h);
	l2=dist(x2,y2,z2,0,0,h);
	alpha=atan2(y2,x2)-atan2(y1,x1);
	norm(alpha);
	if(alpha>pi)
	   alpha=2*pi-alpha;
	l=alpha*r;
	cj=sqrt(r*r+h*h);
	theta=l/cj;
	double u1,v1,u2,v2;
	u1=0;
	v1=l1;
	u2=l2*sin(theta);
	v2=l2*cos(theta);
	res=sqrt((u1-u2)*(u1-u2)+(v1-v2)*(v1-v2));
    theta=2*pi-theta;
  	u1=0;
	v1=l1;
	u2=l2*sin(theta);
	v2=l2*cos(theta);
	res=min(res,sqrt((u1-u2)*(u1-u2)+(v1-v2)*(v1-v2)));
    return res;
}
double compute(double alpha,double beta)
{
	return solve(xa,ya,za,r*cos(alpha),r*sin(alpha),0)+solve(xb,yb,zb,r*cos(beta),r*sin(beta),0)+dist(r*cos(alpha),r*sin(alpha),0,r*cos(beta),r*sin(beta),0);
}
double compute(double alpha)
{
	double theta,vl,ch,ret=inf;
	for(theta=0;theta<2*pi;theta+=dtheta)
	{
		vl=compute(alpha,theta);
		if(ret>vl)
		{
			ret=vl;
			ch=theta;
		}
	}
	lb=max(0.,ch-dtheta);
	rb=min(2*pi,ch+dtheta);
	while(lb<rb)
	{
		mxb=(2*lb+rb)/3;
		myb=(lb+2*rb)/3;
		if(compute(alpha,mxb)>compute(alpha,myb))
		    lb=mxb+eps;
        else
            rb=myb-eps;
	}
	vl=compute(alpha,0.5*(lb+rb));
	if(ret>vl)
	   ret=vl;
    return ret;
}
int main()
{
	int i,j,s,p,q,it1,it2;
	scanf("%lf%lf",&r,&h);
	scanf("%lf%lf%lf%lf%lf%lf",&xa,&ya,&za,&xb,&yb,&zb);
	ans=inf;
	if(fabs(za)>eps&&fabs(zb)>eps)
	   ans=min(ans,solve(xa,ya,za,xb,yb,zb));
	if(fabs(za)<eps&&fabs(zb)<eps)
	   ans=min(ans,dist(xa,ya,za,xb,yb,zb));
	if(fabs(zb)<eps)
	{
	    swap(xa,xb);
	    swap(ya,yb);
	    swap(za,zb);
	}
	double theta,vl,ch,mi=inf;
	dtheta=2*pi/bound;
	mi=inf;
	for(theta=0;theta<2*pi;theta+=dtheta)
	{
		vl=solve(xa,ya,za,r*cos(theta),r*sin(theta),0)+solve(xb,yb,zb,r*cos(theta),r*sin(theta),0);
		if(mi>vl)
		{
			mi=vl;
			ch=theta;
		}
		if(ans>vl)
		   ans=vl;
	}
	la=max(0.,ch-dtheta);
	ra=min(2*pi,ch+dtheta);
	while(la<ra)
	{
		mxa=(2*la+ra)/3;
		mya=(la+2*ra)/3;
		lv=solve(xa,ya,za,r*cos(mxa),r*sin(mxa),0)+solve(xb,yb,zb,r*cos(mxa),r*sin(mxa),0);
        rv=solve(xa,ya,za,r*cos(mya),r*sin(mya),0)+solve(xb,yb,zb,r*cos(mya),r*sin(mya),0);
    	if(lv>rv)
           la=mxa+eps;
        else
           ra=mya-eps;
	}
	vl=solve(xa,ya,za,r*cos(0.5*(la+ra)),r*sin(0.5*(la+ra)),0)+solve(xb,yb,zb,r*cos(0.5*(la+ra)),r*sin(0.5*(la+ra)),0);
	if(ans>vl)
	   ans=vl;
	mi=inf;
	for(theta=0;theta<2*pi;theta+=dtheta)
	{
		vl=compute(theta);
		if(mi>vl)
        {
        	mi=vl;
        	ch=theta;
        }
        if(ans>vl)
           ans=vl;
	}
    la=max(0.,ch-dtheta);
    ra=min(2*pi,ch+dtheta);
    while(la<ra)
    {
    	mxa=(2*la+ra)/3;
    	mya=(la+2*ra)/3;
    	if(compute(mxa)>compute(mya))
    	    la=mxa+eps;
	    else
	        ra=mya-eps;
    }
    vl=compute(0.5*(la+ra));
    if(ans>vl)
       ans=vl;
    printf("%.20f\n",ans);
	return 0;
}

#define pi 3.1415926535897932384626433832795

#include<bits/stdc++.h>

#define eps 1e-7

using namespace std;

typedef long double DO;

template<typename T, typename U> inline void smin(T &a, const U &b) {if(a>b) a=b;}

template<typename T, typename U> inline void smax(T &a, const U &b) {if(a<b) a=b;}

struct point {

	DO x, y, z;

	inline void input() {cin>>x>>y>>z;}

	inline DO al() {return atan2l(y, x);}

	inline DO nor2() {return *this**this;}

	inline DO nor() {return sqrtl(*this**this);}

	inline DO operator * (point a) {return x*a.x+y*a.y+z*a.z;}

	inline point(DO x=0, DO y=0, DO z=0) : x(x), y(y), z(z) {}

	inline point operator - (point a) {return point(x-a.x, y-a.y, z-a.z);}

	inline point operator + (point a) {return point(x+a.x, y+a.y, z+a.z);}

	inline point norm() {DO s=nor(); if(s<eps) return *this; return point(x/s, y/s, z/s);}

};

DO r, h, R, one=pi/4, whole=2*pi, len;

inline DO calc_laterals(point a, point b) {

	DO x=r*fabsl(a.al()-b.al()); smin(x, len-x);

	DO da2=(a-point(0, 0, h)).nor2(), da=sqrtl(da2);

	DO db2=(b-point(0, 0, h)).nor2(), db=sqrtl(db2);

	return sqrtl(da2+db2-2*da*db*cosl(x/R));

}

point A, AA, B, DA, DB, focus;

inline DO calc_down_lateral(DO angle) {

	DO x=r*cosl(angle), y=r*sinl(angle);

	return (AA-point(x, y, 0)).nor()+calc_laterals(point(x, y, 0), B);

}

inline DO solve() {

	DO ans=calc_down_lateral(B.al());

	for(DO angle=one; angle<=whole; angle+=one) {

		DO st=angle-one, ed=angle;

		while(ed-st>eps) {

			DO a=(st+st+ed)/3, b=(st+ed+ed)/3;

			if(calc_down_lateral(a)>calc_down_lateral(b)) st=a;

			else ed=b;

		}

		smin(ans, calc_down_lateral(st));

	}

	return ans;

}

main() {

#ifndef	ONLINE_JUDGE

	freopen("in.in", "r", stdin);

	freopen("out.out", "w", stdout);

#endif

	cin>>r>>h;

	len=whole*r, R=sqrtl(r*r+h*h);

	focus=point(0, 0, h);

	A.input(), B.input();

	if(B.z<eps) swap(A, B);

	DA=focus+(A-focus).norm()*R, DB=focus+(B-focus).norm()*R;

	DO ans=1e13;

	if(A.z<eps) {

		if(B.z<eps) ans=(A-B).nor();

		else AA=A, ans=solve();

	}

	else {

		ans=calc_laterals(A, B);

		AA=point(r*cosl(A.al()), r*sinl(A.al())), smin(ans, calc_laterals(A, AA)+solve());

		for(DO angle=one; angle<=whole; angle+=one) {

			DO st=angle-one, ed=angle;

			while(ed-st>eps) {

				DO a=(st+st+ed)/3, b=(st+ed+ed)/3;

				AA=point(r*cos(a), r*sin(a)); DO sa=calc_laterals(A, AA)+calc_down_lateral(a);

				AA=point(r*cos(b), r*sin(b)); DO sb=calc_laterals(A, AA)+calc_down_lateral(b);

				if(sa>sb) st=a;

				else ed=b;

			}

			AA=point(r*cosl(st), r*sinl(st)), smin(ans, calc_laterals(A, AA)+solve());

		}

	}

	printf("%.7lf", (double)ans);

}

#include <bits/stdc++.h>

#define inf 0x3f3f3f3f

#define MOD 1000000007

#define pb push_back

#define sq(x) ((x)*(x))

#define x first

#define y second

#define eps 1e-12

#define bpt(x) (__builtin_popcount(x))

#define bptl(x) (__builtin_popcountll(x))

#define bit(x, y) (((x)>>(y))&1)

#define bclz(x) (__builtin_clz(x))

#define bclzl(x) (__builtin_clzll(x))

#define bctz(x) (__builtin_ctz(x))

#define bctzl(x) (__builtin_ctzll(x))

#define sgn(x) (((x)>eps)-((x)<-eps))

#define PQ priority_queue<pii, vector<pii>, greater<pii> >

using namespace std;

typedef long long INT;

typedef vector<int> VI;

typedef pair<int, int> pii;

typedef pair<pii, int> pi3;

typedef long double DO;

template<typename T, typename U> inline void smin(T &a, U b) {if (a>b) a=b;}

template<typename T, typename U> inline void smax(T &a, U b) {if (a<b) a=b;}

template<class T>inline void gn(T &x) {char c, sg=0; while (c=getchar(), (c>'9' || c<'0') && c!='-');for((c=='-'?sg=1, c=getchar():0), x=0; c>='0' && c<='9'; c=getchar()) x=(x<<1)+(x<<3)+c-'0';if (sg) x=-x;}

template<class T, class T1>inline void gn(T &x, T1 &y) {gn(x); gn(y);}

template<class T, class T1, class T2>inline void gn(T &x, T1 &y, T2 &z) {gn(x); gn(y); gn(z);}

template<class T>inline void print(T x) {if (x<0) {putchar('-');return print(-x);}if (x<10) {putchar('0'+x);return;} print(x/10);putchar(x%10+'0');}

template<class T>inline void printsp(T x) {print(x); putchar(' ');}

template<class T>inline void println(T x) {print(x); putchar('\n');}

template<class T, class U>inline void print(T x, U y) {printsp(x); println(y);}

template<class T, class U, class V>inline void print(T x, U y, V z) {printsp(x); printsp(y); println(z);}

int power(int a, int b, int m, int ans=1) {

	for (; b; b>>=1, a=1LL*a*a%m) if (b&1) ans=1LL*ans*a%m;

	return ans;

}

struct point {

	DO x, y, z;

	point (DO x=0, DO y=0, DO z=0) : x(x), y(y), z(z) {}

	point operator - (point a) {return point(x-a.x, y-a.y, z-a.z);}

	point operator + (point a) {return point(x+a.x, y+a.y, z+a.z);}

	point operator * (DO a) {return point(x*a, y*a, z*a);}

	point operator / (DO a) {return point(x/a, y/a, z/a);}

	point operator ^ (point a) {return point(y*a.z-z*a.y, -(x*a.z-z*a.x), x*a.y-y*a.x);}

	DO    operator * (point a) {return x*a.x+y*a.y+z*a.z;}

	point norm() {DO s=nor(); if (s<eps) return *this; return point(x/s, y/s, z/s);}

	DO nor() {return sqrtl(*this**this);}

	bool operator < (const point &a) const {

		if (fabsl(x-a.x)>eps) return x<a.x;

		if (fabsl(y-a.y)>eps) return y<a.y;

		return z<a.z-eps;

	}

	bool operator > (const point &a) const {

		if (fabsl(x-a.x)>eps) return x>a.x;

		if (fabsl(y-a.y)>eps) return y>a.y;

		return z>a.z-eps;

	}

	bool operator == (const point &a) const {

		if (fabsl(x-a.x)>eps) return 0;

		if (fabsl(y-a.y)>eps) return 0;

		return fabs(z-a.z)<eps;

	}

	void input() {cin>>x>>y>>z;}

	void print() {printf("%lf %lf %lf\n", (double)x, (double)y, (double)z);}

};

void print_ans(DO x) {

	cout<<fixed<<setprecision(15)<<x<<endl;

	exit(0);

}

DO L, pi;

DO calc(point &a, DO &lb, DO &phib, DO &r, DO &al) {

	DO be=al*L/r;

	DO ans=(a-point(r*cosl(be), r*sinl(be), 0)).nor();

	return ans+sqrtl(max((DO)0, (L*L+lb*lb-2*lb*L*cosl(al-phib))));

}

DO ST[1111];

point a, b;

DO r, h;

point H=point(0, 0, h);

DO calc3(point a, DO al) {

	DO alpha=atan2l(a.y, a.x);

	if (alpha<0) alpha+=2*pi;

	DO la=(H-a).nor();

	return sqrtl((H-a)*(H-a)+L*L-2*la*L*cosl(alpha*r/L-al));

}

DO calc2(DO al, DO be) {

	DO alpha=al*r/L, beta=be*r/L;

	return calc3(a, alpha)+calc3(b, beta)+min(fabsl(al-be), 2*pi-fabsl(al-be))*r;

}

DO calc1(DO al) {

	DO ans=1e100;

	for (int i=0; i<6; i++) {

		DO st=pi/3*i, ed=st+pi/2;

		for (int j=0; j<50; j++) {

			DO x1=(st*2+ed)/3, x2=(st+ed*2)/3;

			if (calc2(al, x1)<calc2(al, x2)) ed=x2;

			else st=x1;

		}

		smin(ans, calc2(al, st));

	}

	return ans;

}

int main() {

#ifndef ONLINE_JUDGE

	freopen("in.in", "r", stdin);

	freopen("out.out", "w", stdout);

#endif

	cin>>r>>h;

	a.input(); b.input();

	L=sqrtl(r*r+h*h), pi=acosl(-1.0);

	if (a.z<eps && b.z<eps) print_ans((a-b).nor());

	if (a.z>b.z-eps) swap(a, b);

	if (b.z>h-eps) {

		if (a.z>h-eps) print_ans((DO)0.0);

		if (a.z<eps) print_ans(L+r-a.nor());

		print_ans((H-a).nor());

	}

	if (a.z>eps) {

		DO al=atan2l(a.y, a.x);

		DO be=atan2l(b.y, b.x);

		if (al<0) al+=2*pi;

		if (be<0) be+=2*pi;

		DO la=(H-a).nor();

		DO lb=(H-b).nor();

		DO phia=al*r/L, phib=be*r/L;

		DO ans=sqrtl(max((DO)0.0, (H-a)*(H-a)+(H-b)*(H-b)-2*la*lb*cosl(phia-phib)));

		for (int i=0; i<6; i++) {

			DO st=pi/3*i, ed=st+pi/2;

			for (int j=0; j<50; j++) {

				DO x1=(st*2+ed)/3, x2=(st+ed*2)/3;

				if (calc1(x1)<calc1(x2)) ed=x2;

				else st=x1;

			}

			smin(ans, calc1(st));

		}

		print_ans(ans);

	}

	DO al=atan2l(a.y, a.x);

	DO be=atan2l(b.y, b.x);

	if (al<0) al+=2*pi;

	if (be<0) be+=2*pi;

	DO lb=(H-b).nor();

	DO phib=be*r/L;

	DO ans=(DO)1e100;

	for (int j=0; j<6; j++) {

		DO st=(pi/3*j)*r/L, ed=(pi/3*j+pi/2)*r/L;

		for (int i=0; i<200; i++) {

			DO x1=(st*2+ed)/3, x2=(st+ed*2)/3;

			if (calc(a, lb, phib, r, x1)<calc(a, lb, phib, r, x2)) ed=x2;

			else st=x1;

		}

		smin(ans, calc(a, lb, phib, r, st));

	}

	print_ans(ans);

	return 0;

}

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <climits>
#include <cstring>
#include <string>
#include <vector>
#include <stack>
#include <queue>
#include <set>
#include <map>
#include <algorithm>

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;
/*    printf("aTheta=%.9lf\n", aTheta * 180.0 / pi);
    printf("bTheta=%.9lf\n", bTheta * 180.0 / pi);
    printf("alpha=%.9lf\n", alpha * 180.0 / pi);
*/
    if(isGreaterThan((aTheta - bTheta), alpha / 2.0))
    {
        // find mirror and do shieat
        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;

    minDegree = atan2(yHi, xHi);
    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);
//        printf("middle=%.9lf - left=%.9lf - right=%.9lf\n", middle * 180.0 / pi, left * 180.0/pi, right * 180.0/ pi);
//        printf("x=%.9lf - y=%.9lf\n", x, y);
//        cout << "leftVal=" << leftVal << " - rightVal=" << rightVal << " - midVal=" << midVal << endl;
        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));
    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;
}

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <climits>
#include <cstring>
#include <string>
#include <vector>
#include <stack>
#include <queue>
#include <set>
#include <map>
#include <algorithm>

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;
/*    printf("aTheta=%.9lf\n", aTheta * 180.0 / pi);
    printf("bTheta=%.9lf\n", bTheta * 180.0 / pi);
    printf("alpha=%.9lf\n", alpha * 180.0 / pi);
*/
    if(isGreaterThan((aTheta - bTheta), alpha / 2.0))
    {
        // find mirror and do shieat
        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;

//    minDegree = atan2(yHi, xHi);
    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);
//        printf("middle=%.9lf - left=%.9lf - right=%.9lf\n", middle * 180.0 / pi, left * 180.0/pi, right * 180.0/ pi);
//        printf("x=%.9lf - y=%.9lf\n", x, y);
//        cout << "leftVal=" << leftVal << " - rightVal=" << rightVal << " - midVal=" << midVal << endl;
        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));
    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;
}

#include <set>
#include <map>
#include <queue>
#include <deque>
#include <cmath>
#include <ctime>
#include <bitset>
#include <vector>
#include <string>
#include <cstdio>
#include <cassert>
#include <cstring>
#include <iostream>
#include <algorithm>
#define For(i,x,y)  for(int i=(int)(x);i<=(int)(y);i++)
#define Forn(i,x,y) for(int i=(int)(x);i>=(int)(y);i--)
#define Rep(i,x,y)  for(int i=(int)(x);i< (int)(y);i++)
#define mk make_pair
#define pb push_back
#define fi first
#define se second
using namespace std;
typedef long double db;
typedef long long ll;
typedef pair<int,int> PII;
const int N=200005;
const int inf=1e9;
const ll Inf=1e10;
const int P=1000000007;
const db  pi=acos(-1);

db r,h,Sqr,l;
db X1,X2,Y1,Y2,Z1,Z2;

void read(db &x){
	double z;
	scanf("%lf",&z);
	x=z;
}

db sqr(db x){return x*x;}

db Fbb(db A,db B,db D,db E){
	return sqrt(sqr(A-D)+sqr(B-E));
}

db Faa(db A,db B,db C,db D,db E,db F){
	if(fabs(C-h)<1e-6) return sqrt(D*D+E*E+sqr(F-h));
	if(fabs(F-h)<1e-6) return sqrt(A*A+B*B+sqr(C-h));
	db X3=A*h/(h-C),Y3=B*h/(h-C),X4=D*h/(h-F),Y4=E*h/(h-F);
	db u=Sqr*2-sqr(X3-X4)-sqr(Y3-Y4);
	u/=2*Sqr;
	db the=acos(u);
	db phi=the*r/l;
	db D1=sqr(A)+sqr(B)+sqr(C-h),D2=sqr(D)+sqr(E)+sqr(F-h);
	return sqrt(D1+D2-2*sqrt(D1)*sqrt(D2)*cos(phi));
}

db Fab(db X,db Y,db Z,db E,db F,db the){
	db X3=r*cos(the),Y3=r*sin(the);
	return Faa(X,Y,Z,X3,Y3,0)+Fbb(E,F,X3,Y3);
}

db Fab2(db the){
	db X3=cos(the)*r,Y3=sin(the)*r;
	db l=0,r=2*pi,T1,T2;
	For(i,1,200){
		db md1=(9*l+r)/10.,md2=(l+9*r)/10.;
		T1=Fab(X2,Y2,Z2,X3,Y3,md1);
		T2=Fab(X2,Y2,Z2,X3,Y3,md2);
		if(T1>T2) l=md1;else r=md2;
	}
	return T1+Faa(X1,Y1,Z1,X3,Y3,0);
}

int main(){
	read(r);read(h);Sqr=r*r;
	l=sqrt(r*r+h*h);
	read(X1);read(Y1);read(Z1);
	read(X2);read(Y2);read(Z2);

	if(Z1==0&&Z2==0){
		printf("%.16lf\n",double(Fbb(X1,Y1,X2,Y2)));
		return 0;
	}
	if(Z1!=0&&Z2!=0){
		db ans=Faa(X1,Y1,Z1,X2,Y2,Z2);
		db l=0,r=2*pi,T1,T2;
		For(i,1,200){
			db md1=(9*l+r)/10.,md2=(l+9*r)/10.;
			T1=Fab2(md1);
			T2=Fab2(md2);
			if(T1>T2) l=md1;else r=md2;
		}
		ans=min(ans,T1);
		printf("%.16lf\n",double(ans));
		return 0;
	}
	if(Z1==0){
		swap(X1,X2);
		swap(Y1,Y2);
		swap(Z1,Z2);
	}
	db l=0,r=2*pi,T1,T2;
	For(i,1,500){
		db md1=(29*l+r)/30.,md2=(l+29*r)/30.;
		if((T1=Fab(X1,Y1,Z1,X2,Y2,md1))>(T2=Fab(X1,Y1,Z1,X2,Y2,md2))) l=md1;else r=md2;
	}
	printf("%.16lf\n",double(T1));
	return 0;
}

#include <bits/stdc++.h>

#define inf 0x3f3f3f3f

#define MOD 1000000007

#define pb push_back

#define sq(x) ((x)*(x))

#define x first

#define y second

#define eps 1e-12

#define bpt(x) (__builtin_popcount(x))

#define bptl(x) (__builtin_popcountll(x))

#define bit(x, y) (((x)>>(y))&1)

#define bclz(x) (__builtin_clz(x))

#define bclzl(x) (__builtin_clzll(x))

#define bctz(x) (__builtin_ctz(x))

#define bctzl(x) (__builtin_ctzll(x))

#define sgn(x) (((x)>eps)-((x)<-eps))

#define PQ priority_queue<pii, vector<pii>, greater<pii> >

using namespace std;

typedef long long INT;

typedef vector<int> VI;

typedef pair<int, int> pii;

typedef pair<pii, int> pi3;

typedef long double DO;

template<typename T, typename U> inline void smin(T &a, U b) {if (a>b) a=b;}

template<typename T, typename U> inline void smax(T &a, U b) {if (a<b) a=b;}

template<class T>inline void gn(T &x) {char c, sg=0; while (c=getchar(), (c>'9' || c<'0') && c!='-');for((c=='-'?sg=1, c=getchar():0), x=0; c>='0' && c<='9'; c=getchar()) x=(x<<1)+(x<<3)+c-'0';if (sg) x=-x;}

template<class T, class T1>inline void gn(T &x, T1 &y) {gn(x); gn(y);}

template<class T, class T1, class T2>inline void gn(T &x, T1 &y, T2 &z) {gn(x); gn(y); gn(z);}

template<class T>inline void print(T x) {if (x<0) {putchar('-');return print(-x);}if (x<10) {putchar('0'+x);return;} print(x/10);putchar(x%10+'0');}

template<class T>inline void printsp(T x) {print(x); putchar(' ');}

template<class T>inline void println(T x) {print(x); putchar('\n');}

template<class T, class U>inline void print(T x, U y) {printsp(x); println(y);}

template<class T, class U, class V>inline void print(T x, U y, V z) {printsp(x); printsp(y); println(z);}

int power(int a, int b, int m, int ans=1) {

	for (; b; b>>=1, a=1LL*a*a%m) if (b&1) ans=1LL*ans*a%m;

	return ans;

}

struct point {

	DO x, y, z;

	point (DO x=0, DO y=0, DO z=0) : x(x), y(y), z(z) {}

	point operator - (point a) {return point(x-a.x, y-a.y, z-a.z);}

	point operator + (point a) {return point(x+a.x, y+a.y, z+a.z);}

	point operator * (DO a) {return point(x*a, y*a, z*a);}

	point operator / (DO a) {return point(x/a, y/a, z/a);}

	point operator ^ (point a) {return point(y*a.z-z*a.y, -(x*a.z-z*a.x), x*a.y-y*a.x);}

	DO    operator * (point a) {return x*a.x+y*a.y+z*a.z;}

	point norm() {DO s=nor(); if (s<eps) return *this; return point(x/s, y/s, z/s);}

	DO nor() {return sqrtl(*this**this);}

	bool operator < (const point &a) const {

		if (fabs(x-a.x)>eps) return x<a.x;

		if (fabs(y-a.y)>eps) return y<a.y;

		return z<a.z-eps;

	}

	bool operator > (const point &a) const {

		if (fabs(x-a.x)>eps) return x>a.x;

		if (fabs(y-a.y)>eps) return y>a.y;

		return z>a.z-eps;

	}

	bool operator == (const point &a) const {

		if (fabs(x-a.x)>eps) return 0;

		if (fabs(y-a.y)>eps) return 0;

		return fabs(z-a.z)<eps;

	}

	void input() {cin>>x>>y>>z;}

	void print() {printf("%lf %lf %lf\n", (double)x, (double)y, (double)z);}

};

void print_ans(DO x) {

	cout<<fixed<<setprecision(15)<<x<<endl;

	exit(0);

}

DO L, pi;

DO calc(point &a, DO &lb, DO &phib, DO &r, DO &al) {

	DO be=al*L/r;

	DO ans=(a-point(r*cosl(be), r*sinl(be), 0)).nor();

	return ans+sqrtl(max((DO)0, (L*L+lb*lb-2*lb*L*cosl(al-phib))));

}

DO ST[1111];

int main() {

#ifndef ONLINE_JUDGE

	freopen("in.in", "r", stdin);

	freopen("out.out", "w", stdout);

#endif

	point a, b;

	DO r, h;

	cin>>r>>h;

	a.input(); b.input();

	L=sqrtl(r*r+h*h), pi=acosl(-1.0);

	point H=point(0, 0, h);

	if (a.z<eps && b.z<eps) print_ans((a-b).nor());

	if (a.z>b.z+eps) swap(a, b);

	if (b.z>h-eps) {

		if (a.z>h-eps) print_ans((DO)0.0);

		if (a.z<eps) print_ans(L+r-a.nor());

		print_ans((H-a).nor());

	}

	if (a.z>eps) {

		DO al=atan2l(a.y, a.x);

		DO be=atan2l(b.y, b.x);

		if (al<0) al+=2*pi;

		if (be<0) be+=2*pi;

		DO la=(H-a).nor();

		DO lb=(H-b).nor();

		DO phia=al*r/L, phib=be*r/L;

		print_ans(sqrtl(max((DO)0.0, (H-a)*(H-a)+(H-b)*(H-b)-2*la*lb*cosl(phia-phib))));

	}

	DO al=atan2l(a.y, a.x);

	DO be=atan2l(b.y, b.x);

	if (al<0) al+=2*pi;

	if (be<0) be+=2*pi;

	DO lb=(H-b).nor();

	DO phib=be*r/L;

	DO ans=1e100;

	int N=0; ST[N++]=0;

	ST[N++]=al*r/L;

	ST[N++]=2*pi*r/L;

	if (al>pi+eps) {

		ST[N++]=(al-pi)*r/L;

	} else {

		ST[N++]=(al+pi)*r/L;

	}

	ST[N++]=phib;

	if (phib>pi+eps) {

		ST[N++]=phib-pi;

	} else if (2*pi*r/L-eps>phib+pi) {

		ST[N++]=phib+pi;

	}

	sort(ST, ST+N);

	int n=N; N=1;

	for (int i=1; i<n; i++) if (fabsl(ST[i]-ST[N-1])>eps) ST[N++]=ST[i];

	N--;

	for (int j=0; j<N; j++) {

		DO st=ST[j], ed=ST[j+1];

		for (int i=0; i<200; i++) {

			DO x1=(st*2+ed)/3, x2=(st+ed*2)/3;

			if (calc(a, lb, phib, r, x1)<calc(a, lb, phib, r, x2)) ed=x2;

			else st=x1;

		}

		smin(ans, calc(a, lb, phib, r, st));

	}

	print_ans(ans);

	return 0;

}

#define pi 3.1415926535897932384626433832795

#include<bits/stdc++.h>

#define eps 1e-13

using namespace std;

typedef long double DO;

template<typename T, typename U> inline void smin(T &a, const U &b) {if(a>b) a=b;}

struct point {

	DO x, y, z;

	inline point(DO x=0, DO y=0, DO z=0) : x(x), y(y), z(z) {}

	inline point operator - (point a) {return point(x-a.x, y-a.y, z-a.z);}

	inline point operator + (point a) {return point(x+a.x, y+a.y, z+a.z);}

	inline point operator * (DO a) {return point(x*a, y*a, z*a);}

	inline point operator / (DO a) {return point(x/a, y/a, z/a);}

	inline DO operator * (point a) {return x*a.x+y*a.y+z*a.z;}

	inline point norm() {DO s=nor(); if(s<eps) return *this; return point(x/s, y/s, z/s);}

	inline DO nor() {return sqrtl(*this**this);}

	inline DO nor2() {return *this**this;}

	inline point rotate(DO al) {return *this&point(cosl(al), sinl(al), z);}

	inline point operator & (point a) {return point(x*a.x-y*a.y, x*a.y+y*a.x, z);}

	inline void input() {cin>>x>>y>>z;}

};

DO r, h, R, R2, len;

point focus, a, b, c, ac, A;

inline DO calc1(DO x) {

	point d=c.rotate(x/r);

	DO ans1=(A-d).nor();

	smin(x, len-x);

	DO D2=(b-focus).nor2(), D=sqrtl(D2);

	DO ans2=sqrtl(R2+D2-2*R*D*cosl(x/R));

	smin(ans2, (d-focus).nor()+D);

	return ans1+ans2;

}

inline DO solve() {

	DO st=0, ed=len;

	while(ed-st>eps) {

		DO a=(st+st+ed)/3, b=(st+ed+ed)/3;

		if(calc1(a)>calc1(b)) st=a;

		else ed=b;

	}

	return calc1(st);

}

inline DO calc2(DO x) {

	A=ac.rotate(x/r);

	smin(x, len-x);

	DO D2=(a-focus).nor2(), D=sqrtl(D2);

	return sqrtl(R2+D2-2*R*D*cosl(x/R)) + calc1(0);

}

inline DO angle(point a, point b) {

	DO res=a*b/a.nor()/b.nor();

	res=acosl(res);

	return res;

}

inline DO kong() {

	DO aa2=(a-focus).nor2(), aa=sqrtl(aa2);

	DO bb2=(b-focus).nor2(), bb=sqrtl(bb2);

	DO x=angle(c, ac)*r;

	smin(x, len-x);

	return sqrtl(aa2+bb2-2*aa*bb*cosl(x/R));

}

main() {

#ifndef	ONLINE_JUDGE

	freopen("in.in", "r", stdin);

	freopen("out.out", "w", stdout);

#endif

	cin>>r>>h; a.input(), b.input();

	if(fabsl(b.z)<eps) swap(a, b);

	len=2*pi*r;

	R2=h*h+r*r, R=sqrtl(R2);

	focus=point(0, 0, h);

	c=focus+(b-focus).norm()*R;

	if(fabsl(a.z)<eps) {

		if(fabsl(b.z)<eps) printf("%.7lf", (double)(a-b).nor());

		else {

			A=a;

			printf("%.7lf", (double)solve());

		}

	}

	else {

		ac=focus+(a-focus).norm()*R;

		printf("%.7lf", (double)min(kong(), calc2(0)));

	}

}

#define pi 3.1415926535897932384626433832795

#include<bits/stdc++.h>

#define eps 1e-13

using namespace std;

typedef long double DO;

template<typename T, typename U> inline void smin(T &a, const U &b) {if(a>b) a=b;}

struct point {

	DO x, y, z;

	inline point(DO x=0, DO y=0, DO z=0) : x(x), y(y), z(z) {}

	inline point operator - (point a) {return point(x-a.x, y-a.y, z-a.z);}

	inline point operator + (point a) {return point(x+a.x, y+a.y, z+a.z);}

	inline point operator * (DO a) {return point(x*a, y*a, z*a);}

	inline point operator / (DO a) {return point(x/a, y/a, z/a);}

	inline DO operator * (point a) {return x*a.x+y*a.y+z*a.z;}

	inline point norm() {DO s=nor(); if(s<eps) return *this; return point(x/s, y/s, z/s);}

	inline DO nor() {return sqrtl(*this**this);}

	inline DO nor2() {return *this**this;}

	inline point rotate(DO al) {return *this&point(cosl(al), sinl(al), z);}

	inline point operator & (point a) {return point(x*a.x-y*a.y, x*a.y+y*a.x, z);}

	inline void input() {cin>>x>>y>>z;}

};

DO r, h, R, R2, len;

point focus, a, b, c, ac, A;

inline DO calc1(DO x) {

	point d=c.rotate(x/r);

	DO ans1=(A-d).nor();

	smin(x, len-x);

	DO D2=(b-focus).nor2(), D=sqrtl(D2);

	DO ans2=sqrtl(R2+D2-2*R*D*cosl(x/R));

	return ans1+ans2;

}

inline DO solve() {

	DO mn=calc1(0);

	for(DO xx=len/6; xx<=len; xx+=len) {

		DO st=xx-len, ed=xx;

		while(ed-st>eps) {

			DO a=(st+st+ed)/3, b=(st+ed+ed)/3;

			if(calc1(a)>calc1(b)) st=a;

			else ed=b;

		}

		smin(mn, calc1(st));

	}

	return mn;

}

inline DO calc2(DO x) {

	A=ac.rotate(x/r);

	smin(x, len-x);

	DO D2=(a-focus).nor2(), D=sqrtl(D2);

	return sqrtl(R2+D2-2*R*D*cosl(x/R)) + calc1(0);

}

inline DO angle(point a, point b) {

	DO res=a*b/a.nor()/b.nor();

	res=acosl(res);

	return res;

}

inline DO kong() {

	DO aa2=(a-focus).nor2(), aa=sqrtl(aa2);

	DO bb2=(b-focus).nor2(), bb=sqrtl(bb2);

	DO x=angle(c, ac)*r;

	smin(x, len-x);

	return sqrtl(aa2+bb2-2*aa*bb*cosl(x/R));

}

main() {

#ifndef	ONLINE_JUDGE

	freopen("in.in", "r", stdin);

	freopen("out.out", "w", stdout);

#endif

	cin>>r>>h; a.input(), b.input();

	if(fabsl(b.z)<eps) swap(a, b);

	len=2*pi*r;

	R2=h*h+r*r, R=sqrtl(R2);

	focus=point(0, 0, h);

	c=focus+(b-focus).norm()*R;

	if(fabsl(a.z)<eps) {

		if(fabsl(b.z)<eps) printf("%.7lf", (double)(a-b).nor());

		else {

			A=a;

			printf("%.7lf", (double)solve());

		}

	}

	else {

		ac=focus+(a-focus).norm()*R;

		DO st=atan2l(a.y, b.x)-pi/180., ed=st+pi/90.;

		while(ed-st>eps) {

			DO a=(st+st+ed)/3, b=(st+ed+ed)/3;

			if(calc2(a)>calc2(b)) st=a;

			else ed=b;

		}

		printf("%.7lf", (double)min(calc2(0), min(kong(), calc2(st))));

	}

}

#pragma comment(linker, "/STACK:65777216")

#include <algorithm>
#include <iostream>
#include <string>
#include<sstream>
#include<string.h>
#include <cstdio>
#include <vector>
#include <bitset>
#include <cmath>
#include <queue>
#include<stack>
#include <set>
#include <map>
#include<ctime>

using namespace std;

typedef long long ll;
typedef vector<int> vi;
typedef pair<int,int> pii;
typedef pair<double,double> pdd;
typedef unsigned long long ull;

#define FOR(i,a,b) for (int i(a); i < (b); i++)
#define REP(i,n) FOR(i,0,n)
#define SORT(v) sort((v).begin(),(v).end())
#define UN(v) sort((v).begin(),(v).end()),v.erase(unique(v.begin(),v.end()),v.end())
#define CL(a,b) memset(a,b,sizeof(a))
#define pb push_back

typedef double ld;
const ld pi = acosl(-1.);
const ld eps = 1e-17;

int r,h;

ld getAngle(ld x,ld y, ld z){
	ld H = h - z;
	ld R = r * H / h;
	ld X = 0;
	ld Y = R;
	ld d = sqrtl((x-X)*(x-X)+(y-Y)*(y-Y));
	ld a = asinl(d/2/R)*2;
	ld l = a * R / sqrtl(R*R+H*H);
	if(x>0) l=-l;
	return l;
}

ld conDist(ld z,ld Z,ld a){
	ld r1 = sqrtl(h*h+r*r+0.)/h*(h-z);
	ld r2 = sqrtl(h*h+r*r+0.)/h*(h-Z);
	ld x = r1;
	ld y = 0;
	ld X = cosl(a)*r2;
	ld Y = sinl(a)*r2;

	//cout<<x<<' '<<y<<' '<<X<<' '<<Y<<' '<<r1<<' '<<r2<<' '<<a<<endl;
	return sqrtl((x-X)*(x-X)+(y-Y)*(y-Y));
}

ld getOnConus(ld x,ld y,ld z,ld X, ld Y,ld Z){
	ld a1 = getAngle(x,y,z);
	ld a2 = getAngle(X,Y,Z);
	ld a = fabsl(a2-a1);
	ld A = r / sqrtl(h*h+r*r+0.) * 2 * pi;
	//cout<<a<<' '<<A<<endl;
	return min(conDist(z,Z,a),conDist(z,Z,A-a));
}

ld getOnConus(ld x,ld y,ld z,ld X, ld Y){
	if(z>eps) return getOnConus(x,y,z,X,Y,0);
	return sqrtl((x-X)*(x-X)+(y-Y)*(y-Y));
}

ld getD(ld x,ld y,ld z,ld X, ld Y,ld Z,ld XX,ld YY,ld XXX,ld YYY){
	ld res = sqrtl((XX-XXX)*(XX-XXX)+(YY-YYY)*(YY-YYY));
	res += getOnConus(x,y,z,XX,YY);
	res += getOnConus(X,Y,Z,XXX,YYY);
	if(0)if(res<1.6)
	{
		cout<<x<<' '<<y<<' '<<z<<" -> "<<XX<<' '<<YY<<" = "<<getOnConus(x,y,z,XX,YY,0)<<endl;
		cout<<X<<' '<<Y<<' '<<Z<<" -> "<<XXX<<' '<<YYY<<" = "<<getOnConus(X,Y,Z,XXX,YYY,0)<<endl;
		cout<<res<<": "<<sqrt((XX-XXX)*(XX-XXX)+(YY-YYY)*(YY-YYY))<<' '<<endl;
	}
	return res;
}

ld getD(ld x,ld y,ld z,ld X, ld Y,ld Z,ld XX,ld YY){
	ld res = 1e100;
	REP(i,20){
		ld a = 2*pi/10*i;
		ld b = a + pi;
		REP(j,30){
			ld s1 = (a*2+b)/3;
			ld s2 = (a+2*b)/3;
			ld d1 = getD(x,y,z,X,Y,Z,XX,YY,cosl(s1)*r,sinl(s1)*r);
			ld d2 = getD(x,y,z,X,Y,Z,XX,YY,cosl(s1)*r,sinl(s1)*r);
			res = min(res,d1);
			res = min(res,d2);
			if(d1<d2) b = s2;
			else a = s1;
		}
	}
	return res;
}

ld go(ld x,ld y,ld z,ld X, ld Y,ld Z){
	ld res = getOnConus(x,y,z,X,Y,Z);
	if(z<eps || Z<eps) res = 1e100;
	//cout<<res<<endl;
	REP(i,20){
		ld a = 2*pi/10*i;
		ld b = a + pi;
		REP(j,30){
			ld s1 = (a*2+b)/3;
			ld s2 = (a+2*b)/3;
			ld d1 = getD(x,y,z,X,Y,Z,cosl(s1)*r,sinl(s1)*r);
			ld d2 = getD(x,y,z,X,Y,Z,cosl(s1)*r,sinl(s1)*r);
			res = min(res,d1);
			res = min(res,d2);
			if(d1<d2) b = s2;
			else a = s1;
		}
	}
	return res;
}

int main(){
#ifdef LocalHost
    freopen("input.txt","r",stdin);
//    freopen("output.txt","w",stdout);
#endif

	cin>>r>>h;
	long double x,y,z,X,Y,Z;
	cin>>x>>y>>z>>X>>Y>>Z;
	if(z<eps && Z<eps)
		printf("%.10lf\n",(double)sqrt((x-X)*(x-X)+(y-Y)*(y-Y)));
	else printf("%.10lf\n",(double)go(x,y,z,X,Y,Z));
		//printf("%.10lf\n",(double)min(go(x,y,z,X,Y,Z),go(X,Y,Z,x,y,z)));

#ifdef LocalHost
	cout<<endl<<endl<<"TIME: "<<clock()<<endl;
#endif
    return 0;
}

#define pi 3.1415926535897932384626433832795

#include<bits/stdc++.h>

#define eps 1e-13

using namespace std;

typedef long double DO;

template<typename T, typename U> inline void smin(T &a, const U &b) {if(a>b) a=b;}

struct point {

	DO x, y, z;

	inline point(DO x=0, DO y=0, DO z=0) : x(x), y(y), z(z) {}

	inline point operator - (point a) {return point(x-a.x, y-a.y, z-a.z);}

	inline point operator + (point a) {return point(x+a.x, y+a.y, z+a.z);}

	inline point operator * (DO a) {return point(x*a, y*a, z*a);}

	inline point operator / (DO a) {return point(x/a, y/a, z/a);}

	inline DO operator * (point a) {return x*a.x+y*a.y+z*a.z;}

	inline point norm() {DO s=nor(); if(s<eps) return *this; return point(x/s, y/s, z/s);}

	inline DO nor() {return sqrtl(*this**this);}

	inline DO nor2() {return *this**this;}

	inline point rotate(DO al) {return *this&point(cosl(al), sinl(al), z);}

	inline point operator & (point a) {return point(x*a.x-y*a.y, x*a.y+y*a.x, z);}

	inline void input() {cin>>x>>y>>z;}

};

DO r, h, R, R2, len;

point focus, a, b, c, ac, A;

inline DO calc1(DO x) {

	point d=c.rotate(x/r);

	DO ans1=(A-d).nor();

	smin(x, len-x);

	DO D2=(b-focus).nor2(), D=sqrtl(D2);

	DO ans2=sqrtl(R2+D2-2*R*D*cosl(x/R));

	return ans1+ans2;

}

inline DO solve() {

	DO st=0, ed=len;

	while(ed-st>eps) {

		DO a=(st+st+ed)/3, b=(st+ed+ed)/3;

		if(calc1(a)>calc1(b)) st=a;

		else ed=b;

	}

	return calc1(st);

}

inline DO calc2(DO x) {

	A=ac.rotate(x/r);

	smin(x, len-x);

	DO D2=(a-focus).nor2(), D=sqrtl(D2);

	return sqrtl(R2+D2-2*R*D*cosl(x/R)) + calc1(0);

}

inline DO angle(point a, point b) {

	DO res=a*b/a.nor()/b.nor();

	res=acosl(res);

	return res;

}

inline DO kong() {

	DO aa2=(a-focus).nor2(), aa=sqrtl(aa2);

	DO bb2=(b-focus).nor2(), bb=sqrtl(bb2);

	DO x=angle(c, ac)*r;

	smin(x, len-x);

	return sqrtl(aa2+bb2-2*aa*bb*cosl(x/R));

}

main() {

#ifndef	ONLINE_JUDGE

	freopen("in.in", "r", stdin);

	freopen("out.out", "w", stdout);

#endif

	cin>>r>>h; a.input(), b.input();

	if(fabsl(b.z)<eps) swap(a, b);

	len=2*pi*r;

	R2=h*h+r*r, R=sqrtl(R2);

	focus=point(0, 0, h);

	c=focus+(b-focus).norm()*R;

	if(fabsl(a.z)<eps) {

		if(fabsl(b.z)<eps) printf("%.7lf", (double)(a-b).nor());

		else {

			A=a;

			printf("%.7lf", (double)solve());

		}

	}

	else {

		ac=focus+(a-focus).norm()*R;

		printf("%.7lf", (double)min(kong(), calc2(0)));

	}

}

#pragma comment(linker, "/STACK:65777216")

#include <algorithm>
#include <iostream>
#include <string>
#include<sstream>
#include<string.h>
#include <cstdio>
#include <vector>
#include <bitset>
#include <cmath>
#include <queue>
#include<stack>
#include <set>
#include <map>
#include<ctime>

using namespace std;

typedef long long ll;
typedef vector<int> vi;
typedef pair<int,int> pii;
typedef pair<double,double> pdd;
typedef unsigned long long ull;

#define FOR(i,a,b) for (int i(a); i < (b); i++)
#define REP(i,n) FOR(i,0,n)
#define SORT(v) sort((v).begin(),(v).end())
#define UN(v) sort((v).begin(),(v).end()),v.erase(unique(v.begin(),v.end()),v.end())
#define CL(a,b) memset(a,b,sizeof(a))
#define pb push_back

typedef long double ld;
const ld pi = acosl(-1.);
const ld eps = 1e-17;

int r,h;

ld getAngle(ld x,ld y, ld z){
	ld H = h - z;
	if(H<eps) return 0;
	ld R = r * H / h;
	ld X = 0;
	ld Y = R;
	ld d = sqrtl((x-X)*(x-X)+(y-Y)*(y-Y));
	ld a = asinl(d/2/R)*2;
	ld l = a * R / sqrtl(R*R+H*H);
	if(x>0) l=-l;
	return l;
}

ld conDist(ld z,ld Z,ld a){
	ld r1 = sqrtl(h*h+r*r+0.)/h*(h-z);
	ld r2 = sqrtl(h*h+r*r+0.)/h*(h-Z);
	ld x = r1;
	ld y = 0;
	ld X = cosl(a)*r2;
	ld Y = sinl(a)*r2;
	return sqrtl((x-X)*(x-X)+(y-Y)*(y-Y));
}

ld getOnConus(ld x,ld y,ld z,ld X, ld Y,ld Z){
	ld a1 = getAngle(x,y,z);
	ld a2 = getAngle(X,Y,Z);
	ld a = fabsl(a2-a1);
	ld A = r / sqrtl(h*h+r*r+0.) * 2 * pi;
	return min(conDist(z,Z,a),conDist(z,Z,A-a));
}

ld getOnConus(ld x,ld y,ld z,ld X, ld Y){
	if(z>eps) return getOnConus(x,y,z,X,Y,0);
	return sqrtl((x-X)*(x-X)+(y-Y)*(y-Y));
}

ld getD(ld x,ld y,ld z,ld X, ld Y,ld Z,ld XX,ld YY,ld XXX,ld YYY){
	ld res = sqrtl((XX-XXX)*(XX-XXX)+(YY-YYY)*(YY-YYY));
	res += getOnConus(x,y,z,XX,YY);
	res += getOnConus(X,Y,Z,XXX,YYY);
	return res;
}

ld getD(ld x,ld y,ld z,ld X, ld Y,ld Z,ld XX,ld YY){
	ld res = 1e100;
	REP(i,4){
		ld a = 2*pi/2*i;
		ld b = a + pi;
		REP(j,50){
			ld s1 = (a*2+b)/3;
			ld s2 = (a+2*b)/3;
			ld d1 = getD(x,y,z,X,Y,Z,XX,YY,cosl(s1)*r,sinl(s1)*r);
			ld d2 = getD(x,y,z,X,Y,Z,XX,YY,cosl(s2)*r,sinl(s2)*r);
			res = min(res,min(d1,d2));
			if(d1<d2) b = s2;
			else a = s1;
		}
	}
	return res;
}

ld go(ld x,ld y,ld z,ld X, ld Y,ld Z){
	ld res = getOnConus(x,y,z,X,Y,Z);
	if(z<eps || Z<eps) res = 1e100;
	REP(i,4){
		ld a = 2*pi/2*i;
		ld b = a + pi;
		REP(j,50){
			ld s1 = (a*2+b)/3;
			ld s2 = (a+2*b)/3;
			ld d1 = getD(x,y,z,X,Y,Z,cosl(s1)*r,sinl(s1)*r);
			ld d2 = getD(x,y,z,X,Y,Z,cosl(s2)*r,sinl(s2)*r);
			res = min(res,min(d1,d2));
			if(d1<d2) b = s2;
			else a = s1;
		}
	}
	return res;
}

int main(){
#ifdef LocalHost
    freopen("input.txt","r",stdin);
//    freopen("output.txt","w",stdout);
#endif

	cin>>r>>h;
	long double x,y,z,X,Y,Z;
	cin>>x>>y>>z>>X>>Y>>Z;
	if(z<eps && Z<eps)
		printf("%.10lf\n",(double)sqrt((x-X)*(x-X)+(y-Y)*(y-Y)));
	else printf("%.10lf\n",(double)go(x,y,z,X,Y,Z));

#ifdef LocalHost
	cout<<endl<<endl<<"TIME: "<<clock()<<endl;
#endif
    return 0;
}

#include"bits/stdc++.h"
#define eps 1e-6

typedef double DO;
using namespace std;
template<typename A, typename B> inline void smin(A &a, const B &b) {if(a>b) a=b;}

struct point {
	DO x, y, z;
	inline point(DO x=0, DO y=0, DO z=0) : x(x), y(y), z(z) {}
	inline point operator - (point a) {return point(x-a.x, y-a.y, z-a.z);}
	inline DO al() {return atan2(y, x);}
	inline DO nor2() {return *this**this;}
	inline DO nor() {return sqrt(*this**this);}
	inline DO operator * (point a) {return x*a.x+y*a.y+z*a.z;}
	inline void input() {scanf("%lf %lf %lf", &x, &y, &z);}
} A, B, A_, B_, F;

DO r, h, R;
DO all=6.283185307179586476925286766559;
DO _120=2.0943951023931954923084289221863;

inline DO dist(point a, point b) {
	DO al=fabs(a.al()-b.al()); smin(al, all-al);
	DO da=(a-F).nor2(), db=(b-F).nor2();
	return sqrt(da+db-2*sqrt(da*db)*cos(r*al/R));
}

inline DO calc_A() {
	DO ans=1e100;
	for(DO st_=0; st_<all; st_+=_120) {
		DO st=st_, ed=st+_120;
		while(ed-st>eps) {
			DO a=(st+st+ed)/3; B_={r*cos(a), r*sin(a)}; DO val_a=(A_-B_).nor()+dist(B, B_);
			DO b=(st+ed+ed)/3; B_={r*cos(b), r*sin(b)}; DO val_b=(A_-B_).nor()+dist(B, B_);
			if(val_a<val_b) ed=b;
			else st=a;
		}
		DO al=(st+ed)/2; B_={r*cos(al), r*sin(al)}; smin(ans, (A_-B_).nor()+dist(B, B_));
	}
	return ans;
}

main() {
	scanf("%lf %lf", &r, &h);
	F=point(0, 0, h);
	R=sqrt(r*r+h*h);

	A.input(), B.input();
	if(A.z>B.z) swap(A, B);

	DO ans;
	if(B.z<eps) ans=(A-B).nor();
	else if(A.z<eps) A_=A, ans=calc_A();
	else {
		ans=dist(A, B);
		for(DO st_=0; st_<all; st_+=_120) {
			DO st=st_, ed=st+_120;
			while(ed-st>eps) {
				DO a=(st+st+ed)/3; A_={r*cos(a), r*sin(a)}; DO val_a=dist(A, A_)+calc_A();
				DO b=(st+ed+ed)/3; A_={r*cos(b), r*sin(b)}; DO val_b=dist(A, A_)+calc_A();
				if(val_a<val_b) ed=b;
				else st=a;
			}
			DO al=(st+ed)/2; A_={r*cos(al), r*sin(al)}; smin(ans, dist(A, A_)+calc_A());
		}
	}
	printf("%.7lf", ans);
}

//ТЫ НАРКОМАН ЧТО ЛИ ЧИТАТЬ ЭТО

#include <algorithm>
#include <functional>
#include <numeric>
#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <ctime>
#include <cstring>
#include <cassert>
#include <vector>
#include <list>
#include <map>
#include <set>
#include <deque>
#include <queue>
#include <bitset>
#include <sstream>

using namespace std;

#define forn(i, n) for(int i = 0; i < int(n); ++i)
#define for1(i, n) for(int i = 1; i <= int(n); ++i)
#define ford(i, n) for(int i = int(n) - 1; i >= 0; --i)
#define fore(i, l, r) for(int i = int(l); i < int(r); ++i)
#define sz(v) int((v).size())
#define all(v) (v).begin(), (v).end()
#define pb push_back
#define X first
#define Y second

typedef long long li;
typedef long double ld;
typedef pair<ld, ld> pt;

template<typename T> T abs(T a) { return a < 0 ? -a : a; }
template<typename T> T sqr(T a) { return a*a; }

const int INF = (int)1e9;
const ld EPS = 1e-9;
const ld PI = 3.1415926535897932384626433832795;

const int MAGIC = 1500;
const int ITER = 0;

struct pt3{
    ld X, Y, Z;

    pt3(){ X = Y = Z = 0; }
    pt3(const ld& X, const ld& Y, const ld& Z) : X(X), Y(Y), Z(Z){}
};

inline ld dist(const pt3& a, const pt3& b){
    return sqrtl(sqr(a.X - b.X) + sqr(a.Y - b.Y) + sqr(a.Z - b.Z));
}

inline ld dist2(const pt3& a, const pt3& b){
    return (sqr(a.X - b.X) + sqr(a.Y - b.Y) + sqr(a.Z - b.Z));
}

inline ld leng(const pt3& a){
    return sqrtl(a.X*a.X + a.Y*a.Y + a.Z*a.Z);
}

inline pt3 operator - (const pt3& a, const pt3& b){
    return pt3(a.X - b.X, a.Y - b.Y, a.Z - b.Z);
}

inline pt3 norm(const pt3& a, const ld& nln){
    ld ln = leng(a);
    return pt3(a.X * (nln / ln), a.Y * (nln / ln), a.Z * (nln / ln));
}

inline ld distAng(const ld& a, const ld& b){
    if(a > b)
        return min(a - b, b + 2*PI - a);
    else
        return min(b - a, a + 2*PI - b);
}

ld h, r;
pt3 a, b, ap, bp, t;
ld aa, ba, ard, brd, ad, bd, ar, br, trd;

inline pt3 getPoint(const ld& ang){
    return pt3(r*cos(ang), r*sin(ang), 0);
}

inline pt3 project(const pt3& a){
    pt3 v = norm(a - t, sqrtl(sqr(a.Z) + dist2(a, t) - sqr(h - a.Z)));
    return pt3(a.X + v.X, a.Y + v.Y, a.Z + v.Z);
}

inline ld distCon(const ld& z1, const ld& z2, ld ang){
    /*
	if(z1 > z2)
        return distCon(z2, z1, ang);

    if(abs(z2 - h) < EPS){
        return trd * (h - z1) / h;
    }
	*/

    while(ang < 0)
        ang += 2*PI;
    while(ang > 2*PI)
        ang -= 2*PI;
    ang *= r / trd;

    pt a(trd * (h - z1) / h, 0);
    ld r2 = trd * (h - z2) / h;
    pt b(r2 * cos(ang), r2 * sin(ang));

    return sqrtl(sqr(a.X - b.X) + sqr(a.Y - b.Y));
}

inline ld distCon(const pt3& a, const pt3& b){
    ld dif = atan2(a.Y, a.X) - atan2(b.Y, b.X);
    while(dif < 0)
        dif += 2*PI;
    while(dif > 2*PI)
        dif -= 2*PI;

    //cerr << dif << " " << dif * nang << endl;

    return min(distCon(a.Z, b.Z, dif), distCon(a.Z, b.Z, (2*PI - dif)));
}

ld solve2(const pt3& ca){
    if(abs(b.Z) < EPS)
        return dist(ca, b);

    ld d = 2*PI / MAGIC;

    ld ans = 1e100;

    forn(i, MAGIC){
        ld lf = i*d;
        /*
        ld rg = i*d + d;

        forn(j, ITER){
            ld d = (rg - lf) / 3;
            ld ml = lf + d;
            ld mr = rg - d;

            pt3 pl = getPoint(ml), pr = getPoint(mr);

            if(dist(ca, pl) + distCon(0, a.Z, abs(ml - aa)) > dist(ca, pr) + distCon(0, a.Z, abs(mr - aa))){
                lf = ml;
            }else{
                rg = mr;
            }
        }
        */

        ans = min(ans, dist(ca, getPoint(lf)) + min(distCon(0, b.Z, lf - ba), distCon(0, b.Z, ba - lf)));
    }

    return ans;
}

ld solve1(){
    if(abs(a.Z) < EPS)
        return solve2(a);

    ld d = 2*PI / MAGIC;

    ld ans = 1e100;

    forn(i, MAGIC){
        ld lf = i*d;
        /*
        ld rg = i*d + d;

        forn(j, ITER){
            ld d = (rg - lf) / 3;
            ld ml = lf + d;
            ld mr = rg - d;

            pt3 pl = getPoint(ml), pr = getPoint(mr);

            if(distCon(pl, a) + solve2(pl) > distCon(pr, b) + solve2(pr)){
                lf = ml;
            }else{
                rg = mr;
            }
        }
        */

        ans = min(ans, min(distCon(0, a.Z, lf - aa), distCon(0, a.Z, aa - lf)) + solve2(getPoint(lf)));
    }

    return ans;
}

int main(){
    #ifndef ONLINE_JUDGE
        freopen("input.txt", "rt", stdin);
        //freopen("output.txt", "wt", stdout);
    #endif

    cout.precision(10);
    cout << fixed;

    cin >> r >> h >> a.X >> a.Y >> a.Z >> b.X >> b.Y >> b.Z;

    t = pt3(0, 0, h);
    trd = sqrtl(r*r + h*h);

	if(a.Z < EPS && b.Z < EPS){
		cout << dist(a, b) << endl;
		return 0;
	}

    if(a.X < EPS && a.Y < EPS && abs(a.Z - h) < EPS){
		if(b.Z < EPS){
			cout << trd + r - dist(b, pt3(0, 0, 0)) << endl;
		}else{
			cout << dist(a, b) << endl;
		}

		return 0;
	}

    if(b.X < EPS && b.Y < EPS && abs(b.Z - h) < EPS){
		if(a.Z < EPS){
			cout << trd + r - dist(a, pt3(0, 0, 0)) << endl;
		}else{
			cout << dist(a, b) << endl;
		}
		return 0;
	}

    if(abs(a.Z) > EPS){
        ap = project(a);
        ad = dist(a, ap);
        ard = sqrtl(r*r + h*h) / h * (h - a.Z);
        aa = atan2(ap.Y, ap.X);
        while(aa < 0)
            aa += 2*PI;
        ar = sqrtl(dist2(a, t) - sqr(h - a.Z));
    }

    if(abs(b.Z) > EPS){
        bp = project(b);
        bd = dist(b, ap);
        brd = sqrtl(r*r + h*h) / h * (h - b.Z);
        ba = atan2(bp.Y, bp.X);
        while(ba < 0)
            ba += 2*PI;
        br = sqrtl(dist2(b, t) - sqr(h - b.Z));
    }

    ld conDist = 1e100;

    if(abs(a.Z) > EPS && abs(b.Z) > EPS){
        conDist = distCon(a, b);
    }

    //cerr << clock() << endl;

    cout << min(conDist,solve1()) << endl;

    //cerr << clock() << endl;

    return 0;
}

#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <string>
#include <set>
#include <vector>
#include <cmath>
#include <cassert>
#include <cstdlib>
#include <map>
#include <queue>
#include <deque>
#include <bitset>

#define y0 y63475625
#define y1 y28435
#define j0 jfd0sf
#define j1 je90ue0
#define sqr(x) ((x)*(x))
#define fi first
#define se second
#define pb push_back
#define mp make_pair
#define re return
#define sz(x) ((int)(x).size())
#define all(x) (x).begin(), (x).end()
#define rep(i, n) for (int i = 0; i < (n); i++)
#define rrep(i, n) for (int i = (n) - 1; i >= 0; i--)
#define sqrt(x) (sqrt(abs(x)))
#define fill(a, x) memset(a, x, sizeof(a))

using namespace std;

typedef vector <int> vi;
typedef vector <vi> vvi;
typedef long long ll;
typedef long double ld;
typedef pair <int, int> ii;
typedef vector <ii> vii;
typedef double D;
typedef pair <ll, ll> pll;
typedef vector <string> vs;

template <class T> T abs(const T a) {
    return a > 0 ? a : -a;
}

const double PI = 2.0 * acos(1.0);

const ld eps = 1e-12;

ld alpha;

int n;
int m;

ld dist(ld xa, ld ya, ld xb, ld yb) {
    ld ra = sqrt(sqr(xa) + sqr(ya));
    ld rb = sqrt(sqr(xb) + sqr(yb));
    if (abs(xa) < eps && abs(ya) < eps) {
        re rb * alpha;
    }
    if (abs(xb) < eps && abs(yb) < eps) {
        re ra * alpha;
    }

    double angle = acos((xa * xb + ya * yb) / ra / rb);
    if (fabs(angle) < eps)
        re abs(rb - ra) * alpha;
    ld co = rb * sin(angle / alpha);
    ld si = (ra - rb * cos(angle / alpha));
    ld f0 = alpha * atan2(si, co);
    ld a = 1.0 / (ra * cos(f0 / alpha));
    re abs(alpha / a * (tan((angle - f0) / alpha) + tan(f0 / alpha)));
}

int main()
{
    ld r, h;
    cin >> r >> h;
    ld xa, ya, za, xb, yb, zb;
    cin >> xa >> ya >> za;
    cin >> xb >> yb >> zb;
    if (abs(zb) < eps && abs(za) < eps) {
        printf("%.10lf\n", (D)sqrt(sqr(xb - xa) + sqr(yb - ya)));
        re 0;
    }
    if (abs(zb) < eps) {
        swap(xa, xb);
        swap(ya, yb);
        swap(za, zb);
    }

    alpha = sqrt(1.0 + sqr(h / r));
    if (abs(za) > eps && abs(zb) > eps) {
        printf("%.10lf\n", (D)dist(xa, ya, xb, yb));
    } else {
        //todo
        ld L = 0.0, R = 2.0 * M_PI;
        ld ans = 1e20;
        ld fans = -1;
        rep(i, 2000) {
            rep(j, 100) {
                double f = L + (R - L) / 100.0 * j;
                ld x = r * cos(f);
                ld y = r * sin(f);
                ld tmp = sqrt(sqr(xa - x) + sqr(ya - y)) + dist(x, y, xb, yb);
                if (tmp < ans) {
                    ans = tmp;
                    fans = f;
                }
            }
            ld d = R - L;
            L = fans - d / 2.0 * 0.9;
            R = fans + d / 2.0 * 0.9;
        }
        printf("%.10lf\n", (D)ans);
    }
    return 0;
}

#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <string>
#include <set>
#include <vector>
#include <cmath>
#include <cassert>
#include <cstdlib>
#include <map>
#include <queue>
#include <deque>
#include <bitset>

#define y0 y63475625
#define y1 y28435
#define j0 jfd0sf
#define j1 je90ue0
#define sqr(x) ((x)*(x))
#define fi first
#define se second
#define pb push_back
#define mp make_pair
#define re return
#define sz(x) ((int)(x).size())
#define all(x) (x).begin(), (x).end()
#define rep(i, n) for (int i = 0; i < (n); i++)
#define rrep(i, n) for (int i = (n) - 1; i >= 0; i--)
#define sqrt(x) (sqrt(abs(x)))
#define fill(a, x) memset(a, x, sizeof(a))

using namespace std;

typedef vector <int> vi;
typedef vector <vi> vvi;
typedef long long ll;
typedef long double ld;
typedef pair <int, int> ii;
typedef vector <ii> vii;
typedef double D;
typedef pair <ll, ll> pll;
typedef vector <string> vs;

template <class T> T abs(const T a) {
    return a > 0 ? a : -a;
}

const double PI = 2.0 * acos(1.0);

const ld eps = 1e-12;

ld alpha;

int n;
int m;

ld dist(ld ra, ld rb, ld angle) {
    if (abs(ra) < eps) {
        re rb * alpha;
    }
    if (abs(rb) < eps) {
        re ra * alpha;
    }
    if (fabs(angle) < eps)
        re abs(rb - ra) * alpha;
    ld co = rb * sin(angle / alpha);
    ld si = (ra - rb * cos(angle / alpha));
    ld q = sqrt(sqr(co) + sqr(si));
    co /= q; si /= q;
    ld f0 = alpha * atan2(si, co);
    re abs(alpha * ra * (co * tan((angle - f0) / alpha) + si));
}

int main()
{
    ld r, h;
    cin >> r >> h;
    ld xa, ya, za, xb, yb, zb;
    cin >> xa >> ya >> za;
    cin >> xb >> yb >> zb;
    if (abs(zb) < eps && abs(za) < eps) {
        printf("%.10lf\n", (D)sqrt(sqr(xb - xa) + sqr(yb - ya)));
        re 0;
    }
    if (abs(zb) < eps) {
        swap(xa, xb);
        swap(ya, yb);
        swap(za, zb);
    }

    alpha = sqrt(1.0 + sqr(h / r));
    if (abs(za) > eps && abs(zb) > eps) {
        ld ra = sqrt(sqr(xa) + sqr(ya));
        ld rb = sqrt(sqr(xb) + sqr(yb));
        ld angle = -1.0;
        if (abs(ra) > eps && abs(rb) > eps)
            angle = acos((xa * xb + ya * yb) / ra / rb);
        ld ans = dist(ra, rb, angle);
        ld fans1 = -1, fans2 = -1;
        rep(i, 1) {
            ld L1 = -M_PI / 2, R1 = M_PI / 2.0;
            ld L2 = -M_PI / 2, R2 = M_PI / 2.0;
            n = 1600;
            rep(j, n) {
                ld f1 = L1 + (R1 - L1) * j / (ld)n;
                rep(k, n) {
                    ld f2 = L2 + (R2 - L2) * k / (ld)n;
                    ld tmp = r * sqrt(2.0 - 2.0 * cos(angle + f1 - f2)) + dist(r, ra, f1) + dist(r, rb, f2);
                    if (tmp < ans) {
                        ans = tmp;
                        fans1 = f1;
                        fans2 = f2;
                    }
                }
            }
            ld d = R1 - L1;
            L1 = fans1 - d / 2.0 * 0.99;
            L2 = fans2 - d / 2.0 * 0.99;
            R1 = fans1 + d / 2.0 * 0.99;
            R2 = fans2 + d / 2.0 * 0.99;
        }
        printf("%.10lf\n", (D)ans);
        re 0;
    } else {
        //todo
        ld L = 0.0, R = 2.0 * M_PI;
        ld ans = 1e20;
        ld fans = -1;
        ld rb = sqrt(sqr(xb) + sqr(yb));
        rep(i, 200) {
            rep(j, 1000) {
                double f = L + (R - L) / 100.0 * j;
                ld x = r * cos(f);
                ld y = r * sin(f);
                ld angle = -1.0;
                if (abs(rb) > eps)
                    angle = acos((x * xb + y * yb) / rb / r);
                ld tmp = sqrt(sqr(xa - x) + sqr(ya - y)) + dist(r, rb, angle);
                if (tmp < ans) {
                    ans = tmp;
                    fans = f;
                }
            }
            ld d = R - L;
            L = fans - d / 2.0 * 0.9;
            R = fans + d / 2.0 * 0.9;
        }
        printf("%.10lf\n", (D)ans);
    }
    return 0;
}

#include <iostream>
#include <cmath>
#include <cstdlib>

using namespace std;

double error=1e-9;

double r,h,lado,perimetro;

struct point {
  double x,y,z;
  point() {
  }
  point(double inx,double iny,double inz) {
    x=inx;y=iny;z=inz;
  }
};

point operator-(point p1,point p2)
{
  p1.x-=p2.x;
  p1.y-=p2.y;
  p1.z-=p2.z;
  return p1;
}

point rotar(point p,double a)
{
  point nextp=p;
  nextp.x=p.x*cos(a)-p.y*sin(a);
  nextp.y=p.x*sin(a)+p.y*cos(a);
  return nextp;
}

double cuad(double x)
{
  return x*x;
}

double abs(point p)
{
  return sqrt(cuad(p.x)+cuad(p.y)+cuad(p.z));
}

point p1,pp1;
point p2,pp2;

point obtenpp(double a)
{
  double arg=a*r/lado;
  return point(lado*cos(arg),lado*sin(arg),0);
}

double distap1(double a)
{
  return abs(pp1-obtenpp(a));
}

double distap2(double a)
{
  return abs(pp2-obtenpp(a));
}

double buscar1(double a1,double a2)
{
  //if (abs(a1-a2)<error) return distap1(a1)+abs(p2-point(r*cos(a1),r*sin(a1),0));
  //int imin=0;
  double solmin=distap1(a1)+abs(p2-point(r*cos(a1),r*sin(a1),0));
  for (int i=0;i<=1000;i++) {
    double a=(a1*(1000-i)+a2*i)/1000;
    double solact=distap1(a)+abs(p2-point(r*cos(a),r*sin(a),0));
    if (solact<solmin)
      //imin=i;
      solmin=solact;
  }
  return solmin;
  /*
  int iinf=max(imin-1,0);
  int isup=min(imin+1,100);
  return buscar1(p2,a1*(100-iinf)+a2*iinf,a1*(100-isup),a2*isup);
  */
}

double buscar2(double a1,double a2)
{
  double solmin=distap1(a1)+distap2(a1);
  for (int i=0;i<=1000;i++) {
    for (int j=i;j<=1000;j++) {
      double aa1=(a1*(1000-i)+a2*i)/1000;
      double aa2=(a1*(1000-j)+a2*j)/1000;
      double solact=distap1(aa1)+distap2(aa2)+
	abs(point(r*cos(aa1),r*sin(aa1),0)-point(r*cos(aa2),r*sin(aa2),0));
      if (solact<solmin)
	solmin=solact;
    }
  }
  return solmin;
}

int main()
{
  cout.setf(ios::fixed);
  cout.precision(10);
  cin>>r>>h>>p1.x>>p1.y>>p1.z>>p2.x>>p2.y>>p2.z;
  lado=sqrt(cuad(r)+cuad(h));
  perimetro=2*M_PI*r;
  if (p1.z<error and p2.z<error) {
    cout<<abs(p1-p2)<<endl;
    exit(0);
  }
  if (p1.z<p2.z) swap(p1,p2);
  if (p1.z>h-error) {
    if (p2.z<error)
      cout<<r-sqrt(cuad(p2.x)+cuad(p2.y))+abs(p1-point(r,0,0))<<endl;
    else
      cout<<abs(p1-p2)<<endl;
    exit(0);
  }
  double a=atan2(p1.y,p1.x);
  p1=rotar(p1,-a);
  p2=rotar(p2,-a);
  if (p2.y<0) p2.y=-p2.y;
  double a1=0;
  if (abs(p2-point(0,0,0))<error) {
    cout<<r+abs(p1-point(r,0,0))<<endl;
    exit(0);
  }
  double a2=atan2(p2.y,p2.x);
  if (a2<0) a2=-a2;
  pp1=point(abs(point(0,0,h)-p1),0,0);
  double lenp2=abs(point(0,0,h)-p2);
  double aa2=a2*r/lado;
  pp2=point(lenp2*cos(aa2),lenp2*sin(aa2),0);
  if (pp2.y<0) pp2.y=-pp2.y;
  double sol;
  if (p2.z<error) {
    sol=buscar1(a1,a2);
  } else {
    sol=min(abs(pp1-pp2),buscar2(a1,a2));
  }
  cout<<sol<<endl;
}

//ТЫ НАРКОМАН ЧТО ЛИ ЧИТАТЬ ЭТО

#include <algorithm>
#include <functional>
#include <numeric>
#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <ctime>
#include <cstring>
#include <cassert>
#include <vector>
#include <list>
#include <map>
#include <set>
#include <deque>
#include <queue>
#include <bitset>
#include <sstream>

using namespace std;

#define forn(i, n) for(int i = 0; i < int(n); ++i)
#define for1(i, n) for(int i = 1; i <= int(n); ++i)
#define ford(i, n) for(int i = int(n) - 1; i >= 0; --i)
#define fore(i, l, r) for(int i = int(l); i < int(r); ++i)
#define sz(v) int((v).size())
#define all(v) (v).begin(), (v).end()
#define pb push_back
#define X first
#define Y second

typedef long long li;
typedef long double ld;
typedef pair<ld, ld> pt;

template<typename T> T abs(T a) { return a < 0 ? -a : a; }
template<typename T> T sqr(T a) { return a*a; }

const int INF = (int)1e9;
const ld EPS = 1e-9;
const ld PI = 3.1415926535897932384626433832795;

const int MAGIC = 1500;
const int ITER = 0;

struct pt3{
    ld X, Y, Z;

    pt3(){ X = Y = Z = 0; }
    pt3(const ld& X, const ld& Y, const ld& Z) : X(X), Y(Y), Z(Z){}
};

inline ld dist(const pt3& a, const pt3& b){
    return sqrtl(sqr(a.X - b.X) + sqr(a.Y - b.Y) + sqr(a.Z - b.Z));
}

inline ld dist2(const pt3& a, const pt3& b){
    return (sqr(a.X - b.X) + sqr(a.Y - b.Y) + sqr(a.Z - b.Z));
}

inline ld leng(const pt3& a){
    return sqrtl(a.X*a.X + a.Y*a.Y + a.Z*a.Z);
}

inline pt3 operator - (const pt3& a, const pt3& b){
    return pt3(a.X - b.X, a.Y - b.Y, a.Z - b.Z);
}

inline pt3 norm(const pt3& a, const ld& nln){
    ld ln = leng(a);
    return pt3(a.X * (nln / ln), a.Y * (nln / ln), a.Z * (nln / ln));
}

inline ld distAng(const ld& a, const ld& b){
    if(a > b)
        return min(a - b, b + 2*PI - a);
    else
        return min(b - a, a + 2*PI - b);
}

ld h, r;
pt3 a, b, ap, bp, t;
ld aa, ba, ard, brd, ad, bd, ar, br, trd;

inline pt3 getPoint(const ld& ang){
    return pt3(r*cos(ang), r*sin(ang), 0);
}

inline pt3 project(const pt3& a){
    pt3 v = norm(a - t, sqrtl(sqr(a.Z) + dist2(a, t) - sqr(h - a.Z)));
    return pt3(a.X + v.X, a.Y + v.Y, a.Z + v.Z);
}

inline ld distCon(const ld& z1, const ld& z2, ld ang){
    while(ang < 0)
        ang += 2*PI;
    while(ang > 2*PI)
        ang -= 2*PI;
    ang *= r / trd;

    pt a(trd * (h - z1) / h, 0);
    ld r2 = trd * (h - z2) / h;
    pt b(r2 * cos(ang), r2 * sin(ang));

    return sqrtl(sqr(a.X - b.X) + sqr(a.Y - b.Y));
}

inline ld distCon(const pt3& a, const pt3& b){
    ld dif = atan2(a.Y, a.X) - atan2(b.Y, b.X);
    while(dif < 0)
        dif += 2*PI;
    while(dif > 2*PI)
        dif -= 2*PI;

    //cerr << dif << " " << dif * nang << endl;

    return min(distCon(a.Z, b.Z, dif), distCon(a.Z, b.Z, (2*PI - dif)));
}

ld solve2(const pt3& ca){
    if(abs(b.Z) < EPS)
        return dist(ca, b);

    ld d = 2*PI / MAGIC;

    ld ans = 1e100;

    forn(i, MAGIC){
        ld lf = i*d;
        /*
        ld rg = i*d + d;

        forn(j, ITER){
            ld d = (rg - lf) / 3;
            ld ml = lf + d;
            ld mr = rg - d;

            pt3 pl = getPoint(ml), pr = getPoint(mr);

            if(dist(ca, pl) + distCon(0, a.Z, abs(ml - aa)) > dist(ca, pr) + distCon(0, a.Z, abs(mr - aa))){
                lf = ml;
            }else{
                rg = mr;
            }
        }
        */

        ans = min(ans, dist(ca, getPoint(lf)) + min(distCon(0, b.Z, lf - ba), distCon(0, b.Z, ba - lf)));
    }

    return ans;
}

ld solve1(){
    if(abs(a.Z) < EPS)
        return solve2(a);

    ld d = 2*PI / MAGIC;

    ld ans = 1e100;

    forn(i, MAGIC){
        ld lf = i*d;
        /*
        ld rg = i*d + d;

        forn(j, ITER){
            ld d = (rg - lf) / 3;
            ld ml = lf + d;
            ld mr = rg - d;

            pt3 pl = getPoint(ml), pr = getPoint(mr);

            if(distCon(pl, a) + solve2(pl) > distCon(pr, b) + solve2(pr)){
                lf = ml;
            }else{
                rg = mr;
            }
        }
        */

        ans = min(ans, min(distCon(0, a.Z, lf - aa), distCon(0, a.Z, aa - lf)) + solve2(getPoint(lf)));
    }

    return ans;
}

int main(){
    #ifndef ONLINE_JUDGE
        freopen("input.txt", "rt", stdin);
        //freopen("output.txt", "wt", stdout);
    #endif

    cout.precision(10);
    cout << fixed;

    cin >> r >> h >> a.X >> a.Y >> a.Z >> b.X >> b.Y >> b.Z;

    t = pt3(0, 0, h);
    trd = sqrtl(r*r + h*h);

    if( (abs(a.X) < EPS && abs(a.Y) < EPS && abs(a.Z - h) < EPS) ||
        (abs(b.X) < EPS && abs(b.Y) < EPS && abs(b.Z - h) < EPS) || (abs(a.Z) < EPS && abs(b.Z) < EPS)){
        cout << dist(a, b) << endl;
        return 0;
    }

    if(abs(a.Z) > EPS){
        ap = project(a);
        ad = dist(a, ap);
        ard = sqrtl(r*r + h*h) / h * (h - a.Z);
        aa = atan2(ap.Y, ap.X);
        while(aa < 0)
            aa += 2*PI;
        ar = sqrtl(dist2(a, t) - sqr(h - a.Z));
    }

    if(abs(b.Z) > EPS){
        bp = project(b);
        bd = dist(b, ap);
        brd = sqrtl(r*r + h*h) / h * (h - b.Z);
        ba = atan2(bp.Y, bp.X);
        while(ba < 0)
            ba += 2*PI;
        br = sqrtl(dist2(b, t) - sqr(h - b.Z));
    }

    ld conDist = 1e100;

    if(abs(a.Z) > EPS && abs(b.Z) > EPS){
        conDist = distCon(a, b);
    }

    //cerr << clock() << endl;

    cout << min(conDist,solve1()) << endl;

    //cerr << clock() << endl;

    return 0;
}

#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <string>
#include <set>
#include <vector>
#include <cmath>
#include <cassert>
#include <cstdlib>
#include <map>
#include <queue>
#include <deque>
#include <bitset>

#define y0 y63475625
#define y1 y28435
#define j0 jfd0sf
#define j1 je90ue0
#define sqr(x) ((x)*(x))
#define fi first
#define se second
#define pb push_back
#define mp make_pair
#define re return
#define sz(x) ((int)(x).size())
#define all(x) (x).begin(), (x).end()
#define rep(i, n) for (int i = 0; i < (n); i++)
#define rrep(i, n) for (int i = (n) - 1; i >= 0; i--)
#define sqrt(x) (sqrt(abs(x)))
#define fill(a, x) memset(a, x, sizeof(a))

using namespace std;

typedef vector <int> vi;
typedef vector <vi> vvi;
typedef long long ll;
typedef long double ld;
typedef pair <int, int> ii;
typedef vector <ii> vii;
typedef double D;
typedef pair <ll, ll> pll;
typedef vector <string> vs;

template <class T> T abs(const T a) {
    return a > 0 ? a : -a;
}

const double PI = 2.0 * acos(1.0);

const ld eps = 1e-12;

ld alpha;

int n;
int m;

ld dist(ld xa, ld ya, ld xb, ld yb) {
    ld ra = sqrt(sqr(xa) + sqr(ya));
    ld rb = sqrt(sqr(xb) + sqr(yb));
    if (abs(xa) < eps && abs(ya) < eps) {
        re rb * alpha;
    }
    if (abs(xb) < eps && abs(yb) < eps) {
        re ra * alpha;
    }

    double angle = acos((xa * xb + ya * yb) / ra / rb);
    if (fabs(angle) < eps)
        re abs(rb - ra) * alpha;
    ld co = rb * sin(angle / alpha);
    ld si = (ra - rb * cos(angle / alpha));
    ld f0 = alpha * atan2(si, co);
    ld a = 1.0 / (ra * cos(f0 / alpha));
    /*cerr << ra << ' ' << 1.0 / (a * cos(f0 / alpha)) << endl;
    cerr << rb << ' ' << 1.0 / (a * cos((angle - f0) / alpha)) << endl;
    cerr.precision(20);
    cerr << a << ' ' << f0 << ' ' << alpha << endl;*/
    re abs(alpha / a * (tan((angle - f0) / alpha) + tan(f0 / alpha)));
}

int main()
{
    ld r, h;
    cin >> r >> h;
    ld xa, ya, za, xb, yb, zb;
    cin >> xa >> ya >> za;
    cin >> xb >> yb >> zb;
    if (abs(zb) < eps && abs(za) < eps) {
        printf("%.10lf\n", (D)sqrt(sqr(xb - xa) + sqr(yb - ya)));
        re 0;
    }
    if (abs(zb) < eps) {
        swap(xa, xb);
        swap(ya, yb);
        swap(za, zb);
    }

    alpha = sqrt(1.0 + sqr(h / r));
    if (abs(za) > eps && abs(zb) > eps) {
        ld ans = dist(xa, ya, xb, yb);
        ld fans1 = -1, fans2 = -1;
        rep(i, 200) {
            ld L1 = 0.0, R1 = 2.0 * M_PI;
            ld L2 = 0.0, R2 = 2.0 * M_PI;
            n = 30;
            rep(j, n) {
                ld f1 = L1 + (R1 - L1) * j / (ld)n;
                rep(k, n) {
                    ld f2 = L2 + (R2 - L2) * k / (ld)n;
                    ld x1 = r * cos(f1), y1 = r * sin(f1), x2 = r * cos(f2), y2 = r * sin(f2);
                    ld tmp = sqrt(sqr(x1 - x2) + sqr(y1 - y2)) + dist(xa, ya, x1, y1) + dist(x2, y2, xb, yb);
                    if (tmp < ans) {
                        ans = tmp;
                        fans1 = f1;
                        fans2 = f2;
                    }
                }
            }
            ld d = R1 - L1;
            L1 = fans1 - d / 2.0 * 0.7;
            L2 = fans2 - d / 2.0 * 0.7;
            R1 = fans1 + d / 2.0 * 0.7;
            R2 = fans2 + d / 2.0 * 0.7;
        }
        printf("%.10lf\n", (D)ans);
        re 0;
    } else {
        //todo
        ld L = 0.0, R = 2.0 * M_PI;
        ld ans = 1e20;
        ld fans = -1;
        rep(i, 2000) {
            rep(j, 100) {
                double f = L + (R - L) / 100.0 * j;
                ld x = r * cos(f);
                ld y = r * sin(f);
                ld tmp = sqrt(sqr(xa - x) + sqr(ya - y)) + dist(x, y, xb, yb);
                if (tmp < ans) {
                    ans = tmp;
                    fans = f;
                }
            }
            ld d = R - L;
            L = fans - d / 2.0 * 0.9;
            R = fans + d / 2.0 * 0.9;
        }
        printf("%.10lf\n", (D)ans);
    }
    return 0;
}

#define pi 3.1415926535897932384626433832795

#include<bits/stdc++.h>

#define eps 1e-8

typedef double DO;

using namespace std;

template<typename T, typename U> inline void smin(T &a, const U &b) {if(a>b) a=b;}

template<typename T, typename U> inline void smax(T &a, const U &b) {if(a<b) a=b;}

struct point {

	DO x, y, z;

	inline point(DO x=0, DO y=0, DO z=0) : x(x), y(y), z(z) {}

	inline point operator - (point a) {return point(x-a.x, y-a.y, z-a.z);}

	inline point operator + (point a) {return point(x+a.x, y+a.y, z+a.z);}

	inline point operator * (DO a) {return point(x*a, y*a, z*a);}

	inline point operator / (DO a) {return point(x/a, y/a, z/a);}

	inline point operator ^ (point a) {return point(y*a.z-z*a.y, -(x*a.z-z*a.x), x*a.y-y*a.x);}

	inline DO operator * (point a) {return x*a.x+y*a.y+z*a.z;}

	inline point norm() {DO s=nor(); if(s<eps) return *this; return point(x/s, y/s, z/s);}

	inline DO nor() {return sqrt(*this**this);}

	inline DO nor2() {return *this**this;}

	inline point rotate(DO al) {return *this&point(cos(al), sin(al), z);}

	inline point operator & (point a) {return point(x*a.x-y*a.y, x*a.y+y*a.x, z);}

	inline bool operator < (const point &a) const {

		if(fabs(x-a.x)>eps) return x<a.x;

		if(fabs(y-a.y)>eps) return y<a.y;

		return z<a.z-eps;

	}

	inline bool operator > (const point &a) const {

		if(fabs(x-a.x)>eps) return x>a.x;

		if(fabs(y-a.y)>eps) return y>a.y;

		return z>a.z+eps;

	}

	inline void input() {scanf("%lf %lf %lf", &x, &y, &z);}

	inline void print() {printf("%lf %lf %lf\n", x, y, z);}

};

DO r, h, R, R2, len;

point focus, a, b, c, ac, A;

inline DO calc1(DO x) {

	point d=c.rotate(x/r);

	DO ans1=(A-d).nor();

	smin(x, len-x);

	DO D2=(b-focus).nor2(), D=sqrt(D2);

	DO ans2=sqrt(R2+D2-2*R*D*cos(x/R));

	return ans1+ans2;

}

inline DO solve() {

	DO st=0, ed=len;

	while(ed-st>eps) {

		DO a=(st+st+ed)/3, b=(st+ed+ed)/3;

		if(calc1(a)>calc1(b)) st=a;

		else ed=b;

	}

	return calc1(st);

}

inline DO calc2(DO x) {

	A=ac.rotate(x/r);

	smin(x, len-x);

	DO D2=(a-focus).nor2(), D=sqrt(D2);

	return sqrt(R2+D2-2*R*D*cos(x/R))+solve();

}

inline DO angle(point a, point b) {

	DO res=a*b/a.nor()/b.nor();

	res=acos(res);

	return res;

}

inline DO kong() {

	DO aa2=(a-focus).nor2(), aa=sqrt(aa2);

	DO bb2=(b-focus).nor2(), bb=sqrt(bb2);

	DO x=angle(c, ac)*r;

	smin(x, len-x);

	return sqrt(aa2+bb2-2*aa*bb*cos(x/R));

}

main() {

#ifndef	ONLINE_JUDGE

	freopen("in.in", "r", stdin);

	freopen("out.out", "w", stdout);

#endif

	scanf("%lf %lf", &r, &h);

	a.input(), b.input();

	if(b.z==0) swap(a, b);

	len=2*pi*r;

	R2=h*h+r*r, R=sqrt(R2);

	focus=point(0, 0, h);

	c=focus+(b-focus).norm()*R;

	if(a.z==0) {

		if(b.z==0) printf("%.7lf", (a-b).nor());

		else {

			A=a;

			printf("%.7lf", solve());

		}

	}

	else {

		ac=focus+(a-focus).norm()*R;

		DO st=0, ed=len;

		while(ed-st>eps) {

			DO a=(st+st+ed)/3, b=(st+ed+ed)/3;

			if(calc2(a)>calc2(b)) st=a;

			else ed=b;

		}

		printf("%.7lf", min(kong(), calc2(st)));

	}

}

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <climits>
#include <cstring>
#include <string>
#include <vector>
#include <stack>
#include <queue>
#include <set>
#include <map>
#include <algorithm>

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 = isGreaterThan(tmp.first, b.first) ? tmp : b;
    b = isGreaterThan(tmp.first, b.first) ? b : tmp;
    alpha = 2 * pi * r/ sqrt(r * r + h * h);
    aTheta = a.first;
    bTheta = b.first;
    if(isGreaterThan((aTheta - bTheta), alpha / 2.0))
    {
        // find mirror and do shieat
        aTheta = bTheta + (alpha - aTheta + bTheta);
    }

    return euclideanDistance(a.second * cos(aTheta), a.second * sin(aTheta),
                             b.second * cos(bTheta), b.second * sin(bTheta));
}

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;
    right = minDegree + aDegree;

    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 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;

    x = r * cos(left);
    y = r * sin(left);
    minDegree = left;
    minVal = findConeSurfaceDistance(x1, y1, z1, x, y, 0.0) +
             findOptimalSingleBrinkPointDistance(x2, y2, z2, x, y, 0.0);

    for(left = aDegree; left < right; left += aDegree)
    {
        x = r * cos(left);
        y = r * sin(left);
        curr = findConeSurfaceDistance(x1, y1, z1, x, y, 0.0) +
               findOptimalSingleBrinkPointDistance(x2, y2, z2, x, y, 0.0);
        if(curr < minVal)
        {
            minVal = curr;
            minDegree = left;
        }
    }

    left = minDegree - aDegree;
    right = minDegree + aDegree;

    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);
}

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;
}

#include <iostream>
#include <cstdio>
#include <vector>
#include <algorithm>
#include <cstring>
#include <string>
#include <queue>
#include <set>
#include <map>
#include <bitset>
#include <cmath>
#include <ctime>
#pragma comment (linker, "/STACK:256000000")

using namespace std;

const double eps = 1e-9;
const double pi = 2.0 * acos(0.0);
double r, h;

double dist(double x1, double y1, double z1, double x2, double y2, double z2) {
	double dx = x1 - x2;
	double dy = y1 - y2;
	double dz = z1 - z2;
	return sqrt(dx * dx + dy * dy + dz * dz);
}

double dist(double x1, double y1, double x2, double y2) {
	double dx = x1 - x2;
	double dy = y1 - y2;
	return sqrt(dx * dx + dy * dy);
}

double solve(double x1, double y1, double z1, double x2, double y2, double z2) {
	if (fabs(z1) < eps && fabs(z2) < eps) {
		return dist(x1, y1, z1, x2, y2, z2);
	}

	double l1 = dist(x1, y1, z1, 0, 0, h);
	double l2 = dist(x2, y2, z2, 0, 0, h);

	if (fabs(l1) < eps || fabs(l2) < eps) {
		return l1 + l2;
	}

	double coef = l2 / l1;
	double xn = x1 * coef;
	double yn = y1 * coef;
	double zn = h + (z1 - h) * coef;
	double cr = sqrt(l2 * l2 - (h - z2) * (h - z2));
	double ang = acos((xn * x2 + yn * y2) / (cr * cr));

	double length = ang * r;
	double alpha = length / sqrt(r * r + h * h);

	double u1 = l1, v1 = 0.0;
	double u2 = l2 * cos(alpha), v2 = l2 * sin(alpha);

	return dist(u1, v1, u2, v2);
}

double calc(double xa, double ya, double za, double xb, double yb, double zb, double x0, double y0, double z0, double L, double R) {
	double res = 1e20;
	double d = solve(xa, ya, za, x0, y0, z0);
	for (int i = 0; i < 40; ++i) {
		double x = (2.0 * L + R) / 3.0;
		double y = (L + 2.0 * R) / 3.0;

		double x1 = r * cos(x), y1 = r * sin(x);
		double x2 = r * cos(y), y2 = r * sin(y);

		double A = solve(x0, y0, z0, x1, y1, 0.0) + solve(x1, y1, 0.0, xb, yb, zb);
		double B = solve(x0, y0, z0, x2, y2, 0.0) + solve(x2, y2, 0.0, xb, yb, zb);
		res = min(res, d + A);
		res = min(res, d + B);
		if (A < B) {
			R = y;
		} else {
			L = x;
		}
	}
	return res;
}

int main() {
	//freopen("input.txt", "r", stdin);
	//freopen("output.txt", "w", stdout);

	cin >> r >> h;
	double xa, ya, za;
	double xb, yb, zb;
	cin >> xa >> ya >> za;
	cin >> xb >> yb >> zb;

	double res = 1e20;
	if (fabs(za) > eps && fabs(zb) > eps) {
		res = min(res, solve(xa, ya, za, xb, yb, zb));
	}
	if (fabs(za) < eps && fabs(zb) < eps) {
		res = min(res, dist(xa, ya, za, xb, yb, zb));
	}

	double angle = 2.0 * pi / 200;
	for (int step = 0; step < 200; ++step) {
		double left_bound = (double)(step) * angle;
		double right_bound = (double)(step + 1) * angle;

		for (int i = 0; i < 200; ++i) {
			double L = (2.0 * left_bound + right_bound) / 3.0;
			double R = (left_bound + 2.0 * right_bound) / 3.0;

			double valueL = solve(xa, ya, za, r * cos(L), r * sin(L), 0) + solve(r * cos(L), r * sin(L), 0, xb, yb, zb);
			double valueR = solve(xa, ya, za, r * cos(R), r * sin(R), 0) + solve(r * cos(R), r * sin(R), 0, xb, yb, zb);
			res = min(res, valueL);
			res = min(res, valueR);
			if (valueL < valueR) {
				right_bound = R;
			} else {
				left_bound = L;
			}
		}
	}
	//printf("%.12lf\n", res);
	int cnt = 2;
	angle = 2.0 * pi / (double)(cnt);
	for (int stepA = 0; stepA < cnt; ++stepA) {
		for (int stepB = 0; stepB < cnt; ++stepB) {
			double left_bound = (double)(stepA) * angle;
			double right_bound = (double)(stepA + 1) * angle;

			double lB = (double)(stepB) * angle;
			double rB = (double)(stepB + 1) * angle;
			for (int i = 0; i < 40; ++i) {
				double L = (2.0 * left_bound + right_bound) / 3.0;
				double R = (left_bound + 2.0 * right_bound) / 3.0;

				double valueL = calc(xa, ya, za, xb, yb, zb, r * cos(L), r * sin(L), 0.0, lB, rB);
				double valueR = calc(xa, ya, za, xb, yb, zb, r * cos(R), r * sin(R), 0.0, lB, rB);
				res = min(res, valueL);
				res = min(res, valueR);
				if (valueL < valueR) {
					right_bound = R;
				} else {
					left_bound = L;
				}
			}
		}
	}

	printf("%.12lf\n", res);

	return 0;
}

#define pi 3.1415926535897932384626433832795

#include<bits/stdc++.h>

#define eps 1e-13

using namespace std;

typedef long double DO;

template<typename T, typename U> inline void smin(T &a, const U &b) {if(a>b) a=b;}

struct point {

	DO x, y, z;

	inline point(DO x=0, DO y=0, DO z=0) : x(x), y(y), z(z) {}

	inline point operator - (point a) {return point(x-a.x, y-a.y, z-a.z);}

	inline point operator + (point a) {return point(x+a.x, y+a.y, z+a.z);}

	inline point operator * (DO a) {return point(x*a, y*a, z*a);}

	inline point operator / (DO a) {return point(x/a, y/a, z/a);}

	inline DO operator * (point a) {return x*a.x+y*a.y+z*a.z;}

	inline point norm() {DO s=nor(); if(s<eps) return *this; return point(x/s, y/s, z/s);}

	inline DO nor() {return sqrtl(*this**this);}

	inline DO nor2() {return *this**this;}

	inline point rotate(DO al) {return *this&point(cosl(al), sinl(al), z);}

	inline point operator & (point a) {return point(x*a.x-y*a.y, x*a.y+y*a.x, z);}

	inline void input() {cin>>x>>y>>z;}

};

DO r, h, R, R2, len;

point focus, a, b, c, ac, A;

inline DO calc1(DO x) {

	point d=c.rotate(x/r);

	DO ans1=(A-d).nor();

	smin(x, len-x);

	DO D2=(b-focus).nor2(), D=sqrtl(D2);

	DO ans2=sqrtl(R2+D2-2*R*D*cosl(x/R));

	smin(ans2, (d-focus).nor()+D);

	return ans1+ans2;

}

inline DO solve() {

	DO st=0, ed=len;

	while(ed-st>eps) {

		DO a=(st+st+ed)/3, b=(st+ed+ed)/3;

		if(calc1(a)>calc1(b)) st=a;

		else ed=b;

	}

	return calc1(st);

}

inline DO calc2(DO x) {

	A=ac.rotate(x/r);

	smin(x, len-x);

	DO D2=(a-focus).nor2(), D=sqrtl(D2);

	return sqrtl(R2+D2-2*R*D*cosl(x/R)) +solve();

}

inline DO angle(point a, point b) {

	DO res=a*b/a.nor()/b.nor();

	res=acosl(res);

	return res;

}

inline DO kong() {

	DO aa2=(a-focus).nor2(), aa=sqrtl(aa2);

	DO bb2=(b-focus).nor2(), bb=sqrtl(bb2);

	DO x=angle(c, ac)*r;

	smin(x, len-x);

	return min((a-focus).nor()+(b-focus).nor(), sqrtl(aa2+bb2-2*aa*bb*cosl(x/R)));

}

main() {

#ifndef	ONLINE_JUDGE

	freopen("in.in", "r", stdin);

	freopen("out.out", "w", stdout);

#endif

	cin>>r>>h; a.input(), b.input();

	if(fabsl(b.z)<eps) swap(a, b);

	len=2*pi*r;

	R2=h*h+r*r, R=sqrtl(R2);

	focus=point(0, 0, h);

	c=focus+(b-focus).norm()*R;

	if(fabsl(a.z)<eps) {

		if(fabsl(b.z)<eps) printf("%.7lf", (double)(a-b).nor());

		else {

			A=a;

			printf("%.7lf", (double)solve());

		}

	}

	else {

		ac=focus+(a-focus).norm()*R;

		DO st=0, ed=len;

		while(ed-st>eps) {

			DO a=(st+st+ed)/3, b=(st+ed+ed)/3;

			if(calc2(a)>calc2(b)) st=a;

			else ed=b;

		}

		printf("%.7lf", (double)min(kong(), calc2(st)));

	}

}

// eddy1021
#include <bits/stdc++.h>
using namespace std;
typedef double D;
typedef long double LD;
typedef long long ll;
typedef long long LL;
typedef pair<int,int> PII;
typedef pair<LL,LL> PLL;
// typedef pair<LD,LD> Pt;
typedef tuple<int,int,int> tiii;
typedef tuple<LL,LL,LL> tlll;
#define mod9 1000000009ll
#define mod7 1000000007ll
#define INF  1023456789ll
#define INF16 10000000000000000ll
#define FI first
#define SE second
// #define X FI
// #define Y SE
#define PB push_back
#define MP make_pair
#define MT make_tuple
#define eps 1e-9
#define SZ(x) (int)(x).size()
#define ALL(x) (x).begin(), (x).end()
#ifndef ONLINE_JUDGE
#define debug(...) printf(__VA_ARGS__)
#else
#define debug(...)
#endif
inline ll getint(){
  ll _x=0,_tmp=1; char _tc=getchar();
  while( (_tc<'0'||_tc>'9')&&_tc!='-' ) _tc=getchar();
  if( _tc == '-' ) _tc=getchar() , _tmp = -1;
  while(_tc>='0'&&_tc<='9') _x*=10,_x+=(_tc-'0'),_tc=getchar();
  return _x*_tmp;
}
inline ll add( ll _x , ll _y , ll _mod = mod7 ){
  ll _ = _x + _y;
  if( _ >= _mod ) _ -= _mod;
  return _;
}
inline ll sub( ll _x , ll _y , ll _mod = mod7 ){
  ll _ = _x - _y;
  if( _ < 0 ) _ += _mod;
  return _;
}
inline ll mul( ll _x , ll _y , ll _mod = mod7 ){
  ll _ = _x * _y;
  if( _ >= _mod ) _ %= _mod;
  return _;
}
ll mypow( ll _a , ll _x , ll _mod ){
  if( _x == 0 ) return 1ll;
  ll _tmp = mypow( _a , _x / 2 , _mod );
  _tmp = mul( _tmp , _tmp , _mod );
  if( _x & 1 ) _tmp = mul( _tmp , _a , _mod );
  return _tmp;
}
ll mymul( ll _a , ll _x , ll _mod ){
  if( _x == 0 ) return 0ll;
  ll _tmp = mymul( _a , _x / 2 , _mod );
  _tmp = add( _tmp , _tmp , _mod );
  if( _x & 1 ) _tmp = add( _tmp , _a , _mod );
  return _tmp;
}
inline bool equal( LD _x ,  LD _y ){
  return _x > _y - eps && _x < _y + eps;
}
int __ = 1 , _cs;
/*********default*********/
inline LD getLD(){
  D _; scanf( "%lf" , &_ );
  return _;
}
typedef tuple<LD,LD,LD> Pt;
#define X(U) get<0>(U)
#define Y(U) get<1>(U)
#define Z(U) get<2>(U)
inline void scan( Pt& tp ){
  X( tp ) = getLD();
  Y( tp ) = getLD();
  Z( tp ) = getLD();
}
inline void print( const Pt& tp ){
  printf( "(%.6f,%.6f,%.6f)\n" , (D)X( tp ) , (D)Y( tp ) , (D)Z( tp ) );
}
inline bool onbase( const Pt& tp ){
  return equal( Z( tp ) , 0.0 );
}
inline LD sqr( const LD& x ){ return x * x; }
LD r , h , ans , rr;
Pt p[ 2 ];
const LD pi = acosl( -1.0 );
const LD pi2 = 2.0 * acosl( -1.0 );
void build(){
}
void init(){
  r = getLD();
  h = getLD();
  rr = sqrt( sqr( r ) + sqr( h ) );
  scan( p[ 0 ] );
  scan( p[ 1 ] );
}
inline LD dist( const Pt& x , const Pt&y ){
  return sqrt( sqr( X( x ) - X( y ) ) +
               sqr( Y( x ) - Y( y ) ) +
               sqr( Z( x ) - Z( y ) ) );
}
inline LD dist_oncone( const Pt& x , const Pt& y ){
  LD ang1 = atan2( Y( x ) , X( x ) );
  LD ang2 = atan2( Y( y ) , X( y ) );
  LD dang = fabs( ang1 - ang2 );
  dang *= r / rr;
  LD r1 = rr * ( 1.0 - Z( x ) / h );
  LD r2 = rr * ( 1.0 - Z( y ) / h );
  Pt p1 = MT( r1 , 0.0 , 0.0 );
  Pt p2 = MT( cosl( dang ) * r2 , sinl( dang ) * r2 , 0.0 );
  return dist( p1 , p2 );
}
inline void cal1(){
  ans = min( ans , dist( p[ 0 ] , p[ 1 ] ) );
}
inline void cal2(){
#define K 3500000
  for( int i = 0 ; i < K ; i ++ ){
    Pt tmp = MT( cosl( (LD)i / (LD)K * pi2 ) * r ,
                 sinl( (LD)i / (LD)K * pi2 ) * r ,
                 0.0 );
    ans = min( ans , dist( tmp , p[ 0 ] ) + dist_oncone( tmp , p[ 1 ] ) );
  }
}
inline void cal3(){
#define KK 1500
  ans = min( ans , dist_oncone( p[ 0 ] , p[ 1 ] ) );
  for( int i = 0 ; i < KK ; i ++ )
    for( int j = i + 1 ; j < KK ; j ++ ){
      Pt tmp1 = MT( cosl( (LD)i / (LD)KK * pi2 ) * r ,
                    sinl( (LD)i / (LD)KK * pi2 ) * r ,
                    0.0 );
      Pt tmp2 = MT( cosl( (LD)j / (LD)KK * pi2 ) * r ,
                    sinl( (LD)j / (LD)KK * pi2 ) * r ,
                    0.0 );
      ans = min( ans , min( dist_oncone( tmp1 , p[ 0 ] ) , dist_oncone( tmp2 , p[ 0 ] ) ) +
                       min( dist_oncone( tmp1 , p[ 1 ] ) , dist_oncone( tmp2 , p[ 1 ] ) ) +
                       dist( tmp1 , tmp2 ) );
    }
}
void solve(){
  ans = 1e40;
  if( onbase( p[ 0 ] ) && onbase( p[ 1 ] ) ) cal1();
  else if( onbase( p[ 0 ] ) || onbase( p[ 1 ] ) ){
    if( onbase( p[ 1 ] ) ) swap( p[ 0 ] , p[ 1 ] );
    cal2();
  }else cal3();
  printf( "%.12f\n" , (D)ans );
}
int main(){
  build();
  //__ = getint();
  while( __ -- ){
    init();
    solve();
  }
}

#include <set>
#include <map>
#include <queue>
#include <deque>
#include <cmath>
#include <ctime>
#include <bitset>
#include <vector>
#include <string>
#include <cstdio>
#include <cassert>
#include <cstring>
#include <iostream>
#include <algorithm>
#define For(i,x,y)  for(int i=(int)(x);i<=(int)(y);i++)
#define Forn(i,x,y) for(int i=(int)(x);i>=(int)(y);i--)
#define Rep(i,x,y)  for(int i=(int)(x);i< (int)(y);i++)
#define mk make_pair
#define pb push_back
#define fi first
#define se second
using namespace std;
typedef long double db;
typedef long long ll;
typedef pair<int,int> PII;
const int N=200005;
const int inf=1e9;
const ll Inf=1e10;
const int P=1000000007;
const db  pi=acos(-1);

db r,h,Sqr,l;
db X1,X2,Y1,Y2,Z1,Z2;

void read(db &x){
	double z;
	scanf("%lf",&z);
	x=z;
}

db sqr(db x){return x*x;}

db Fbb(db A,db B,db D,db E){
	return sqrt(sqr(A-D)+sqr(B-E));
}

db Faa(db A,db B,db C,db D,db E,db F){
	if(fabs(C-h)<1e-6) return sqrt(D*D+E*E+sqr(F-h));
	if(fabs(F-h)<1e-6) return sqrt(A*A+B*B+sqr(C-h));
	db X3=A*h/(h-C),Y3=B*h/(h-C),X4=D*h/(h-F),Y4=E*h/(h-F);
	db u=Sqr*2-sqr(X3-X4)-sqr(Y3-Y4);
	u/=2*Sqr;
	db the=acos(u);
	db phi=the*r/l;
	db D1=sqr(A)+sqr(B)+sqr(C-h),D2=sqr(D)+sqr(E)+sqr(F-h);
	return sqrt(D1+D2-2*sqrt(D1)*sqrt(D2)*cos(phi));
}

db Fab(db X,db Y,db Z,db E,db F,db the){
	db X3=r*cos(the),Y3=r*sin(the);
	return Faa(X,Y,Z,X3,Y3,0)+Fbb(E,F,X3,Y3);
}

db Al=0,Ar=0;
db Fab2(db the){
	db X3=cos(the)*r,Y3=sin(the)*r;
	db l=Al,r=Ar,T1,T2;
	For(i,1,400){
		db md1=(9*l+r)/10.,md2=(l+9*r)/10.;
		T1=Fab(X2,Y2,Z2,X3,Y3,md1);
		T2=Fab(X2,Y2,Z2,X3,Y3,md2);
		if(T1>T2) l=md1;else r=md2;
	}
	return T1+Faa(X1,Y1,Z1,X3,Y3,0);
}

int main(){
	read(r);read(h);Sqr=r*r;
	l=sqrt(r*r+h*h);
	read(X1);read(Y1);read(Z1);
	read(X2);read(Y2);read(Z2);

	if(Z1==0&&Z2==0){
		printf("%.16lf\n",double(Fbb(X1,Y1,X2,Y2)));
		return 0;
	}
	if(Z1!=0&&Z2!=0){
		Al=atan2(Y1,X1);
		Ar=atan2(Y2,X2);
		if(Al>Ar) swap(Al,Ar);
		db ans=Faa(X1,Y1,Z1,X2,Y2,Z2);
		db l=Al,r=Ar,T1,T2;
		For(i,1,200){
			db md1=(9*l+r)/10.,md2=(l+9*r)/10.;
			T1=Fab2(md1);
			T2=Fab2(md2);
			if(T1>T2) l=md1;else r=md2;
		}
		ans=min(ans,T1);
		printf("%.16lf\n",double(ans));
		return 0;
	}
	if(Z1==0){
		swap(X1,X2);
		swap(Y1,Y2);
		swap(Z1,Z2);
	}
	db l=0,r=2*pi,T1,T2;
	For(i,1,500){
		db md1=(29*l+r)/30.,md2=(l+29*r)/30.;
		if((T1=Fab(X1,Y1,Z1,X2,Y2,md1))>(T2=Fab(X1,Y1,Z1,X2,Y2,md2))) l=md1;else r=md2;
	}
	printf("%.16lf\n",double(T1));
	return 0;
}

#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <string>
#include <set>
#include <vector>
#include <cmath>
#include <cassert>
#include <cstdlib>
#include <map>
#include <queue>
#include <deque>
#include <bitset>

#define y0 y63475625
#define y1 y28435
#define j0 jfd0sf
#define j1 je90ue0
#define sqr(x) ((x)*(x))
#define fi first
#define se second
#define pb push_back
#define mp make_pair
#define re return
#define sz(x) ((int)(x).size())
#define all(x) (x).begin(), (x).end()
#define rep(i, n) for (int i = 0; i < (n); i++)
#define rrep(i, n) for (int i = (n) - 1; i >= 0; i--)
#define sqrt(x) (sqrt(abs(x)))
#define fill(a, x) memset(a, x, sizeof(a))

using namespace std;

typedef vector <int> vi;
typedef vector <vi> vvi;
typedef long long ll;
typedef long double ld;
typedef pair <int, int> ii;
typedef vector <ii> vii;
typedef double D;
typedef pair <ll, ll> pll;
typedef vector <string> vs;

template <class T> T abs(const T a) {
    return a > 0 ? a : -a;
}

const double PI = 2.0 * acos(1.0);

const ld eps = 1e-12;

ld alpha;

int n;
int m;

ld dist(ld ra, ld rb, ld angle) {
    if (abs(ra) < eps) {
        re rb * alpha;
    }
    if (abs(rb) < eps) {
        re ra * alpha;
    }
    if (fabs(angle) < eps)
        re abs(rb - ra) * alpha;
    ld co = rb * sin(angle / alpha);
    ld si = (ra - rb * cos(angle / alpha));
    ld q = sqrt(sqr(co) + sqr(si));
    co /= q; si /= q;
    //ld f0 = alpha * atan2(si, co);
    ld tmp = tan(angle / alpha), tg = si / co;
    re abs(alpha * ra * (co * (tmp - tg) / (1.0 + tmp * tg) + si));
}

int main()
{
    ld r, h;
    cin >> r >> h;
    ld xa, ya, za, xb, yb, zb;
    cin >> xa >> ya >> za;
    cin >> xb >> yb >> zb;
    if (abs(zb) < eps && abs(za) < eps) {
        printf("%.10lf\n", (D)sqrt(sqr(xb - xa) + sqr(yb - ya)));
        re 0;
    }
    if (abs(zb) < eps) {
        swap(xa, xb);
        swap(ya, yb);
        swap(za, zb);
    }

    alpha = sqrt(1.0 + sqr(h / r));
    if (abs(za) > eps && abs(zb) > eps) {
        ld ra = sqrt(sqr(xa) + sqr(ya));
        ld rb = sqrt(sqr(xb) + sqr(yb));
        ld angle = -1.0;
        if (abs(ra) > eps && abs(rb) > eps)
            angle = acos((xa * xb + ya * yb) / ra / rb);
        ld ans = dist(ra, rb, angle);
        ld fans1 = -1, fans2 = -1;
        rep(i, 1) {
            ld L1 = -M_PI / 2, R1 = M_PI / 2.0;
            ld L2 = -M_PI / 2, R2 = M_PI / 2.0;
            n = 1780;
            rep(j, n) {
                ld f1 = L1 + (R1 - L1) * j / (ld)n;
                rep(k, n) {
                    ld f2 = L2 + (R2 - L2) * k / (ld)n;
                    ld tmp = r * sqrt(2.0 - 2.0 * cos(angle + f1 - f2)) + dist(r, ra, f1) + dist(r, rb, f2);
                    if (tmp < ans) {
                        ans = tmp;
                        fans1 = f1;
                        fans2 = f2;
                    }
                }
            }
            ld d = R1 - L1;
            L1 = fans1 - d / 2.0 * 0.99;
            L2 = fans2 - d / 2.0 * 0.99;
            R1 = fans1 + d / 2.0 * 0.99;
            R2 = fans2 + d / 2.0 * 0.99;
        }
        printf("%.10lf\n", (D)ans);
        re 0;
    } else {
        //todo
        ld L = 0.0, R = 2.0 * M_PI;
        ld ans = 1e20;
        ld fans = -1;
        ld rb = sqrt(sqr(xb) + sqr(yb));
        rep(i, 200) {
            rep(j, 1000) {
                double f = L + (R - L) / 100.0 * j;
                ld x = r * cos(f);
                ld y = r * sin(f);
                ld angle = -1.0;
                if (abs(rb) > eps)
                    angle = acos((x * xb + y * yb) / rb / r);
                ld tmp = sqrt(sqr(xa - x) + sqr(ya - y)) + dist(r, rb, angle);
                if (tmp < ans) {
                    ans = tmp;
                    fans = f;
                }
            }
            ld d = R - L;
            L = fans - d / 2.0 * 0.9;
            R = fans + d / 2.0 * 0.9;
        }
        printf("%.10lf\n", (D)ans);
    }
    return 0;
}

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <climits>
#include <cstring>
#include <string>
#include <vector>
#include <stack>
#include <queue>
#include <set>
#include <map>
#include <algorithm>

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;
/*
    printf("aTheta=%.9lf\n", aTheta * 180.0 / pi);
    printf("bTheta=%.9lf\n", bTheta * 180.0 / pi);
    printf("alpha=%.9lf\n", alpha * 180.0 / pi);
*/
    if(isGreaterThan((aTheta - bTheta), alpha / 2.0))
    {
        // find mirror and do shieat
        aTheta = bTheta + (alpha - aTheta + bTheta);
    }

    return euclideanDistance(a.second * cos(aTheta), a.second * sin(aTheta),
                             b.second * cos(bTheta), b.second * sin(bTheta));
}

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;
        }
    }

    minDegree = atan2(yHi, xHi);
    left = minDegree - aDegree * 2;
    right = minDegree + aDegree * 2;

    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 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;

    x = r * cos(left);
    y = r * sin(left);
    minDegree = left;
    minVal = findConeSurfaceDistance(x1, y1, z1, x, y, 0.0) +
             findOptimalSingleBrinkPointDistance(x2, y2, z2, x, y, 0.0);

    for(left = aDegree; left < right; left += aDegree)
    {
        x = r * cos(left);
        y = r * sin(left);
        curr = findConeSurfaceDistance(x1, y1, z1, x, y, 0.0) +
               findOptimalSingleBrinkPointDistance(x2, y2, z2, x, y, 0.0);
        if(curr < minVal)
        {
            minVal = curr;
            minDegree = left;
        }
    }

    minDegree = atan2(y1, x1);
    left = minDegree - aDegree * 2;
    right = minDegree + aDegree * 2;

    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);
//        printf("middle=%.9lf - x=%.9lf - y=%.9lf\n", middle * 180.0 / pi, x, y);
//        cout << "middle=" << middle * 180.0 / pi << " - leftVal=" << leftVal << " - rightVal=" << rightVal << " - midVal=" << midVal << endl;
        if(leftVal > rightVal)
        {
            leftVal = midVal;
            left = middle;
        }
        else
        {
            rightVal = midVal;
            right = middle;
        }
    }
    return min(leftVal, rightVal);
}

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;
}

//ТЫ НАРКОМАН ЧТО ЛИ ЧИТАТЬ ЭТО

#include <algorithm>
#include <functional>
#include <numeric>
#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <ctime>
#include <cstring>
#include <cassert>
#include <vector>
#include <list>
#include <map>
#include <set>
#include <deque>
#include <queue>
#include <bitset>
#include <sstream>

using namespace std;

#define forn(i, n) for(int i = 0; i < int(n); ++i)
#define for1(i, n) for(int i = 1; i <= int(n); ++i)
#define ford(i, n) for(int i = int(n) - 1; i >= 0; --i)
#define fore(i, l, r) for(int i = int(l); i < int(r); ++i)
#define sz(v) int((v).size())
#define all(v) (v).begin(), (v).end()
#define pb push_back
#define X first
#define Y second

typedef long long li;
typedef long double ld;
typedef pair<ld, ld> pt;

template<typename T> T abs(T a) { return a < 0 ? -a : a; }
template<typename T> T sqr(T a) { return a*a; }

const int INF = (int)1e9;
const ld EPS = 1e-13;
const ld PI = 3.1415926535897932384626433832795;

const int MAGIC = 2000;
const int ITER = 0;

struct pt3{
    ld X, Y, Z;

    pt3(){ X = Y = Z = 0; }
    pt3(const ld& X, const ld& Y, const ld& Z) : X(X), Y(Y), Z(Z){}
};

inline ld dist(const pt3& a, const pt3& b){
    return sqrtl(sqr(a.X - b.X) + sqr(a.Y - b.Y) + sqr(a.Z - b.Z));
}

inline ld dist2(const pt3& a, const pt3& b){
    return (sqr(a.X - b.X) + sqr(a.Y - b.Y) + sqr(a.Z - b.Z));
}

inline ld leng(const pt3& a){
    return sqrtl(a.X*a.X + a.Y*a.Y + a.Z*a.Z);
}

inline pt3 operator - (const pt3& a, const pt3& b){
    return pt3(a.X - b.X, a.Y - b.Y, a.Z - b.Z);
}

inline pt3 norm(const pt3& a, const ld& nln){
    ld ln = leng(a);
    return pt3(a.X * (nln / ln), a.Y * (nln / ln), a.Z * (nln / ln));
}

inline ld distAng(const ld& a, const ld& b){
    if(a > b)
        return min(a - b, b + 2*PI - a);
    else
        return min(b - a, a + 2*PI - b);
}

ld h, r;
pt3 a, b, ap, bp, t;
ld aa, ba, ard, brd, ad, bd, ar, br, trd;

inline pt3 getPoint(const ld& ang){
    return pt3(r*cos(ang), r*sin(ang), 0);
}

inline pt3 project(const pt3& a){
    pt3 v = norm(a - t, sqrtl(sqr(a.Z) + dist2(a, t) - sqr(h - a.Z)));
    return pt3(a.X + v.X, a.Y + v.Y, a.Z + v.Z);
}

inline ld distCon(const ld& z1, const ld& z2, ld ang){
    /*
    if(z1 > z2)
        return distCon(z2, z1, ang);

    if(abs(z2 - h) < EPS){
        return trd * (h - z1) / h;
    }
    */

    while(ang < 0)
        ang += 2*PI;
    while(ang > 2*PI)
        ang -= 2*PI;
    ang *= r / trd;

    pt a(trd * (h - z1) / h, 0);
    ld r2 = trd * (h - z2) / h;
    pt b(r2 * cos(ang), r2 * sin(ang));

    return sqrtl(sqr(a.X - b.X) + sqr(a.Y - b.Y));
}

inline ld distCon(const pt3& a, const pt3& b){
    ld dif = atan2(a.Y, a.X) - atan2(b.Y, b.X);
    while(dif < 0)
        dif += 2*PI;
    while(dif > 2*PI)
        dif -= 2*PI;

    //cerr << dif << " " << dif * nang << endl;

    return min(distCon(a.Z, b.Z, dif), distCon(a.Z, b.Z, (2*PI - dif)));
}

ld solve2(const pt3& ca){
    if(abs(b.Z) < EPS)
        return dist(ca, b);

    int curMagic = (a.Z < EPS) ? (MAGIC * MAGIC) : (MAGIC);

    ld d = 2*PI / curMagic;

    ld ans = 1e100;

    forn(i, curMagic){
        ld lf = i*d;
        /*
        ld rg = i*d + d;

        forn(j, ITER){
            ld d = (rg - lf) / 3;
            ld ml = lf + d;
            ld mr = rg - d;

            pt3 pl = getPoint(ml), pr = getPoint(mr);

            if(dist(ca, pl) + distCon(0, a.Z, abs(ml - aa)) > dist(ca, pr) + distCon(0, a.Z, abs(mr - aa))){
                lf = ml;
            }else{
                rg = mr;
            }
        }
        */

        ans = min(ans, dist(ca, getPoint(lf)) + min(distCon(0, b.Z, lf - ba), distCon(0, b.Z, ba - lf)));
    }

    return ans;
}

ld solve1(){
    if(abs(a.Z) < EPS)
        return solve2(a);

    ld d = 2*PI / MAGIC;

    ld ans = 1e100;

    forn(i, MAGIC){
        ld lf = i*d;
        /*
        ld rg = i*d + d;

        forn(j, ITER){
            ld d = (rg - lf) / 3;
            ld ml = lf + d;
            ld mr = rg - d;

            pt3 pl = getPoint(ml), pr = getPoint(mr);

            if(distCon(pl, a) + solve2(pl) > distCon(pr, b) + solve2(pr)){
                lf = ml;
            }else{
                rg = mr;
            }
        }
        */

        ans = min(ans, min(distCon(0, a.Z, lf - aa), distCon(0, a.Z, aa - lf)) + solve2(getPoint(lf)));
    }

    return ans;
}

int main(){
    #ifndef ONLINE_JUDGE
        freopen("input.txt", "rt", stdin);
        //freopen("output.txt", "wt", stdout);
    #endif

    cout.precision(10);
    cout << fixed;

    cin >> r >> h >> a.X >> a.Y >> a.Z >> b.X >> b.Y >> b.Z;

    if(b.Z < EPS)
        swap(a, b);

    t = pt3(0, 0, h);
    trd = sqrtl(r*r + h*h);

    if(a.Z < EPS && b.Z < EPS){
        cout << dist(a, b) << endl;
        return 0;
    }

    if(a.X < EPS && a.Y < EPS && abs(a.Z - h) < EPS){
        if(b.Z < EPS){
            cout << trd + r - dist(b, pt3(0, 0, 0)) << endl;
        }else{
            cout << dist(a, b) << endl;
        }

        return 0;
    }

    if(b.X < EPS && b.Y < EPS && abs(b.Z - h) < EPS){
        if(a.Z < EPS){
            cout << trd + r - dist(a, pt3(0, 0, 0)) << endl;
        }else{
            cout << dist(a, b) << endl;
        }
        return 0;
    }

    if(abs(a.Z) > EPS){
        ap = project(a);
        ad = dist(a, ap);
        ard = sqrtl(r*r + h*h) / h * (h - a.Z);
        aa = atan2(ap.Y, ap.X);
        while(aa < 0)
            aa += 2*PI;
        ar = sqrtl(dist2(a, t) - sqr(h - a.Z));
    }

    if(abs(b.Z) > EPS){
        bp = project(b);
        bd = dist(b, ap);
        brd = sqrtl(r*r + h*h) / h * (h - b.Z);
        ba = atan2(bp.Y, bp.X);
        while(ba < 0)
            ba += 2*PI;
        br = sqrtl(dist2(b, t) - sqr(h - b.Z));
    }

    ld conDist = 1e100;

    if(abs(a.Z) > EPS && abs(b.Z) > EPS){
        conDist = distCon(a, b);
    }

    //cerr << clock() << endl;

    cout << min(conDist,solve1()) << endl;

    cerr << clock() << endl;

    return 0;
}

#define pi 3.1415926535897932384626433832795

#include<bits/stdc++.h>

#define eps 1e-13

using namespace std;

typedef long double DO;

template<typename T, typename U> inline void smin(T &a, const U &b) {if(a>b) a=b;}

struct point {

	DO x, y, z;

	inline point(DO x=0, DO y=0, DO z=0) : x(x), y(y), z(z) {}

	inline point operator - (point a) {return point(x-a.x, y-a.y, z-a.z);}

	inline point operator + (point a) {return point(x+a.x, y+a.y, z+a.z);}

	inline point operator * (DO a) {return point(x*a, y*a, z*a);}

	inline point operator / (DO a) {return point(x/a, y/a, z/a);}

	inline DO operator * (point a) {return x*a.x+y*a.y+z*a.z;}

	inline point norm() {DO s=nor(); if(s<eps) return *this; return point(x/s, y/s, z/s);}

	inline DO nor() {return sqrtl(*this**this);}

	inline DO nor2() {return *this**this;}

	inline point rotate(DO al) {return *this&point(cosl(al), sinl(al), z);}

	inline point operator & (point a) {return point(x*a.x-y*a.y, x*a.y+y*a.x, z);}

	inline void input() {cin>>x>>y>>z;}

};

DO r, h, R, R2, len;

point focus, a, b, c, ac, A;

inline DO calc1(DO x) {

	point d=c.rotate(x/r);

	DO ans1=(A-d).nor();

	smin(x, len-x);

	DO D2=(b-focus).nor2(), D=sqrtl(D2);

	DO ans2=sqrtl(R2+D2-2*R*D*cosl(x/R));

	return ans1+ans2;

}

inline DO solve() {

	DO st=0, ed=len;

	while(ed-st>eps) {

		DO a=(st+st+ed)/3, b=(st+ed+ed)/3;

		if(calc1(a)>calc1(b)) st=a;

		else ed=b;

	}

	return calc1(st);

}

inline DO calc2(DO x) {

	A=ac.rotate(x/r);

	smin(x, len-x);

	DO D2=(a-focus).nor2(), D=sqrtl(D2);

	return sqrtl(R2+D2-2*R*D*cosl(x/R)) + calc1(0);

}

inline DO angle(point a, point b) {

	DO res=a*b/a.nor()/b.nor();

	res=acosl(res);

	return res;

}

inline DO kong() {

	DO aa2=(a-focus).nor2(), aa=sqrtl(aa2);

	DO bb2=(b-focus).nor2(), bb=sqrtl(bb2);

	DO x=angle(c, ac)*r;

	smin(x, len-x);

	return sqrtl(aa2+bb2-2*aa*bb*cosl(x/R));

}

main() {

#ifndef	ONLINE_JUDGE

	freopen("in.in", "r", stdin);

	freopen("out.out", "w", stdout);

#endif

	cin>>r>>h; a.input(), b.input();

	if(fabsl(b.z)<eps) swap(a, b);

	len=2*pi*r;

	R2=h*h+r*r, R=sqrtl(R2);

	focus=point(0, 0, h);

	c=focus+(b-focus).norm()*R;

	if(fabsl(a.z)<eps) {

		if(fabsl(b.z)<eps) printf("%.7lf", (double)(a-b).nor());

		else {

			A=a;

			printf("%.7lf", (double)solve());

		}

	}

	else {

		ac=focus+(a-focus).norm()*R;

		printf("%.7lf", (double)min(kong(), calc2(0)));

	}

}

#define pi 3.1415926535897932384626433832795

#include<bits/stdc++.h>

#define eps 1e-13

using namespace std;

typedef long double DO;

template<typename T, typename U> inline void smin(T &a, const U &b) {if(a>b) a=b;}

struct point {

	DO x, y, z;

	inline point(DO x=0, DO y=0, DO z=0) : x(x), y(y), z(z) {}

	inline point operator - (point a) {return point(x-a.x, y-a.y, z-a.z);}

	inline point operator + (point a) {return point(x+a.x, y+a.y, z+a.z);}

	inline point operator * (DO a) {return point(x*a, y*a, z*a);}

	inline point operator / (DO a) {return point(x/a, y/a, z/a);}

	inline DO operator * (point a) {return x*a.x+y*a.y+z*a.z;}

	inline point norm() {DO s=nor(); if(s<eps) return *this; return point(x/s, y/s, z/s);}

	inline DO nor() {return sqrtl(*this**this);}

	inline DO nor2() {return *this**this;}

	inline point rotate(DO al) {return *this&point(cosl(al), sinl(al), z);}

	inline point operator & (point a) {return point(x*a.x-y*a.y, x*a.y+y*a.x, z);}

	inline void input() {cin>>x>>y>>z;}

};

DO r, h, R, R2, len;

point focus, a, b, c, ac, A;

inline DO calc1(DO x) {

	point d=c.rotate(x/r);

	DO ans1=(A-d).nor();

	smin(x, len-x);

	DO D2=(b-focus).nor2(), D=sqrtl(D2);

	DO ans2=sqrtl(R2+D2-2*R*D*cosl(x/R));

	smin(ans2, (d-focus).nor()+D);

	return ans1+ans2;

}

inline DO calc2(DO x) {

	A=ac.rotate(x/r);

	smin(x, len-x);

	DO D2=(a-focus).nor2(), D=sqrtl(D2);

	return sqrtl(R2+D2-2*R*D*cosl(x/R)) + calc1(0);

}

inline DO angle(point a, point b) {

	DO res=a*b/a.nor()/b.nor();

	res=acosl(res);

	return res;

}

inline DO kong() {

	DO aa2=(a-focus).nor2(), aa=sqrtl(aa2);

	DO bb2=(b-focus).nor2(), bb=sqrtl(bb2);

	DO x=angle(c, ac)*r;

	smin(x, len-x);

	return sqrtl(aa2+bb2-2*aa*bb*cosl(x/R));

}

main() {

#ifndef	ONLINE_JUDGE

	freopen("in.in", "r", stdin);

	freopen("out.out", "w", stdout);

#endif

	cin>>r>>h; a.input(), b.input();

	if(fabsl(b.z)<eps) swap(a, b);

	len=2*pi*r;

	R2=h*h+r*r, R=sqrtl(R2);

	focus=point(0, 0, h);

	c=focus+(b-focus).norm()*R;

	if(fabsl(a.z)<eps) {

		if(fabsl(b.z)<eps) printf("%.7lf", (double)(a-b).nor());

		else {

			A=a;

			printf("%.7lf", (double)calc1(0));

		}

	}

	else {

		ac=focus+(a-focus).norm()*R;

		printf("%.7lf", (double)min(kong(), calc2(0)));

	}

}

#include <bits/stdc++.h>

#define inf 0x3f3f3f3f

#define MOD 1000000007

#define pb push_back

#define sq(x) ((x)*(x))

#define x first

#define y second

#define eps 1e-12

#define bpt(x) (__builtin_popcount(x))

#define bptl(x) (__builtin_popcountll(x))

#define bit(x, y) (((x)>>(y))&1)

#define bclz(x) (__builtin_clz(x))

#define bclzl(x) (__builtin_clzll(x))

#define bctz(x) (__builtin_ctz(x))

#define bctzl(x) (__builtin_ctzll(x))

#define sgn(x) (((x)>eps)-((x)<-eps))

#define PQ priority_queue<pii, vector<pii>, greater<pii> >

using namespace std;

typedef long long INT;

typedef vector<int> VI;

typedef pair<int, int> pii;

typedef pair<pii, int> pi3;

typedef long double DO;

template<typename T, typename U> inline void smin(T &a, U b) {if (a>b) a=b;}

template<typename T, typename U> inline void smax(T &a, U b) {if (a<b) a=b;}

template<class T>inline void gn(T &x) {char c, sg=0; while (c=getchar(), (c>'9' || c<'0') && c!='-');for((c=='-'?sg=1, c=getchar():0), x=0; c>='0' && c<='9'; c=getchar()) x=(x<<1)+(x<<3)+c-'0';if (sg) x=-x;}

template<class T, class T1>inline void gn(T &x, T1 &y) {gn(x); gn(y);}

template<class T, class T1, class T2>inline void gn(T &x, T1 &y, T2 &z) {gn(x); gn(y); gn(z);}

template<class T>inline void print(T x) {if (x<0) {putchar('-');return print(-x);}if (x<10) {putchar('0'+x);return;} print(x/10);putchar(x%10+'0');}

template<class T>inline void printsp(T x) {print(x); putchar(' ');}

template<class T>inline void println(T x) {print(x); putchar('\n');}

template<class T, class U>inline void print(T x, U y) {printsp(x); println(y);}

template<class T, class U, class V>inline void print(T x, U y, V z) {printsp(x); printsp(y); println(z);}

int power(int a, int b, int m, int ans=1) {

	for (; b; b>>=1, a=1LL*a*a%m) if (b&1) ans=1LL*ans*a%m;

	return ans;

}

struct point {

	DO x, y, z;

	point (DO x=0, DO y=0, DO z=0) : x(x), y(y), z(z) {}

	point operator - (point a) {return point(x-a.x, y-a.y, z-a.z);}

	point operator + (point a) {return point(x+a.x, y+a.y, z+a.z);}

	point operator * (DO a) {return point(x*a, y*a, z*a);}

	point operator / (DO a) {return point(x/a, y/a, z/a);}

	point operator ^ (point a) {return point(y*a.z-z*a.y, -(x*a.z-z*a.x), x*a.y-y*a.x);}

	DO    operator * (point a) {return x*a.x+y*a.y+z*a.z;}

	point norm() {DO s=nor(); if (s<eps) return *this; return point(x/s, y/s, z/s);}

	DO nor() {return sqrtl(*this**this);}

	bool operator < (const point &a) const {

		if (fabsl(x-a.x)>eps) return x<a.x;

		if (fabsl(y-a.y)>eps) return y<a.y;

		return z<a.z-eps;

	}

	bool operator > (const point &a) const {

		if (fabsl(x-a.x)>eps) return x>a.x;

		if (fabsl(y-a.y)>eps) return y>a.y;

		return z>a.z-eps;

	}

	bool operator == (const point &a) const {

		if (fabsl(x-a.x)>eps) return 0;

		if (fabsl(y-a.y)>eps) return 0;

		return fabs(z-a.z)<eps;

	}

	void input() {cin>>x>>y>>z;}

	void print() {printf("%lf %lf %lf\n", (double)x, (double)y, (double)z);}

};

void print_ans(DO x) {

	cout<<fixed<<setprecision(15)<<x<<endl;

	exit(0);

}

DO L, pi;

DO calc(point &a, DO &lb, DO &phib, DO &r, DO &al) {

	DO be=al*L/r;

	DO ans=(a-point(r*cosl(be), r*sinl(be), 0)).nor();

	return ans+sqrtl(max((DO)0, (L*L+lb*lb-2*lb*L*cosl(al-phib))));

}

DO ST[1111];

point a, b;

DO r, h;

point H;

DO calc3(point a, DO al) {

	DO alpha=atan2l(a.y, a.x);

	if (alpha<0) alpha+=2*pi;

	DO la=(H-a).nor();

	return sqrtl((H-a)*(H-a)+L*L-2*la*L*cosl(alpha*r/L-al));

}

DO calc2(DO al, DO be) {

	DO alpha=al*r/L, beta=be*r/L;

	point c=point(cosl(al)*r, sinl(al)*r), d=point(cosl(be)*r, sinl(be)*r);

	return calc3(a, alpha)+calc3(b, beta)+(c-d).nor();

}

DO calc1(DO al) {

	DO ans=1e100;

	for (int i=0; i<6; i++) {

		DO st=pi/3*i, ed=st+pi/2;

		for (int j=0; j<50; j++) {

			DO x1=(st*2+ed)/3, x2=(st+ed*2)/3;

			if (calc2(al, x1)<calc2(al, x2)) ed=x2;

			else st=x1;

		}

		smin(ans, calc2(al, st));

	}

	return ans;

}

int main() {

#ifndef ONLINE_JUDGE

	freopen("in.in", "r", stdin);

	freopen("out.out", "w", stdout);

#endif

	cin>>r>>h;

	a.input(); b.input();

	L=sqrtl(r*r+h*h), pi=acosl(-1.0);

	if (a.z<eps && b.z<eps) print_ans((a-b).nor());

	if (a.z>b.z-eps) swap(a, b);

	H=point(0, 0, h);

	if (b.z>h-eps) {

		if (a.z>h-eps) print_ans((DO)0.0);

		if (a.z<eps) print_ans(L+r-a.nor());

		print_ans((H-a).nor());

	}

	if (a.z>eps) {

		DO al=atan2l(a.y, a.x);

		DO be=atan2l(b.y, b.x);

		if (al<0) al+=2*pi;

		if (be<0) be+=2*pi;

		DO la=(H-a).nor();

		DO lb=(H-b).nor();

		DO phia=al*r/L, phib=be*r/L;

		DO ans=sqrtl(max((DO)0.0, (H-a)*(H-a)+(H-b)*(H-b)-2*la*lb*cosl(phia-phib)));

		for (int i=0; i<6; i++) {

			DO st=pi/3*i, ed=st+pi/2;

			for (int j=0; j<50; j++) {

				DO x1=(st*2+ed)/3, x2=(st+ed*2)/3;

				if (calc1(x1)<calc1(x2)) ed=x2;

				else st=x1;

			}

			smin(ans, calc1(st));

		}

		print_ans(ans);

	}

	DO al=atan2l(a.y, a.x);

	DO be=atan2l(b.y, b.x);

	if (al<0) al+=2*pi;

	if (be<0) be+=2*pi;

	DO lb=(H-b).nor();

	DO phib=be*r/L;

	DO ans=(DO)1e100;

	for (int j=0; j<6; j++) {

		DO st=(pi/3*j)*r/L, ed=(pi/3*j+pi/2)*r/L;

		for (int i=0; i<200; i++) {

			DO x1=(st*2+ed)/3, x2=(st+ed*2)/3;

			if (calc(a, lb, phib, r, x1)<calc(a, lb, phib, r, x2)) ed=x2;

			else st=x1;

		}

		smin(ans, calc(a, lb, phib, r, st));

	}

	print_ans(ans);

	return 0;

}

#define pi 3.1415926535897932384626433832795

#include<bits/stdc++.h>

#define eps 1e-8

typedef double DO;

using namespace std;

template<typename T, typename U> inline void smin(T &a, const U &b) {if(a>b) a=b;}

template<typename T, typename U> inline void smax(T &a, const U &b) {if(a<b) a=b;}

struct point {

	DO x, y, z;

	inline point(DO x=0, DO y=0, DO z=0) : x(x), y(y), z(z) {}

	inline point operator - (point a) {return point(x-a.x, y-a.y, z-a.z);}

	inline point operator + (point a) {return point(x+a.x, y+a.y, z+a.z);}

	inline point operator * (DO a) {return point(x*a, y*a, z*a);}

	inline point operator / (DO a) {return point(x/a, y/a, z/a);}

	inline point operator ^ (point a) {return point(y*a.z-z*a.y, -(x*a.z-z*a.x), x*a.y-y*a.x);}

	inline DO operator * (point a) {return x*a.x+y*a.y+z*a.z;}

	inline point norm() {DO s=nor(); if(s<eps) return *this; return point(x/s, y/s, z/s);}

	inline DO nor() {return sqrt(nor2());}

	inline DO nor2() {return *this**this;}

	inline DO al() {return atan2(y, x);}

	inline bool operator < (const point &a) const {

		if(fabs(x-a.x)>eps) return x<a.x;

		if(fabs(y-a.y)>eps) return y<a.y;

		return z<a.z-eps;

	}

	inline bool operator > (const point &a) const {

		if(fabs(x-a.x)>eps) return x>a.x;

		if(fabs(y-a.y)>eps) return y>a.y;

		return z>a.z+eps;

	}

	inline bool operator == (const point &a) const {

		if(fabs(x-a.x)>eps) return 0;

		if(fabs(y-a.y)>eps) return 0;

		return fabs(z-a.z)<eps;

	}

	inline void input() {scanf("%lf %lf %lf", &x, &y, &z);}

	inline void print() {printf("%lf %lf %lf\n", x, y, z);}

};

DO whole=2*pi, step=whole/3;

DO r, h, R;

point A, AA, B;

inline DO calc_laterals(point a, point b) {

	DO al=fabs(a.al()-b.al()); smin(al, whole-al);

	DO dada=(a-point(0, 0, h)).nor2(), da=sqrt(dada);

	DO dbdb=(b-point(0, 0, h)).nor2(), db=sqrt(dbdb);

	return sqrt(dada+dbdb-2*da*db*cos(r*al/R));

}

inline DO solve() {

	DO ans=1e13;

	for(DO sst=0; sst<whole; sst+=step) {

		DO st=sst, ed=st+step;

		while(ed-st>eps) {

			DO a=(st+st+ed)/3, b=(st+ed+ed)/3;

			point aa=point(r*cos(a), r*sin(a)); DO sa=(AA-aa).nor()+calc_laterals(aa, B);

			point bb=point(r*cos(b), r*sin(b)); DO sb=(AA-bb).nor()+calc_laterals(bb, B);

			if(sa>sb) st=a;

			else ed=b;

		}

		point aa=point(r*cos(st), r*sin(st)); smin(ans, (AA-aa).nor()+calc_laterals(aa, B));

		point bb=point(r*cos(ed), r*sin(ed)); smin(ans, (AA-bb).nor()+calc_laterals(bb, B));

	}

	return ans;

}

main() {

#ifndef	ONLINE_JUDGE

	freopen("in.in", "r", stdin);

	freopen("out.out", "w", stdout);

#endif

	scanf("%lf %lf", &r, &h);

	R=sqrt(r*r+h*h);

	A.input(), B.input();

	if(B.z<eps) swap(A, B);

	DO ans;

	if(A.z<eps) {

		if(B.z<eps) ans=(A-B).nor();

		else AA=A, ans=solve();

	}

	else {

		ans=calc_laterals(A, B);

		for(DO sst=0; sst<whole; sst+=step) {

			DO st=sst, ed=st+step;

			while(ed-st>eps) {

				DO a=(st+st+ed)/3, b=(st+ed+ed)/3;

				AA=point(r*cos(a), r*sin(a)); DO sa=calc_laterals(A, AA)+solve();

				AA=point(r*cos(b), r*sin(b)); DO sb=calc_laterals(A, AA)+solve();

				if(sa>sb) st=a;

				else ed=b;

			}

			AA=point(r*cos(st), r*sin(st)); smin(ans, calc_laterals(A, AA)+solve());

			AA=point(r*cos(ed), r*sin(ed)); smin(ans, calc_laterals(A, AA)+solve());

		}

	}

	printf("%.7lf", ans);

}

#define pi 3.1415926535897932384626433832795

#include<bits/stdc++.h>

#define eps 1e-13

using namespace std;

typedef long double DO;

template<typename T, typename U> inline void smin(T &a, const U &b) {if(a>b) a=b;}

struct point {

	DO x, y, z;

	inline point(DO x=0, DO y=0, DO z=0) : x(x), y(y), z(z) {}

	inline point operator - (point a) {return point(x-a.x, y-a.y, z-a.z);}

	inline point operator + (point a) {return point(x+a.x, y+a.y, z+a.z);}

	inline point operator * (DO a) {return point(x*a, y*a, z*a);}

	inline point operator / (DO a) {return point(x/a, y/a, z/a);}

	inline DO operator * (point a) {return x*a.x+y*a.y+z*a.z;}

	inline point norm() {DO s=nor(); if(s<eps) return *this; return point(x/s, y/s, z/s);}

	inline DO nor() {return sqrtl(*this**this);}

	inline DO nor2() {return *this**this;}

	inline point rotate(DO al) {return *this&point(cosl(al), sinl(al), z);}

	inline point operator & (point a) {return point(x*a.x-y*a.y, x*a.y+y*a.x, z);}

	inline void input() {cin>>x>>y>>z;}

};

DO r, h, R, R2, len;

point focus, a, b, c, ac, A;

inline DO calc1(DO x) {

	point d=c.rotate(x/r);

	DO ans1=(A-d).nor();

	smin(x, len-x);

	DO D2=(b-focus).nor2(), D=sqrtl(D2);

	DO ans2=sqrtl(R2+D2-2*R*D*cosl(x/R));

	smin(ans2, (d-focus).nor()+D);

	return ans1+ans2;

}

inline DO solve() {

	return calc1(0);

}

inline DO calc2(DO x) {

	A=ac.rotate(x/r);

	smin(x, len-x);

	DO D2=(a-focus).nor2(), D=sqrtl(D2);

	return sqrtl(R2+D2-2*R*D*cosl(x/R)) + solve();

}

inline DO angle(point a, point b) {

	DO res=a*b/a.nor()/b.nor();

	res=acosl(res);

	return res;

}

inline DO kong() {

	DO aa2=(a-focus).nor2(), aa=sqrtl(aa2);

	DO bb2=(b-focus).nor2(), bb=sqrtl(bb2);

	DO x=angle(c, ac)*r;

	smin(x, len-x);

	return sqrtl(aa2+bb2-2*aa*bb*cosl(x/R));

}

main() {

#ifndef	ONLINE_JUDGE

	freopen("in.in", "r", stdin);

	freopen("out.out", "w", stdout);

#endif

	cin>>r>>h; a.input(), b.input();

	if(fabsl(b.z)<eps) swap(a, b);

	len=2*pi*r;

	R2=h*h+r*r, R=sqrtl(R2);

	focus=point(0, 0, h);

	c=focus+(b-focus).norm()*R;

	if(fabsl(a.z)<eps && fabsl(b.z)<eps) printf("%.7lf", (double)(a-b).nor());

	else {

		ac=focus+(a-focus).norm()*R;

		printf("%.7lf", (double)min(kong(), calc2(0)));

	}

}

#include "bits/stdc++.h"
#define x first
#define y second
#define sq(_) ((_)*(_))
using namespace std;
using DO = long double;
using pdd = pair<DO, DO>;
pdd operator + (const pdd &a, const pdd &b) {return {a.x+b.x, a.y+b.y};}
pdd operator - (const pdd &a, const pdd &b) {return {a.x-b.x, a.y-b.y};}
pdd operator * (const pdd &a, const DO &b) {return {a.x*b, a.y*b};}
pdd operator / (const pdd &a, const DO &b) {return {a.x/b, a.y/b};}
DO  operator * (const pdd &a, const pdd &b) {return a.x*b.x+a.y*b.y;}
DO  operator ^ (const pdd &a, const pdd &b) {return a.x*b.y-a.y*b.x;}
DO len(const pdd &a) {return sqrtl(a*a);}
pdd rot(const pdd &a, const DO &alp) {
  return {a.x*cosl(alp)-a.y*sinl(alp), a.x*sinl(alp)+a.y*cosl(alp)};
}
DO alp(const pdd &a) {
  return atan2l(a.y, a.x);
}

const DO pi = acosl(-1);
const DO eps = 1e-10;
int sgn(const DO &a) {
  return a<-eps ? -1 : a>eps;
}

DO h, r, R;

pdd get(DO ax, DO ay) {
  pdd p = {ax, ay};
  DO len = ::len(p);
  if(sgn(len) == 0) {
    return {r, 0};
  }else {
    return p*(r/len);
  }
}

DO f(DO ax, DO ay, DO az, DO bx, DO by, DO bz) {
  pdd p, q;
  p = get(ax, ay);
  q = get(bx, by);
  if(sgn(p^q)<0) {
    swap(p, q);
    swap(ax, bx);
    swap(ay, by);
    swap(az, bz);
  }
  DO ap = alp(p);
  DO aq = alp(q);
  DO al = aq-ap;
  al=al*(r/R);
  DO a = sqrtl(sq(ax)+sq(ay)+sq(h-az));
  DO b = sqrtl(sq(bx)+sq(by)+sq(h-bz));
  DO c=sq(a)+sq(b)-2*a*b*cosl(al);
  c=max((DO)0, c);
  return sqrtl(c);
}

DO f1(DO ax, DO ay, DO bx, DO by, DO bz) {
  pdd p = get(ax, ay);
  pdd p1, p2;
  int step = 100;
  DO st=0, ed=pi*2, md1, md2, v1, v2;
  while(step--) {
    md1=(st+st+ed)/3;
    md2=(st+ed+ed)/3;
    p1=rot(p, md1);
    p2=rot(p, md2);
    v1=len(pdd(ax, ay)-p1)+f(p1.x, p1.y, 0, bx, by, bz);
    v2=len(pdd(ax, ay)-p2)+f(p2.x, p2.y, 0, bx, by, bz);
    if(v1<v2) {
      ed=md2;
    }else {
      st=md1;
    }
  }
  p1=rot(p, st);
  v1=len(pdd(ax, ay)-p1)+f(p1.x, p1.y, 0, bx, by, bz);
  return v1;
}

int main() {
#ifndef ONLINE_JUDGE
  freopen("in.in", "r", stdin);
  freopen("out.out", "w", stdout);
#endif
  cout<<fixed<<setprecision(9);
  cin>>r>>h;
  R = sqrtl(r*r+h*h);
  DO ax, ay, az, bx, by, bz;
  cin>>ax>>ay>>az>>bx>>by>>bz;
  if(sgn(az) == 0 && sgn(bz) == 0) {
    cout<<sqrtl(sq(ax-bx)+sq(ay-by))<<endl;
    return 0;
  }
  if(sgn(az) == 0) {
    cout<<f1(ax, ay, bx, by, bz)<<endl;
    return 0;
  }
  if(sgn(bz) == 0) {
    cout<<f1(bx, by, ax, ay, az)<<endl;
    return 0;
  }
  DO ans = f(ax, ay, az, bx, by, bz);
  pdd p = get(ax, ay);
  int step = 100;
  DO st=0, ed=pi*2, md1, md2, v1, v2;
  pdd p1, p2;
  while(step--) {
    md1=(st+st+ed)/3;
    md2=(st+ed+ed)/3;
    p1=rot(p, md1);
    p2=rot(p, md2);
    v1=f(p1.x, p1.y, 0, bx, by, bz)+f1(p1.x, p1.y, bx, by, bz);
    v2=f(p2.x, p2.y, 0, bx, by, bz)+f1(p2.x, p2.y, bx, by, bz);
    if(v1 < v2) {
      ed=md2;
    }else {
      st=md1;
    }
  }
  p1=rot(p, st);
  v1=f(p1.x, p1.y, 0, ax, ay, az)+f1(p1.x, p1.y, bx, by, bz);
  ans=min(ans, v1);
  cout<<ans<<endl;
  return 0;
}

#define pi 3.1415926535897932384626433832795

#include<bits/stdc++.h>

#define eps 1e-13

using namespace std;

typedef long double DO;

template<typename T, typename U> inline void smin(T &a, const U &b) {if(a>b) a=b;}

struct point {

	DO x, y, z;

	inline point(DO x=0, DO y=0, DO z=0) : x(x), y(y), z(z) {}

	inline point operator - (point a) {return point(x-a.x, y-a.y, z-a.z);}

	inline point operator + (point a) {return point(x+a.x, y+a.y, z+a.z);}

	inline point operator * (DO a) {return point(x*a, y*a, z*a);}

	inline point operator / (DO a) {return point(x/a, y/a, z/a);}

	inline DO operator * (point a) {return x*a.x+y*a.y+z*a.z;}

	inline point norm() {DO s=nor(); if(s<eps) return *this; return point(x/s, y/s, z/s);}

	inline DO nor() {return sqrtl(*this**this);}

	inline DO nor2() {return *this**this;}

	inline point rotate(DO al) {return *this&point(cosl(al), sinl(al), z);}

	inline point operator & (point a) {return point(x*a.x-y*a.y, x*a.y+y*a.x, z);}

	inline void input() {cin>>x>>y>>z;}

};

DO r, h, R, R2, len;

point focus, a, b, c, ac, A;

inline DO calc1(DO x) {

	point d=c.rotate(x/r);

	DO ans1=(A-d).nor();

	smin(x, len-x);

	DO D2=(b-focus).nor2(), D=sqrtl(D2);

	DO ans2=sqrtl(R2+D2-2*R*D*cosl(x/R));

	return ans1+ans2;

}

inline DO solve() {

	DO st=0, ed=len;

	while(ed-st>eps) {

		DO a=(st+st+ed)/3, b=(st+ed+ed)/3;

		if(calc1(a)>calc1(b)) st=a;

		else ed=b;

	}

	return calc1(st);

}

inline DO calc2(DO x) {

	A=ac.rotate(x/r);

	smin(x, len-x);

	DO D2=(a-focus).nor2(), D=sqrtl(D2);

	return sqrtl(R2+D2-2*R*D*cosl(x/R))+solve();

}

inline DO angle(point a, point b) {

	DO res=a*b/a.nor()/b.nor();

	res=acosl(res);

	return res;

}

inline DO kong() {

	DO aa2=(a-focus).nor2(), aa=sqrtl(aa2);

	DO bb2=(b-focus).nor2(), bb=sqrtl(bb2);

	DO x=angle(c, ac)*r;

	smin(x, len-x);

	return sqrtl(aa2+bb2-2*aa*bb*cosl(x/R));

}

main() {

#ifndef	ONLINE_JUDGE

	freopen("in.in", "r", stdin);

	freopen("out.out", "w", stdout);

#endif

	cin>>r>>h; a.input(), b.input();

	if(fabsl(b.z)<eps) swap(a, b);

	len=2*pi*r;

	R2=h*h+r*r, R=sqrtl(R2);

	focus=point(0, 0, h);

	c=focus+(b-focus).norm()*R;

	if(fabsl(a.z)<eps) {

		if(fabsl(b.z)<eps) printf("%.7lf", (double)(a-b).nor());

		else {

			A=a;

			printf("%.7lf", (double)solve());

		}

	}

	else {

		ac=focus+(a-focus).norm()*R;

		DO st=0, ed=len;

		while(ed-st>eps) {

			DO a=(st+st+ed)/3, b=(st+ed+ed)/3;

			if(calc2(a)>calc2(b)) st=a;

			else ed=b;

		}

		printf("%.7lf", (double)min((a-focus).nor()+(b-focus).nor(), min(kong(), calc2(st))));

	}

}

#include<bits/stdc++.h>
using namespace std;

typedef double DB;
const DB PI = acos(DB(-1));
const DB INF = 1e10;
const DB EPS = 1e-8;

inline DB sqr(DB x) {
	return x * x;
}

struct PT {
	DB x, y;

	PT() {}
	PT(DB x, DB y) : x(x), y(y) {}
	void in() {
		scanf("%lf%lf", &x, &y);
	}
};

bool operator<(const PT& p1, const PT& p2) {
	if (fabs(p1.x - p2.x) > EPS) return p1.x < p2.x;
	return p1.y + EPS < p2.y;
}

bool operator==(const PT& p1, const PT& p2) {
	return fabs(p1.x - p2.x) < EPS && fabs(p1.y - p2.y) < EPS;
}

PT operator+(PT p1, PT p2) {
	return PT(p1.x + p2.x, p1.y + p2.y);
}

PT operator-(PT p1, PT p2) {
	return PT(p1.x - p2.x, p1.y - p2.y);
}

PT operator*(PT p, DB c) {
	return PT(p.x * c, p.y * c);
}

PT operator/(PT p, DB c) {
	return PT(p.x / c, p.y / c);
}

DB dis(PT p) {
	return sqrt(sqr(p.x) + sqr(p.y));
}

DB dis2(PT p) {
	return sqr(p.x) + sqr(p.y);
}

DB dis2(PT p1, PT p2) {
	return sqr(p1.x - p2.x) + sqr(p1.y - p2.y);
}

DB dis(PT p1, PT p2) {
	return sqrt(dis2(p1, p2));
}

DB vect(PT p1, PT p2) {
	return p1.x * p2.y - p2.x * p1.y;
}

DB scal(PT p1, PT p2) {
	return p1.x * p2.x + p1.y * p2.y;
}

DB getAngle(PT p) {
	return atan2(p.y, p.x);
}

DB vect(PT p, PT p1, PT p2) {
	return vect(p1 - p, p2 - p);
}

DB scal(PT p, PT p1, PT p2) {
	return scal(p1 - p, p2 - p);
}

DB getAngle(PT p, PT p1, PT p2) {
	return getAngle(p2 - p) - getAngle(p1 - p);
}

DB getAngle180(PT p, PT p1, PT p2) {
	return acos(scal(p, p1, p2) / dis(p, p1) / dis(p, p2));
}

DB disToLine(PT p, PT p1, PT p2) {
	return fabs(vect(p, p1, p2)) / dis(p1, p2);
}

DB disToSeg(PT p, PT p1, PT p2) {
	if (scal(p1, p, p2) < 0) return dis(p, p1);
	if (scal(p2, p, p1) < 0) return dis(p, p2);
	return disToLine(p, p1, p2);
}

bool onLine(PT p, PT p1, PT p2) {
	return fabs(vect(p1 - p, p2 - p)) < EPS;
}

bool onSeg(PT p, PT p1, PT p2) {
	if (!onLine(p, p1, p2)) return 0;
	return (p1.x - p.x) * (p2.x - p.x) < EPS && (p1.y - p.y) * (p2.y - p.y) < EPS;
}

PT projection(PT a, PT b, PT p) {
	return a + (a - b) * scal(p - a, a - b) / dis2(a - b);
}

int posLineLine(PT p1, PT p2, PT p3, PT p4, PT& p) {
	DB s1 = vect(p1, p2, p3), s2 = vect(p1, p2, p4);
	if (fabs(s1 - s2) < EPS) {
		if (fabs(s1) < EPS) return 2;
		return 0;
	}
	p = p3 + (p4 - p3) * s1 / (s1 - s2);
	return 1;
}

int posCirLine(PT p, DB r, PT p1, PT p2, PT *q) {
	DB a, b, c, d2, d;
	a = dis2(p1, p2);
	b = scal(p1, p, p2);
	c = dis2(p, p1) - sqr(r);
	d2 = sqr(b) - a * c;
	if (d2 < -EPS) return 0;
	d = sqrt(fabs(d2));
	q[0] = p1 + (p2 - p1) * (b + d) / a;
	if (d2 < EPS) return 1;
	q[1] = p1 + (p2 - p1) * (b - d) / a;
	return 2;
}

int posCirCir(PT p1, DB r1, PT p2, DB r2, PT *q) {
	DB dx, dy, d, e, f2, f;
	dx = p2.x - p1.x, dy = p2.y - p1.y;
	d = dis(p1, p2);
	e = (sqr(r1) - sqr(r2) + sqr(d)) / 2 / d;
	f2 = sqr(r1) - sqr(e);
	if (f2 < -EPS) return 0;
	f = sqrt(fabs(f2));
	q[0] = PT(p1.x + (e * dx - f * dy) / d, p1.y + (e * dy + f * dx) / d);
	if (f2 < EPS) return 1;
	q[1] = PT(p1.x + (e * dx + f * dy) / d, p1.y + (e * dy - f * dx) / d);
	return 2;
}

DB calcArea(PT *p, int n) {
	DB rlt = 0;
	for (int i = 0; i < n; i++) rlt += vect(p[i], p[(i + 1) % n]);
	return rlt / 2;
}

int inPolygon(PT p, PT *q, int m) {
	PT p1, p2;
	int k = 0;
	for (int i = 0; i < m; i++) {
		p1 = q[i], p2 = q[(i + 1) % m];
		if (onSeg(p, p1, p2)) return 2;
		if (p1.y > p2.y) swap(p1, p2);
		if (p1.y < p.y + EPS && p.y + EPS < p2.y && vect(p, p1, p2) > 0) k++;
	}
	return k % 2;
}

int convex_hull(PT *p, int n, PT *q) {
	sort(p, p + n);
	n = unique(p, p + n) - p;
	if (n == 1) {
		q[0] = p[0];
		return 1;
	}
	int m = 0;
	for (int i = 0; i < n; i++) {
		while (m > 1 && vect(q[m - 2], q[m - 1], p[i]) < EPS) m--;
		q[m++] = p[i];
	}
	int k = m;
	for (int i = n - 2; i >= 0; i--) {
		while (m > k && vect(q[m - 2], q[m - 1], p[i]) < EPS) m--;
		q[m++] = p[i];
	}
	return --m;
}

PT P[2];
DB r, h, z[2];

DB calc(PT A, PT B, DB a, DB b) {
	DB d1 = sqrt(dis2(A) + sqr(h - a));
	DB d2 = sqrt(dis2(B) + sqr(h - b));
	DB ang = getAngle(A) - getAngle(B);
	while (ang < 0) ang += 2 * PI;
	while (ang > 2 * PI) ang -= 2 * PI;
	if (ang > PI) ang = 2 * PI - ang;
	ang = ang * r / sqrt(sqr(r) + sqr(h));
	return sqrt(sqr(d1) + sqr(d2) - 2 * cos(ang) * d1 * d2);
}

DB calc(DB ang) {
	PT C = PT(r * cos(ang), r * sin(ang));
	return calc(P[1], C, z[1], 0) + dis(C, P[0]);
}

int main() {
//	freopen("in.txt", "r", stdin);
	scanf("%lf%lf", &r, &h);
	for (int i = 0; i < 2; i++) P[i].in(), scanf("%lf", &z[i]);
	if (z[0] > z[1]) swap(P[0], P[1]), swap(z[0], z[1]);
	if (z[1] < EPS) return printf("%.10lf\n", dis(P[0], P[1])), 0;
	if (z[0] > EPS) return printf("%.10lf\n", calc(P[0], P[1], z[0], z[1])), 0;
	DB step = PI / 10;
	DB ma = INF, which;
	for (DB now = -PI; now < PI - EPS; now += step) {
		DB ret = calc(now);
		if (ma > ret) {
			ma = ret;
			which = now;
		}
	}
	DB st = which - PI / 5, en = which + PI / 5;
	for (int times = 0; times < 100; times++) {
		DB md1 = (st + st + en) / 3, md2 = (st + en + en) / 3;
		if (calc(md1) < calc(md2)) en = md2;
		else st = md1;
	}
	printf("%.10lf\n", calc(st));
}

#include <bits/stdc++.h>

#define inf 0x3f3f3f3f

#define MOD 1000000007

#define pb push_back

#define sq(x) ((x)*(x))

#define x first

#define y second

#define eps 1e-12

#define bpt(x) (__builtin_popcount(x))

#define bptl(x) (__builtin_popcountll(x))

#define bit(x, y) (((x)>>(y))&1)

#define bclz(x) (__builtin_clz(x))

#define bclzl(x) (__builtin_clzll(x))

#define bctz(x) (__builtin_ctz(x))

#define bctzl(x) (__builtin_ctzll(x))

#define sgn(x) (((x)>eps)-((x)<-eps))

#define PQ priority_queue<pii, vector<pii>, greater<pii> >

using namespace std;

typedef long long INT;

typedef vector<int> VI;

typedef pair<int, int> pii;

typedef pair<pii, int> pi3;

typedef long double DO;

template<typename T, typename U> inline void smin(T &a, U b) {if (a>b) a=b;}

template<typename T, typename U> inline void smax(T &a, U b) {if (a<b) a=b;}

template<class T>inline void gn(T &x) {char c, sg=0; while (c=getchar(), (c>'9' || c<'0') && c!='-');for((c=='-'?sg=1, c=getchar():0), x=0; c>='0' && c<='9'; c=getchar()) x=(x<<1)+(x<<3)+c-'0';if (sg) x=-x;}

template<class T, class T1>inline void gn(T &x, T1 &y) {gn(x); gn(y);}

template<class T, class T1, class T2>inline void gn(T &x, T1 &y, T2 &z) {gn(x); gn(y); gn(z);}

template<class T>inline void print(T x) {if (x<0) {putchar('-');return print(-x);}if (x<10) {putchar('0'+x);return;} print(x/10);putchar(x%10+'0');}

template<class T>inline void printsp(T x) {print(x); putchar(' ');}

template<class T>inline void println(T x) {print(x); putchar('\n');}

template<class T, class U>inline void print(T x, U y) {printsp(x); println(y);}

template<class T, class U, class V>inline void print(T x, U y, V z) {printsp(x); printsp(y); println(z);}

int power(int a, int b, int m, int ans=1) {

	for (; b; b>>=1, a=1LL*a*a%m) if (b&1) ans=1LL*ans*a%m;

	return ans;

}

struct point {

	DO x, y, z;

	point (DO x=0, DO y=0, DO z=0) : x(x), y(y), z(z) {}

	point operator - (point a) {return point(x-a.x, y-a.y, z-a.z);}

	point operator + (point a) {return point(x+a.x, y+a.y, z+a.z);}

	point operator * (DO a) {return point(x*a, y*a, z*a);}

	point operator / (DO a) {return point(x/a, y/a, z/a);}

	point operator ^ (point a) {return point(y*a.z-z*a.y, -(x*a.z-z*a.x), x*a.y-y*a.x);}

	DO    operator * (point a) {return x*a.x+y*a.y+z*a.z;}

	point norm() {DO s=nor(); if (s<eps) return *this; return point(x/s, y/s, z/s);}

	DO nor() {return sqrtl(*this**this);}

	bool operator < (const point &a) const {

		if (fabsl(x-a.x)>eps) return x<a.x;

		if (fabsl(y-a.y)>eps) return y<a.y;

		return z<a.z-eps;

	}

	bool operator > (const point &a) const {

		if (fabsl(x-a.x)>eps) return x>a.x;

		if (fabsl(y-a.y)>eps) return y>a.y;

		return z>a.z-eps;

	}

	bool operator == (const point &a) const {

		if (fabsl(x-a.x)>eps) return 0;

		if (fabsl(y-a.y)>eps) return 0;

		return fabs(z-a.z)<eps;

	}

	void input() {cin>>x>>y>>z;}

	void print() {printf("%lf %lf %lf\n", (double)x, (double)y, (double)z);}

};

void print_ans(DO x) {

	cout<<fixed<<setprecision(15)<<x<<endl;

	exit(0);

}

DO L, pi;

DO calc(point &a, DO &lb, DO &phib, DO &r, DO &al) {

	DO be=al*L/r;

	DO ans=(a-point(r*cosl(be), r*sinl(be), 0)).nor();

	return ans+sqrtl(max((DO)0, (L*L+lb*lb-2*lb*L*cosl(al-phib))));

}

DO ST[1111];

int main() {

#ifndef ONLINE_JUDGE

	freopen("in.in", "r", stdin);

	freopen("out.out", "w", stdout);

#endif

	point a, b;

	DO r, h;

	cin>>r>>h;

	a.input(); b.input();

	L=sqrtl(r*r+h*h), pi=acosl(-1.0);

	point H=point(0, 0, h);

	if (a.z<eps && b.z<eps) print_ans((a-b).nor());

	if (a.z>b.z+eps) swap(a, b);

	if (b.z>h-eps) {

		if (a.z>h-eps) print_ans((DO)0.0);

		if (a.z<eps) print_ans(L+r-a.nor());

		print_ans((H-a).nor());

	}

	if (a.z>eps) {

		DO al=atan2l(a.y, a.x);

		DO be=atan2l(b.y, b.x);

		if (al<0) al+=2*pi;

		if (be<0) be+=2*pi;

		DO la=(H-a).nor();

		DO lb=(H-b).nor();

		DO phia=al*r/L, phib=be*r/L;

		print_ans(sqrtl(max((DO)0.0, (H-a)*(H-a)+(H-b)*(H-b)-2*la*lb*cosl(phia-phib))));

	}

	DO al=atan2l(a.y, a.x);

	DO be=atan2l(b.y, b.x);

	if (al<0) al+=2*pi;

	if (be<0) be+=2*pi;

	DO lb=(H-b).nor();

	DO phib=be*r/L;

	DO ans=(DO)1e100;

	for (int j=0; j<6; j++) {

		DO st=pi/3*j, ed=st+pi/2;

		for (int i=0; i<200; i++) {

			DO x1=(st*2+ed)/3, x2=(st+ed*2)/3;

			if (calc(a, lb, phib, r, x1)<calc(a, lb, phib, r, x2)) ed=x2;

			else st=x1;

		}

		smin(ans, calc(a, lb, phib, r, st));

	}

	print_ans(ans);

	return 0;

}

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <climits>
#include <cstring>
#include <string>
#include <vector>
#include <stack>
#include <queue>
#include <set>
#include <map>
#include <algorithm>

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;
/*    printf("aTheta=%.9lf\n", aTheta * 180.0 / pi);
    printf("bTheta=%.9lf\n", bTheta * 180.0 / pi);
    printf("alpha=%.9lf\n", alpha * 180.0 / pi);
*/
    if(isGreaterThan((aTheta - bTheta), alpha / 2.0))
    {
        // find mirror and do shieat
        aTheta = bTheta + (alpha - aTheta + bTheta);
    }

    return euclideanDistance(a.second * cos(aTheta), a.second * sin(aTheta),
                             b.second * cos(bTheta), b.second * sin(bTheta));
}

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;
        }
    }

    minDegree = atan2(yHi, xHi);
    left = minDegree - aDegree * 64;
    right = minDegree + aDegree * 64;

    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 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;

    x = r * cos(left);
    y = r * sin(left);
    minDegree = left;
    minVal = findConeSurfaceDistance(x1, y1, z1, x, y, 0.0) +
             findOptimalSingleBrinkPointDistance(x2, y2, z2, x, y, 0.0);

    for(left = aDegree; left < right; left += aDegree)
    {
        x = r * cos(left);
        y = r * sin(left);
        curr = findConeSurfaceDistance(x1, y1, z1, x, y, 0.0) +
               findOptimalSingleBrinkPointDistance(x2, y2, z2, x, y, 0.0);
        if(curr < minVal)
        {
            minVal = curr;
            minDegree = left;
        }
    }

    minDegree = atan2(y1, x1);
    left = minDegree - aDegree * 4;
    right = minDegree + aDegree * 4;

    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);
//        printf("middle=%.9lf - x=%.9lf - y=%.9lf\n", middle * 180.0 / pi, x, y);
//        cout << "middle=" << middle * 180.0 / pi << " - leftVal=" << leftVal << " - rightVal=" << rightVal << " - midVal=" << midVal << endl;
        if(leftVal > rightVal)
        {
            leftVal = midVal;
            left = middle;
        }
        else
        {
            rightVal = midVal;
            right = middle;
        }
    }
    return min(leftVal, rightVal);
}

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;
}

#define pi 3.1415926535897932384626433832795

#include<bits/stdc++.h>

#define eps 1e-7

typedef double DO;

using namespace std;

template<typename T, typename U> inline void smin(T &a, const U &b) {if(a>b) a=b;}

struct point {

	DO x, y, z;

	inline point(DO x=0, DO y=0, DO z=0) : x(x), y(y), z(z) {}

	inline point operator - (point a) {return point(x-a.x, y-a.y, z-a.z);}

	inline point operator + (point a) {return point(x+a.x, y+a.y, z+a.z);}

	inline point operator * (DO a) {return point(x*a, y*a, z*a);}

	inline point operator / (DO a) {return point(x/a, y/a, z/a);}

	inline DO operator * (point a) {return x*a.x+y*a.y+z*a.z;}

	inline point norm() {DO s=nor(); if(s<eps) return *this; return point(x/s, y/s, z/s);}

	inline DO nor() {return sqrtl(*this**this);}

	inline DO nor2() {return *this**this;}

	inline point rotate(DO al) {return *this&point(cosl(al), sinl(al), z);}

	inline point operator & (point a) {return point(x*a.x-y*a.y, x*a.y+y*a.x, z);}

	inline void input() {scanf("%lf %lf %lf", &x, &y, &z);}

};

DO r, h, R, R2, len;

point focus, a, b, c, ac, A;

inline DO calc1(DO x) {

	point d=c.rotate(x/r);

	DO ans1=(A-d).nor();

	smin(x, len-x);

	DO D2=(b-focus).nor2(), D=sqrtl(D2);

	DO ans2=sqrtl(R2+D2-2*R*D*cosl(x/R));

	smin(ans2, (d-focus).nor()+D);

	return ans1+ans2;

}

inline DO solve() {

	DO st=0, ed=len;

	while(ed-st>eps) {

		DO a=(st+st+ed)/3, b=(st+ed+ed)/3;

		if(calc1(a)>calc1(b)) st=a;

		else ed=b;

	}

	return calc1(st);

}

inline DO calc2(DO x) {

	A=ac.rotate(x/r);

	smin(x, len-x);

	DO D2=(a-focus).nor2(), D=sqrtl(D2);

	return sqrtl(R2+D2-2*R*D*cosl(x/R)) + calc1(0);

}

inline DO angle(point a, point b) {

	DO res=a*b/a.nor()/b.nor();

	res=acosl(res);

	return res;

}

inline DO kong() {

	DO aa2=(a-focus).nor2(), aa=sqrtl(aa2);

	DO bb2=(b-focus).nor2(), bb=sqrtl(bb2);

	DO x=angle(c, ac)*r;

	smin(x, len-x);

	return sqrtl(aa2+bb2-2*aa*bb*cosl(x/R));

}

main() {

#ifndef	ONLINE_JUDGE

	freopen("in.in", "r", stdin);

	freopen("out.out", "w", stdout);

#endif

	cin>>r>>h; a.input(), b.input();

	if(fabsl(b.z)<eps) swap(a, b);

	len=2*pi*r;

	R2=h*h+r*r, R=sqrtl(R2);

	focus=point(0, 0, h);

	c=focus+(b-focus).norm()*R;

	if(fabsl(a.z)<eps) {

		if(fabsl(b.z)<eps) printf("%.7lf", (a-b).nor());

		else {

			A=a;

			printf("%.7lf", solve());

		}

	}

	else {

		ac=focus+(a-focus).norm()*R;

		printf("%.7lf", (double)min(kong(), calc2(0)));

	}

}

#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <string>
#include <set>
#include <vector>
#include <cmath>
#include <cassert>
#include <cstdlib>
#include <map>
#include <queue>
#include <deque>
#include <bitset>

#define y0 y63475625
#define y1 y28435
#define j0 jfd0sf
#define j1 je90ue0
#define sqr(x) ((x)*(x))
#define fi first
#define se second
#define pb push_back
#define mp make_pair
#define re return
#define sz(x) ((int)(x).size())
#define all(x) (x).begin(), (x).end()
#define rep(i, n) for (int i = 0; i < (n); i++)
#define rrep(i, n) for (int i = (n) - 1; i >= 0; i--)
#define sqrt(x) (sqrt(abs(x)))
#define fill(a, x) memset(a, x, sizeof(a))

using namespace std;

typedef vector <int> vi;
typedef vector <vi> vvi;
typedef long long ll;
typedef long double ld;
typedef pair <int, int> ii;
typedef vector <ii> vii;
typedef double D;
typedef pair <ll, ll> pll;
typedef vector <string> vs;

template <class T> T abs(const T a) {
    return a > 0 ? a : -a;
}

const double PI = 2.0 * acos(1.0);

const ld eps = 1e-12;

ld alpha;

int n;
int m;

ld dist(ld xa, ld ya, ld xb, ld yb) {
    ld ra = sqrt(sqr(xa) + sqr(ya));
    ld rb = sqrt(sqr(xb) + sqr(yb));
    if (abs(xa) < eps && abs(ya) < eps) {
        re rb * alpha;
    }
    if (abs(xb) < eps && abs(yb) < eps) {
        re ra * alpha;
    }

    double angle = acos((xa * xb + ya * yb) / ra / rb);
    if (fabs(angle) < eps)
        re abs(rb - ra) * alpha;
    ld co = rb * sin(angle / alpha);
    ld si = (ra - rb * cos(angle / alpha));
    ld f0 = alpha * atan2(si, co);
    ld a = 1.0 / (ra * cos(f0 / alpha));
    /*cerr << ra << ' ' << 1.0 / (a * cos(f0 / alpha)) << endl;
    cerr << rb << ' ' << 1.0 / (a * cos((angle - f0) / alpha)) << endl;
    cerr.precision(20);
    cerr << a << ' ' << f0 << ' ' << alpha << endl;*/
    re abs(alpha / a * (tan((angle - f0) / alpha) + tan(f0 / alpha)));
}

int main()
{
    ld r, h;
    cin >> r >> h;
    ld xa, ya, za, xb, yb, zb;
    cin >> xa >> ya >> za;
    cin >> xb >> yb >> zb;
    if (abs(zb) < eps && abs(za) < eps) {
        printf("%.10lf\n", (D)sqrt(sqr(xb - xa) + sqr(yb - ya)));
        re 0;
    }
    if (abs(zb) < eps) {
        swap(xa, xb);
        swap(ya, yb);
        swap(za, zb);
    }

    alpha = sqrt(1.0 + sqr(h / r));
    if (abs(za) > eps && abs(zb) > eps) {
        ld ans = dist(xa, ya, xb, yb);
        ld fans1 = -1, fans2 = -1;
        rep(i, 2) {
            ld L1 = 0.0, R1 = 2.0 * M_PI;
            ld L2 = 0.0, R2 = 2.0 * M_PI;
            n = 600;
            rep(j, n) {
                ld f1 = L1 + (R1 - L1) * j / (ld)n;
                rep(k, n) {
                    ld f2 = L2 + (R2 - L2) * k / (ld)n;
                    ld x1 = r * cos(f1), y1 = r * sin(f1), x2 = r * cos(f2), y2 = r * sin(f2);
                    ld tmp = sqrt(sqr(x1 - x2) + sqr(y1 - y2)) + dist(xa, ya, x1, y1) + dist(x2, y2, xb, yb);
                    if (tmp < ans) {
                        ans = tmp;
                        fans1 = f1;
                        fans2 = f2;
                    }
                }
            }
            ld d = R1 - L1;
            L1 = fans1 - d / 2.0 * 0.3;
            L2 = fans2 - d / 2.0 * 0.3;
            R1 = fans1 + d / 2.0 * 0.3;
            R2 = fans2 + d / 2.0 * 0.3;
        }
        printf("%.10lf\n", (D)ans);
        re 0;
    } else {
        //todo
        ld L = 0.0, R = 2.0 * M_PI;
        ld ans = 1e20;
        ld fans = -1;
        rep(i, 2000) {
            rep(j, 100) {
                double f = L + (R - L) / 100.0 * j;
                ld x = r * cos(f);
                ld y = r * sin(f);
                ld tmp = sqrt(sqr(xa - x) + sqr(ya - y)) + dist(x, y, xb, yb);
                if (tmp < ans) {
                    ans = tmp;
                    fans = f;
                }
            }
            ld d = R - L;
            L = fans - d / 2.0 * 0.9;
            R = fans + d / 2.0 * 0.9;
        }
        printf("%.10lf\n", (D)ans);
    }
    return 0;
}

#include<stdio.h>
#include<math.h>
#include<algorithm>
#include<stdlib.h>
#include<string.h>
#include<string>
using namespace std;
typedef double db;
const db pi=acos(-1),eps=1e-1;
struct p{
    db x,y,z;
}a,b,c,v;
void set(p&a,db x,db y,db z){
    a.x=x;a.y=y;a.z=z;
}
void swap(db&a,db&b){
    db c=a;a=b;b=c;
}
db sqr(db a){
    return a*a;
}
void swap(p&a,p&b){
    p c=a;a=b;b=c;
}
db r,h,l,z;
db dis(p a,p b){
    return sqrt(sqr(a.x-b.x)+sqr(a.y-b.y)+sqr(a.z-b.z));
}
db abs(db x){
    if(x<0)return -x;
    return x;
}
db cc(db a,db b,db z){
    return sqrt(sqr(a)+sqr(b)-2*cos(z)*a*b);
}
db aa(p a){
    return atan2(a.y,a.x);
}
db zt(p a,p b){
    db z=abs(aa(a)-aa(b));
    return min(z,2*pi-z);
}
db zt(db z){
    return z*r/l;
}
db diss(p a,p b){
    return cc(dis(a,v),dis(b,v),zt(zt(a,b)));
}
db rt(p&a,db z){
    set(a,a.x*cos(z)-a.y*sin(z),a.x*sin(z)+a.y*cos(z),a.z);
}
p rp(db z){
    p o;
    set(o,r*cos(z),r*sin(z),0);
    return o;
}
db ff(p a,p b,db z){
    p o=rp(z);
    return diss(b,o)+dis(a,o);
}
db fff(p a,p b,db z){
    p o=rp(z);
    db ll=min(z,aa(b))-eps,rr=max(z,aa(b))+eps,m1,m2;
    for(int i=200;i;i--){
        m1=ll+(rr-ll)*0.49;
        m2=ll+(rr-ll)*0.51;
        if(ff(o,b,m1)<ff(o,b,m2))rr=m2;else ll=m1;
    }
    return diss(a,o)+ff(o,b,ll);
}
int main(){
    scanf("%lf%lf",&r,&h);
    scanf("%lf%lf%lf",&a.x,&a.y,&a.z);
    scanf("%lf%lf%lf",&b.x,&b.y,&b.z);
    if(a.z==0&&b.z==0){
        printf("%.15lf\n",dis(a,b));
        return 0;
    }
    set(v,0,0,h);
    l=sqrt(sqr(r)+sqr(h));
    if(a.z> 0&&b.z> 0){
        db lll=min(aa(a),aa(b))-eps,rrr=max(aa(a),aa(b))+eps,m1,m2;
        for(int i=200;i;i--){
            m1=lll+(rrr-lll)*0.49;
            m2=lll+(rrr-lll)*0.51;
            if(fff(a,b,m1)<fff(a,b,m2))rrr=m2;else lll=m1;
        }
   //         printf("%.15lf\n%.15lf\n",diss(a,b),fff(a,b,lll));
        printf("%.15lf\n",min(diss(a,b),fff(a,b,lll)));
        return 0;
    }
    if(b.z==0)swap(a,b);
    rt(b,-aa(a));
    set(a,sqrt(sqr(a.x)+sqr(a.y)),0,0);
    if(b.y<0)set(b,b.x,-b.y,b.z);
    db ll=0,rr=aa(b),m1,m2;
    for(int i=200;i;i--){
        m1=ll+(rr-ll)*0.49;
        m2=ll+(rr-ll)*0.51;
        if(ff(a,b,m1)<ff(a,b,m2))rr=m2;else ll=m1;
    }
    printf("%.15lf\n",ff(a,b,ll));
    return 0;
}

#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <string>
#include <set>
#include <vector>
#include <cmath>
#include <cassert>
#include <cstdlib>
#include <map>
#include <queue>
#include <deque>
#include <bitset>

#define y0 y63475625
#define y1 y28435
#define j0 jfd0sf
#define j1 je90ue0
#define sqr(x) ((x)*(x))
#define fi first
#define se second
#define pb push_back
#define mp make_pair
#define re return
#define sz(x) ((int)(x).size())
#define all(x) (x).begin(), (x).end()
#define rep(i, n) for (int i = 0; i < (n); i++)
#define rrep(i, n) for (int i = (n) - 1; i >= 0; i--)
#define sqrt(x) (sqrt(abs(x)))
#define fill(a, x) memset(a, x, sizeof(a))

using namespace std;

typedef vector <int> vi;
typedef vector <vi> vvi;
typedef long long ll;
typedef long double ld;
typedef pair <int, int> ii;
typedef vector <ii> vii;
typedef double D;
typedef pair <ll, ll> pll;
typedef vector <string> vs;

template <class T> T abs(const T a) {
    return a > 0 ? a : -a;
}

const double PI = 2.0 * acos(1.0);

const ld eps = 1e-12;

ld alpha;

int n;
int m;

ld dist(ld xa, ld ya, ld xb, ld yb) {
    ld ra = sqrt(sqr(xa) + sqr(ya));
    ld rb = sqrt(sqr(xb) + sqr(yb));
    if (abs(xa) < eps && abs(ya) < eps) {
        re rb * alpha;
    }
    if (abs(xb) < eps && abs(yb) < eps) {
        re ra * alpha;
    }

    double angle = acos((xa * xb + ya * yb) / ra / rb);
    if (fabs(angle) < eps)
        re abs(rb - ra) * alpha;
    ld co = rb * sin(angle / alpha);
    ld si = (ra - rb * cos(angle / alpha));
    ld f0 = alpha * atan2(si, co);
    ld a = 1.0 / (ra * cos(f0 / alpha));
    re abs(alpha / a * (tan((angle - f0) / alpha) + tan(f0 / alpha)));
}

int main()
{
    ld r, h;
    cin >> r >> h;
    ld xa, ya, za, xb, yb, zb;
    cin >> xa >> ya >> za;
    cin >> xb >> yb >> zb;
    if (abs(zb) < eps && abs(za) < eps) {
        printf("%.10lf\n", (D)sqrt(sqr(xb - xa) + sqr(yb - ya)));
        re 0;
    }
    if (abs(zb) < eps) {
        swap(xa, xb);
        swap(ya, yb);
        swap(za, zb);
    }

    alpha = sqrt(1.0 + sqr(h / r));
    if (abs(za) > eps && abs(zb) > eps) {
        printf("%.10lf\n", (D)dist(xa, ya, xb, yb));
    } else {
        //todo
        ld L = 0.0, R = 2.0 * M_PI;
        ld ans = 1e20;
        ld fans = -1;
        rep(i, 2000) {
            rep(j, 100) {
                double f = L + (R - L) / 100.0 * j;
                ld x = r * cos(f);
                ld y = r * sin(f);
                ld tmp = sqrt(sqr(xa - x) + sqr(ya - y)) + dist(x, y, xb, yb);
                if (tmp < ans) {
                    ans = tmp;
                    fans = f;
                }
            }
            ld d = R - L;
            L = fans - d / 2.0 * 0.9;
            R = fans + d / 2.0 * 0.9;
        }
        printf("%.10lf\n", (D)ans);
    }
    return 0;
}

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <climits>
#include <cstring>
#include <string>
#include <vector>
#include <stack>
#include <queue>
#include <set>
#include <map>
#include <algorithm>

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 z1, double x2, double y2, double z2)
{
    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;
/*    printf("aTheta=%.9lf\n", aTheta * 180.0 / pi);
    printf("bTheta=%.9lf\n", bTheta * 180.0 / pi);
    printf("alpha=%.9lf\n", alpha * 180.0 / pi);
*/
    if(isGreaterThan((aTheta - bTheta), alpha / 2.0))
    {
        // find mirror and do shieat
        aTheta = bTheta + (alpha - aTheta + bTheta);
    }

    return euclideanDistance(a.second * cos(aTheta), a.second * sin(aTheta), 0.0,
                             b.second * cos(bTheta), b.second * sin(bTheta), 0.0);
}

double sortaBinarySearch(double left, double right,
                         double xHi, double yHi, double zHi,
                         double xLo, double yLo, double zLo,
                         double (*distCalculator)(double, double, double,
                                                  double, double, double,
                                                  double, double, double))
{
    double x, y, leftVal, rightVal, middle, midVal;

    x = r * cos(left);
    y = r * sin(left);
    leftVal = distCalculator(xHi, yHi, zHi, xLo, yLo, zLo, x, y, 0.0);
    x = r * cos(right);
    y = r * sin(right);
    rightVal = distCalculator(xHi, yHi, zHi, xLo, yLo, zLo, x, y, 0.0);

    while(!isZero(right - left))
    {
        middle = (left + right) / 2.0;
        x = r * cos(middle);
        y = r * sin(middle);
        midVal = distCalculator(xHi, yHi, zHi, xLo, yLo, zLo, x, y, 0.0);
        if(leftVal > rightVal)
        {
            leftVal = midVal;
            left = middle;
        }
        else
        {
            rightVal = midVal;
            right = middle;
        }
    }
    return min(leftVal, rightVal);
}

double singleBrinkDist(double xHi, double yHi, double zHi,
                       double xLo, double yLo, double zLo,
                       double x, double y, double z)
{
    return euclideanDistance(x, y, 0.0, xLo, yLo, 0.0) +
           findConeSurfaceDistance(xHi, yHi, zHi, x, y, 0.0);
}

double findOptimalSingleBrinkPointDistance(double xHi, double yHi, double zHi,
                                           double xLo, double yLo, double zLo)
{
    double minDegree, minVal, aDegree = pi / 180.0;

    minDegree = atan2(yHi, xHi);
    minVal = sortaBinarySearch(minDegree + aDegree, minDegree + aDegree,
                               xHi, yHi, zHi, xLo, yLo, zLo, &singleBrinkDist);
    minVal = min(minVal, sortaBinarySearch(minDegree - 2.0 * aDegree, minDegree + 2.0 * aDegree,
                                           xHi, yHi, zHi, xLo, yLo, zLo, &singleBrinkDist));
    minVal = min(minVal, sortaBinarySearch(minDegree - 3.0 * aDegree, minDegree + 3.0 * aDegree,
                                           xHi, yHi, zHi, xLo, yLo, zLo, &singleBrinkDist));
    minVal = min(minVal, sortaBinarySearch(minDegree - 4.0 * aDegree, minDegree + 4.0 * aDegree,
                                           xHi, yHi, zHi, xLo, yLo, zLo, &singleBrinkDist));
    return minVal;
}

double doubleBrinkDist(double x1, double y1, double z1,
                       double x2, double y2, double z2,
                       double x, double y, double z)
{
    return findConeSurfaceDistance(x1, y1, z1, x, y, 0.0) +
           findOptimalSingleBrinkPointDistance(x2, y2, z2, x, y, 0.0);
}

double findOptimalDistance(double x1, double y1, double z1,
                           double x2, double y2, double z2,
                           double (*distCalculator)(double, double, double,
                                                    double, double, double,
                                                    double, double, double))
{
    double minDegree, minVal, aDegree = pi / 180.0;

    minDegree = atan2(y1, x1);
    minVal = 1000000007.0;
    for(int i=1; i <= 180; ++i)
    {
        minVal = min(minVal, sortaBinarySearch(minDegree - i * aDegree, minDegree + i * aDegree,
                                               x1, y1, z1, x2, y2, z2, distCalculator));
    }
    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 = findOptimalDistance(x2, y2, z2, x1, y1, z1, &singleBrinkDist);
            if(isZero(x1 * x1 + y1 * y1 - r * r))
                res = min(res, findConeSurfaceDistance(x1, y1, z1, x2, y2, z2));
        }
    }
    else if(pt2OnBase)
    {
        res = findOptimalDistance(x1, y1, z1, x2, y2, z2, &singleBrinkDist);
        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, findOptimalDistance(x1, y1, z1, x2, y2, z2, &doubleBrinkDist));
    }

    printf("%.9lf\n", res);

    return 0;
}

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <climits>
#include <cstring>
#include <string>
#include <vector>
#include <stack>
#include <queue>
#include <set>
#include <map>
#include <algorithm>

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;
/*    printf("aTheta=%.9lf\n", aTheta * 180.0 / pi);
    printf("bTheta=%.9lf\n", bTheta * 180.0 / pi);
    printf("alpha=%.9lf\n", alpha * 180.0 / pi);
*/
    if(isGreaterThan((aTheta - bTheta), alpha / 2.0))
    {
        // find mirror and do shieat
        aTheta = bTheta + (alpha - aTheta + bTheta);
    }

    return euclideanDistance(a.second * cos(aTheta), a.second * sin(aTheta),
                             b.second * cos(bTheta), b.second * sin(bTheta));
}

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;

    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 sortaBinarySearch(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);
//        printf("middle=%.9lf - left=%.9lf - right=%.9lf\n", middle * 180.0 / pi, left * 180.0/pi, right * 180.0/ pi);
//        printf("x=%.9lf - y=%.9lf\n", x, y);
//        cout << "leftVal=" << leftVal << " - rightVal=" << rightVal << " - midVal=" << midVal << endl;
        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;

    x = r * cos(left);
    y = r * sin(left);
    minDegree = left;
    minVal = findConeSurfaceDistance(x1, y1, z1, x, y, 0.0) +
             findOptimalSingleBrinkPointDistance(x2, y2, z2, x, y, 0.0);

    for(left = aDegree; left < right; left += aDegree)
    {
        x = r * cos(left);
        y = r * sin(left);
        curr = findConeSurfaceDistance(x1, y1, z1, x, y, 0.0) +
               findOptimalSingleBrinkPointDistance(x2, y2, z2, x, y, 0.0);
        if(curr < minVal)
        {
            minVal = curr;
            minDegree = left;
        }
    }

   minDegree = atan2(y1, x1);
    minVal = sortaBinarySearch(minDegree - aDegree, minDegree + aDegree, x1, y1, z1, x2, y2, z2);
    minVal = min(minVal, sortaBinarySearch(minDegree - 2 * aDegree, minDegree + 2 * aDegree, x1, y1, z1, x2, y2, z2));
    minVal = min(minVal, sortaBinarySearch(minDegree - 4 * aDegree, minDegree + 4 * aDegree, x1, y1, z1, x2, y2, z2));
    minVal = min(minVal, sortaBinarySearch(minDegree - 8 * aDegree, minDegree + 8 * aDegree, x1, y1, z1, x2, y2, z2));
    minVal = min(minVal, sortaBinarySearch(minDegree - 16 * aDegree, minDegree + 16 * aDegree, x1, y1, z1, x2, y2, z2));
    minVal = min(minVal, sortaBinarySearch(minDegree - 32 * aDegree, minDegree + 32 * aDegree, x1, y1, z1, x2, y2, z2));
    minVal = min(minVal, sortaBinarySearch(minDegree - 64 * aDegree, minDegree + 64 * aDegree, x1, y1, z1, x2, y2, z2));

}

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;
}

#pragma comment(linker, "/STACK:65777216")

#include <algorithm>
#include <iostream>
#include <string>
#include<sstream>
#include<string.h>
#include <cstdio>
#include <vector>
#include <bitset>
#include <cmath>
#include <queue>
#include<stack>
#include <set>
#include <map>
#include<ctime>

using namespace std;

typedef long long ll;
typedef vector<int> vi;
typedef pair<int,int> pii;
typedef pair<double,double> pdd;
typedef unsigned long long ull;

#define FOR(i,a,b) for (int i(a); i < (b); i++)
#define REP(i,n) FOR(i,0,n)
#define SORT(v) sort((v).begin(),(v).end())
#define UN(v) sort((v).begin(),(v).end()),v.erase(unique(v.begin(),v.end()),v.end())
#define CL(a,b) memset(a,b,sizeof(a))
#define pb push_back

typedef long double ld;
const ld pi = acosl(-1.);
const ld eps = 1e-17;

int r,h;

ld getAngle(ld x,ld y, ld z){
	ld H = h - z;
	if(H<eps) return 0;
	ld R = r * H / h;
	ld X = 0;
	ld Y = R;
	ld d = sqrtl((x-X)*(x-X)+(y-Y)*(y-Y));
	ld a = asinl(d/2/R)*2;
	ld l = a * R / sqrtl(R*R+H*H);
	if(x>0) l=-l;
	return l;
}

ld conDist(ld z,ld Z,ld a){
	ld r1 = sqrtl(h*h+r*r+0.)/h*(h-z);
	ld r2 = sqrtl(h*h+r*r+0.)/h*(h-Z);
	ld x = r1;
	ld y = 0;
	ld X = cosl(a)*r2;
	ld Y = sinl(a)*r2;
	return sqrtl((x-X)*(x-X)+(y-Y)*(y-Y));
}

ld getOnConus(ld x,ld y,ld z,ld X, ld Y,ld Z){
	ld a1 = getAngle(x,y,z);
	ld a2 = getAngle(X,Y,Z);
	ld a = fabsl(a2-a1);
	ld A = r / sqrtl(h*h+r*r+0.) * 2 * pi;
	return min(conDist(z,Z,a),conDist(z,Z,A-a));
}

ld getOnConus(ld x,ld y,ld z,ld X, ld Y){
	if(z>eps) return getOnConus(x,y,z,X,Y,0);
	return sqrtl((x-X)*(x-X)+(y-Y)*(y-Y));
}

ld getD(ld x,ld y,ld z,ld X, ld Y,ld Z,ld XX,ld YY,ld XXX,ld YYY){
	ld res = sqrtl((XX-XXX)*(XX-XXX)+(YY-YYY)*(YY-YYY));
	res += getOnConus(x,y,z,XX,YY);
	res += getOnConus(X,Y,Z,XXX,YYY);
	return res;
}

ld getD(ld x,ld y,ld z,ld X, ld Y,ld Z,ld XX,ld YY){
	ld res = 1e100;
	REP(i,6){
		ld a = 2*pi/3*i;
		ld b = a + pi;
		REP(j,30){
			ld s1 = (a*2+b)/3;
			ld s2 = (a+2*b)/3;
			ld d1 = getD(x,y,z,X,Y,Z,XX,YY,cosl(s1)*r,sinl(s1)*r);
			ld d2 = getD(x,y,z,X,Y,Z,XX,YY,cosl(s2)*r,sinl(s2)*r);
			res = min(res,min(d1,d2));
			if(d1<d2) b = s2;
			else a = s1;
		}
	}
	return res;
}

ld go(ld x,ld y,ld z,ld X, ld Y,ld Z){
	ld res = getOnConus(x,y,z,X,Y,Z);
	if(z<eps || Z<eps) res = 1e100;
	REP(i,6){
		ld a = 2*pi/3*i;
		ld b = a + pi;
		REP(j,30){
			ld s1 = (a*2+b)/3;
			ld s2 = (a+2*b)/3;
			ld d1 = getD(x,y,z,X,Y,Z,cosl(s1)*r,sinl(s1)*r);
			ld d2 = getD(x,y,z,X,Y,Z,cosl(s2)*r,sinl(s2)*r);
			res = min(res,min(d1,d2));
			if(d1<d2) b = s2;
			else a = s1;
		}
	}
	return res;
}

int main(){
#ifdef LocalHost
    freopen("input.txt","r",stdin);
//    freopen("output.txt","w",stdout);
#endif

	cin>>r>>h;
	long double x,y,z,X,Y,Z;
	cin>>x>>y>>z>>X>>Y>>Z;
	if(z<eps && Z<eps)
		printf("%.10lf\n",(double)sqrt((x-X)*(x-X)+(y-Y)*(y-Y)));
	else printf("%.10lf\n",(double)go(x,y,z,X,Y,Z));

#ifdef LocalHost
	cout<<endl<<endl<<"TIME: "<<clock()<<endl;
#endif
    return 0;
}

#include<bits/stdc++.h>
using namespace std;

typedef long double DB;
const DB PI = acos(DB(-1));
const DB INF = 1e10;
const DB EPS = 1e-12;

inline DB sqr(DB x) {
	return x * x;
}

struct PT {
	DB x, y;

	PT() {}
	PT(DB x, DB y) : x(x), y(y) {}
	void in() {
		double _x, _y;
		scanf("%lf%lf", &_x, &_y);
		x = _x, y = _y;
	}
};

bool operator<(const PT& p1, const PT& p2) {
	if (fabs(p1.x - p2.x) > EPS) return p1.x < p2.x;
	return p1.y + EPS < p2.y;
}

bool operator==(const PT& p1, const PT& p2) {
	return fabs(p1.x - p2.x) < EPS && fabs(p1.y - p2.y) < EPS;
}

PT operator+(PT p1, PT p2) {
	return PT(p1.x + p2.x, p1.y + p2.y);
}

PT operator-(PT p1, PT p2) {
	return PT(p1.x - p2.x, p1.y - p2.y);
}

PT operator*(PT p, DB c) {
	return PT(p.x * c, p.y * c);
}

PT operator/(PT p, DB c) {
	return PT(p.x / c, p.y / c);
}

DB dis(PT p) {
	return sqrt(sqr(p.x) + sqr(p.y));
}

DB dis2(PT p) {
	return sqr(p.x) + sqr(p.y);
}

DB dis2(PT p1, PT p2) {
	return sqr(p1.x - p2.x) + sqr(p1.y - p2.y);
}

DB dis(PT p1, PT p2) {
	return sqrt(dis2(p1, p2));
}

DB vect(PT p1, PT p2) {
	return p1.x * p2.y - p2.x * p1.y;
}

DB scal(PT p1, PT p2) {
	return p1.x * p2.x + p1.y * p2.y;
}

DB getAngle(PT p) {
	return atan2(p.y, p.x);
}

DB vect(PT p, PT p1, PT p2) {
	return vect(p1 - p, p2 - p);
}

DB scal(PT p, PT p1, PT p2) {
	return scal(p1 - p, p2 - p);
}

DB getAngle(PT p, PT p1, PT p2) {
	return getAngle(p2 - p) - getAngle(p1 - p);
}

DB getAngle180(PT p, PT p1, PT p2) {
	return acos(scal(p, p1, p2) / dis(p, p1) / dis(p, p2));
}

DB disToLine(PT p, PT p1, PT p2) {
	return fabs(vect(p, p1, p2)) / dis(p1, p2);
}

DB disToSeg(PT p, PT p1, PT p2) {
	if (scal(p1, p, p2) < 0) return dis(p, p1);
	if (scal(p2, p, p1) < 0) return dis(p, p2);
	return disToLine(p, p1, p2);
}

bool onLine(PT p, PT p1, PT p2) {
	return fabs(vect(p1 - p, p2 - p)) < EPS;
}

bool onSeg(PT p, PT p1, PT p2) {
	if (!onLine(p, p1, p2)) return 0;
	return (p1.x - p.x) * (p2.x - p.x) < EPS && (p1.y - p.y) * (p2.y - p.y) < EPS;
}

PT projection(PT a, PT b, PT p) {
	return a + (a - b) * scal(p - a, a - b) / dis2(a - b);
}

int posLineLine(PT p1, PT p2, PT p3, PT p4, PT& p) {
	DB s1 = vect(p1, p2, p3), s2 = vect(p1, p2, p4);
	if (fabs(s1 - s2) < EPS) {
		if (fabs(s1) < EPS) return 2;
		return 0;
	}
	p = p3 + (p4 - p3) * s1 / (s1 - s2);
	return 1;
}

int posCirLine(PT p, DB r, PT p1, PT p2, PT *q) {
	DB a, b, c, d2, d;
	a = dis2(p1, p2);
	b = scal(p1, p, p2);
	c = dis2(p, p1) - sqr(r);
	d2 = sqr(b) - a * c;
	if (d2 < -EPS) return 0;
	d = sqrt(fabs(d2));
	q[0] = p1 + (p2 - p1) * (b + d) / a;
	if (d2 < EPS) return 1;
	q[1] = p1 + (p2 - p1) * (b - d) / a;
	return 2;
}

int posCirCir(PT p1, DB r1, PT p2, DB r2, PT *q) {
	DB dx, dy, d, e, f2, f;
	dx = p2.x - p1.x, dy = p2.y - p1.y;
	d = dis(p1, p2);
	e = (sqr(r1) - sqr(r2) + sqr(d)) / 2 / d;
	f2 = sqr(r1) - sqr(e);
	if (f2 < -EPS) return 0;
	f = sqrt(fabs(f2));
	q[0] = PT(p1.x + (e * dx - f * dy) / d, p1.y + (e * dy + f * dx) / d);
	if (f2 < EPS) return 1;
	q[1] = PT(p1.x + (e * dx + f * dy) / d, p1.y + (e * dy - f * dx) / d);
	return 2;
}

DB calcArea(PT *p, int n) {
	DB rlt = 0;
	for (int i = 0; i < n; i++) rlt += vect(p[i], p[(i + 1) % n]);
	return rlt / 2;
}

int inPolygon(PT p, PT *q, int m) {
	PT p1, p2;
	int k = 0;
	for (int i = 0; i < m; i++) {
		p1 = q[i], p2 = q[(i + 1) % m];
		if (onSeg(p, p1, p2)) return 2;
		if (p1.y > p2.y) swap(p1, p2);
		if (p1.y < p.y + EPS && p.y + EPS < p2.y && vect(p, p1, p2) > 0) k++;
	}
	return k % 2;
}

int convex_hull(PT *p, int n, PT *q) {
	sort(p, p + n);
	n = unique(p, p + n) - p;
	if (n == 1) {
		q[0] = p[0];
		return 1;
	}
	int m = 0;
	for (int i = 0; i < n; i++) {
		while (m > 1 && vect(q[m - 2], q[m - 1], p[i]) < EPS) m--;
		q[m++] = p[i];
	}
	int k = m;
	for (int i = n - 2; i >= 0; i--) {
		while (m > k && vect(q[m - 2], q[m - 1], p[i]) < EPS) m--;
		q[m++] = p[i];
	}
	return --m;
}

PT P[2];
DB r, h, z[2];

DB calc(PT A, PT B, DB a, DB b) {
	DB d1 = sqrt(dis2(A) + sqr(h - a));
	DB d2 = sqrt(dis2(B) + sqr(h - b));
	DB ang = getAngle(A) - getAngle(B);
	while (ang < 0) ang += 2 * PI;
	while (ang > 2 * PI) ang -= 2 * PI;
	if (ang > PI) ang = 2 * PI - ang;
	ang = ang * r / sqrt(sqr(r) + sqr(h));
	return sqrt(sqr(d1) + sqr(d2) - 2 * cos(ang) * d1 * d2);
}

DB calc(PT A, PT B, DB a, DB b, DB ang) {
	PT C = PT(r * cos(ang), r * sin(ang));
	return calc(B, C, b, 0) + dis(C, A);
}

DB calc1(PT A, PT B, DB a, DB b) {
	DB step = PI / 100;
	DB ma = INF, which;
	for (DB now = -PI; now < PI - EPS; now += step) {
		DB ret = calc(A, B, a, b, now);
		if (ma > ret) {
			ma = ret;
			which = now;
		}
	}
	DB st = which - PI / 500, en = which + PI / 50;
	for (int times = 0; times < 200; times++) {
		DB md1 = (st + st + en) / 3, md2 = (st + en + en) / 3;
		if (calc(A, B, a, b, md1) < calc(A, B, a, b, md2)) en = md2;
		else st = md1;
	}
	return calc(A, B, a, b, st);
}

DB calc1(PT A, PT B, DB a, DB b, DB ang) {
	PT C = PT(r * cos(ang), r * sin(ang));
	return calc(A, C, a, 0) + calc1(C, B, 0, b);
}

DB calc2(PT A, PT B, DB a, DB b) {
	DB step = PI / 100;
	DB ma = INF, which;
	for (DB now = -PI; now < PI - EPS; now += step) {
		DB ret = calc1(A, B, a, b, now);
		if (ma > ret) {
			ma = ret;
			which = now;
		}
	}
	DB st = which - PI / 500, en = which + PI / 50;
	for (int times = 0; times < 200; times++) {
		DB md1 = (st + st + en) / 3, md2 = (st + en + en) / 3;
		if (calc1(A, B, a, b, md1) < calc1(A, B, a, b, md2)) en = md2;
		else st = md1;
	}
	return calc1(A, B, a, b, st);
}

int main() {
//	freopen("in.txt", "r", stdin);
	double _r, _h; scanf("%lf%lf", &_r, &_h);
	r = _r, h = _h;
	for (int i = 0; i < 2; i++) {
		double _z;
		P[i].in();
		scanf("%lf", &_z);
		z[i] = _z;
	}
	if (z[0] > z[1]) swap(P[0], P[1]), swap(z[0], z[1]);
	if (z[1] < EPS) return printf("%.20lf\n", (double)dis(P[0], P[1])), 0;
	if (z[0] > EPS) return printf("%.20lf\n", (double)min(calc(P[0], P[1], z[0], z[1]), calc2(P[0], P[1], z[0], z[1]))), 0;
	printf("%.20lf\n", (double)calc1(P[0], P[1], z[0], z[1]));
}

#include<iostream>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<stdio.h>
using namespace std;
const int bound=50;
const double eps=1e-6,inf=1e9+9,pi=acos(-1.0);
double ans,r,h,xa,ya,za,xb,yb,zb,la,ra,mxa,mya,lb,rb,mxb,myb,lv,rv,lz,rz;
double dtheta;
double dist(double x1,double y1,double z1,double x2,double y2,double z2)
{
	return sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2)+(z1-z2)*(z1-z2));
}
void norm(double &theta)
{
	while(theta<-eps)
	   theta+=2*pi;
    while(theta>2*pi-eps)
       theta-=2*pi;
}
double solve(double x1,double y1,double z1,double x2,double y2,double z2)
{
	double l1,l2,l,cj,alpha,dj,theta,res;
	if(fabs(z1)<eps&&fabs(z2)<eps)
	    return dist(x1,y1,z1,x2,y2,z2);
	l1=dist(x1,y1,z1,0,0,h);
	l2=dist(x2,y2,z2,0,0,h);
	alpha=atan2(y2,x2)-atan2(y1,x1);
	norm(alpha);
	if(alpha>pi)
	   alpha=2*pi-alpha;
	l=alpha*r;
	cj=sqrt(r*r+h*h);
	theta=l/cj;
	double u1,v1,u2,v2;
	u1=0;
	v1=l1;
	u2=l2*sin(theta);
	v2=l2*cos(theta);
	res=sqrt((u1-u2)*(u1-u2)+(v1-v2)*(v1-v2));
    theta=2*pi-theta;
  	u1=0;
	v1=l1;
	u2=l2*sin(theta);
	v2=l2*cos(theta);
	res=min(res,sqrt((u1-u2)*(u1-u2)+(v1-v2)*(v1-v2)));
    return res;
}
double compute(double alpha,double beta)
{
	return solve(xa,ya,za,r*cos(alpha),r*sin(alpha),0)+solve(xb,yb,zb,r*cos(beta),r*sin(beta),0)+dist(r*cos(alpha),r*sin(alpha),0,r*cos(beta),r*sin(beta),0);
}
double compute(double alpha)
{
	double theta,vl,ch,ret=inf;
	for(theta=0;theta<2*pi;theta+=dtheta)
	{
		vl=compute(alpha,theta);
		if(ret>vl)
		{
			ret=vl;
			ch=theta;
		}
	}
	lb=max(0.,ch-dtheta);
	rb=min(2*pi,ch+dtheta);
	while(lb<rb)
	{
	//	mxb=(2*lb+rb)/3;
	//	myb=(lb+2*rb)/3;
		mxb=0.5*(lb+rb);
		myb=mxb+eps;
		if(compute(alpha,mxb)>compute(alpha,myb))
		    lb=mxb+eps;
        else
            rb=mxb-eps;
	}
	vl=compute(alpha,0.5*(lb+rb));
	if(ret>vl)
	   ret=vl;
    return ret;
}
int main()
{
	int i,j,s,p,q,it1,it2;
	scanf("%lf%lf",&r,&h);
	scanf("%lf%lf%lf%lf%lf%lf",&xa,&ya,&za,&xb,&yb,&zb);
	ans=inf;
	if(fabs(za)>eps&&fabs(zb)>eps)
	   ans=min(ans,solve(xa,ya,za,xb,yb,zb));
	if(fabs(za)<eps&&fabs(zb)<eps)
	   ans=min(ans,dist(xa,ya,za,xb,yb,zb));
	if(fabs(zb)<eps)
	{
	    swap(xa,xb);
	    swap(ya,yb);
	    swap(za,zb);
	}
	double theta,vl,ch,mi=inf;
	dtheta=2*pi/bound;
	mi=inf;
	for(theta=0;theta<2*pi;theta+=dtheta)
	{
		vl=solve(xa,ya,za,r*cos(theta),r*sin(theta),0)+solve(xb,yb,zb,r*cos(theta),r*sin(theta),0);
		if(mi>vl)
		{
			mi=vl;
			ch=theta;
		}
		if(ans>vl)
		   ans=vl;
	}
	la=max(0.,ch-dtheta);
	ra=min(2*pi,ch+dtheta);
	while(la<ra)
	{
		mxa=0.5*(la+ra);
		mya=mxa+eps;
		lv=solve(xa,ya,za,r*cos(mxa),r*sin(mxa),0)+solve(xb,yb,zb,r*cos(mxa),r*sin(mxa),0);
        rv=solve(xa,ya,za,r*cos(mya),r*sin(mya),0)+solve(xb,yb,zb,r*cos(mya),r*sin(mya),0);
		if(lv>rv)
		   la=mxa+eps;
		else
		   ra=mxa-eps;
	}
	vl=solve(xa,ya,za,r*cos(0.5*(la+ra)),r*sin(0.5*(la+ra)),0)+solve(xb,yb,zb,r*cos(0.5*(la+ra)),r*sin(0.5*(la+ra)),0);
	if(ans>vl)
	   ans=vl;
	mi=inf;
	for(theta=0;theta<2*pi;theta+=dtheta)
	{
		vl=compute(theta);
		if(mi>vl)
        {
        	mi=vl;
        	ch=theta;
        }
        if(ans>vl)
           ans=vl;
	}
    la=max(0.,ch-dtheta);
    ra=min(2*pi,ch+dtheta);
    while(la<ra)
    {
    //	mxa=(2*la+ra)/3;
    //	mya=(la+2*ra)/3;
        mxa=0.5*(la+ra);
        mya=mxa+eps;
		if(compute(mxa)>compute(mya))
    	    la=mxa+eps;
	    else
	        ra=mxa-eps;
    }
    vl=compute(0.5*(la+ra));
    if(ans>vl)
       ans=vl;
    printf("%.20f\n",ans);
	return 0;
}

#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <string>
#include <set>
#include <vector>
#include <cmath>
#include <cassert>
#include <cstdlib>
#include <map>
#include <queue>
#include <deque>
#include <bitset>

#define y0 y63475625
#define y1 y28435
#define j0 jfd0sf
#define j1 je90ue0
#define sqr(x) ((x)*(x))
#define fi first
#define se second
#define pb push_back
#define mp make_pair
#define re return
#define sz(x) ((int)(x).size())
#define all(x) (x).begin(), (x).end()
#define rep(i, n) for (int i = 0; i < (n); i++)
#define rrep(i, n) for (int i = (n) - 1; i >= 0; i--)
#define sqrt(x) (sqrt(abs(x)))
#define fill(a, x) memset(a, x, sizeof(a))

using namespace std;

typedef vector <int> vi;
typedef vector <vi> vvi;
typedef long long ll;
typedef long double ld;
typedef pair <int, int> ii;
typedef vector <ii> vii;
typedef double D;
typedef pair <ll, ll> pll;
typedef vector <string> vs;

template <class T> T abs(const T a) {
    return a > 0 ? a : -a;
}

const double PI = 2.0 * acos(1.0);

const ld eps = 1e-12;

ld alpha;

int n;
int m;

ld dist(ld ra, ld rb, ld angle) {
    if (abs(ra) < eps) {
        re rb * alpha;
    }
    if (abs(rb) < eps) {
        re ra * alpha;
    }
    if (fabs(angle) < eps)
        re abs(rb - ra) * alpha;
    ld co = rb * sin(angle / alpha);
    ld si = (ra - rb * cos(angle / alpha));
    ld q = sqrt(sqr(co) + sqr(si));
    co /= q; si /= q;
    //ld f0 = alpha * atan2(si, co);
    ld tmp = tan(angle / alpha), tg = si / co;
    re abs(alpha * ra * (co * (tmp - tg) / (1.0 + tmp * tg) + si));
}

int main()
{
    ld r, h;
    cin >> r >> h;
    ld xa, ya, za, xb, yb, zb;
    cin >> xa >> ya >> za;
    cin >> xb >> yb >> zb;
    if (abs(zb) < eps && abs(za) < eps) {
        printf("%.10lf\n", (D)sqrt(sqr(xb - xa) + sqr(yb - ya)));
        re 0;
    }
    if (abs(zb) < eps) {
        swap(xa, xb);
        swap(ya, yb);
        swap(za, zb);
    }

    alpha = sqrt(1.0 + sqr(h / r));
    if (abs(za) > eps && abs(zb) > eps) {
        ld ra = sqrt(sqr(xa) + sqr(ya));
        ld rb = sqrt(sqr(xb) + sqr(yb));
        ld angle = -1.0;
        if (abs(ra) > eps && abs(rb) > eps)
            angle = acos((xa * xb + ya * yb) / ra / rb);
        ld ans = dist(ra, rb, angle);
        ld fans1 = -1, fans2 = -1;
        rep(i, 1) {
            ld L1 = -M_PI / 8, R1 = M_PI / 8.0;
            ld L2 = -M_PI / 8, R2 = M_PI / 8.0;
            n = 1780;
            rep(j, n) {
                ld f1 = L1 + (R1 - L1) * j / (ld)n;
                rep(k, n) {
                    ld f2 = L2 + (R2 - L2) * k / (ld)n;
                    ld tmp = r * sqrt(2.0 - 2.0 * cos(angle + f1 - f2)) + dist(r, ra, f1) + dist(r, rb, f2);
                    if (tmp < ans) {
                        ans = tmp;
                        fans1 = f1;
                        fans2 = f2;
                    }
                }
            }
            ld d = R1 - L1;
            L1 = fans1 - d / 2.0 * 0.99;
            L2 = fans2 - d / 2.0 * 0.99;
            R1 = fans1 + d / 2.0 * 0.99;
            R2 = fans2 + d / 2.0 * 0.99;
        }
        printf("%.10lf\n", (D)ans);
        re 0;
    } else {
        //todo
        ld L = 0.0, R = 2.0 * M_PI;
        ld ans = 1e20;
        ld fans = -1;
        ld rb = sqrt(sqr(xb) + sqr(yb));
        rep(i, 200) {
            rep(j, 1000) {
                double f = L + (R - L) / 100.0 * j;
                ld x = r * cos(f);
                ld y = r * sin(f);
                ld angle = -1.0;
                if (abs(rb) > eps)
                    angle = acos((x * xb + y * yb) / rb / r);
                ld tmp = sqrt(sqr(xa - x) + sqr(ya - y)) + dist(r, rb, angle);
                if (tmp < ans) {
                    ans = tmp;
                    fans = f;
                }
            }
            ld d = R - L;
            L = fans - d / 2.0 * 0.9;
            R = fans + d / 2.0 * 0.9;
        }
        printf("%.10lf\n", (D)ans);
    }
    return 0;
}

#include <set>
#include <map>
#include <queue>
#include <deque>
#include <cmath>
#include <ctime>
#include <bitset>
#include <vector>
#include <string>
#include <cstdio>
#include <cassert>
#include <cstring>
#include <iostream>
#include <algorithm>
#define For(i,x,y)  for(int i=(int)(x);i<=(int)(y);i++)
#define Forn(i,x,y) for(int i=(int)(x);i>=(int)(y);i--)
#define Rep(i,x,y)  for(int i=(int)(x);i< (int)(y);i++)
#define mk make_pair
#define pb push_back
#define fi first
#define se second
using namespace std;
typedef long double db;
typedef long long ll;
typedef pair<int,int> PII;
const int N=200005;
const int inf=1e9;
const ll Inf=1e10;
const int P=1000000007;
const db  pi=acos(-1);

db r,h,Sqr,l;
db X1,X2,Y1,Y2,Z1,Z2;

void read(db &x){
	double z;
	scanf("%lf",&z);
	x=z;
}

db sqr(db x){return x*x;}

db Fbb(db A,db B,db D,db E){
	return sqrt(sqr(A-D)+sqr(B-E));
}

db Faa(db A,db B,db C,db D,db E,db F){
	if(fabs(C-h)<1e-6) return sqrt(D*D+E*E+sqr(F-h));
	if(fabs(F-h)<1e-6) return sqrt(A*A+B*B+sqr(C-h));
	db X3=A*h/(h-C),Y3=B*h/(h-C),X4=D*h/(h-F),Y4=E*h/(h-F);
	db u=Sqr*2-sqr(X3-X4)-sqr(Y3-Y4);
	u/=2*Sqr;
	db the=acos(u);
	db phi=the*r/l;
	db D1=sqr(A)+sqr(B)+sqr(C-h),D2=sqr(D)+sqr(E)+sqr(F-h);
	return sqrt(D1+D2-2*sqrt(D1)*sqrt(D2)*cos(phi));
}

db Fab(db X,db Y,db Z,db E,db F,db the){
	db X3=r*cos(the),Y3=r*sin(the);
	return Faa(X,Y,Z,X3,Y3,0)+Fbb(E,F,X3,Y3);
}

db Fab2(db the){
	db X3=cos(the)*r,Y3=sin(the)*r;
	db l=0,r=2*pi,T1,T2;
	For(i,1,500){
		db md1=(2*l+r)/3.,md2=(l+2*r)/3.;
		T1=Fab(X2,Y2,Z2,X3,Y3,md1);
		T2=Fab(X2,Y2,Z2,X3,Y3,md2);
		if(T1>T2) l=md1;else r=md2;
	}
	return T1+Faa(X1,Y1,Z1,X3,Y3,0);
}

int main(){
	read(r);read(h);Sqr=r*r;
	l=sqrt(r*r+h*h);
	read(X1);read(Y1);read(Z1);
	read(X2);read(Y2);read(Z2);

	if(Z1==0&&Z2==0){
		printf("%.16lf\n",double(Fbb(X1,Y1,X2,Y2)));
		return 0;
	}
	if(Z1!=0&&Z2!=0){
		db ans=Faa(X1,Y1,Z1,X2,Y2,Z2);
		db l=0,r=2*pi,T1,T2;
		For(i,1,500){
			db md1=(2*l+r)/3.,md2=(l+2*r)/3.;
			T1=Fab2(md1);
			T2=Fab2(md2);
			if(T1>T2) l=md1;else r=md2;
		}
		ans=min(ans,T1);
		printf("%.16lf\n",double(ans));
		return 0;
	}
	if(Z1==0){
		swap(X1,X2);
		swap(Y1,Y2);
		swap(Z1,Z2);
	}
	db l=0,r=2*pi,T1,T2;
	For(i,1,500){
		db md1=(2*l+r)/3.,md2=(l+2*r)/3.;
		if((T1=Fab(X1,Y1,Z1,X2,Y2,md1))>(T2=Fab(X1,Y1,Z1,X2,Y2,md2))) l=md1;else r=md2;
	}
	printf("%.16lf\n",double(T1));
	return 0;
}

#include <iostream>
#include <cstdio>
#include <vector>
#include <algorithm>
#include <cstring>
#include <string>
#include <queue>
#include <set>
#include <map>
#include <bitset>
#include <cmath>
#include <ctime>
#pragma comment (linker, "/STACK:256000000")

using namespace std;

const double eps = 1e-9;
const double pi = 2.0 * acos(0.0);
double r, h;

double dist(double x1, double y1, double z1, double x2, double y2, double z2) {
	double dx = x1 - x2;
	double dy = y1 - y2;
	double dz = z1 - z2;
	return sqrt(dx * dx + dy * dy + dz * dz);
}

double dist(double x1, double y1, double x2, double y2) {
	double dx = x1 - x2;
	double dy = y1 - y2;
	return sqrt(dx * dx + dy * dy);
}

double solve(double x1, double y1, double z1, double x2, double y2, double z2) {
	if (fabs(z1) < eps && fabs(z2) < eps) {
		return dist(x1, y1, z1, x2, y2, z2);
	}

	double l1 = dist(x1, y1, z1, 0, 0, h);
	double l2 = dist(x2, y2, z2, 0, 0, h);

	if (fabs(l1) < eps || fabs(l2) < eps) {
		return l1 + l2;
	}

	double coef = l2 / l1;
	double xn = x1 * coef;
	double yn = y1 * coef;
	double zn = h + (z1 - h) * coef;
	double cr = sqrt(l2 * l2 - (h - z2) * (h - z2));
	double ang = acos((xn * x2 + yn * y2) / (cr * cr));

	double length = ang * r;
	double alpha = length / sqrt(r * r + h * h);

	double u1 = l1, v1 = 0.0;
	double u2 = l2 * cos(alpha), v2 = l2 * sin(alpha);

	return dist(u1, v1, u2, v2);
}

double calc(double xa, double ya, double za, double xb, double yb, double zb, double x0, double y0, double z0, double L, double R) {
	double res = 1e20;
	double d = solve(xa, ya, za, x0, y0, z0);
	for (int i = 0; i < 30; ++i) {
		double x = (2.0 * L + R) / 3.0;
		double y = (L + 2.0 * R) / 3.0;

		double x1 = r * cos(x), y1 = r * sin(x);
		double x2 = r * cos(y), y2 = r * sin(y);

		double A = solve(x0, y0, z0, x1, y1, 0.0) + solve(x1, y1, 0.0, xb, yb, zb);
		double B = solve(x0, y0, z0, x2, y2, 0.0) + solve(x2, y2, 0.0, xb, yb, zb);
		res = min(res, d + A);
		res = min(res, d + B);
		if (A < B) {
			R = y;
		} else {
			L = x;
		}
	}
	return res;
}

int main() {
	//freopen("input.txt", "r", stdin);
	//freopen("output.txt", "w", stdout);

	cin >> r >> h;
	double xa, ya, za;
	double xb, yb, zb;
	cin >> xa >> ya >> za;
	cin >> xb >> yb >> zb;

	double res = 1e20;
	if (fabs(za) > eps && fabs(zb) > eps) {
		res = min(res, solve(xa, ya, za, xb, yb, zb));
	}
	if (fabs(za) < eps && fabs(zb) < eps) {
		res = min(res, dist(xa, ya, za, xb, yb, zb));
	}

	double angle = 2.0 * pi / 4;
	for (int step = 0; step < 4; ++step) {
		double left_bound = (double)(step) * angle;
		double right_bound = (double)(step + 1) * angle;

		for (int i = 0; i < 30; ++i) {
			double L = (2.0 * left_bound + right_bound) / 3.0;
			double R = (left_bound + 2.0 * right_bound) / 3.0;

			double valueL = solve(xa, ya, za, r * cos(L), r * sin(L), 0) + solve(r * cos(L), r * sin(L), 0, xb, yb, zb);
			double valueR = solve(xa, ya, za, r * cos(R), r * sin(R), 0) + solve(r * cos(R), r * sin(R), 0, xb, yb, zb);
			res = min(res, valueL);
			res = min(res, valueR);
			if (valueL < valueR) {
				right_bound = R;
			} else {
				left_bound = L;
			}
		}
	}
	//printf("%.12lf\n", res);
	int cnt = 4;
	angle = 2.0 * pi / (double)(cnt);
	for (int stepA = 0; stepA < cnt; ++stepA) {
		for (int stepB = 0; stepB < cnt; ++stepB) {
			double left_bound = (double)(stepA) * angle;
			double right_bound = (double)(stepA + 1) * angle;

			double lB = (double)(stepB) * angle;
			double rB = (double)(stepB + 1) * angle;
			for (int i = 0; i < 30; ++i) {
				double L = (2.0 * left_bound + right_bound) / 3.0;
				double R = (left_bound + 2.0 * right_bound) / 3.0;

				double valueL = calc(xa, ya, za, xb, yb, zb, r * cos(L), r * sin(L), 0.0, lB, rB);
				double valueR = calc(xa, ya, za, xb, yb, zb, r * cos(R), r * sin(R), 0.0, lB, rB);
				res = min(res, valueL);
				res = min(res, valueR);
				if (valueL < valueR) {
					right_bound = R;
				} else {
					left_bound = L;
				}
			}
		}
	}

	printf("%.12lf\n", res);

	return 0;
}

#include <bits/stdc++.h>

#define inf 0x3f3f3f3f

#define MOD 1000000007

#define pb push_back

#define sq(x) ((x)*(x))

#define x first

#define y second

#define eps 1e-11

#define bpt(x) (__builtin_popcount(x))

#define bptl(x) (__builtin_popcountll(x))

#define bit(x, y) (((x)>>(y))&1)

#define bclz(x) (__builtin_clz(x))

#define bclzl(x) (__builtin_clzll(x))

#define bctz(x) (__builtin_ctz(x))

#define bctzl(x) (__builtin_ctzll(x))

#define sgn(x) (((x)>eps)-((x)<-eps))

#define PQ priority_queue<pii, vector<pii>, greater<pii> >

using namespace std;

typedef long long INT;

typedef vector<int> VI;

typedef pair<int, int> pii;

typedef pair<pii, int> pi3;

typedef long double DO;

template<typename T, typename U> inline void smin(T &a, U b) {if (a>b) a=b;}

template<typename T, typename U> inline void smax(T &a, U b) {if (a<b) a=b;}

template<class T>inline void gn(T &x) {char c, sg=0; while (c=getchar(), (c>'9' || c<'0') && c!='-');for((c=='-'?sg=1, c=getchar():0), x=0; c>='0' && c<='9'; c=getchar()) x=(x<<1)+(x<<3)+c-'0';if (sg) x=-x;}

template<class T, class T1>inline void gn(T &x, T1 &y) {gn(x); gn(y);}

template<class T, class T1, class T2>inline void gn(T &x, T1 &y, T2 &z) {gn(x); gn(y); gn(z);}

template<class T>inline void print(T x) {if (x<0) {putchar('-');return print(-x);}if (x<10) {putchar('0'+x);return;} print(x/10);putchar(x%10+'0');}

template<class T>inline void printsp(T x) {print(x); putchar(' ');}

template<class T>inline void println(T x) {print(x); putchar('\n');}

template<class T, class U>inline void print(T x, U y) {printsp(x); println(y);}

template<class T, class U, class V>inline void print(T x, U y, V z) {printsp(x); printsp(y); println(z);}

int power(int a, int b, int m, int ans=1) {

	for (; b; b>>=1, a=1LL*a*a%m) if (b&1) ans=1LL*ans*a%m;

	return ans;

}

struct point {

	DO x, y, z;

	point (DO x=0, DO y=0, DO z=0) : x(x), y(y), z(z) {}

	point operator - (point a) {return point(x-a.x, y-a.y, z-a.z);}

	point operator + (point a) {return point(x+a.x, y+a.y, z+a.z);}

	point operator * (DO a) {return point(x*a, y*a, z*a);}

	point operator / (DO a) {return point(x/a, y/a, z/a);}

	point operator ^ (point a) {return point(y*a.z-z*a.y, -(x*a.z-z*a.x), x*a.y-y*a.x);}

	DO    operator * (point a) {return x*a.x+y*a.y+z*a.z;}

	point norm() {DO s=nor(); if (s<eps) return *this; return point(x/s, y/s, z/s);}

	DO nor() {return sqrt(*this**this);}

	bool operator < (const point &a) const {

		if (fabs(x-a.x)>eps) return x<a.x;

		if (fabs(y-a.y)>eps) return y<a.y;

		return z<a.z-eps;

	}

	bool operator > (const point &a) const {

		if (fabs(x-a.x)>eps) return x>a.x;

		if (fabs(y-a.y)>eps) return y>a.y;

		return z>a.z-eps;

	}

	bool operator == (const point &a) const {

		if (fabs(x-a.x)>eps) return 0;

		if (fabs(y-a.y)>eps) return 0;

		return fabs(z-a.z)<eps;

	}

	void input() {cin>>x>>y>>z;}

	void print() {printf("%lf %lf %lf\n", (double)x, (double)y, (double)z);}

};

void print_ans(DO x) {

	cout<<fixed<<setprecision(15)<<x<<endl;

	exit(0);

}

DO L, pi;

DO calc(point &a, DO &lb, DO &phib, DO &r, DO &al) {

	DO be=al*L/r;

	DO ans=(a-point(r*cosl(be), r*sinl(be), 0)).nor();

	return ans+sqrtl(max((DO)0, (L*L+lb*lb-2*lb*L*cosl(al-phib))));

}

DO ST[1111];

int main() {

#ifndef ONLINE_JUDGE

	freopen("in.in", "r", stdin);

	freopen("out.out", "w", stdout);

#endif

	point a, b;

	DO r, h;

	cin>>r>>h;

	a.input(); b.input();

	L=sqrtl(r*r+h*h), pi=acosl(-1);

	point H=point(0, 0, h);

	if (a.z<eps && b.z<eps) print_ans((a-b).nor());

	if (a.z>b.z+eps) swap(a, b);

	if (b.z>h-eps) {

		if (a.z>h-eps) print_ans((DO)0.0);

		if (a.z<eps) print_ans(L+r-a.nor());

		print_ans((H-a).nor());

	}

	if (a.z>eps) {

		DO al=atan2l(a.y, a.x);

		DO be=atan2l(b.y, b.x);

		if (al<0) al+=2*pi;

		if (be<0) be+=2*pi;

		DO la=(H-a).nor();

		DO lb=(H-b).nor();

		DO ra=sqrtl(a.x*a.x+a.y*a.y);

		DO rb=sqrtl(b.x*b.x+b.y*b.y);

		DO phia=al*ra/la, phib=be*rb/lb;

		print_ans(sqrtl(max((DO)0.0, (H-a)*(H-a)+(H-b)*(H-b)-2*la*lb*cosl(phia-phib))));

	}

	DO al=atan2l(a.y, a.x);

	DO be=atan2l(b.y, b.x);

	if (al<0) al+=2*pi;

	if (be<0) be+=2*pi;

	DO lb=(H-b).nor();

	DO rb=sqrtl(b.x*b.x+b.y*b.y);

	DO phib=be*rb/lb;

	DO ans=1e100;

	int N=0; ST[N++]=0;

	ST[N++]=al*r/L;

	ST[N++]=2*pi*r/L;

	if (al>pi+eps) {

		ST[N++]=(al-pi)*r/L;

	} else {

		ST[N++]=(al+pi)*r/L;

	}

	ST[N++]=phib;

	if (phib>pi+eps) {

		ST[N++]=phib-pi;

	} else {

		ST[N++]=phib+pi;

	}

	sort(ST, ST+N);

	int n=N; N=1;

	for (int i=1; i<n; i++) if (ST[i]>ST[N-1]+eps) ST[N++]=ST[i];

	N--;

	for (int i=0; i<N; i++) {

		DO st=ST[i], ed=ST[i+1];

		for (int i=0; i<200; i++) {

			DO x1=(st*2+ed)/3, x2=(st+ed*2)/3;

			if (calc(a, lb, phib, r, x1)<calc(a, lb, phib, r, x2)) ed=x2;

			else st=x1;

		}

		smin(ans, calc(a, lb, phib, r, st));

	}

	print_ans(ans);

	return 0;

}

#define pi 3.1415926535897932384626433832795

#include<bits/stdc++.h>

#define eps 1e-7

using namespace std;

typedef long double DO;

template<typename T, typename U> inline void smin(T &a, const U &b) {if(a>b) a=b;}

template<typename T, typename U> inline void smax(T &a, const U &b) {if(a<b) a=b;}

struct point {

	DO x, y, z;

	inline void input() {cin>>x>>y>>z;}

	inline DO al() {return atan2l(y, x);}

	inline DO nor2() {return *this**this;}

	inline DO nor() {return sqrtl(*this**this);}

	inline void print() {cout<<x<<' '<<y<<' '<<z<<endl;}

	inline DO operator * (point a) {return x*a.x+y*a.y+z*a.z;}

	inline point(DO x=0, DO y=0, DO z=0) : x(x), y(y), z(z) {}

	inline point operator * (DO a) {return point(x*a, y*a, z*a);}

	inline point operator - (point a) {return point(x-a.x, y-a.y, z-a.z);}

	inline point operator + (point a) {return point(x+a.x, y+a.y, z+a.z);}

	inline point norm() {DO s=nor(); if(s<eps) return *this; return point(x/s, y/s, z/s);}

};

DO r, h, R, one=pi/3, whole=2*pi, len;

inline DO calc_laterals(point a, point b) {

	DO x=r*fabsl(a.al()-b.al()); smin(x, len-x);

	DO da2=(a-point(0, 0, h)).nor2(), da=sqrtl(da2);

	DO db2=(b-point(0, 0, h)).nor2(), db=sqrtl(db2);

	return sqrtl(da2+db2-2*da*db*cosl(x/R));

}

point A, AA, B, DA, DB, focus;

inline DO calc_down_lateral(DO angle) {

	DO x=r*cosl(angle), y=r*sinl(angle);

	return (AA-point(x, y, 0)).nor()+calc_laterals(point(x, y, 0), B);

}

inline DO solve() {

	DO ans=(AA-DB).nor()+calc_laterals(DB, B);

	for(DO angle=one; angle<=whole; angle+=one) {

		DO st=angle-one, ed=angle;

		while(ed-st>eps) {

			DO a=(st+st+ed)/3, b=(st+ed+ed)/3;

			if(calc_down_lateral(a)>calc_down_lateral(b)) st=a;

			else ed=b;

		}

		smin(ans, calc_down_lateral(st));

	}

	return ans;

}

main() {

#ifndef	ONLINE_JUDGE

	freopen("in.in", "r", stdin);

	freopen("out.out", "w", stdout);

#endif

	cin>>r>>h;

	len=whole*r, R=sqrtl(r*r+h*h);

	focus=point(0, 0, h);

	A.input(), B.input();

	if(B.z<eps) swap(A, B);

	DA=focus+(A-focus).norm()*R, DB=focus+(B-focus).norm()*R;

	DO ans=1e13;

	if(A.z<eps) {

		if(B.z<eps) ans=(A-B).nor();

		else AA=A, ans=solve();

	}

	else {

		ans=calc_laterals(A, B);

		AA=DA, smin(ans, calc_laterals(A, AA)+solve());

		for(DO angle=one; angle<=whole; angle+=one) {

			DO st=angle-one, ed=angle;

			while(ed-st>eps) {

				DO a=(st+st+ed)/3, b=(st+ed+ed)/3;

				AA=point(r*cosl(a), r*sinl(a)); DO sa=calc_laterals(A, AA)+calc_down_lateral(a);

				AA=point(r*cosl(b), r*sinl(b)); DO sb=calc_laterals(A, AA)+calc_down_lateral(b);

				if(sa>sb) st=a;

				else ed=b;

			}

			AA=point(r*cosl(st), r*sinl(st)), smin(ans, calc_laterals(A, AA)+solve());

		}

	}

	printf("%.7lf", (double)ans);

}

#include<stdio.h>
#include<math.h>
#include<algorithm>
#include<stdlib.h>
#include<string.h>
#include<string>
using namespace std;
typedef double db;
const db pi=acos(-1),eps=0.2;
struct p{
    db x,y,z;
}a,b,c,v;
void set(p&a,db x,db y,db z){
    a.x=x;a.y=y;a.z=z;
}
void swap(db&a,db&b){
    db c=a;a=b;b=c;
}
db sqr(db a){
    return a*a;
}
void swap(p&a,p&b){
    p c=a;a=b;b=c;
}
db r,h,l,z;
db dis(p a,p b){
    return sqrt(sqr(a.x-b.x)+sqr(a.y-b.y)+sqr(a.z-b.z));
}
db abs(db x){
    if(x<0)return -x;
    return x;
}
db cc(db a,db b,db z){
    return sqrt(sqr(a)+sqr(b)-2*cos(z)*a*b);
}
db aa(p a){
    return atan2(a.y,a.x);
}
db zt(p a,p b){
    db z=abs(aa(a)-aa(b));
    return min(z,2*pi-z);
}
db zt(db z){
    return z*r/l;
}
db diss(p a,p b){
    return cc(dis(a,v),dis(b,v),zt(zt(a,b)));
}
p rp(db z){
    p o;
    set(o,r*cos(z),r*sin(z),0);
    return o;
}
db ff(p a,p b,db z){
    p o=rp(z);
    return diss(b,o)+dis(a,o);
}
db fff(p a,p b,db z){
    p o=rp(z);
    db ll=aa(b)-eps,rr=aa(b)+eps,m1,m2;
    for(int i=200;i;i--){
        m1=ll+(rr-ll)*0.49;
        m2=ll+(rr-ll)*0.51;
        if(ff(o,b,m1)<ff(o,b,m2))rr=m2;else ll=m1;
    }
    return diss(a,o)+ff(o,b,ll);
}
int main(){
    scanf("%lf%lf",&r,&h);
    scanf("%lf%lf%lf",&a.x,&a.y,&a.z);
    scanf("%lf%lf%lf",&b.x,&b.y,&b.z);
    if(a.z==0&&b.z==0){
        printf("%.15lf\n",dis(a,b));
        return 0;
    }
    set(v,0,0,h);
    l=sqrt(sqr(r)+sqr(h));
    if(a.z> 0&&b.z> 0){
        db lll=aa(a)-eps,rrr=aa(a)+eps,m1,m2;
        for(int i=200;i;i--){
            m1=lll+(rrr-lll)*0.49;
            m2=lll+(rrr-lll)*0.51;
            if(fff(a,b,m1)<fff(a,b,m2))rrr=m2;else lll=m1;
        }
//        printf("%.15lf\n\n",dis(a,rp(aa(a)))+dis(b,rp(aa(b)))+dis(rp(aa(a)),rp(aa(b))));
//        printf("%.15lf\n%.15lf\n\n",sqrt(sqr(a.x)+sqr(a.y)),sqrt(sqr(b.x)+sqr(b.y)));
//        printf("%.15lf\n%.15lf\n\n",diss(a,b),fff(a,b,lll));
        printf("%.15lf\n",min(diss(a,b),fff(a,b,lll)));
        return 0;
    }
    if(b.z==0)swap(a,b);
    db l1,ll=aa(b)-eps,rr=aa(b)+eps,m1,m2;
    for(int i=200;i;i--){
        m1=ll+(rr-ll)*0.49;
        m2=ll+(rr-ll)*0.51;
        if(ff(a,b,m1)<ff(a,b,m2))rr=m2;else ll=m1;
    }
    l1=ll,ll=aa(a)-eps,rr=aa(a)+eps;
    for(int i=200;i;i--){
        m1=ll+(rr-ll)*0.49;
        m2=ll+(rr-ll)*0.51;
        if(ff(a,b,m1)<ff(a,b,m2))rr=m2;else ll=m1;
    }
    printf("%.15lf\n",min(ff(a,b,ll),ff(a,b,l1)));
    return 0;
}

#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <string>
#include <set>
#include <vector>
#include <cmath>
#include <cassert>
#include <cstdlib>
#include <map>
#include <queue>
#include <deque>
#include <bitset>

#define y0 y63475625
#define y1 y28435
#define j0 jfd0sf
#define j1 je90ue0
#define sqr(x) ((x)*(x))
#define fi first
#define se second
#define pb push_back
#define mp make_pair
#define re return
#define sz(x) ((int)(x).size())
#define all(x) (x).begin(), (x).end()
#define rep(i, n) for (int i = 0; i < (n); i++)
#define rrep(i, n) for (int i = (n) - 1; i >= 0; i--)
#define sqrt(x) (sqrt(abs(x)))
#define fill(a, x) memset(a, x, sizeof(a))

using namespace std;

typedef vector <int> vi;
typedef vector <vi> vvi;
typedef long long ll;
typedef long double ld;
typedef pair <int, int> ii;
typedef vector <ii> vii;
typedef double D;
typedef pair <ll, ll> pll;
typedef vector <string> vs;

template <class T> T abs(const T a) {
    return a > 0 ? a : -a;
}

const double PI = 2.0 * acos(1.0);

const ld eps = 1e-12;

ld alpha;

int n;
int m;

ld dist(ld ra, ld rb, ld angle) {
    if (abs(ra) < eps) {
        re rb * alpha;
    }
    if (abs(rb) < eps) {
        re ra * alpha;
    }
    if (fabs(angle) < eps)
        re abs(rb - ra) * alpha;
    ld co = rb * sin(angle / alpha);
    ld si = (ra - rb * cos(angle / alpha));
    ld q = sqrt(sqr(co) + sqr(si));
    co /= q; si /= q;
    //ld f0 = alpha * atan2(si, co);
    ld tmp = tan(angle / alpha), tg = si / co;
    re abs(alpha * ra * (co * (tmp - tg) / (1.0 + tmp * tg) + si));
}

int main()
{
    ld r, h;
    cin >> r >> h;
    ld xa, ya, za, xb, yb, zb;
    cin >> xa >> ya >> za;
    cin >> xb >> yb >> zb;
    if (abs(zb) < eps && abs(za) < eps) {
        printf("%.10lf\n", (D)sqrt(sqr(xb - xa) + sqr(yb - ya)));
        re 0;
    }
    if (abs(zb) < eps) {
        swap(xa, xb);
        swap(ya, yb);
        swap(za, zb);
    }

    alpha = sqrt(1.0 + sqr(h / r));
    if (abs(za) > eps && abs(zb) > eps) {
        ld ra = sqrt(sqr(xa) + sqr(ya));
        ld rb = sqrt(sqr(xb) + sqr(yb));
        ld angle = -1.0;
        if (abs(ra) > eps && abs(rb) > eps)
            angle = acos((xa * xb + ya * yb) / ra / rb);
        ld ans = dist(ra, rb, angle);
        ld fans1 = -1, fans2 = -1;
        rep(i, 1) {
            ld L1 = -M_PI / 2, R1 = M_PI / 2.0;
            ld L2 = -M_PI / 2, R2 = M_PI / 2.0;
            n = 1780;
            rep(j, n) {
                ld f1 = L1 + (R1 - L1) * j / (ld)n;
                rep(k, n) {
                    ld f2 = L2 + (R2 - L2) * k / (ld)n;
                    ld tmp = r * sqrt(2.0 - 2.0 * cos(angle + f1 - f2)) + dist(r, ra, f1) + dist(r, rb, f2);
                    if (tmp < ans) {
                        ans = tmp;
                        fans1 = f1;
                        fans2 = f2;
                    }
                }
            }
            ld d = R1 - L1;
            L1 = fans1 - d / 2.0 * 0.99;
            L2 = fans2 - d / 2.0 * 0.99;
            R1 = fans1 + d / 2.0 * 0.99;
            R2 = fans2 + d / 2.0 * 0.99;
        }
        printf("%.10lf\n", (D)ans);
        re 0;
    } else {
        //todo
        ld L = 0.0, R = 2.0 * M_PI;
        ld ans = 1e20;
        ld fans = -1;
        ld rb = sqrt(sqr(xb) + sqr(yb));
        rep(i, 200) {
            rep(j, 1000) {
                double f = L + (R - L) / 100.0 * j;
                ld x = r * cos(f);
                ld y = r * sin(f);
                ld angle = -1.0;
                if (abs(rb) > eps)
                    angle = acos((x * xb + y * yb) / rb / r);
                ld tmp = sqrt(sqr(xa - x) + sqr(ya - y)) + dist(r, rb, angle);
                if (tmp < ans) {
                    ans = tmp;
                    fans = f;
                }
            }
            ld d = R - L;
            L = fans - d / 2.0 * 0.9;
            R = fans + d / 2.0 * 0.9;
        }
        printf("%.10lf\n", (D)ans);
    }
    return 0;
}

#include <set>
#include <map>
#include <queue>
#include <deque>
#include <cmath>
#include <ctime>
#include <bitset>
#include <vector>
#include <string>
#include <cstdio>
#include <cassert>
#include <cstring>
#include <iostream>
#include <algorithm>
#define For(i,x,y)  for(int i=(int)(x);i<=(int)(y);i++)
#define Forn(i,x,y) for(int i=(int)(x);i>=(int)(y);i--)
#define Rep(i,x,y)  for(int i=(int)(x);i< (int)(y);i++)
#define mk make_pair
#define pb push_back
#define fi first
#define se second
using namespace std;
typedef long double db;
typedef long long ll;
typedef pair<int,int> PII;
const int N=200005;
const int inf=1e9;
const ll Inf=1e10;
const int P=1000000007;
const db  pi=acos(-1);

db r,h,Sqr,l;
db X1,X2,Y1,Y2,Z1,Z2;

void read(db &x){
	double z;
	scanf("%lf",&z);
	x=z;
}

db sqr(db x){return x*x;}

db Fbb(db A,db B,db D,db E){
	return sqrt(sqr(A-D)+sqr(B-E));
}

db Faa(db A,db B,db C,db D,db E,db F){
	if(fabs(C-h)<1e-6) return sqrt(D*D+E*E+sqr(F-h));
	if(fabs(F-h)<1e-6) return sqrt(A*A+B*B+sqr(C-h));
	db X3=A*h/(h-C),Y3=B*h/(h-C),X4=D*h/(h-F),Y4=E*h/(h-F);
	db u=Sqr*2-sqr(X3-X4)-sqr(Y3-Y4);
	u/=2*Sqr;
	db the=acos(u);
	db phi=the*r/l;
	db D1=sqr(A)+sqr(B)+sqr(C-h),D2=sqr(D)+sqr(E)+sqr(F-h);
	return sqrt(D1+D2-2*sqrt(D1)*sqrt(D2)*cos(phi));
}

db Fab(db X,db Y,db Z,db E,db F,db the){
	db X3=r*cos(the),Y3=r*sin(the);
	return Faa(X,Y,Z,X3,Y3,0)+Fbb(E,F,X3,Y3);
}

db Fab2(db the){
	db X3=cos(the)*r,Y3=sin(the)*r;
	db l=0,r=2*pi,T1,T2;
	For(i,1,300){
		db md1=(9*l+r)/10.,md2=(l+9*r)/10.;
		T1=Fab(X2,Y2,Z2,X3,Y3,md1);
		T2=Fab(X2,Y2,Z2,X3,Y3,md2);
		if(T1>T2) l=md1;else r=md2;
	}
	return T1+Faa(X1,Y1,Z1,X3,Y3,0);
}

int main(){
	read(r);read(h);Sqr=r*r;
	l=sqrt(r*r+h*h);
	read(X1);read(Y1);read(Z1);
	read(X2);read(Y2);read(Z2);

	if(Z1==0&&Z2==0){
		printf("%.16lf\n",double(Fbb(X1,Y1,X2,Y2)));
		return 0;
	}
	if(Z1!=0&&Z2!=0){
		db ans=Faa(X1,Y1,Z1,X2,Y2,Z2);
		db l=0,r=2*pi,T1,T2;
		For(i,1,300){
			db md1=(9*l+r)/10.,md2=(l+9*r)/10.;
			T1=Fab2(md1);
			T2=Fab2(md2);
			if(T1>T2) l=md1;else r=md2;
		}
		ans=min(ans,T1);
		printf("%.16lf\n",double(ans));
		return 0;
	}
	if(Z1==0){
		swap(X1,X2);
		swap(Y1,Y2);
		swap(Z1,Z2);
	}
	db l=0,r=2*pi,T1,T2;
	For(i,1,500){
		db md1=(2*l+r)/3.,md2=(l+2*r)/3.;
		if((T1=Fab(X1,Y1,Z1,X2,Y2,md1))>(T2=Fab(X1,Y1,Z1,X2,Y2,md2))) l=md1;else r=md2;
	}
	printf("%.16lf\n",double(T1));
	return 0;
}

#include <bits/stdc++.h>

#define inf 0x3f3f3f3f

#define MOD 1000000007

#define pb push_back

#define sq(x) ((x)*(x))

#define x first

#define y second

#define eps 1e-12

#define bpt(x) (__builtin_popcount(x))

#define bptl(x) (__builtin_popcountll(x))

#define bit(x, y) (((x)>>(y))&1)

#define bclz(x) (__builtin_clz(x))

#define bclzl(x) (__builtin_clzll(x))

#define bctz(x) (__builtin_ctz(x))

#define bctzl(x) (__builtin_ctzll(x))

#define sgn(x) (((x)>eps)-((x)<-eps))

#define PQ priority_queue<pii, vector<pii>, greater<pii> >

using namespace std;

typedef long long INT;

typedef vector<int> VI;

typedef pair<int, int> pii;

typedef pair<pii, int> pi3;

typedef long double DO;

template<typename T, typename U> inline void smin(T &a, U b) {if (a>b) a=b;}

template<typename T, typename U> inline void smax(T &a, U b) {if (a<b) a=b;}

template<class T>inline void gn(T &x) {char c, sg=0; while (c=getchar(), (c>'9' || c<'0') && c!='-');for((c=='-'?sg=1, c=getchar():0), x=0; c>='0' && c<='9'; c=getchar()) x=(x<<1)+(x<<3)+c-'0';if (sg) x=-x;}

template<class T, class T1>inline void gn(T &x, T1 &y) {gn(x); gn(y);}

template<class T, class T1, class T2>inline void gn(T &x, T1 &y, T2 &z) {gn(x); gn(y); gn(z);}

template<class T>inline void print(T x) {if (x<0) {putchar('-');return print(-x);}if (x<10) {putchar('0'+x);return;} print(x/10);putchar(x%10+'0');}

template<class T>inline void printsp(T x) {print(x); putchar(' ');}

template<class T>inline void println(T x) {print(x); putchar('\n');}

template<class T, class U>inline void print(T x, U y) {printsp(x); println(y);}

template<class T, class U, class V>inline void print(T x, U y, V z) {printsp(x); printsp(y); println(z);}

int power(int a, int b, int m, int ans=1) {

	for (; b; b>>=1, a=1LL*a*a%m) if (b&1) ans=1LL*ans*a%m;

	return ans;

}

struct point {

	DO x, y, z;

	point (DO x=0, DO y=0, DO z=0) : x(x), y(y), z(z) {}

	point operator - (point a) {return point(x-a.x, y-a.y, z-a.z);}

	point operator + (point a) {return point(x+a.x, y+a.y, z+a.z);}

	point operator * (DO a) {return point(x*a, y*a, z*a);}

	point operator / (DO a) {return point(x/a, y/a, z/a);}

	point operator ^ (point a) {return point(y*a.z-z*a.y, -(x*a.z-z*a.x), x*a.y-y*a.x);}

	DO    operator * (point a) {return x*a.x+y*a.y+z*a.z;}

	point norm() {DO s=nor(); if (s<eps) return *this; return point(x/s, y/s, z/s);}

	DO nor() {return sqrtl(*this**this);}

	bool operator < (const point &a) const {

		if (fabsl(x-a.x)>eps) return x<a.x;

		if (fabsl(y-a.y)>eps) return y<a.y;

		return z<a.z-eps;

	}

	bool operator > (const point &a) const {

		if (fabsl(x-a.x)>eps) return x>a.x;

		if (fabsl(y-a.y)>eps) return y>a.y;

		return z>a.z-eps;

	}

	bool operator == (const point &a) const {

		if (fabsl(x-a.x)>eps) return 0;

		if (fabsl(y-a.y)>eps) return 0;

		return fabs(z-a.z)<eps;

	}

	void input() {cin>>x>>y>>z;}

	void print() {printf("%lf %lf %lf\n", (double)x, (double)y, (double)z);}

};

void print_ans(DO x) {

	cout<<fixed<<setprecision(15)<<x<<endl;

	exit(0);

}

DO L, pi;

DO calc(point &a, DO &lb, DO &phib, DO &r, DO &al) {

	DO be=al*L/r;

	return r-a.nor()+sqrtl(max((DO)0, (L*L+lb*lb-2*lb*L*cosl(be-phib))));

}

DO ST[1111];

point a, b;

DO r, h;

point H;

DO calc3(point a, DO al) {

	DO alpha=atan2l(a.y, a.x);

	if (alpha<0) alpha+=2*pi;

	DO la=(H-a).nor();

	return sqrtl((H-a)*(H-a)+L*L-2*la*L*cosl(alpha*r/L-al));

}

DO calc2(DO al, DO be) {

	DO alpha=al*r/L, beta=be*r/L;

	point c=point(cosl(al)*r, sinl(al)*r), d=point(cosl(be)*r, sinl(be)*r);

	return calc3(a, alpha)+calc3(b, beta)+(c-d).nor();

}

DO calc1(DO al) {

	DO ans=1e100;

	for (int i=0; i<6; i++) {

		DO st=pi/3*i, ed=st+pi/2;

		for (int j=0; j<50; j++) {

			DO x1=(st*2+ed)/3, x2=(st+ed*2)/3;

			if (calc2(al, x1)<calc2(al, x2)) ed=x2;

			else st=x1;

		}

		smin(ans, calc2(al, st));

	}

	return ans;

}

int main() {

#ifndef ONLINE_JUDGE

	freopen("in.in", "r", stdin);

	freopen("out.out", "w", stdout);

#endif

	cin>>r>>h;

	a.input(); b.input();

	L=sqrtl(r*r+h*h), pi=acosl(-1.0);

	if (a.z<eps && b.z<eps) print_ans((a-b).nor());

	if (a.z>b.z-eps) swap(a, b);

	H=point(0, 0, h);

	if (b.z>h-eps) {

		if (a.z>h-eps) print_ans((DO)0.0);

		if (a.z<eps) print_ans(L+r-a.nor());

		print_ans((H-a).nor());

	}

	if (a.z>eps) {

		DO al=atan2l(a.y, a.x);

		DO be=atan2l(b.y, b.x);

		if (al<0) al+=2*pi;

		if (be<0) be+=2*pi;

		DO la=(H-a).nor();

		DO lb=(H-b).nor();

		DO phia=al*r/L, phib=be*r/L;

		DO ans=sqrtl(max((DO)0.0, (H-a)*(H-a)+(H-b)*(H-b)-2*la*lb*cosl(phia-phib)));

		for (int i=0; i<6; i++) {

			DO st=pi/3*i, ed=st+pi/2;

			for (int j=0; j<50; j++) {

				DO x1=(st*2+ed)/3, x2=(st+ed*2)/3;

				if (calc1(x1)<calc1(x2)) ed=x2;

				else st=x1;

			}

			smin(ans, calc1(st));

		}

		print_ans(ans);

	}

	DO al=atan2l(a.y, a.x);

	DO be=atan2l(b.y, b.x);

	if (al<0) al+=2*pi;

	if (be<0) be+=2*pi;

	DO lb=(H-b).nor();

	DO phib=be*r/L;

	DO ans=(DO)1e100;

	for (int j=0; j<6; j++) {

		DO st=(pi/3*j)*r/L, ed=(pi/3*j+pi/2)*r/L;

		for (int i=0; i<200; i++) {

			DO x1=(st*2+ed)/3, x2=(st+ed*2)/3;

			if (calc(a, lb, phib, r, x1)<calc(a, lb, phib, r, x2)) ed=x2;

			else st=x1;

		}

		smin(ans, calc(a, lb, phib, r, st));

	}

	print_ans(ans);

	return 0;

}

#define pi 3.1415926535897932384626433832795

#include<bits/stdc++.h>

#define eps 1e-9

typedef double DO;

using namespace std;

template<typename T, typename U> inline void smin(T &a, const U &b) {if(a>b) a=b;}

template<typename T, typename U> inline void smax(T &a, const U &b) {if(a<b) a=b;}

struct point {

	DO x, y, z;

	inline point(DO x=0, DO y=0, DO z=0) : x(x), y(y), z(z) {}

	inline point operator - (point a) {return point(x-a.x, y-a.y, z-a.z);}

	inline point operator + (point a) {return point(x+a.x, y+a.y, z+a.z);}

	inline point operator * (DO a) {return point(x*a, y*a, z*a);}

	inline point operator / (DO a) {return point(x/a, y/a, z/a);}

	inline point operator ^ (point a) {return point(y*a.z-z*a.y, -(x*a.z-z*a.x), x*a.y-y*a.x);}

	inline DO operator * (point a) {return x*a.x+y*a.y+z*a.z;}

	inline point norm() {DO s=nor(); if(s<eps) return *this; return point(x/s, y/s, z/s);}

	inline DO nor() {return sqrt(nor2());}

	inline DO nor2() {return *this**this;}

	inline DO al() {return atan2(y, x);}

	inline bool operator < (const point &a) const {

		if(fabs(x-a.x)>eps) return x<a.x;

		if(fabs(y-a.y)>eps) return y<a.y;

		return z<a.z-eps;

	}

	inline bool operator > (const point &a) const {

		if(fabs(x-a.x)>eps) return x>a.x;

		if(fabs(y-a.y)>eps) return y>a.y;

		return z>a.z+eps;

	}

	inline bool operator == (const point &a) const {

		if(fabs(x-a.x)>eps) return 0;

		if(fabs(y-a.y)>eps) return 0;

		return fabs(z-a.z)<eps;

	}

	inline void input() {scanf("%lf %lf %lf", &x, &y, &z);}

	inline void print() {printf("%lf %lf %lf\n", x, y, z);}

};

DO whole=2*pi, step=whole/3;

DO r, h, R;

point A, AA, B;

inline DO calc_laterals(point a, point b) {

	DO al=fabs(a.al()-b.al()); smin(al, whole-al);

	DO dada=(a-point(0, 0, h)).nor2(), da=sqrt(dada);

	DO dbdb=(b-point(0, 0, h)).nor2(), db=sqrt(dbdb);

	return sqrt(dada+dbdb-2*da*db*cos(r*al/R));

}

inline DO solve() {

	DO ans=1e13;

	for(DO sst=0; sst<whole; sst+=step) {

		DO st=sst, ed=st+step;

		while(ed-st>eps) {

			DO a=(st+st+ed)/3, b=(st+ed+ed)/3;

			point aa=point(r*cos(a), r*sin(a)); DO sa=(AA-aa).nor()+calc_laterals(aa, B);

			point bb=point(r*cos(b), r*sin(b)); DO sb=(AA-bb).nor()+calc_laterals(bb, B);

			if(sa>sb) st=a;

			else ed=b;

		}

		point aa=point(r*cos(st), r*sin(st)); smin(ans, (AA-aa).nor()+calc_laterals(aa, B));

		point bb=point(r*cos(ed), r*sin(ed)); smin(ans, (AA-bb).nor()+calc_laterals(bb, B));

	}

	return ans;

}

main() {

#ifndef	ONLINE_JUDGE

	freopen("in.in", "r", stdin);

	freopen("out.out", "w", stdout);

#endif

	scanf("%lf %lf", &r, &h);

	R=sqrt(r*r+h*h);

	A.input(), B.input();

	if(B.z<eps) swap(A, B);

	DO ans;

	if(A.z<eps) {

		if(B.z<eps) ans=(A-B).nor();

		else AA=A, ans=solve();

	}

	else {

		ans=calc_laterals(A, B);

		for(DO sst=0; sst<whole; sst+=step) {

			DO st=sst, ed=st+step;

			while(ed-st>eps) {

				DO a=(st+st+ed)/3, b=(st+ed+ed)/3;

				AA=point(r*cos(a), r*sin(a)); DO sa=calc_laterals(A, AA)+solve();

				AA=point(r*cos(b), r*sin(b)); DO sb=calc_laterals(A, AA)+solve();

				if(sa>sb) st=a;

				else ed=b;

			}

			AA=point(r*cos(st), r*sin(st)); smin(ans, calc_laterals(A, AA)+solve());

			AA=point(r*cos(ed), r*sin(ed)); smin(ans, calc_laterals(A, AA)+solve());

		}

	}

	printf("%.7lf", ans);

}

#include<stdio.h>
#include<math.h>
#include<algorithm>
#include<stdlib.h>
#include<string.h>
#include<string>
using namespace std;
typedef double db;
const db pi=acos(-1),eps=0.1;
struct p{
    db x,y,z;
}a,b,c,v;
void set(p&a,db x,db y,db z){
    a.x=x;a.y=y;a.z=z;
}
void swap(db&a,db&b){
    db c=a;a=b;b=c;
}
db sqr(db a){
    return a*a;
}
void swap(p&a,p&b){
    p c=a;a=b;b=c;
}
db r,h,l,z;
db dis(p a,p b){
    return sqrt(sqr(a.x-b.x)+sqr(a.y-b.y)+sqr(a.z-b.z));
}
db abs(db x){
    if(x<0)return -x;
    return x;
}
db cc(db a,db b,db z){
    return sqrt(sqr(a)+sqr(b)-2*cos(z)*a*b);
}
db aa(p a){
    return atan2(a.y,a.x);
}
db zt(p a,p b){
    db z=abs(aa(a)-aa(b));
    return min(z,2*pi-z);
}
db zt(db z){
    return z*r/l;
}
db diss(p a,p b){
    return cc(dis(a,v),dis(b,v),zt(zt(a,b)));
}
db rt(p&a,db z){
    set(a,a.x*cos(z)-a.y*sin(z),a.x*sin(z)+a.y*cos(z),a.z);
}
p rp(db z){
    p o;
    set(o,r*cos(z),r*sin(z),0);
    return o;
}
db ff(p a,p b,db z){
    p o=rp(z);
    return diss(b,o)+dis(a,o);
}
db fff(p a,p b,db z){
    p o=rp(z);
    db ll=aa(b)-eps,rr=aa(b)+eps,m1,m2;
    for(int i=200;i;i--){
        m1=ll+(rr-ll)*0.49;
        m2=ll+(rr-ll)*0.51;
        if(ff(o,b,m1)<ff(o,b,m2))rr=m2;else ll=m1;
    }
    return diss(a,o)+ff(o,b,ll);
}
int main(){
    scanf("%lf%lf",&r,&h);
    scanf("%lf%lf%lf",&a.x,&a.y,&a.z);
    scanf("%lf%lf%lf",&b.x,&b.y,&b.z);
    if(a.z==0&&b.z==0){
        printf("%.15lf\n",dis(a,b));
        return 0;
    }
    set(v,0,0,h);
    l=sqrt(sqr(r)+sqr(h));
    if(a.z> 0&&b.z> 0){
        db lll=aa(a)-eps,rrr=aa(a)+eps,m1,m2;
        for(int i=200;i;i--){
            m1=lll+(rrr-lll)*0.49;
            m2=lll+(rrr-lll)*0.51;
            if(fff(a,b,m1)<fff(a,b,m2))rrr=m2;else lll=m1;
        }
//        printf("%.15lf\n\n",dis(a,rp(aa(a)))+dis(b,rp(aa(b)))+dis(rp(aa(a)),rp(aa(b))));
//        printf("%.15lf\n%.15lf\n\n",sqrt(sqr(a.x)+sqr(a.y)),sqrt(sqr(b.x)+sqr(b.y)));
//        printf("%.15lf\n%.15lf\n\n",diss(a,b),fff(a,b,lll));
        printf("%.15lf\n",min(diss(a,b),fff(a,b,lll)));
        return 0;
    }
    if(b.z==0)swap(a,b);
    rt(b,-aa(a));
    set(a,sqrt(sqr(a.x)+sqr(a.y)),0,0);
    if(b.y<0)set(b,b.x,-b.y,b.z);
    db ll=0,rr=aa(b),m1,m2;
    for(int i=200;i;i--){
        m1=ll+(rr-ll)*0.49;
        m2=ll+(rr-ll)*0.51;
        if(ff(a,b,m1)<ff(a,b,m2))rr=m2;else ll=m1;
    }
    printf("%.15lf\n",ff(a,b,ll));
	return 0;
}

// eddy1021
#include <bits/stdc++.h>
using namespace std;
typedef double D;
typedef long double LD;
typedef long long ll;
typedef long long LL;
typedef pair<int,int> PII;
typedef pair<LL,LL> PLL;
// typedef pair<LD,LD> Pt;
typedef tuple<int,int,int> tiii;
typedef tuple<LL,LL,LL> tlll;
#define mod9 1000000009ll
#define mod7 1000000007ll
#define INF  1023456789ll
#define INF16 10000000000000000ll
#define FI first
#define SE second
// #define X FI
// #define Y SE
#define PB push_back
#define MP make_pair
#define MT make_tuple
#define eps 1e-9
#define SZ(x) (int)(x).size()
#define ALL(x) (x).begin(), (x).end()
#ifndef ONLINE_JUDGE
#define debug(...) printf(__VA_ARGS__)
#else
#define debug(...)
#endif
inline ll getint(){
  ll _x=0,_tmp=1; char _tc=getchar();
  while( (_tc<'0'||_tc>'9')&&_tc!='-' ) _tc=getchar();
  if( _tc == '-' ) _tc=getchar() , _tmp = -1;
  while(_tc>='0'&&_tc<='9') _x*=10,_x+=(_tc-'0'),_tc=getchar();
  return _x*_tmp;
}
inline ll add( ll _x , ll _y , ll _mod = mod7 ){
  ll _ = _x + _y;
  if( _ >= _mod ) _ -= _mod;
  return _;
}
inline ll sub( ll _x , ll _y , ll _mod = mod7 ){
  ll _ = _x - _y;
  if( _ < 0 ) _ += _mod;
  return _;
}
inline ll mul( ll _x , ll _y , ll _mod = mod7 ){
  ll _ = _x * _y;
  if( _ >= _mod ) _ %= _mod;
  return _;
}
ll mypow( ll _a , ll _x , ll _mod ){
  if( _x == 0 ) return 1ll;
  ll _tmp = mypow( _a , _x / 2 , _mod );
  _tmp = mul( _tmp , _tmp , _mod );
  if( _x & 1 ) _tmp = mul( _tmp , _a , _mod );
  return _tmp;
}
ll mymul( ll _a , ll _x , ll _mod ){
  if( _x == 0 ) return 0ll;
  ll _tmp = mymul( _a , _x / 2 , _mod );
  _tmp = add( _tmp , _tmp , _mod );
  if( _x & 1 ) _tmp = add( _tmp , _a , _mod );
  return _tmp;
}
inline bool equal( LD _x ,  LD _y ){
  return _x > _y - eps && _x < _y + eps;
}
int __ = 1 , _cs;
/*********default*********/
inline LD getLD(){
  D _; scanf( "%lf" , &_ );
  return _;
}
typedef tuple<LD,LD,LD> Pt;
#define X(U) get<0>(U)
#define Y(U) get<1>(U)
#define Z(U) get<2>(U)
inline void scan( Pt& tp ){
  X( tp ) = getLD();
  Y( tp ) = getLD();
  Z( tp ) = getLD();
}
inline void print( const Pt& tp ){
  printf( "(%.6f,%.6f,%.6f)\n" , (D)X( tp ) , (D)Y( tp ) , (D)Z( tp ) );
}
inline bool onbase( const Pt& tp ){
  return equal( Z( tp ) , 0.0 );
}
inline LD sqr( const LD& x ){ return x * x; }
LD r , h , ans , rr;
Pt p[ 2 ];
const LD pi = acosl( -1.0 );
const LD pi2 = 2.0 * acosl( -1.0 );
void build(){
}
void init(){
  r = getLD();
  h = getLD();
  rr = sqrt( sqr( r ) + sqr( h ) );
  scan( p[ 0 ] );
  scan( p[ 1 ] );
}
inline LD dist( const Pt& x , const Pt&y ){
  return sqrt( sqr( X( x ) - X( y ) ) +
               sqr( Y( x ) - Y( y ) ) +
               sqr( Z( x ) - Z( y ) ) );
}
inline LD dist_oncone( const Pt& x , const Pt& y ){
  LD ang1 = atan2( Y( x ) , X( x ) );
  LD ang2 = atan2( Y( y ) , X( y ) );
  LD dang = fabs( ang1 - ang2 );
  dang *= r / rr;
  LD r1 = rr * ( 1.0 - Z( x ) / h );
  LD r2 = rr * ( 1.0 - Z( y ) / h );
  Pt p1 = MT( r1 , 0.0 , 0.0 );
  Pt p2 = MT( cosl( dang ) * r2 , sinl( dang ) * r2 , 0.0 );
  return dist( p1 , p2 );
}
inline void cal1(){
  ans = min( ans , dist( p[ 0 ] , p[ 1 ] ) );
}
inline void cal2(){
#define K 3500000
  for( int i = 0 ; i < K ; i ++ ){
    Pt tmp = MT( cosl( (LD)i / (LD)K * pi2 ) * r ,
                 sinl( (LD)i / (LD)K * pi2 ) * r ,
                 0.0 );
    ans = min( ans , dist( tmp , p[ 0 ] ) + dist_oncone( tmp , p[ 1 ] ) );
  }
}
#define KK 950
#define DD 0.95
inline LD cal4( const Pt& p1 , const Pt& p2 ){
  LD bans = 1e40 , st = atan2( Y( p2 ) , X( p2 ) ) , nst = st , dlt = pi - eps;
  for( int i = 0 ; i < KK ; i ++ ){
    for( int j = -1 ; j <= 1 ; j += 2 ){
      LD tst = st + dlt * j;
      Pt tmp = MT( cosl( tst ) * r , sinl( tst ) * r , 0.0 );
      LD tans = dist_oncone( p2 , tmp ) + dist( p1 , tmp );
      if( tans < bans )
        bans = tans, nst = tst;
    }
    dlt *= DD;
    st = nst;
  }
  return bans;
}
inline void cal3(){
  ans = min( ans , dist_oncone( p[ 0 ] , p[ 1 ] ) );
  LD bans = 1e40 , st = atan2( Y( p[ 0 ] ) , X( p[ 0 ] ) ) , nst = st , dlt = pi - eps;
  for( int i = 0 ; i < KK ; i ++ ){
    for( int j = -1 ; j <= 1 ; j += 2 ){
      LD tst = st + dlt * j;
      Pt tmp = MT( cosl( tst ) * r , sinl( tst ) * r , 0.0 );
      LD tans = dist_oncone( p[ 0 ] , tmp ) + cal4( tmp , p[ 1 ] );
      ans = min( ans , tans );
      if( tans < bans )
        bans = tans, nst = tst;
    }
    dlt *= DD;
    st = nst;
  }
}
void solve(){
  ans = 1e40;
  if( onbase( p[ 0 ] ) && onbase( p[ 1 ] ) ) cal1();
  else if( onbase( p[ 0 ] ) || onbase( p[ 1 ] ) ){
    if( onbase( p[ 1 ] ) ) swap( p[ 0 ] , p[ 1 ] );
    cal2();
  }else cal3();
  printf( "%.12f\n" , (D)ans );
}
int main(){
  build();
  //__ = getint();
  while( __ -- ){
    init();
    solve();
  }
}

#define pi 3.1415926535897932384626433832795

#include<bits/stdc++.h>

#define eps 1e-12

typedef long double DO;

using namespace std;

template<typename T, typename U> inline void smin(T &a, const U &b) {if(a>b) a=b;}

struct point {

	DO x, y, z;

	inline point(DO x=0, DO y=0, DO z=0) : x(x), y(y), z(z) {}

	inline point operator - (point a) {return point(x-a.x, y-a.y, z-a.z);}

	inline point operator + (point a) {return point(x+a.x, y+a.y, z+a.z);}

	inline point operator * (DO a) {return point(x*a, y*a, z*a);}

	inline point operator / (DO a) {return point(x/a, y/a, z/a);}

	inline point operator ^ (point a) {return point(y*a.z-z*a.y, -(x*a.z-z*a.x), x*a.y-y*a.x);}

	inline DO operator * (point a) {return x*a.x+y*a.y+z*a.z;}

	inline point norm() {DO s=nor(); if(s<eps) return *this; return point(x/s, y/s, z/s);}

	inline DO nor() {return sqrtl(*this**this);}

	inline DO nor2() {return *this**this;}

	inline point rotate(DO al) {return *this&point(cosl(al), sinl(al), z);}

	inline point operator & (point a) {return point(x*a.x-y*a.y, x*a.y+y*a.x, z);}

	inline void input() {cin>>x>>y>>z;}

};

DO r, h, R, R2, len;

point focus, a, b, c, ac, A;

inline DO calc1(DO x) {

	point d=c.rotate(x/r);

	DO ans1=(A-d).nor();

	smin(x, len-x);

	DO D2=(b-focus).nor2(), D=sqrtl(D2);

	DO ans2=sqrtl(R2+D2-2*R*D*cosl(x/R));

	return ans1+ans2;

}

inline DO solve() {

	DO st=0, ed=len;

	while(ed-st>eps) {

		DO a=(st+st+ed)/3, b=(st+ed+ed)/3;

		if(calc1(a)>calc1(b)) st=a;

		else ed=b;

	}

	return calc1(st);

}

inline DO calc2(DO x) {

	A=ac.rotate(x/r);

	smin(x, len-x);

	DO D2=(a-focus).nor2(), D=sqrt(D2);

	return sqrtl(R2+D2-2*R*D*cosl(x/R))+solve();

}

inline DO angle(point a, point b) {

	DO res=a*b/a.nor()/b.nor();

	res=acosl(res);

	return res;

}

inline DO kong() {

	DO aa2=(a-focus).nor2(), aa=sqrtl(aa2);

	DO bb2=(b-focus).nor2(), bb=sqrtl(bb2);

	DO x=angle(c, ac)*r;

	smin(x, len-x);

	return sqrtl(aa2+bb2-2*aa*bb*cosl(x/R));

}

main() {

#ifndef	ONLINE_JUDGE

	freopen("in.in", "r", stdin);

	freopen("out.out", "w", stdout);

#endif

	cin>>r>>h;

	a.input(), b.input();

	if(fabsl(b.z)<eps) swap(a, b);

	len=2*pi*r;

	R2=h*h+r*r, R=sqrtl(R2);

	focus=point(0, 0, h);

	c=focus+(b-focus).norm()*R;

	if(fabsl(a.z)<eps) {

		if(fabsl(b.z)<eps) printf("%.7lf", (double)(a-b).nor());

		else {

			A=a;

			printf("%.7lf", (double)solve());

		}

	}

	else {

		ac=focus+(a-focus).norm()*R;

		DO st=0, ed=len;

		while(ed-st>eps) {

			DO a=(st+st+ed)/3, b=(st+ed+ed)/3;

			if(calc2(a)>calc2(b)) st=a;

			else ed=b;

		}

		printf("%.7lf", (double)min(kong(), calc2(st)));

	}

}

#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <string>
#include <set>
#include <vector>
#include <cmath>
#include <cassert>
#include <cstdlib>
#include <map>
#include <queue>
#include <deque>
#include <bitset>

#define y0 y63475625
#define y1 y28435
#define j0 jfd0sf
#define j1 je90ue0
#define sqr(x) ((x)*(x))
#define fi first
#define se second
#define pb push_back
#define mp make_pair
#define re return
#define sz(x) ((int)(x).size())
#define all(x) (x).begin(), (x).end()
#define rep(i, n) for (int i = 0; i < (n); i++)
#define rrep(i, n) for (int i = (n) - 1; i >= 0; i--)
#define sqrt(x) (sqrt(abs(x)))
#define fill(a, x) memset(a, x, sizeof(a))

using namespace std;

typedef vector <int> vi;
typedef vector <vi> vvi;
typedef long long ll;
typedef long double ld;
typedef pair <int, int> ii;
typedef vector <ii> vii;
typedef double D;
typedef pair <ll, ll> pll;
typedef vector <string> vs;

template <class T> T abs(const T a) {
    return a > 0 ? a : -a;
}

const double PI = 2.0 * acos(1.0);

const ld eps = 1e-12;

ld alpha;

int n;
int m;

ld dist(ld ra, ld rb, ld angle) {
    if (abs(ra) < eps) {
        re rb * alpha;
    }
    if (abs(rb) < eps) {
        re ra * alpha;
    }
    if (fabs(angle) < eps)
        re abs(rb - ra) * alpha;
    ld co = rb * sin(angle / alpha);
    ld si = (ra - rb * cos(angle / alpha));
    ld q = sqrt(sqr(co) + sqr(si));
    co /= q; si /= q;
    ld f0 = alpha * atan2(si, co);
    re abs(alpha * ra * (co * tan((angle - f0) / alpha) + si));
}

int main()
{
    ld r, h;
    cin >> r >> h;
    ld xa, ya, za, xb, yb, zb;
    cin >> xa >> ya >> za;
    cin >> xb >> yb >> zb;
    if (abs(zb) < eps && abs(za) < eps) {
        printf("%.10lf\n", (D)sqrt(sqr(xb - xa) + sqr(yb - ya)));
        re 0;
    }
    if (abs(zb) < eps) {
        swap(xa, xb);
        swap(ya, yb);
        swap(za, zb);
    }

    alpha = sqrt(1.0 + sqr(h / r));
    if (abs(za) > eps && abs(zb) > eps) {
        ld ra = sqrt(sqr(xa) + sqr(ya));
        ld rb = sqrt(sqr(xb) + sqr(yb));
        ld angle = -1.0;
        if (abs(ra) > eps && abs(rb) > eps)
            angle = acos((xa * xb + ya * yb) / ra / rb);
        ld ans = dist(ra, rb, angle);
        ld fans1 = -1, fans2 = -1;
        rep(i, 1) {
            ld L1 = -M_PI / 2, R1 = M_PI / 2.0;
            ld L2 = -M_PI / 2, R2 = M_PI / 2.0;
            n = 2000;
            rep(j, n) {
                ld f1 = L1 + (R1 - L1) * j / (ld)n;
                rep(k, n) {
                    ld f2 = L2 + (R2 - L2) * k / (ld)n;
                    ld tmp = r * sqrt(2.0 - 2.0 * cos(angle + f1 - f2)) + dist(r, ra, f1) + dist(r, rb, f2);
                    if (tmp < ans) {
                        ans = tmp;
                        fans1 = f1;
                        fans2 = f2;
                    }
                }
            }
            ld d = R1 - L1;
            L1 = fans1 - d / 2.0 * 0.99;
            L2 = fans2 - d / 2.0 * 0.99;
            R1 = fans1 + d / 2.0 * 0.99;
            R2 = fans2 + d / 2.0 * 0.99;
        }
        printf("%.10lf\n", (D)ans);
        re 0;
    } else {
        //todo
        /*ld L = 0.0, R = 2.0 * M_PI;
        ld ans = 1e20;
        ld fans = -1;
        rep(i, 2000) {
            rep(j, 100) {
                double f = L + (R - L) / 100.0 * j;
                ld x = r * cos(f);
                ld y = r * sin(f);
                ld tmp = sqrt(sqr(xa - x) + sqr(ya - y)) + dist(x, y, xb, yb);
                if (tmp < ans) {
                    ans = tmp;
                    fans = f;
                }
            }
            ld d = R - L;
            L = fans - d / 2.0 * 0.9;
            R = fans + d / 2.0 * 0.9;
        }
        printf("%.10lf\n", (D)ans);*/
    }
    return 0;
}

#include <iostream>
#include <cstdio>
#include <vector>
#include <algorithm>
#include <cstring>
#include <string>
#include <queue>
#include <set>
#include <map>
#include <bitset>
#include <cmath>
#include <ctime>
#pragma comment (linker, "/STACK:256000000")

using namespace std;

const double eps = 1e-9;
const double pi = 2.0 * acos(0.0);
double r, h;

double dist(double x1, double y1, double z1, double x2, double y2, double z2) {
	double dx = x1 - x2;
	double dy = y1 - y2;
	double dz = z1 - z2;
	return sqrt(dx * dx + dy * dy + dz * dz);
}

double dist(double x1, double y1, double x2, double y2) {
	double dx = x1 - x2;
	double dy = y1 - y2;
	return sqrt(dx * dx + dy * dy);
}

double solve(double x1, double y1, double z1, double x2, double y2, double z2) {
	if (fabs(z1) < eps && fabs(z2) < eps) {
		return dist(x1, y1, z1, x2, y2, z2);
	}

	double l1 = dist(x1, y1, z1, 0, 0, h);
	double l2 = dist(x2, y2, z2, 0, 0, h);

	if (fabs(l1) < eps || fabs(l2) < eps) {
		return l1 + l2;
	}

	double coef = l2 / l1;
	double xn = x1 * coef;
	double yn = y1 * coef;
	double zn = h + (z1 - h) * coef;
	double cr = sqrt(l2 * l2 - (h - z2) * (h - z2));
	double ang = acos((xn * x2 + yn * y2) / (cr * cr));

	double length = ang * r;
	double alpha = length / sqrt(r * r + h * h);

	double u1 = l1, v1 = 0.0;
	double u2 = l2 * cos(alpha), v2 = l2 * sin(alpha);

	return dist(u1, v1, u2, v2);
}

/*double solve(double x1, double y1, double z1, double x2, double y2, double z2) {
	double A = solve1(x1, y1, z1, x2, y2, z2);
	double B = solve1(x2, y2, z2, x1, y1, z1);

	if (fabs(A - B) > eps) {
		int t = 0;
		solve1(x1, y1, z1, x2, y2, z2);
		solve1(x2, y2, z2, x1, y1, z1);
	}
	return min(A, B);
}*/

double calc(double xa, double ya, double za, double xb, double yb, double zb, double x0, double y0, double z0, double L, double R) {
	double res = 1e20;
	double d = solve(xa, ya, za, x0, y0, z0);
	for (int i = 0; i < 60; ++i) {
		double x = (2.0 * L + R) / 3.0;
		double y = (L + 2.0 * R) / 3.0;

		double x1 = r * cos(x), y1 = r * sin(x);
		double x2 = r * cos(y), y2 = r * sin(y);

		double A = solve(x0, y0, z0, x1, y1, 0.0) + solve(x1, y1, 0.0, xb, yb, zb);
		double B = solve(x0, y0, z0, x2, y2, 0.0) + solve(x2, y2, 0.0, xb, yb, zb);
		res = min(res, d + A);
		res = min(res, d + B);
		if (A < B) {
			R = y;
		} else {
			L = x;
		}
	}
	return res;
}

int main() {
	//freopen("input.txt", "r", stdin);
	//freopen("output.txt", "w", stdout);

	cin >> r >> h;
	double xa, ya, za;
	double xb, yb, zb;
	cin >> xa >> ya >> za;
	cin >> xb >> yb >> zb;

	double res = 1e20;
	if (fabs(za) > eps && fabs(zb) > eps) {
		res = min(res, solve(xa, ya, za, xb, yb, zb));
	}
	if (fabs(za) < eps && fabs(zb) < eps) {
		res = min(res, dist(xa, ya, za, xb, yb, zb));
	}

	double angle = 2.0 * pi / 1000;
	for (int step = 0; step < 1000; ++step) {
		double left_bound = (double)(step) * angle;
		double right_bound = (double)(step + 1) * angle;

		for (int i = 0; i < 200; ++i) {
			double L = (2.0 * left_bound + right_bound) / 3.0;
			double R = (left_bound + 2.0 * right_bound) / 3.0;

			double valueL = solve(xa, ya, za, r * cos(L), r * sin(L), 0) + solve(r * cos(L), r * sin(L), 0, xb, yb, zb);
			double valueR = solve(xa, ya, za, r * cos(R), r * sin(R), 0) + solve(r * cos(R), r * sin(R), 0, xb, yb, zb);
			res = min(res, valueL);
			res = min(res, valueR);
			if (valueL < valueR) {
				right_bound = R;
			} else {
				left_bound = L;
			}
		}
	}
	//printf("%.12lf\n", res);
	int cnt = 5;
	angle = 2.0 * pi / (double)(cnt);
	res = 1e20;
	for (int stepA = 0; stepA < cnt; ++stepA) {
		for (int stepB = 0; stepB < cnt; ++stepB) {
			double left_bound = (double)(stepA) * angle;
			double right_bound = (double)(stepA + 1) * angle;

			double lB = (double)(stepB) * angle;
			double rB = (double)(stepB + 1) * angle;
			for (int i = 0; i < 60; ++i) {
				double L = (2.0 * left_bound + right_bound) / 3.0;
				double R = (left_bound + 2.0 * right_bound) / 3.0;

				double valueL = calc(xa, ya, za, xb, yb, zb, r * cos(L), r * sin(L), 0.0, lB, rB);
				double valueR = calc(xa, ya, za, xb, yb, zb, r * cos(R), r * sin(R), 0.0, lB, rB);
				res = min(res, valueL);
				res = min(res, valueR);
				if (valueL < valueR) {
					right_bound = R;
				} else {
					left_bound = L;
				}
			}
		}
	}

	printf("%.12lf\n", res);

	return 0;
}

#include<stdio.h>
#include<math.h>
#include<algorithm>
#include<stdlib.h>
#include<string.h>
#include<string>
using namespace std;
typedef double db;
const db pi=acos(-1),eps=0.2;
struct p{
    db x,y,z;
}a,b,c,v;
void set(p&a,db x,db y,db z){
    a.x=x;a.y=y;a.z=z;
}
void swap(db&a,db&b){
    db c=a;a=b;b=c;
}
db sqr(db a){
    return a*a;
}
void swap(p&a,p&b){
    p c=a;a=b;b=c;
}
db r,h,l,z;
db dis(p a,p b){
    return sqrt(sqr(a.x-b.x)+sqr(a.y-b.y)+sqr(a.z-b.z));
}
db abs(db x){
    if(x<0)return -x;
    return x;
}
db cc(db a,db b,db z){
    return sqrt(sqr(a)+sqr(b)-2*cos(z)*a*b);
}
db aa(p a){
    return atan2(a.y,a.x);
}
db zt(p a,p b){
    db z=abs(aa(a)-aa(b));
    return min(z,2*pi-z);
}
db zt(db z){
    return z*r/l;
}
db diss(p a,p b){
    return cc(dis(a,v),dis(b,v),zt(zt(a,b)));
}
db rt(p&a,db z){
    set(a,a.x*cos(z)-a.y*sin(z),a.x*sin(z)+a.y*cos(z),a.z);
}
p rp(db z){
    p o;
    set(o,r*cos(z),r*sin(z),0);
    return o;
}
db ff(p a,p b,db z){
    p o=rp(z);
    return diss(b,o)+dis(a,o);
}
db fff(p a,p b,db z){
    p o=rp(z);
    db ll=aa(b)-eps,rr=aa(b)+eps,m1,m2;
    for(int i=200;i;i--){
        m1=ll+(rr-ll)*0.49;
        m2=ll+(rr-ll)*0.51;
        if(ff(o,b,m1)<ff(o,b,m2))rr=m2;else ll=m1;
    }
    return diss(a,o)+ff(o,b,ll);
}
int main(){
    scanf("%lf%lf",&r,&h);
    scanf("%lf%lf%lf",&a.x,&a.y,&a.z);
    scanf("%lf%lf%lf",&b.x,&b.y,&b.z);
    if(a.z==0&&b.z==0){
        printf("%.15lf\n",dis(a,b));
        return 0;
    }
    set(v,0,0,h);
    l=sqrt(sqr(r)+sqr(h));
    if(a.z> 0&&b.z> 0){
        db lll=aa(a)-eps,rrr=aa(a)+eps,m1,m2;
        for(int i=200;i;i--){
            m1=lll+(rrr-lll)*0.49;
            m2=lll+(rrr-lll)*0.51;
            if(fff(a,b,m1)<fff(a,b,m2))rrr=m2;else lll=m1;
        }
//        printf("%.15lf\n\n",dis(a,rp(aa(a)))+dis(b,rp(aa(b)))+dis(rp(aa(a)),rp(aa(b))));
//        printf("%.15lf\n%.15lf\n\n",sqrt(sqr(a.x)+sqr(a.y)),sqrt(sqr(b.x)+sqr(b.y)));
//        printf("%.15lf\n%.15lf\n\n",diss(a,b),fff(a,b,lll));
        printf("%.15lf\n",min(diss(a,b),fff(a,b,lll)));
        return 0;
    }
    if(b.z==0)swap(a,b);
    rt(b,-aa(a));
    set(a,sqrt(sqr(a.x)+sqr(a.y)),0,0);
    if(b.y<0)set(b,b.x,-b.y,b.z);
    db ll=0,rr=aa(b),m1,m2;
    for(int i=200;i;i--){
        m1=ll+(rr-ll)*0.49;
        m2=ll+(rr-ll)*0.51;
        if(ff(a,b,m1)<ff(a,b,m2))rr=m2;else ll=m1;
    }
    printf("%.15lf\n",ff(a,b,ll));
	return 0;
}

#include <iostream>
#include <cstdio>
#include <vector>
#include <algorithm>
#include <cstring>
#include <string>
#include <queue>
#include <set>
#include <map>
#include <bitset>
#include <cmath>
#include <ctime>
#pragma comment (linker, "/STACK:256000000")

using namespace std;

const double eps = 1e-9;
const double pi = 2.0 * acos(0.0);
double r, h;

double dist(double x1, double y1, double z1, double x2, double y2, double z2) {
	double dx = x1 - x2;
	double dy = y1 - y2;
	double dz = z1 - z2;
	return sqrt(dx * dx + dy * dy + dz * dz);
}

double dist(double x1, double y1, double x2, double y2) {
	double dx = x1 - x2;
	double dy = y1 - y2;
	return sqrt(dx * dx + dy * dy);
}

double solve(double x1, double y1, double z1, double x2, double y2, double z2) {
	if (fabs(z1) < eps && fabs(z2) < eps) {
		return dist(x1, y1, z1, x2, y2, z2);
	}

	double l1 = dist(x1, y1, z1, 0, 0, h);
	double l2 = dist(x2, y2, z2, 0, 0, h);

	if (fabs(l1) < eps || fabs(l2) < eps) {
		return l1 + l2;
	}

	double coef = l2 / l1;
	double xn = x1 * coef;
	double yn = y1 * coef;
	double cr = sqrt(l2 * l2 - (h - z2) * (h - z2));
	double ang = acos((xn * x2 + yn * y2) / (cr * cr));

	double length = ang * cr;
	double alpha = length / l2;

	double u1 = l1, v1 = 0.0;
	double u2 = l2 * cos(alpha), v2 = l2 * sin(alpha);

	return dist(u1, v1, u2, v2);
}

int main() {
	//freopen("input.txt", "r", stdin);
	//freopen("output.txt", "w", stdout);

	cin >> r >> h;
	double xa, ya, za;
	double xb, yb, zb;
	cin >> xa >> ya >> za;
	cin >> xb >> yb >> zb;

	double res = 1e20;
	if (fabs(za) > eps && fabs(zb) > eps) {
		res = min(res, solve(xa, ya, za, xb, yb, zb));
	}
	if (fabs(za) < eps && fabs(zb) < eps) {
		res = min(res, dist(xa, ya, za, xb, yb, zb));
	}

	double angle = 2.0 * pi / 100.0;
	for (int step = 0; step < 100; ++step) {
		double left_bound = (double)(step) * angle;
		double right_bound = (double)(step + 1) * angle;

		for (int i = 0; i < 200; ++i) {
			double L = (2.0 * left_bound + right_bound) / 3.0;
			double R = (left_bound + 2.0 * right_bound) / 3.0;

			double valueL = solve(xa, ya, za, r * cos(L), r * sin(L), 0) + solve(r * cos(L), r * sin(L), 0, xb, yb, zb);
			double valueR = solve(xa, ya, za, r * cos(R), r * sin(R), 0) + solve(r * cos(R), r * sin(R), 0, xb, yb, zb);
			res = min(res, valueL);
			res = min(res, valueR);
			if (valueL < valueR) {
				right_bound = R;
			} else {
				left_bound = L;
			}
		}
	}

	printf("%.12lf\n", res);

	return 0;
}

#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <string>
#include <set>
#include <vector>
#include <cmath>
#include <cassert>
#include <cstdlib>
#include <map>
#include <queue>
#include <deque>
#include <bitset>

#define y0 y63475625
#define y1 y28435
#define j0 jfd0sf
#define j1 je90ue0
#define sqr(x) ((x)*(x))
#define fi first
#define se second
#define pb push_back
#define mp make_pair
#define re return
#define sz(x) ((int)(x).size())
#define all(x) (x).begin(), (x).end()
#define rep(i, n) for (int i = 0; i < (n); i++)
#define rrep(i, n) for (int i = (n) - 1; i >= 0; i--)
#define sqrt(x) (sqrt(abs(x)))
#define fill(a, x) memset(a, x, sizeof(a))

using namespace std;

typedef vector <int> vi;
typedef vector <vi> vvi;
typedef long long ll;
typedef long double ld;
typedef pair <int, int> ii;
typedef vector <ii> vii;
typedef double D;
typedef pair <ll, ll> pll;
typedef vector <string> vs;

template <class T> T abs(const T a) {
    return a > 0 ? a : -a;
}

const double PI = 2.0 * acos(1.0);

const ld eps = 1e-12;

ld alpha;

int n;
int m;

ld dist(ld ra, ld rb, ld angle) {
    if (abs(ra) < eps) {
        re rb * alpha;
    }
    if (abs(rb) < eps) {
        re ra * alpha;
    }
    if (fabs(angle) < eps)
        re abs(rb - ra) * alpha;
    ld co = rb * sin(angle / alpha);
    ld si = (ra - rb * cos(angle / alpha));
    ld q = sqrt(sqr(co) + sqr(si));
    co /= q; si /= q;
    //ld f0 = alpha * atan2(si, co);
    ld tmp = tan(angle / alpha), tg = si / co;
    re abs(alpha * ra * (co * (tmp - tg) / (1.0 + tmp * tg) + si));
}

int main()
{
    ld r, h;
    cin >> r >> h;
    ld xa, ya, za, xb, yb, zb;
    cin >> xa >> ya >> za;
    cin >> xb >> yb >> zb;
    if (abs(zb) < eps && abs(za) < eps) {
        printf("%.10lf\n", (D)sqrt(sqr(xb - xa) + sqr(yb - ya)));
        re 0;
    }
    if (abs(zb) < eps) {
        swap(xa, xb);
        swap(ya, yb);
        swap(za, zb);
    }

    alpha = sqrt(1.0 + sqr(h / r));
    if (abs(za) > eps && abs(zb) > eps) {
        ld ra = sqrt(sqr(xa) + sqr(ya));
        ld rb = sqrt(sqr(xb) + sqr(yb));
        ld angle = -1.0;
        if (abs(ra) > eps && abs(rb) > eps)
            angle = acos((xa * xb + ya * yb) / ra / rb);
        ld ans = dist(ra, rb, angle);
        ld fans1 = -1, fans2 = -1;
        rep(i, 1) {
            ld L1 = -M_PI / 6, R1 = M_PI / 6.0;
            ld L2 = -M_PI / 6, R2 = M_PI / 6.0;
            n = 1780;
            rep(j, n) {
                ld f1 = L1 + (R1 - L1) * j / (ld)n;
                rep(k, n) {
                    ld f2 = L2 + (R2 - L2) * k / (ld)n;
                    ld tmp = r * sqrt(2.0 - 2.0 * cos(angle + f1 - f2)) + dist(r, ra, f1) + dist(r, rb, f2);
                    if (tmp < ans) {
                        ans = tmp;
                        fans1 = f1;
                        fans2 = f2;
                    }
                }
            }
            ld d = R1 - L1;
            L1 = fans1 - d / 2.0 * 0.99;
            L2 = fans2 - d / 2.0 * 0.99;
            R1 = fans1 + d / 2.0 * 0.99;
            R2 = fans2 + d / 2.0 * 0.99;
        }
        printf("%.10lf\n", (D)ans);
        re 0;
    } else {
        //todo
        ld L = 0.0, R = 2.0 * M_PI;
        ld ans = 1e20;
        ld fans = -1;
        ld rb = sqrt(sqr(xb) + sqr(yb));
        rep(i, 200) {
            rep(j, 1000) {
                double f = L + (R - L) / 100.0 * j;
                ld x = r * cos(f);
                ld y = r * sin(f);
                ld angle = -1.0;
                if (abs(rb) > eps)
                    angle = acos((x * xb + y * yb) / rb / r);
                ld tmp = sqrt(sqr(xa - x) + sqr(ya - y)) + dist(r, rb, angle);
                if (tmp < ans) {
                    ans = tmp;
                    fans = f;
                }
            }
            ld d = R - L;
            L = fans - d / 2.0 * 0.9;
            R = fans + d / 2.0 * 0.9;
        }
        printf("%.10lf\n", (D)ans);
    }
    return 0;
}

#define pi 3.1415926535897932384626433832795

#include<bits/stdc++.h>

#define eps 1e-8

using namespace std;

typedef long double DO;

template<typename T, typename U> inline void smin(T &a, const U &b) {if(a>b) a=b;}

template<typename T, typename U> inline void smax(T &a, const U &b) {if(a<b) a=b;}

struct point {

	DO x, y, z;

	inline void input() {cin>>x>>y>>z;}

	inline DO al() {return atan2l(y, x);}

	inline DO nor2() {return *this**this;}

	inline DO nor() {return sqrtl(*this**this);}

	inline void print() {cout<<x<<' '<<y<<' '<<z<<endl;}

	inline DO operator * (point a) {return x*a.x+y*a.y+z*a.z;}

	inline point(DO x=0, DO y=0, DO z=0) : x(x), y(y), z(z) {}

	inline point operator * (DO a) {return point(x*a, y*a, z*a);}

	inline point operator - (point a) {return point(x-a.x, y-a.y, z-a.z);}

	inline point operator + (point a) {return point(x+a.x, y+a.y, z+a.z);}

	inline point norm() {DO s=nor(); if(s<eps) return *this; return point(x/s, y/s, z/s);}

};

DO r, h, R, one=pi/4, whole=2*pi, len;

inline DO calc_laterals(point a, point b) {

	DO x=r*fabsl(a.al()-b.al()); smin(x, len-x);

	DO da2=(a-point(0, 0, h)).nor2(), da=sqrtl(da2);

	DO db2=(b-point(0, 0, h)).nor2(), db=sqrtl(db2);

	return sqrtl(da2+db2-2*da*db*cosl(x/R));

}

point A, AA, B, DA, DB, focus;

inline DO calc_down_lateral(DO angle) {

	DO x=r*cosl(angle), y=r*sinl(angle);

	return (AA-point(x, y, 0)).nor()+calc_laterals(point(x, y, 0), B);

}

inline DO solve() {

	DO ans=(AA-DB).nor()+calc_laterals(DB, B);

	for(DO angle=one; angle<=whole; angle+=one) {

		DO st=angle-one, ed=angle;

		while(ed-st>eps) {

			DO a=(st+st+ed)/3, b=(st+ed+ed)/3;

			if(calc_down_lateral(a)>calc_down_lateral(b)) st=a;

			else ed=b;

		}

		smin(ans, calc_down_lateral(st));

	}

	return ans;

}

main() {

#ifndef	ONLINE_JUDGE

	freopen("in.in", "r", stdin);

	freopen("out.out", "w", stdout);

#endif

	cin>>r>>h;

	len=whole*r, R=sqrtl(r*r+h*h);

	focus=point(0, 0, h);

	A.input(), B.input();

	if(B.z<eps) swap(A, B);

	DA=focus+(A-focus).norm()*R, DB=focus+(B-focus).norm()*R;

	DO ans=1e13;

	if(A.z<eps) {

		if(B.z<eps) ans=(A-B).nor();

		else AA=A, ans=solve();

	}

	else {

		ans=calc_laterals(A, B);

		AA=DA, smin(ans, calc_laterals(A, AA)+solve());

		for(DO angle=one; angle<=whole; angle+=one) {

			DO st=angle-one, ed=angle;

			while(ed-st>eps) {

				DO a=(st+st+ed)/3, b=(st+ed+ed)/3;

				AA=point(r*cos(a), r*sin(a)); DO sa=calc_laterals(A, AA)+calc_down_lateral(a);

				AA=point(r*cos(b), r*sin(b)); DO sb=calc_laterals(A, AA)+calc_down_lateral(b);

				if(sa>sb) st=a;

				else ed=b;

			}

			AA=point(r*cosl(st), r*sinl(st)), smin(ans, calc_laterals(A, AA)+solve());

		}

	}

	printf("%.7lf", (double)ans);

}

#include<iostream>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<stdio.h>
using namespace std;
const double eps=1e-9,inf=1e9+9,pi=acos(-1.0),dtheta=pi/4.;
double ans,r,h,xa,ya,za,xb,yb,zb,la,ra,mxa,mya,lb,rb,mxb,myb,lv,rv,lz,rz;
double dist(double x1,double y1,double z1,double x2,double y2,double z2)
{
	return sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2)+(z1-z2)*(z1-z2));
}
void norm(double &theta)
{
	while(theta<-eps)
	   theta+=2*pi;
    while(theta>2*pi-eps)
       theta-=2*pi;
}
double solve(double x1,double y1,double z1,double x2,double y2,double z2)
{
	double l1,l2,l,cj,alpha,dj,theta,res;
	if(fabs(z1)<eps&&fabs(z2)<eps)
	    return dist(x1,y1,z1,x2,y2,z2);
	l1=dist(x1,y1,z1,0,0,h);
	l2=dist(x2,y2,z2,0,0,h);
	alpha=atan2(y2,x2)-atan2(y1,x1);
	norm(alpha);
	if(alpha>pi)
	   alpha=2*pi-alpha;
	l=alpha*r;
	cj=sqrt(r*r+h*h);
	theta=l/cj;
	double u1,v1,u2,v2;
	u1=0;
	v1=l1;
	u2=l2*sin(theta);
	v2=l2*cos(theta);
	res=sqrt((u1-u2)*(u1-u2)+(v1-v2)*(v1-v2));
    theta=2*pi-theta;
  	u1=0;
	v1=l1;
	u2=l2*sin(theta);
	v2=l2*cos(theta);
	res=min(res,sqrt((u1-u2)*(u1-u2)+(v1-v2)*(v1-v2)));
    return res;
}
int main()
{
	int i,j,s,p,q,it1,it2;
	scanf("%lf%lf",&r,&h);
	scanf("%lf%lf%lf%lf%lf%lf",&xa,&ya,&za,&xb,&yb,&zb);
	ans=inf;
	if(fabs(za)>eps&&fabs(zb)>eps)
	   ans=min(ans,solve(xa,ya,za,xb,yb,zb));
	if(fabs(za)<eps&&fabs(zb)<eps)
	   ans=min(ans,dist(xa,ya,za,xb,yb,zb));
	if(fabs(zb)<eps)
	{
	    swap(xa,xb);
	    swap(ya,yb);
	    swap(za,zb);
	}
	la=0;
	ra=2*pi;
	for(it1=0;it1<1000;it1++)
	{
		mxa=(29.*la+ra)/30.;
		mya=(la+29.*ra)/30.;
	    lv=solve(xa,ya,za,r*cos(mxa),r*sin(mxa),0)+solve(xb,yb,zb,r*cos(mxa),r*sin(mxa),0);
        rv=solve(xa,ya,za,r*cos(mya),r*sin(mya),0)+solve(xb,yb,zb,r*cos(mya),r*sin(mya),0);
        ans=min(ans,lv);
        ans=min(ans,rv);
    	if(lv>rv)
           la=mxa;
        else
           ra=mya;
	}
    la=0;
    ra=2*pi;
	for(it1=0;it1<500;it1++)
    {
    	 mxa=(49.*la+ra)/50.;
   	     mya=(la+49.*ra)/50.;
   	     lb=0;
   	     rb=2*pi;
   	     for(it2=0;it2<500;it2++)
   	     {
     	    mxb=(49.0*lb+rb)/50.;
     	    myb=(lb+49.0*rb)/50.;
     	    lv=solve(xa,ya,za,r*cos(mxa),r*sin(mxa),0)+solve(xb,yb,zb,r*cos(mxb),r*sin(mxb),0)+dist(r*cos(mxa),r*sin(mxa),0,r*cos(mxb),r*sin(mxb),0);
     	    rv=solve(xa,ya,za,r*cos(mxa),r*sin(mxa),0)+solve(xb,yb,zb,r*cos(myb),r*sin(myb),0)+dist(r*cos(mxa),r*sin(mxa),0,r*cos(myb),r*sin(myb),0);
			 if(lv>rv)
     	       lb=mxb;
  	        else
  	           rb=myb;
		  }
		  mxb=0.5*(lb+rb);
		  lz=solve(xa,ya,za,r*cos(mxa),r*sin(mxa),0)+solve(xb,yb,zb,r*cos(mxb),r*sin(mxb),0)+dist(r*cos(mxa),r*sin(mxa),0,r*cos(mxb),r*sin(mxb),0);
          lb=0;
   	      rb=2*pi;
		  for(it2=0;it2<500;it2++)
          {
          	   	mxb=(49.*lb+rb)/50.;
     	     	myb=(lb+49.*rb)/50.;
     	        lv=solve(xa,ya,za,r*cos(mya),r*sin(mya),0)+solve(xb,yb,zb,r*cos(mxb),r*sin(mxb),0)+dist(r*cos(mya),r*sin(mya),0,r*cos(mxb),r*sin(mxb),0);
     	        rv=solve(xa,ya,za,r*cos(mya),r*sin(mya),0)+solve(xb,yb,zb,r*cos(myb),r*sin(myb),0)+dist(r*cos(mya),r*sin(mya),0,r*cos(myb),r*sin(myb),0);
     	        ans=min(ans,lv);
     	        ans=min(ans,rv);
			    if(lv>rv)
     	           lb=mxb;
  	            else
  	               rb=myb;
          }
          mxb=0.5*(lb+rb);
          rz=solve(xa,ya,za,r*cos(mya),r*sin(mya),0)+solve(xb,yb,zb,r*cos(mxb),r*sin(mxb),0)+dist(r*cos(mya),r*sin(mya),0,r*cos(mxb),r*sin(mxb),0);
          if(lz>rz)
             la=mxa;
          else
             ra=mya;
    }
    printf("%.20f\n",ans);
	return 0;
}

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <climits>
#include <cstring>
#include <string>
#include <vector>
#include <stack>
#include <queue>
#include <set>
#include <map>
#include <algorithm>

using namespace std;

double h, r;
double pi = 3.14159265359;

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;
    pair<double, double> coord;
    angleOnCircle = (isZero(x) ? atan(y/x) : pi/2.0) + (x > 0.0 ? 0 : pi);
    if(isZero(x))
    {
        angleOnCircle = pi / 2.0  + (y > 0.0 ? 0.0 : pi);
    }
    else
    {
        tmp = y / x;
        angleOnCircle = atan(tmp);
        if(tmp < 0.0)
        {
            angleOnCircle = (x < 0.0 ? (pi + angleOnCircle) : (pi + pi + angleOnCircle));
        }
        else if(x < 0)
        {
            angleOnCircle += pi;
        }
    }

    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));

    coord.first = d * (cosTheta);
    coord.second = d * (sinTheta);
    return coord;
}

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;
    double tmp1, tmp2;
    a = findCoordinatesOnPlane(x1, y1, z1);
    b = findCoordinatesOnPlane(x2, y2, z2);
    tmp1 = a.first - b.first;
    tmp2 = a.second - b.second;
    return sqrt(tmp1 * tmp1 + tmp2 * tmp2);
}

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;
    right = minDegree + aDegree;

    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 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;

    x = r * cos(left);
    y = r * sin(left);
    minDegree = left;
    minVal = findConeSurfaceDistance(x1, y1, z1, x, y, 0.0) +
             findOptimalSingleBrinkPointDistance(x2, y2, z2, x, y, 0.0);

    for(left = aDegree; left < right; left += aDegree)
    {
        x = r * cos(left);
        y = r * sin(left);
        curr = findConeSurfaceDistance(x1, y1, z1, x, y, 0.0) +
               findOptimalSingleBrinkPointDistance(x2, y2, z2, x, y, 0.0);
        if(curr < minVal)
        {
            minVal = curr;
            minDegree = left;
        }
    }

    left = minDegree - aDegree;
    right = minDegree + aDegree;

    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);
}

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);
        }
    }
    else if(pt2OnBase)
    {
        res = findOptimalSingleBrinkPointDistance(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;
}

#include <set>
#include <map>
#include <queue>
#include <deque>
#include <cmath>
#include <ctime>
#include <bitset>
#include <vector>
#include <string>
#include <cstdio>
#include <cassert>
#include <cstring>
#include <iostream>
#include <algorithm>
#define For(i,x,y)  for(int i=(int)(x);i<=(int)(y);i++)
#define Forn(i,x,y) for(int i=(int)(x);i>=(int)(y);i--)
#define Rep(i,x,y)  for(int i=(int)(x);i< (int)(y);i++)
#define mk make_pair
#define pb push_back
#define fi first
#define se second
using namespace std;
typedef long double db;
typedef long long ll;
typedef pair<int,int> PII;
const int N=200005;
const int inf=1e9;
const ll Inf=1e10;
const int P=1000000007;
const db  pi=acos(-1);

db r,h,Sqr,l;
db X1,X2,Y1,Y2,Z1,Z2;

void read(db &x){
	double z;
	scanf("%lf",&z);
	x=z;
}

db sqr(db x){return x*x;}

db Fbb(db A,db B,db D,db E){
	return sqrt(sqr(A-D)+sqr(B-E));
}

db Faa(db A,db B,db C,db D,db E,db F){
	if(fabs(C-h)<1e-6) return sqrt(D*D+E*E+sqr(F-h));
	if(fabs(F-h)<1e-6) return sqrt(A*A+B*B+sqr(C-h));
	db X3=A*h/(h-C),Y3=B*h/(h-C),X4=D*h/(h-F),Y4=E*h/(h-F);
	db u=Sqr*2-sqr(X3-X4)-sqr(Y3-Y4);
	u/=2*Sqr;
	db the=acos(u);
	db phi=the*r/l;
	db D1=sqr(A)+sqr(B)+sqr(C-h),D2=sqr(D)+sqr(E)+sqr(F-h);
	return sqrt(D1+D2-2*sqrt(D1)*sqrt(D2)*cos(phi));
}

db Fab(db X,db Y,db Z,db E,db F,db the){
	db X3=r*cos(the),Y3=r*sin(the);
	return Faa(X,Y,Z,X3,Y3,0)+Fbb(E,F,X3,Y3);
}

db Fab2(db the){
	db X3=cos(the)*r,Y3=sin(the)*r;
	db l=0,r=2*pi,T1,T2;
	For(i,1,100){
		db md1=(6*l+r)/7.,md2=(l+6*r)/7.;
		T1=Fab(X2,Y2,Z2,X3,Y3,md1);
		T2=Fab(X2,Y2,Z2,X3,Y3,md2);
		if(T1>T2) l=md1;else r=md2;
	}
	return T1+Faa(X1,Y1,Z1,X3,Y3,0);
}

int main(){
	read(r);read(h);Sqr=r*r;
	l=sqrt(r*r+h*h);
	read(X1);read(Y1);read(Z1);
	read(X2);read(Y2);read(Z2);

	if(Z1==0&&Z2==0){
		printf("%.16lf\n",double(Fbb(X1,Y1,X2,Y2)));
		return 0;
	}
	if(Z1!=0&&Z2!=0){
		db ans=Faa(X1,Y1,Z1,X2,Y2,Z2);
		db l=0,r=2*pi,T1,T2;
		For(i,1,100){
			db md1=(6*l+r)/7.,md2=(l+6*r)/7.;
			T1=Fab2(md1);
			T2=Fab2(md2);
			if(T1>T2) l=md1;else r=md2;
		}
		ans=min(ans,T1);
		printf("%.16lf\n",double(ans));
		return 0;
	}
	if(Z1==0){
		swap(X1,X2);
		swap(Y1,Y2);
		swap(Z1,Z2);
	}
	db l=0,r=2*pi,T1,T2;
	For(i,1,500){
		db md1=(2*l+r)/3.,md2=(l+2*r)/3.;
		if((T1=Fab(X1,Y1,Z1,X2,Y2,md1))>(T2=Fab(X1,Y1,Z1,X2,Y2,md2))) l=md1;else r=md2;
	}
	printf("%.16lf\n",double(T1));
	return 0;
}

#include<bits/stdc++.h>

using namespace std;

typedef double DO;
typedef long long INT;
typedef pair<int, int> pii;
typedef vector<int> VI;

template<typename A, typename B> inline void smin(A &a, const B &b) {if(a>b) a=b;}

const DO eps = 1e-7;

struct point {
	DO x, y, z;
	inline point(DO x=0, DO y=0, DO z=0) : x(x), y(y), z(z) {}
	inline point operator - (point a) {return point(x-a.x, y-a.y, z-a.z);}
	inline DO al() {return atan2(y, x);}
	inline DO nor2() {return *this**this;}
	inline DO nor() {return sqrt(*this**this);}
	inline DO operator * (point a) {return x*a.x+y*a.y+z*a.z;}
	inline void input() {scanf("%lf %lf %lf", &x, &y, &z);}
	inline void print() {printf("%lf %lf %lf\n", x, y, z);}
} A, B, O;

DO r, R, h;

const DO pi = acosl(-1);
const DO all = 2 * pi;
const DO al120 = pi * 2 / 3;

DO calc_dst(point a, point b) {
    DO al = abs(a.al() - b.al());
    smin(al, all - al);
    DO A = (a - O).nor2(); DO B = (b - O).nor2();
    return sqrtl(A + B - 2 * sqrtl(A * B) * cos(r * al / R));
}

inline DO calc(DO a, point A) {
	point tmp = {r * cos(a), r * sin(a)};
	return (A - tmp).nor() + calc_dst(B, tmp);
}

inline DO calc(point A) {
    DO ans = 1e111;
    for(DO l=0; l<all; l+=al120) {
        DO st = l, ed = l + al120+0.1;
        while(ed - st > eps) {
			DO a = (st * 2 + ed) / 3;
			DO b = (st + ed * 2) / 3;
            if(calc(a, A) < calc(b, A)) ed = b;
            else st = a;
        }
        DO mid = (st + ed) / 2;
        smin(ans, calc(mid, A));
    }
    return ans;
}

inline DO calc1(DO a, point A) {
	point tmp = {cos(a) * r, sin(a) * r};
	return calc_dst(A, tmp) + calc(tmp);
}

int solve() {
	scanf("%lf %lf", &r, &h);
	R = sqrtl(r *r + h * h);
	O = point(0, 0, h);
	A.input(); B.input();
	DO ans;
    if(A.z > B.z) swap(A, B);
    if(B.z < eps) ans = (A - B).nor();
    else if(A.z < eps) ans = calc(A);
    else {
        ans = calc_dst(A, B);
		for(DO l=0; l<all; l+=al120) {
            DO st = st, ed = st + al120 + 0.1;
            while(ed - st > eps) {
				DO a = (st * 2 + ed) / 3;
				DO b = (st + ed * 2) / 3;
				if(calc1(a, A) < calc1(b, A)) ed = b;
				else st = a;
            }
            DO mid = (st + ed) / 2;
            smin(ans, calc1(mid, A));
		}
    }
	cout << fixed << setprecision(10) << ans << endl;
}

int main() {
#ifndef	ONLINE_JUDGE
	freopen("in.in", "r", stdin);
	freopen("out.out", "w", stdout);
#endif
	solve();
	return 0;
}

#pragma comment(linker, "/STACK:65777216")

#include <algorithm>
#include <iostream>
#include <string>
#include<sstream>
#include<string.h>
#include <cstdio>
#include <vector>
#include <bitset>
#include <cmath>
#include <queue>
#include<stack>
#include <set>
#include <map>
#include<ctime>

using namespace std;

typedef long long ll;
typedef vector<int> vi;
typedef pair<int,int> pii;
typedef pair<double,double> pdd;
typedef unsigned long long ull;

#define FOR(i,a,b) for (int i(a); i < (b); i++)
#define REP(i,n) FOR(i,0,n)
#define SORT(v) sort((v).begin(),(v).end())
#define UN(v) sort((v).begin(),(v).end()),v.erase(unique(v.begin(),v.end()),v.end())
#define CL(a,b) memset(a,b,sizeof(a))
#define pb push_back

typedef long double ld;
const ld pi = acosl(-1.);
const ld eps = 1e-17;

int r,h;

ld getAngle(ld x,ld y, ld z){
	ld H = h - z;
	if(H<eps) return 0;
	ld R = r * H / h;
	ld X = 0;
	ld Y = R;
	ld d = sqrtl((x-X)*(x-X)+(y-Y)*(y-Y));
	ld a = asinl(d/2/R)*2;
	ld l = a * R / sqrtl(R*R+H*H);
	if(x>0) l=-l;
	return l;
}

ld conDist(ld z,ld Z,ld a){
	ld r1 = sqrtl(h*h+r*r+0.)/h*(h-z);
	ld r2 = sqrtl(h*h+r*r+0.)/h*(h-Z);
	ld x = r1;
	ld y = 0;
	ld X = cosl(a)*r2;
	ld Y = sinl(a)*r2;
	return sqrtl((x-X)*(x-X)+(y-Y)*(y-Y));
}

ld getOnConus(ld x,ld y,ld z,ld X, ld Y,ld Z){
	ld a1 = getAngle(x,y,z);
	ld a2 = getAngle(X,Y,Z);
	ld a = fabsl(a2-a1);
	ld A = r / sqrtl(h*h+r*r+0.) * 2 * pi;
	return min(conDist(z,Z,a),conDist(z,Z,A-a));
}

ld getOnConus(ld x,ld y,ld z,ld X, ld Y){
	if(z>eps) return getOnConus(x,y,z,X,Y,0);
	return sqrtl((x-X)*(x-X)+(y-Y)*(y-Y));
}

ld getD(ld x,ld y,ld z,ld X, ld Y,ld Z,ld XX,ld YY,ld XXX,ld YYY){
	ld res = sqrtl((XX-XXX)*(XX-XXX)+(YY-YYY)*(YY-YYY));
	res += getOnConus(x,y,z,XX,YY);
	res += getOnConus(X,Y,Z,XXX,YYY);
	return res;
}

ld getD(ld x,ld y,ld z,ld X, ld Y,ld Z,ld XX,ld YY){
	ld res = 1e100;
	REP(i,4){
		ld a = 2*pi/2*i;
		ld b = a + pi;
		REP(j,50){
			ld s1 = (a*2+b)/3;
			ld s2 = (a+2*b)/3;
			ld d1 = getD(x,y,z,X,Y,Z,XX,YY,cosl(s1)*r,sinl(s1)*r);
			ld d2 = getD(x,y,z,X,Y,Z,XX,YY,cosl(s2)*r,sinl(s2)*r);
			res = min(res,min(d1,d2));
			if(d1<d2) b = s2;
			else a = s1;
		}
	}
	return res;
}

ld go(ld x,ld y,ld z,ld X, ld Y,ld Z){
	ld res = getOnConus(x,y,z,X,Y,Z);
	if(z<eps || Z<eps) res = 1e100;
	REP(i,4){
		ld a = 2*pi/2*i;
		ld b = a + pi;
		REP(j,50){
			ld s1 = (a*2+b)/3;
			ld s2 = (a+2*b)/3;
			ld d1 = getD(x,y,z,X,Y,Z,cosl(s1)*r,sinl(s1)*r);
			ld d2 = getD(x,y,z,X,Y,Z,cosl(s2)*r,sinl(s2)*r);
			res = min(res,min(d1,d2));
			if(d1<d2) b = s2;
			else a = s1;
		}
	}
	return res;
}

int main(){
#ifdef LocalHost
    freopen("input.txt","r",stdin);
//    freopen("output.txt","w",stdout);
#endif

	cin>>r>>h;
	long double x,y,z,X,Y,Z;
	cin>>x>>y>>z>>X>>Y>>Z;
	if(z<eps && Z<eps)
		printf("%.10lf\n",(double)sqrt((x-X)*(x-X)+(y-Y)*(y-Y)));
	else printf("%.10lf\n",(double)go(x,y,z,X,Y,Z));

#ifdef LocalHost
	cout<<endl<<endl<<"TIME: "<<clock()<<endl;
#endif
    return 0;
}

#pragma comment(linker, "/STACK:65777216")

#include <algorithm>
#include <iostream>
#include <string>
#include<sstream>
#include<string.h>
#include <cstdio>
#include <vector>
#include <bitset>
#include <cmath>
#include <queue>
#include<stack>
#include <set>
#include <map>
#include<ctime>

using namespace std;

typedef long long ll;
typedef vector<int> vi;
typedef pair<int,int> pii;
typedef pair<double,double> pdd;
typedef unsigned long long ull;

#define FOR(i,a,b) for (int i(a); i < (b); i++)
#define REP(i,n) FOR(i,0,n)
#define SORT(v) sort((v).begin(),(v).end())
#define UN(v) sort((v).begin(),(v).end()),v.erase(unique(v.begin(),v.end()),v.end())
#define CL(a,b) memset(a,b,sizeof(a))
#define pb push_back

typedef long double ld;
const ld pi = acosl(-1.);
const ld eps = 1e-17;

int r,h;

ld getAngle(ld x,ld y, ld z){
	ld H = h - z;
	if(H<eps) return 0;
	ld R = r * H / h;
	ld X = 0;
	ld Y = R;
	ld d = sqrtl((x-X)*(x-X)+(y-Y)*(y-Y));
	ld a = asinl(d/2/R)*2;
	ld l = a * R / sqrtl(R*R+H*H);
	if(x>0) l=-l;
	return l;
}

ld conDist(ld z,ld Z,ld a){
	ld r1 = sqrtl(h*h+r*r+0.)/h*(h-z);
	ld r2 = sqrtl(h*h+r*r+0.)/h*(h-Z);
	ld x = r1;
	ld y = 0;
	ld X = cosl(a)*r2;
	ld Y = sinl(a)*r2;
	return sqrtl((x-X)*(x-X)+(y-Y)*(y-Y));
}

ld getOnConus(ld x,ld y,ld z,ld X, ld Y,ld Z){
	ld a1 = getAngle(x,y,z);
	ld a2 = getAngle(X,Y,Z);
	ld a = fabsl(a2-a1);
	ld A = r / sqrtl(h*h+r*r+0.) * 2 * pi;
	return min(conDist(z,Z,a),conDist(z,Z,A-a));
}

ld getOnConus(ld x,ld y,ld z,ld X, ld Y){
	if(z>eps) return getOnConus(x,y,z,X,Y,0);
	return sqrtl((x-X)*(x-X)+(y-Y)*(y-Y));
}

ld getD(ld x,ld y,ld z,ld X, ld Y,ld Z,ld XX,ld YY,ld XXX,ld YYY){
	ld res = sqrtl((XX-XXX)*(XX-XXX)+(YY-YYY)*(YY-YYY));
	res += getOnConus(x,y,z,XX,YY);
	res += getOnConus(X,Y,Z,XXX,YYY);
	return res;
}

ld getD(ld x,ld y,ld z,ld X, ld Y,ld Z,ld XX,ld YY){
	ld res = 1e100;
	REP(i,6){
		ld a = 2*pi/3*i;
		ld b = a + pi;
		REP(j,30){
			ld s1 = (a*2+b)/3;
			ld s2 = (a+2*b)/3;
			ld d1 = getD(x,y,z,X,Y,Z,XX,YY,cosl(s1)*r,sinl(s1)*r);
			ld d2 = getD(x,y,z,X,Y,Z,XX,YY,cosl(s2)*r,sinl(s2)*r);
			res = min(res,min(d1,d2));
			if(d1<d2) b = s2;
			else a = s1;
		}
	}
	return res;
}

ld go(ld x,ld y,ld z,ld X, ld Y,ld Z){
	ld res = getOnConus(x,y,z,X,Y,Z);
	if(z<eps || Z<eps) res = 1e100;
	REP(i,6){
		ld a = 2*pi/3*i;
		ld b = a + pi;
		REP(j,30){
			ld s1 = (a*2+b)/3;
			ld s2 = (a+2*b)/3;
			ld d1 = getD(x,y,z,X,Y,Z,cosl(s1)*r,sinl(s1)*r);
			ld d2 = getD(x,y,z,X,Y,Z,cosl(s2)*r,sinl(s2)*r);
			res = min(res,min(d1,d2));
			if(d1<d2) b = s2;
			else a = s1;
		}
	}
	return res;
}

int main(){
#ifdef LocalHost
    freopen("input.txt","r",stdin);
//    freopen("output.txt","w",stdout);
#endif

	cin>>r>>h;
	long double x,y,z,X,Y,Z;
	cin>>x>>y>>z>>X>>Y>>Z;
	if(z<eps && Z<eps)
		printf("%.10lf\n",(double)sqrt((x-X)*(x-X)+(y-Y)*(y-Y)));
	else printf("%.10lf\n",(double)go(x,y,z,X,Y,Z));

#ifdef LocalHost
	cout<<endl<<endl<<"TIME: "<<clock()<<endl;
#endif
    return 0;
}

#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <string>
#include <set>
#include <vector>
#include <cmath>
#include <cassert>
#include <cstdlib>
#include <map>
#include <queue>
#include <deque>
#include <bitset>

#define y0 y63475625
#define y1 y28435
#define j0 jfd0sf
#define j1 je90ue0
#define sqr(x) ((x)*(x))
#define fi first
#define se second
#define pb push_back
#define mp make_pair
#define re return
#define sz(x) ((int)(x).size())
#define all(x) (x).begin(), (x).end()
#define rep(i, n) for (int i = 0; i < (n); i++)
#define rrep(i, n) for (int i = (n) - 1; i >= 0; i--)
#define sqrt(x) (sqrt(abs(x)))
#define fill(a, x) memset(a, x, sizeof(a))

using namespace std;

typedef vector <int> vi;
typedef vector <vi> vvi;
typedef long long ll;
typedef long double ld;
typedef pair <int, int> ii;
typedef vector <ii> vii;
typedef double D;
typedef pair <ll, ll> pll;
typedef vector <string> vs;

template <class T> T abs(const T a) {
    return a > 0 ? a : -a;
}

const double PI = 2.0 * acos(1.0);

const ld eps = 1e-12;

ld alpha;

int n;
int m;

ld dist(ld xa, ld ya, ld xb, ld yb) {
    ld ra = sqrt(sqr(xa) + sqr(ya));
    ld rb = sqrt(sqr(xb) + sqr(yb));
    if (abs(xa) < eps && abs(ya) < eps) {
        re rb * alpha;
    }
    if (abs(xb) < eps && abs(yb) < eps) {
        re ra * alpha;
    }

    double angle = acos((xa * xb + ya * yb) / ra / rb);
    if (fabs(angle) < eps)
        re abs(rb - ra) * alpha;
    ld co = rb * sin(angle / alpha);
    ld si = (ra - rb * cos(angle / alpha));
    ld f0 = alpha * atan2(si, co);
    ld a = 1.0 / (ra * cos(f0 / alpha));
    re abs(alpha / a * (tan((angle - f0) / alpha) + tan(f0 / alpha)));
}

int main()
{
    ld r, h;
    cin >> r >> h;
    ld xa, ya, za, xb, yb, zb;
    cin >> xa >> ya >> za;
    cin >> xb >> yb >> zb;
    if (abs(zb) < eps && abs(za) < eps) {
        printf("%.10lf\n", (D)sqrt(sqr(xb - xa) + sqr(yb - ya)));
        re 0;
    }
    if (abs(zb) < eps) {
        swap(xa, xb);
        swap(ya, yb);
        swap(za, zb);
    }

    alpha = sqrt(1.0 + sqr(h / r));
    if (abs(za) > eps && abs(zb) > eps) {
        printf("%.10lf\n", (D)dist(xa, ya, xb, yb));
    } else {
        //todo
        ld L = 0.0, R = 2.0 * M_PI;
        ld ans = 1e20;
        ld fans = -1;
        rep(i, 2000) {
            rep(j, 100) {
                double f = L + (R - L) / 100.0 * j;
                ld x = r * cos(f);
                ld y = r * sin(f);
                ld tmp = sqrt(sqr(xa - x) + sqr(ya - y)) + dist(x, y, xb, yb);
                if (tmp < ans) {
                    ans = tmp;
                    fans = f;
                }
            }
            ld d = R - L;
            L = fans - d / 2.0 * 0.9;
            R = fans + d / 2.0 * 0.9;
        }
        printf("%.10lf\n", (D)ans);
    }
    return 0;
}

#define pi 3.1415926535897932384626433832795

#include<bits/stdc++.h>

#define eps 1e-13

using namespace std;

typedef long double DO;

template<typename T, typename U> inline void smin(T &a, const U &b) {if(a>b) a=b;}

struct point {

	DO x, y, z;

	inline point(DO x=0, DO y=0, DO z=0) : x(x), y(y), z(z) {}

	inline point operator - (point a) {return point(x-a.x, y-a.y, z-a.z);}

	inline point operator + (point a) {return point(x+a.x, y+a.y, z+a.z);}

	inline point operator * (DO a) {return point(x*a, y*a, z*a);}

	inline point operator / (DO a) {return point(x/a, y/a, z/a);}

	inline DO operator * (point a) {return x*a.x+y*a.y+z*a.z;}

	inline point norm() {DO s=nor(); if(s<eps) return *this; return point(x/s, y/s, z/s);}

	inline DO nor() {return sqrtl(*this**this);}

	inline DO nor2() {return *this**this;}

	inline point rotate(DO al) {return *this&point(cosl(al), sinl(al), z);}

	inline point operator & (point a) {return point(x*a.x-y*a.y, x*a.y+y*a.x, z);}

	inline void input() {cin>>x>>y>>z;}

};

DO r, h, R, R2, len;

point focus, a, b, c, ac, A;

inline DO calc1(DO x) {

	point d=c.rotate(x/r);

	DO ans1=(A-d).nor();

	smin(x, len-x);

	DO D2=(b-focus).nor2(), D=sqrtl(D2);

	DO ans2=sqrtl(R2+D2-2*R*D*cosl(x/R));

	smin(ans2, (d-focus).nor()+D);

	return ans1+ans2;

}

inline DO solve() {

	DO st=0, ed=len;

	while(ed-st>eps) {

		DO a=(st+st+ed)/3, b=(st+ed+ed)/3;

		if(calc1(a)>calc1(b)) st=a;

		else ed=b;

	}

	return calc1(st);

}

inline DO calc2(DO x) {

	A=ac.rotate(x/r);

	smin(x, len-x);

	DO D2=(a-focus).nor2(), D=sqrtl(D2);

	return sqrtl(R2+D2-2*R*D*cosl(x/R)) +solve();

}

inline DO angle(point a, point b) {

	DO res=a*b/a.nor()/b.nor();

	res=acosl(res);

	return res;

}

inline DO kong() {

	DO aa2=(a-focus).nor2(), aa=sqrtl(aa2);

	DO bb2=(b-focus).nor2(), bb=sqrtl(bb2);

	DO x=angle(c, ac)*r;

	smin(x, len-x);

	return min((a-focus).nor()+(b-focus).nor(), sqrtl(aa2+bb2-2*aa*bb*cosl(x/R)));

}

main() {

#ifndef	ONLINE_JUDGE

	freopen("in.in", "r", stdin);

	freopen("out.out", "w", stdout);

#endif

	cin>>r>>h; a.input(), b.input();

	if(fabsl(b.z)<eps) swap(a, b);

	len=2*pi*r;

	R2=h*h+r*r, R=sqrtl(R2);

	focus=point(0, 0, h);

	c=focus+(b-focus).norm()*R;

	if(fabsl(a.z)<eps) {

		if(fabsl(b.z)<eps) printf("%.7lf", (double)(a-b).nor());

		else {

			A=a;

			printf("%.7lf", (double)solve());

		}

	}

	else {

		ac=focus+(a-focus).norm()*R;

		DO st=0, ed=len;

		while(ed-st>eps) {

			DO a=(st+st+ed)/3, b=(st+ed+ed)/3;

			if(calc2(a)>calc2(b)) st=a;

			else ed=b;

		}

		printf("%.7lf", (double)min(kong(), calc2(st)));

	}

}

#define pi 3.1415926535897932384626433832795

#include<bits/stdc++.h>

#define eps 1e-13

using namespace std;

typedef long double DO;

template<typename T, typename U> inline void smin(T &a, const U &b) {if(a>b) a=b;}

struct point {

	DO x, y, z;

	inline point(DO x=0, DO y=0, DO z=0) : x(x), y(y), z(z) {}

	inline point operator - (point a) {return point(x-a.x, y-a.y, z-a.z);}

	inline point operator + (point a) {return point(x+a.x, y+a.y, z+a.z);}

	inline point operator * (DO a) {return point(x*a, y*a, z*a);}

	inline point operator / (DO a) {return point(x/a, y/a, z/a);}

	inline DO operator * (point a) {return x*a.x+y*a.y+z*a.z;}

	inline point norm() {DO s=nor(); if(s<eps) return *this; return point(x/s, y/s, z/s);}

	inline DO nor() {return sqrtl(*this**this);}

	inline DO nor2() {return *this**this;}

	inline point rotate(DO al) {return *this&point(cosl(al), sinl(al), z);}

	inline point operator & (point a) {return point(x*a.x-y*a.y, x*a.y+y*a.x, z);}

	inline void input() {cin>>x>>y>>z;}

};

DO r, h, R, R2, len;

point focus, a, b, c, ac, A;

inline DO calc1(DO x) {

	point d=c.rotate(x/r);

	DO ans1=(A-d).nor();

	smin(x, len-x);

	DO D2=(b-focus).nor2(), D=sqrtl(D2);

	DO ans2=sqrtl(R2+D2-2*R*D*cosl(x/R));

	return ans1+ans2;

}

inline DO solve() {

	DO st=0, ed=len;

	while(ed-st>eps) {

		DO a=(st+st+ed)/3, b=(st+ed+ed)/3;

		if(calc1(a)>calc1(b)) st=a;

		else ed=b;

	}

	return calc1(st);

}

inline DO calc2(DO x) {

	A=ac.rotate(x/r);

	smin(x, len-x);

	DO D2=(a-focus).nor2(), D=sqrtl(D2);

	return sqrtl(R2+D2-2*R*D*cosl(x/R)) + calc1(0);

}

inline DO angle(point a, point b) {

	DO res=a*b/a.nor()/b.nor();

	res=acosl(res);

	return res;

}

inline DO kong() {

	DO aa2=(a-focus).nor2(), aa=sqrtl(aa2);

	DO bb2=(b-focus).nor2(), bb=sqrtl(bb2);

	DO x=angle(c, ac)*r;

	smin(x, len-x);

	return sqrtl(aa2+bb2-2*aa*bb*cosl(x/R));

}

main() {

#ifndef	ONLINE_JUDGE

	freopen("in.in", "r", stdin);

	freopen("out.out", "w", stdout);

#endif

	cin>>r>>h; a.input(), b.input();

	if(fabsl(b.z)<eps) swap(a, b);

	len=2*pi*r;

	R2=h*h+r*r, R=sqrtl(R2);

	focus=point(0, 0, h);

	c=focus+(b-focus).norm()*R;

	if(fabsl(a.z)<eps) {

		if(fabsl(b.z)<eps) printf("%.7lf", (double)(a-b).nor());

		else {

			A=a;

			printf("%.7lf", (double)solve());

		}

	}

	else {

		ac=focus+(a-focus).norm()*R;

		DO st=0, ed=len;

		while(ed-st>eps) {

			DO a=(st+st+ed)/3, b=(st+ed+ed)/3;

			if(calc2(a)>calc2(b)) st=a;

			else ed=b;

		}

		printf("%.7lf", (double)min(calc2(0), min(kong(), calc2(st))));

	}

}