Problem: Two neighbours, Alan and Bob, live in the city, where there are three buildings only: a cinema, a shop and the house, where they live. The rest is a big asphalt square. 

Once they went to the cinema, and the film impressed them so deeply, that when they left the cinema, they did not want to stop discussing it.

Bob wants to get home, but Alan has to go to the shop first, and only then go home. So, they agreed to cover some distance together discussing the film (their common path might pass through the shop, or they might walk circles around the cinema together), and then to part each other's company and go each his own way. After they part, they will start thinking about their daily pursuits; and even if they meet again, they won't be able to go on with the discussion. Thus, Bob's path will be a continuous curve, having the cinema and the house as its ends. Alan's path — a continuous curve, going through the shop, and having the cinema and the house as its ends.

The film ended late, that's why the whole distance covered by Alan should not differ from the shortest one by more than t1, and the distance covered by Bob should not differ from the shortest one by more than t2.

Find the maximum distance that Alan and Bob will cover together, discussing the film.

Input

The first line contains two integers: t1, t2 (0 ≤ t1, t2 ≤ 100). The second line contains the cinema's coordinates, the third one — the house's, and the last line — the shop's. 

All the coordinates are given in meters, are integer, and do not exceed 100 in absolute magnitude. No two given places are in the same building.

Output

In the only line output one number — the maximum distance that Alan and Bob will cover together, discussing the film. Output the answer accurate to not less than 4 decimal places.

Examples

Input

0 2
0 0
4 0
-3 0


Output

1.0000000000


Input

0 0
0 0
2 0
1 0


Output

2.0000000000

Solution (in JAVA):

Solution:
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.StringTokenizer;

public class k implements Runnable {

	double meTolerance, otherTolerance;
	Vec cinema, house, shop;
	double meShortestPath, otherShortestPath;
	double meMaxAllowed, otherMaxAllowed;
	double shopToHouse;
	
	boolean eq(double a, double b) {
		return Math.abs(a - b) <= Vec.EPS;
	}
	
	//check if intersection of a and b is inside of c
	boolean test(Circle a, Circle b, Circle c) {
		if(c.contains(a.c) && a.contains(b.c)) return true;
		if(a.contains(c.c) && b.contains(c.c)) return true;
		Vec[] inter = a.intersect(b);
		if(inter == null) return false;
		for(Vec pt : inter) {
			if(c.contains(pt)) {
				return true;
			}
		}
		return false;
	}
	
	boolean check(double m) {
		double meDistRemain = meMaxAllowed - m;
		double otherDistRemain = otherMaxAllowed - m - shopToHouse;
		Circle cinemaCircle = new Circle(cinema, m);
		Circle shopCircle = new Circle(shop, otherDistRemain);
		Circle houseCircle = new Circle(house, meDistRemain);
		Circle[] all = {cinemaCircle, shopCircle, houseCircle};
		boolean good = false;
		for(int i = 0; i < 3; ++i) {
			for(int j = 0; j < 3; ++j) if(i != j) {
				for(int k = 0; k < 3; ++k) if(i != k && j != k) {
					good |= test(all[i], all[j], all[k]);
				}
			}
		}
		return good;
	}
	
	double go() {
		//binary search how far out we can walk together
		double lo = 0, hi = Math.min(meMaxAllowed, otherMaxAllowed - shopToHouse);
		for(int it = 0; it < 1000; ++it) {
			double m = (lo + hi) / 2;
			boolean good = check(m);
			if(good) lo = m;
			else hi = m;
		}
		return hi;
	}
	
	public void solve(FS in, PrintWriter out) {
		otherTolerance = in.nextDouble();
		meTolerance = in.nextDouble();
		
		cinema = new Vec(in.nextDouble(), in.nextDouble());
		house = new Vec(in.nextDouble(), in.nextDouble());
		shop = new Vec(in.nextDouble(), in.nextDouble());
		
		double firstHalf = shop.sub(cinema).mag();
		double secondHalf = house.sub(shop).mag();
		double direct = house.sub(cinema).mag();

		meShortestPath = direct;
		otherShortestPath = firstHalf + secondHalf;
		shopToHouse = secondHalf;
		
		meMaxAllowed = meShortestPath + meTolerance;
		otherMaxAllowed = otherShortestPath + otherTolerance;
		
		double ans = go();
		
		if(otherShortestPath <= meMaxAllowed || eq(otherShortestPath, meMaxAllowed)) {
			double cur = 0;
			cur += otherShortestPath;
			cur += Math.min(meMaxAllowed - otherShortestPath, otherMaxAllowed - otherShortestPath);
			ans = Math.max(ans, cur);
		}
		
		out.println(ans);
	}
	
	public void run() {
		System.err.println("go!");
		FS in = new FS();
		PrintWriter out = new PrintWriter(System.out);
		solve(in, out);
		out.close();
	}
	
