unittest
{
	assert( [ "3 4 9 0" ].solve == "5.000000000" );
	assert( [ "3 4 10 40" ].solve == "4.564257194" );
}



import std.conv;
import std.format;
import std.math;
import std.range;
import std.stdio;

void main()
{
	stdin.byLineCopy.solve.writeln;
}

auto solve( Range )( Range input )
if( isInputRange!Range && is( ElementType!Range == string ) )
{
	auto a = 0L;
	auto b = 0L;
	auto h = 0L;
	auto m = 0L;
	input.front.formattedRead!"%s %s %s %s"( a, b, h, m );
	
	auto pa = Point( 0, 0 ) + Vector( a, ( h * 60 + m ) * PI / 360 );
	auto pb = Point( 0, 0 ) + Vector( b, m * PI / 30 );
	return format( "%0.9f", pa.distance( pb ) );
}

// 座標
struct Point
{
	real x = 0;
	real y = 0;
	
	void opOpAssign( string OP )( Vector v ) if( OP == "+" ){ this.x += v.x; this.y += v.y; }
	void opOpAssign( string OP )( Vector v ) if( OP == "-" ){ this.x -= v.x; this.y -= v.y; }
	auto opBinary( string OP )( Vector v ){ auto l = this; l.opOpAssign!OP( v ); return l; }
	
	auto distance( Point p ){ return hypot( p.x - this.x, p.y - this.y ); }
	auto angle( Point p ){ return atan2( p.y - this.y, p.x - this.x ); }
	auto toString(){ return format( "Point(%f, %f)", this.x, this.y ); }
}

// ベクトル
struct Vector
{
	real m = 0;
	real d = 0;		// 0が+x方向、PI_2が+y方向、PIが-x方向、PI_2*3が-y方向
	
	this( real m, real d )
	{
		this.m = m;
		this.d = d;
		if( this.d < -2 * PI || 2 * PI < this.d ) this.d %= PI * 2;
		if( this.d < -PI ) this.d += PI * 2;
		if(  PI < this.d ) this.d -= PI * 2;
	}
	
	this( Point a, Point b )
	{
		this = Vector( a.distance( b ), a.angle( b ) );
	}
	
	auto opUnary( string OP )() if( OP == "+" ){ return this; }
	auto opUnary( string OP )() if( OP == "-" ){ return Vector( m, d + PI ); }
	void opOpAssign( string OP )( real m ) if( OP == "+"  ){ this.m += m; }
	void opOpAssign( string OP )( real m ) if( OP == "-"  ){ this.m -= m; }
	void opOpAssign( string OP )( real m ) if( OP == "*"  ){ this.m *= m; }
	void opOpAssign( string OP )( real m ) if( OP == "/"  ){ this.m /= m; }
	void opOpAssign( string OP )( real m ) if( OP == "^^" ){ this.m ^^= m; }
	auto opBinary( string OP )( real m ){ auto l = this; l.opOpAssign!OP( m ); return l; }
	
	void opOpAssign( string OP )( Vector v ) if( OP == "+" ){ this = Point( 0, 0 ).vector( Point( 0, 0 ) + this + v ); }
	void opOpAssign( string OP )( Vector v ) if( OP == "-" ){ this = Point( 0, 0 ).vector( Point( 0, 0 ) + this - v ); }
	auto opBinary( string OP )( Vector v ){ auto l = this; l.opOpAssign!OP( v ); return l; }
	
	auto turn( real d ){ return Vector( this.m, this.d + d ); }
	auto x(){ return this.m * cos( this.d ); }
	auto y(){ return this.m * sin( this.d ); }
	auto angleBetween( Vector v ){ auto d = abs( this.d - v.d ); return ( d <= PI ) ? d : 2 * PI - d; }
	auto toString(){ return format( "Vector(%f, %f)", this.m, this.d ); }
}
