#include <bits/stdc++.h>

//Common
using namespace std;using f64 = double;using i64=long long;using u64=unsigned long long;
template<typename T> using Arr=vector<T>;template<typename T> using Func=function<T>;template<typename T> using Str=basic_string<T>;
#define hfor(v, s, e) for(int v=(s);(s)<=v&&v<(e);++v)//half-opened range
#define hfori(v, s, e) for(int v=(e)-1;(s)<=v&&v<(e);--v)//inversion
#define hforo(v, s, e) int v=(s);for(;(s)<=v&&v<(e);++v)//out declaration
#define hforoi(v, s, e) int v=(e)-1; for(;(s)<=v&&v<(e);--v)
#define cfor(v, s, e) hfor(v,(s),(e)+1)//closed range
#define cfori(v, s, e) hfori(v,(s),(e)+1)
#define cforo(v, s, e) hforo(v,(s),(e)+1)
#define cforoi(v, s, e) hforoi(v,(s),(e)+1)
#define rep(v,x) hfor(v,0,(x))
#define repi(v,x) hfori(v,0,(x))
#define repo(v,x) hforo(v,0,(x))
#define all(x) (x).begin(),(x).end()
#define sz(x) ((int)(x).size())
#define pushb push_back
#define pushf push_front
#define popb pop_back
#define popf pop_front
#define empl emplace
#define emplb emplace_back
#define emplf emplace_front
#define fi first
#define se second
#define cxp constexpr
#define PQ std::priority_queue

//Math
template<typename T> cxp T inf() { return numeric_limits<T>::max() / 2; }
template<typename T> inline T sq(T x){return x*x;}
int rd(int lb, int ub){static mt19937 rng(time(0)^i64(new int)); return uniform_int_distribution<int>(lb, ub-1)(rng);}
int rd(int ub=inf<int>()){return rd(0,ub);}
const f64 pi=acosl(-1), eps=1e-10;

//IO
template<typename T>ostream& operator<<(ostream& s, const Arr<T>& a) {for(auto i:a) cout<<i<<' '; return s;}
int getint(){int x;cin>>x;return x;}
char getchr(){char x;cin>>x;return x;}
#ifndef DEBUG
	//#pragma GCC optimize ("Ofast") //somtimes it become more slower
	auto __PRE_RUN__=(ios::sync_with_stdio(0), cin.tie(0), cout.tie(0),(cout<<fixed<<setprecision(11)), 0);
#endif

//Functional
namespace fun{
	template<typename U> auto map(const auto& a, auto f){Arr<U> r; for(const auto& x:a)r.pushb(f(x)); return r;}
	template<typename T> auto reduce(const auto& a, T acc){ return accumulate(all(a),acc); }
	template<typename T> auto reduce(const auto& a, T acc, auto f){ return accumulate(all(a),acc,f); }
	template<typename T> T rev(const T& a){return {a.rbegin(),a.rend()};}
	Arr<int> range(int n){ Arr<int> ret(n); rep(i,n)ret[i]=i; return ret; }
	struct defer{ defer(auto f):f(f){} ~defer(){f();} function<void()> f; };
	#define defer(x) auto _##__COUNTER__ = fun::defer([&](){x;});
	#define lam(expr, ...) [&](__VA_ARGS__){return expr;}
}

//Misc
auto split(auto s, auto p){
	Arr<decltype(s)> ret;
	auto it1=s.begin();
	for(auto it2=it1; (it2 = find(it1,s.end(),p)) != s.end(); it1=it2+1)
		ret.pushb({it1, it2});
	ret.pushb({it1,s.end()});
	return ret;
}
int pow2ceil(int x){assert(x);return 1<<(32-__builtin_clz(x-1));}

struct Frac{
	i64 a,b;
	Frac(i64 a=0, i64 b=1):a(a),b(b){normalize();}
	bool operator<(const Frac& r)const{
		//NaN < -inf < ... < inf (for using set conveniently)
		//!(a>b) && !(a<b) <=> a==b
		if(r.is_nan())
			return false;
		if(is_nan())
			return true;
		return a*r.b<r.a*b;
	}
	bool operator>(const Frac& r)const{return r<*this;}
	bool operator==(const Frac& r)const{return !(*this<r)&&!(*this>r);}
	bool operator!=(const Frac& r)const{return !(*this==r);}
	bool operator<=(const Frac& r)const{return *this<r||*this==r;}
	bool operator>=(const Frac& r)const{return *this>r||*this==r;}
	Frac operator+(const Frac& r)const{return {a*r.b+r.a*b, b*r.b};}
	Frac operator*(const Frac& r)const{return {a*r.a, b*r.b};}
	Frac operator/(const Frac& r)const{return (*this)*Frac(r.b,r.a);}
	bool is_singular()const{return !b;}
	bool is_infpos()const{return a>0&&!b;}
	bool is_infneg()const{return a<0&&!b;}
	bool is_nan()const{return !a&&!b;}
	bool is_int()const{return b&&!(a%b);}
	i64 to_integer()const{return a/b;}
	f64 to_f64(){return (f64)a/b;}
	i64 ceil()const{return a/b+(a*b>0)*!!(a%b);}
	i64 floor()const{return a/b-(a*b<0)*!!(a%b);}
	i64 smaller_int()const{return is_int()?to_integer()-1:floor();}
	i64 larger_int()const{return is_int()?to_integer()+1:ceil();}
	void normalize(){
		if(is_singular()){
			if(a)
				a/=abs(a);
			return;
		}

		i64 g = gcd(a,b);
		a/=g; b/=g;
		if(b<0)
			a*=-1, b*=-1;
	}
};