	public static void main(String[] args) {
		new Thread(null, new k(), "lmao", 1L<<28).start();
	}
	static class FS {
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		StringTokenizer st = new StringTokenizer("");
		String next() {
			while(!st.hasMoreElements()) {
				try { st = new StringTokenizer(br.readLine()); }
				catch(Exception e) {}
			}
			return st.nextToken();
		}
		int nextInt() {
			return Integer.parseInt(next());
		}
		double nextDouble() {
			return Double.parseDouble(next());
		}
	}
	
	class Circle {
		Vec c;
		double r;
		
		public Circle(Vec c, double r) {
			this.c=c;
			this.r=r;
		}
		
		public boolean contains(Vec v) { 
			return c.sub(v).mag2()-Vec.EPS*Vec.EPS<=r*r;
		}
		
		//when standing at this circle, returns right tangent, then left tangent
		public Vec[] intersect(Circle o) {
			if (c.equals(o.c)) return null;
			Vec dir=o.c.sub(c);
			double d2=dir.mag2(), d=Math.sqrt(d2);
			if (Vec.eq(r+o.r, d)||Vec.eq(Math.min(r, o.r)+d, Math.max(r, o.r)))
				return new Vec[] {c.add(dir.scale(r/d))};
			if (r+o.r<d||r+d<o.r||o.r+d<r)
				return null;
			
			double d1=(r*r+d2-o.r*o.r)/(2*d);
			double h=Math.sqrt(r*r-d1*d1);
			Vec unitDir=dir.unit();
			Vec rInt=c.add(unitDir.scale(d1).add(unitDir.rot270().scale(h)));
			Vec lInt=c.add(unitDir.scale(d1).add(unitDir.rot90().scale(h)));
			return new Vec[] {rInt, lInt};
		}
		
		public double intersectionArea(Circle o) {
			double d=o.c.sub(c).mag();
			if (r+o.r<d) return 0;
			double minR=Math.min(r, o.r), maxR=Math.max(r, o.r), pi=Math.PI;
			if (Vec.leq(d+minR, maxR)) return pi*minR*minR;
			
			double theta1=2*Math.acos((r*r+d*d-o.r*o.r)/(2*r*d));
			double theta2=2*Math.acos((o.r*o.r+d*d-r*r)/(2*o.r*d));
			double part1Area=theta1/2*r*r;
			double part2Area=theta2/2*o.r*o.r;
			
			double tri1=r*r*Math.sin(theta1)/2;
			double tri2=o.r*o.r*Math.sin(theta2)/2;
			return part1Area+part2Area-tri1-tri2;
		}
		
		//returns right tangent, then left tangent from perspective of the point
		public Vec[] getTangentPoints(Vec p) {
			if (contains(p))
				return null;
			double d2=c.sub(p).mag2();
			return new Circle(p, Math.sqrt(d2-r*r)).intersect(this);
		}
		
		//line going from my left to his right, then my right to his left
		//lines go from me to him
		public Seg[] internalTangentLines(Circle o) {
			Vec[] tangentPoints=new Circle(c, r+o.r).getTangentPoints(o.c);
			Vec offset1=tangentPoints[0].sub(o.c).rot90().unit().scale(o.r);
			Vec offset2=tangentPoints[1].sub(o.c).rot270().unit().scale(o.r);
			return new Seg[] {new Seg(tangentPoints[0].add(offset1), o.c.add(offset1)),
							  new Seg(tangentPoints[1].add(offset2), o.c.add(offset2))};
		}
		
		//right external tangent, then left external tangent, from my perspective
		//lines go from me to him
		public Seg[] externalTangentLines(Circle o) {
			if (o.r>r) {
				Seg[] oAnswer=o.externalTangentLines(this);
				return new Seg[] {new Seg(oAnswer[1].to, oAnswer[1].from), new Seg(oAnswer[0].to, oAnswer[0].from)};
			}
			Vec[] tangentPoints=new Circle(c, r-o.r).getTangentPoints(o.c);
			Vec offset1=tangentPoints[0].sub(o.c).rot270().unit().scale(o.r);
			Vec offset2=tangentPoints[1].sub(o.c).rot90().unit().scale(o.r);
			return new Seg[] {new Seg(tangentPoints[1].add(offset2), o.c.add(offset2)),
							  new Seg(tangentPoints[0].add(offset1), o.c.add(offset1))};
		}
		
		//line (not line segment)-circle intersection in the order of line.dir
		public Vec[] intersectLine(Seg line) {
			Vec closest=line.projectToLine(c);
			double d2=closest.sub(c).mag2();
			if (d2>r*r) return null;
			double l=Math.sqrt(r*r-d2);
			if (Vec.eq(l, 0)) return new Vec[] {closest};
			Vec lVec=line.dir.unit().scale(l);
			return new Vec[] {closest.sub(lVec), closest.add(lVec)};
		}
		
