#include<cmath>
#include<cstdio>
#include<algorithm>

#define rep(i,n) for(int i=0;i<(n);i++)

using namespace std;

const double EPS=1e-8;
const double PI=acos(-1);

struct point{
	double x,y;
	point():x(0),y(0){}
	point(double x,double y):x(x),y(y){}
	point &operator/=(double c){ x/=c; y/=c; return *this; }
	point operator+(const point &a)const{ return point(x+a.x,y+a.y); }
	point operator-(const point &a)const{ return point(x-a.x,y-a.y); }
	point operator/(double c)const{ return point(x/c,y/c); }
};

point operator*(double c,const point &a){ return point(c*a.x,c*a.y); }

double cross(const point &a,const point &b){ return a.x*b.y-a.y*b.x; }

double abs(const point &a){ return sqrt(a.x*a.x+a.y*a.y); }

point rot(const point &a,double theta){ return point(a.x*cos(theta)-a.y*sin(theta),a.x*sin(theta)+a.y*cos(theta)); }

double arg(const point &a){
	double t=atan2(a.y,a.x);
	return t<0?t+2*PI:t;
}

struct line{
	point a,b;
	line(){}
	line(const point &a,const point &b):a(a),b(b){}
};

struct segment{
	point a,b;
	segment(){}
	segment(const point &a,const point &b):a(a),b(b){}
};

enum{CCW=1,CW=-1,ON=0};
int ccw(const point &a,const point &b,const point &c){
	double rdir=cross(b-a,c-a);
	if(rdir> EPS) return CCW;
	if(rdir<-EPS) return CW;
	return ON;
}

bool intersect(const segment &S1,const segment &S2){
	if(max(S1.a.x,S1.b.x)+EPS<min(S2.a.x,S2.b.x)
	|| max(S1.a.y,S1.b.y)+EPS<min(S2.a.y,S2.b.y)
	|| max(S2.a.x,S2.b.x)+EPS<min(S1.a.x,S1.b.x)
	|| max(S2.a.y,S2.b.y)+EPS<min(S1.a.y,S1.b.y)) return false;
	return ccw(S1.a,S1.b,S2.a)*ccw(S1.a,S1.b,S2.b)<=0
		&& ccw(S2.a,S2.b,S1.a)*ccw(S2.a,S2.b,S1.b)<=0;
}

point get_intersect(const line &L1,const line &L2){
	double a1=cross(L1.b-L1.a,L2.b-L2.a);
	double a2=cross(L1.b-L1.a,L1.b-L2.a);
	if(abs(a1)<EPS) return L1.a;
	return L2.a+a2/a1*(L2.b-L2.a);
}

double straight_time(double s,double a,double v0,double v1){ // 初速 v0, 終速 v1 で長さ s の直線を走るときの最短所要時間
	double x=(v1*v1-v0*v0+2*a*s)/(4*a); // 加速-減速を切り替える位置
	double v=sqrt(v0*v0+2*a*x); // x での速度
	return (v-v0)/a+(v-v1)/a;
}

int main(){
	int n;
	double a_max; scanf("%d%lf",&n,&a_max);
	static segment S[40000];
	rep(i,n) scanf("%lf%lf%lf%lf",&S[i].a.x,&S[i].a.y,&S[i].b.x,&S[i].b.y);

	static double r[39999],phi[39999]; // 円弧の半径と中心角
	rep(i,n-1){
		point v1=S[ i ].b-S[ i ].a; v1/=abs(v1);
		point v2=S[i+1].a-S[i+1].b; v2/=abs(v2);
		line L(S[ i ].b,S[ i ].b+rot(v1,-PI/2));
		line M(S[i+1].a,S[i+1].a+rot(v2, PI/2));
		point c;
		if(ccw(L.a,L.b,M.a)==ON) c=(S[i].b+S[i+1].a)/2;
		else                     c=get_intersect(L,M);

		r[i]=abs(S[i].b-c);
		phi[i]=abs(arg(S[i+1].a-c)-arg(S[i].b-c));
		if(phi[i]>PI) phi[i]=2*PI-phi[i];
		if(!intersect(segment(S[i].b,S[i].b+777*v1),segment(S[i+1].a,S[i+1].a+777*v2))) phi[i]=2*PI-phi[i];
	}

	static double s[40000]; // ストレートの長さ
	rep(i,n) s[i]=abs(S[i].a-S[i].b);

	static double limit[40000]; // コーナーの進入速度の上限
	for(int i=n-1;i>=0;i--){
		limit[i]=min(sqrt(a_max*r[i]),sqrt(limit[i+1]*limit[i+1]+2*a_max*s[i+1]));
	}

	double ans=0;
	static double v[40000]; // 実際の進入速度
	rep(i,n-1){
		v[i+1]=min(limit[i],sqrt(v[i]*v[i]+2*a_max*s[i]));
		ans+=straight_time(s[i],a_max,v[i],v[i+1])+r[i]*phi[i]/v[i+1];
	}
	ans+=straight_time(s[n-1],a_max,v[n-1],0);

	printf("%.9f\n",ans);

	return 0;
}

Measured memory_bytes: 3928