template<>
Frac inf(){return {1,0};}

template<typename T>
ostream& operator<<(ostream& s, const Frac& n){return s<<n.a<<'/'<<n.b;}

template<typename T>
struct Vec2 {
	T x, y;
	Vec2() :Vec2(0, 0) {}
	Vec2(T x, T y) :x(x), y(y) {}
	Vec2 operator+(const Vec2& r)const { return Vec2(x+r.x, y+r.y); }
	Vec2 operator-()const { return Vec2(-x,-y); }
	Vec2 operator-(const Vec2& r)const { return *this+-r; }
	Vec2 operator*(T r)const { return Vec2(x*r, y*r); }
	Vec2 operator/(T r)const { return Vec2(x/r, y/r); }
	Vec2 operator+=(const Vec2& r) { return *this=*this+r; }
	Vec2 operator-=(const Vec2& r) { return *this=*this-r; }
	Vec2 operator*=(T r) { return *this=*this*r; }
	Vec2 operator/=(T r) { return *this=*this/r; }
	bool operator==(const Vec2& r)const { return x==r.x && y==r.y; }
	bool operator!=(const Vec2& r)const { return !(*this==r); }
	bool operator<(const Vec2& r)const { return x==r.x ? y<r.y : x<r.x; }
	bool operator<=(const Vec2& r)const { return *this==r || *this<r; }
	bool operator>(const Vec2& r)const { return x== r.x ? y>r.y : x>r.x; }
	bool operator>=(const Vec2& r)const { return *this==r || *this>r; }
	f64 len()const { return hypot(x, y); }
	T lensq()const { return dot(*this); }
	T taxi()const{return abs(x)+abs(y);}
	Vec2 normalized()const { return *this/len(); }
	T dot(const Vec2& r) const { return x*r.x + y*r.y; }
	T dot(const Vec2& a, const Vec2& b) const { return (a-*this).dot(b-*this); }
	T cross(const Vec2& r)const { return x*r.y - y*r.x; }
	T cross(const Vec2& a, const Vec2& b) const { return (a-*this).cross(b-*this); }
	T ccw(const Vec2& a, const Vec2& b) const { return cross(a, b) ? cross(a, b)/abs(cross(a, b)) : 0; }
	f64 angle()const { auto ret=atan2(y, x); return fmod(ret+2*pi, 2*pi); }
	Frac tan()const { return {y, x}; }
	Vec2 project(const Vec2& p)const { Vec2 base = normalized(); return base*base.dot(p); }
	Vec2 ortho()const{ return Vec2(y, -x); }
	Vec2 rot(double rad)const{ return Vec2(cos(rad)*x-sin(rad)*y, sin(rad)*x+cos(rad)*y); }
	Vec2 rot(double s, double c)const{ return Vec2(c*x-s*y, s*x+c*y); }

	static Vec2 inf(){ return {::inf<T>(),::inf<T>()}; }
	static bool cmpccw(const Vec2& l, const Vec2& r, const Vec2& base) {
		T val = base.ccw(l, r);
		assert(base <= l && base <= r);
		if (val == 0)
			//need some thinking but ok. because base should be left-bottom element.
			return l < r;
		return val > 0;
	}
};

template<typename T>
ostream& operator<<(ostream& s, const Vec2<T>& v) { return s<<'('<<v.x<<','<<v.y<<')'; }

template<typename T>
bool ccw(const Vec2<T>& a, const Vec2<T>& b, const Vec2<T>& c){return a.ccw(b,c)<0;}

#define endl '\n'//not interactive?
#define int i64//MLE?
using pint = pair<int,int>;
using tint = tuple<int,int,int>;

signed main(){
	Vec2<f64> a,b;
	cin>>a.y>>b.y;
	int h,m; cin>>h>>m;
	a=a.rot(30*h*pi/180+pi/180*30/60*m);
	b=b.rot(6*m*pi/180);
	cout<<(b-a).len()<<endl;
	return 0;
}



Measured memory_bytes: 4064