		//line segment-circle intersection
		public Vec[] intersectSeg(Seg seg) {
			Vec[] lineIntersections=intersectLine(seg);
			if (lineIntersections==null) return null;
			ArrayList<Vec> contained=new ArrayList<>();
			for (Vec v:lineIntersections)
				if (seg.containsPoint(v))
					contained.add(v);
			if (contained.isEmpty()) return null;
			return contained.toArray(new Vec[contained.size()]);
		}
		
		
		public String toString() {
			DecimalFormat df=new DecimalFormat();
			return "center: "+c+", r: "+df.format(r);
		}
	}
	
	static class Vec {
		static final double EPS=1e-6;
		double x, y;
		
		public Vec(double x, double y) {
			this.x=x;
			this.y=y;
		}
		
		public Vec add(Vec o) {
			return new Vec(x+o.x, y+o.y);
		}
		
		public Vec sub(Vec o) {
			return new Vec(x-o.x, y-o.y);
		}

		public Vec scale(double s) {
			return new Vec(x*s, y*s);
		}
		
		public double dot(Vec o) {
			return x*o.x+y*o.y;
		}
		
		public double cross(Vec o) {
			return x*o.y-y*o.x;
		}
		
		public double mag2() {
			return dot(this);
		}
		
		public double mag() {
			return Math.sqrt(mag2());
		}
		
		public Vec unit() {
			return scale(1/mag());
		}
		
		public Vec rot90() {
			return new Vec(-y, x);
		}
		
		public Vec rot270() {
			return new Vec(y, -x);
		}
		
		public Vec rotate(double theta) {
			double PI=Math.PI;
			double newX=x*Math.cos(theta)+y*Math.cos(PI/2+theta);
			double newY=x*Math.sin(theta)+y*Math.sin(PI/2+theta);
			return new Vec(newX, newY);
		}
		
		//angle between 0 and 2PI
		public double angle() {
			return (Math.atan2(y, x)+2*Math.PI)%(2*Math.PI);
		}
		
		public String toString() {
			DecimalFormat df=new DecimalFormat("#.##");
			return "("+df.format(x)+", "+df.format(y)+")";
		}
		
		static boolean eq(double a, double b) {
			return Math.abs(a-b)<EPS;
		}
		
		static boolean leq(double a, double b) {
			return a-EPS<b;
		}
		
		static boolean geq(double a, double b) {
			return a+EPS>b;
		}
		
		public boolean equals(Object oo) {
			Vec o=(Vec)oo;
			return eq(x, o.x)&&eq(y, o.y);
		}
	}
	
	static class Seg {
		Vec from, to, dir;
		
		public Seg(Vec from, Vec to) {
			this.from=from;
			this.to=to;
			dir=to.sub(from);
		}
		
		//line-line intersection
		public Vec lineIntersect(Seg o) {
			double det=o.dir.x*dir.y-dir.x*o.dir.y;
			if (Vec.eq(det, 0)) return null;
			double dist=(o.dir.x*(o.from.y-from.y)-
					o.dir.y*(o.from.x-from.x))/det;
			return from.add(dir.scale(dist));
		}
		
		public boolean containsPoint(Vec o) {
			double distFromLine=dir.unit().cross(o.sub(from));
			if (!Vec.eq(distFromLine, 0)) return false;
			return Vec.eq(dir.mag(), from.sub(o).mag()+to.sub(o).mag());
		}
		
		//seg-seg intersection
		public Vec segIntersection(Seg o) {
			Vec intersect=lineIntersect(o);
			return containsPoint(intersect)&&o.containsPoint(intersect)?intersect:null;
		}
		
		//returns 1 if above, 0 if on, -1 if below
		public int side(Vec o) {
			Vec oDir=o.sub(from);
			double distFromLine=dir.unit().cross(oDir);
			if (Vec.eq(distFromLine, 0))
				return 0;
			return (int)Math.signum(distFromLine);
		}
		
		public boolean intersects(Seg o) {
			return side(o.from)!=side(o.to) && o.side(from)!=o.side(to);
		}
		
		public Vec getClosestTo(Vec o) {
			double percentThere=o.sub(from).dot(dir)/dir.mag2();
			return from.add(dir.scale(Math.max(0, Math.min(1, percentThere))));
		}
		
		public Vec projectToLine(Vec o) {
			return dir.scale(o.sub(from).dot(dir)/dir.mag2()).add(from);
		}
		
		//toContain must be a point with positive x and y coordinates.
		//this method returns the shortest line segment from the x-axis to the point to the y axis
		public static Seg getShortestSegFromAxesContainingQ1Point(Vec toContain) {
			double slope=-Math.pow(toContain.y/toContain.x, 1.0/3);
			double b=toContain.y-toContain.x*slope;
			double xInt=-b/slope;
			return new Seg(new Vec(0, b), new Vec(xInt, 0));
		}
		
		public String toString() {
			return from+" -> "+to;
		}
	}
}