The configuration of three circles packed inside a triangle such that each circle is tangent to the other two circles and to two of the edges of the triangle has been studied by many mathematicians for more than two centuries. Existence and uniqueness of such circles for an arbitrary triangle are easy to prove. Many methods of numerical calculation or geometric construction of such circles from an arbitrarily given triangle have been discovered. Today, such circles are called the Malfatti circles.

Figure 7 illustrates an example. The Malfatti circles of the triangle with the vertices (20, 80), (-40, -20) and (120, -20) are approximately

* the circle with the center (24.281677, 45.219486) and the radius 21.565935,
* the circle with the center (3.110950, 4.409005) and the radius 24.409005, and
* the circle with the center (54.556724, 7.107493) and the radius 27.107493.



Figure 8 illustrates another example. The Malfatti circles of the triangle with the vertices (20, -20), (120, -20) and (-40, 80) are approximately

* the circle with the center (25.629089, −10.057956) and the radius 9.942044,
* the circle with the center (53.225883, −0.849435) and the radius 19.150565, and
* the circle with the center (19.701191, 19.203466) and the radius 19.913790.



Your mission is to write a program to calculate the radii of the Malfatti circles of the given triangles.

<image>



Input

The input is a sequence of datasets. A dataset is a line containing six integers x1, y1 , x2 , y2, x3 and y3 in this order, separated by a space. The coordinates of the vertices of the given triangle are (x1 , y1 ), (x2 , y2 ) and (x3 , y3 ), respectively. You can assume that the vertices form a triangle counterclockwise. You can also assume that the following two conditions hold.

* All of the coordinate values are greater than −1000 and less than 1000.
* None of the Malfatti circles of the triangle has a radius less than 0.1.



The end of the input is indicated by a line containing six zeros separated by a space.

Output

For each input dataset, three decimal fractions r1 , r2 and r3 should be printed in a line in this order separated by a space. The radii of the Malfatti circles nearest to the vertices with the coordinates (x1 , y1 ), (x2 , y2 ) and (x3 , y3 ) should be r1 , r2 and r3 , respectively.

None of the output values may have an error greater than 0.0001. No extra character should appear in the output.

Example

Input

20 80 -40 -20 120 -20
20 -20 120 -20 -40 80
0 0 1 0 0 1
0 0 999 1 -999 1
897 -916 847 -972 890 -925
999 999 -999 -998 -998 -999
-999 -999 999 -999 0 731
-999 -999 999 -464 -464 999
979 -436 -955 -337 157 -439
0 0 0 0 0 0


Output

21.565935 24.409005 27.107493
9.942044 19.150565 19.913790
0.148847 0.207107 0.207107
0.125125 0.499750 0.499750
0.373458 0.383897 0.100456
0.706768 0.353509 0.353509
365.638023 365.638023 365.601038
378.524085 378.605339 378.605339
21.895803 22.052921 5.895714
#define _USE_MATH_DEFINES
#define _CRT_SECURE_NO_WARNINGS
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <climits>
#include <cfloat>
#include <ctime>
#include <cassert>
#include <map>
#include <utility>
#include <set>
#include <iostream>
#include <memory>
#include <string>
#include <vector>
#include <algorithm>
#include <functional>
#include <sstream>
#include <complex>
#include <stack>
#include <queue>
#include <numeric>
#include <list>

using namespace std;
typedef long long ll;
typedef pair<int, int> Pii;
typedef pair<ll, ll> Pll;

#define FOR(i,n) for(int i = 0; i < (n); i++)
#define sz(c) ((int)(c).size())
#define ten(x) ((int)1e##x)
#define tenll(x) ((ll)1e##x)


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

#pragma region 基本要素(struct,typedef)

typedef double T;

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

	//比較用
	bool operator<(const P &a)const { return (x != a.x) ? (x < a.x) : (y < a.y); }

};

struct S {
	P a, b;
	S() {}
	S(const P& a, const P& b) : a(a), b(b) {}
};

struct L {
	P a, b;
	L() {}
	L(const P& a, const P& b) : a(a), b(b) {}
};

struct C {
	P c;
	T r;
	C() {}
	C(const P &c, T& r) : c(c), r(r) {}
};

#pragma endregion 

#pragma region 基本要素(関数)

T SQ(T x) { return x*x; }
T dist2(const P &a, const P &b) { return SQ(a.x - b.x) + SQ(a.y - b.y); }
T abs2(const P& p) { return SQ(p.x) + SQ(p.y); }
double abs(const P& p) { return sqrt(abs2(p)); }
T dot(const P& a, const P& b) { return a.x*b.x + a.y*b.y; }
T cross(const P& a, const P& b) { return a.x*b.y - a.y*b.x; }
P rot(const P& a, const double theta) {
	return P(a.x*cos(theta) - a.y*sin(theta),a.x*sin(theta) + a.y*cos(theta));
}
double arg(const P &a) { double t = atan2(a.y, a.x); return t<0 ? t + 2 * PI : t; }

enum { CCW = 1, CW = -1, ON = 0 };
int ccw(const P &a, P b, P c) {
	b -= a; c -= a;
	double rdir = cross(b, c);
	double len = abs(b) * abs(c); //誤差対策 (速度がやばい時は外すか、二乗に置き換える)
	if (rdir> EPS * len) return CCW; //cがabより上(反時計周り)
	if (rdir<-EPS * len) return CW; // cがabより下(時計周り)
	return ON; // a,b,cが一直線上
}

#pragma endregion

#pragma region 入出力

std::ostream& operator<<(std::ostream& os, const P& point) { return (os << '(' << point.x << ',' << point.y << ')'); }
std::ostream& operator<<(std::ostream& os, const S& seg) { return (os << '{' << seg.a << ',' << seg.b << '}'); }
std::istream& operator>>(std::istream& is, P& point) { return (is >> point.x >> point.y); }

#pragma endregion

//交点が存在するかどうか
bool intersected(const S &S1, const S &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;
}

#pragma region 距離

//線分と点の距離(2乗)
double dist2(const S &S, const P &p) {
	if (dot(S.b - S.a, p - S.a) <= 0) return dist2(p, S.a);
	if (dot(S.a - S.b, p - S.b) <= 0) return dist2(p, S.b);
	return (double)SQ(cross(S.b - S.a, p - S.a)) / dist2(S.a, S.b);
}

//線分と点の距離
double dist(const S &S, const P &p) { return sqrt(dist2(S, p)); }

//線分と線分の距離
double dist(const S &S1, const S &S2) {
	if (intersected(S1, S2)) return 0;
	return sqrt(min(min(dist2(S1, S2.a), dist2(S1, S2.b)),
		min(dist2(S2, S1.a), dist2(S2, S1.b))));
}

//直線と点の距離
double dist(const L &L, const P &p) {
	return sqrt((double)SQ(cross(L.b - L.a, p - L.a)) / dist2(L.a, L.b));
}

//a -- bの間の円が入った時の、a - b間の距離
//円の間に
double geodist(P a, P b, const C &c) {
	double r = c.r;
	S s(a, b);
	if (dist(s, c.c)>r)
		return abs(a - b);

	a -= c.c;
	b -= c.c;

	double L1 = abs(a);
	double t1 = arg(a) + acos(r / L1); if (t1<0) t1 += 2 * PI;
	double t2 = arg(a) - acos(r / L1); if (t2<0) t2 += 2 * PI;

	double L2 = abs(b);
	double t3 = arg(b) + acos(r / L2); if (t3<0) t3 += 2 * PI;
	double t4 = arg(b) - acos(r / L2); if (t4<0) t4 += 2 * PI;

	double theta = 2 * PI;
	theta = min(theta, min(abs(t1 - t4), 2 * PI - abs(t1 - t4)));
	theta = min(theta, min(abs(t2 - t3), 2 * PI - abs(t2 - t3)));
	return sqrt(L1*L1 - r*r) + sqrt(L2*L2 - r*r) + r*theta;
}

#pragma endregion

#pragma region 面積

//多角形の面積
double area(const vector<P>& v) {
	double ans = 0;
	for (int i = 2; i < (int)v.size(); i++) {
		ans += cross(v[i - 1] - v[0], v[i] - v[0]);
	}
	return abs(ans) / 2;
}

//三角形の面積
double area(const P &a, const P &b, const P &c) {
	return abs(cross(b - a, c - a)) / 2;
}

#pragma endregion

#pragma region 包含

//凸包
vector<P> convex_hull(vector<P>& ps) {
	int n = ps.size(), k = 0;
	sort(ps.begin(), ps.end());
	vector<P> ch(2 * n);
	for (int i = 0; i < n; ch[k++] = ps[i++]) // lower-hull
	while (k >= 2 && ccw(ch[k - 2], ch[k - 1], ps[i]) <= 0) --k;

	for (int i = n - 2, t = k + 1; i >= 0; ch[k++] = ps[i--]) // upper-hull
	while (k >= t && ccw(ch[k - 2], ch[k - 1], ps[i]) <= 0) --k;

	ch.resize(k - 1);

	return ch;
}

//線分の内包判定
//1. AB の 両方の点が多角形に内包されている
//2. ABと多角形の交点がない

//凸でない多角形に頂点が含まれるかどうか
enum { POLY_OUT = -1, POLY_ON = 0, POLY_IN = 1 };
int contains(vector<P>& poly, const P& p) {
	bool in = false;
	FOR(i, sz(poly)) {
		P a = poly[i] - p, b = poly[(i + 1) % sz(poly)] - p;
		if (a.y > b.y) swap(a, b);
		if (a.y <= 0 && 0 < b.y)
			if (cross(a, b) < 0) in = !in;

		if (cross(a, b) == 0 && dot(a, b) <= 0) return POLY_ON;
	}
	return in ? POLY_IN : POLY_OUT;
}

//三角形abcにpが含まれているかどうか(線上の場合も含む)
bool cover(const P& a, const P& b, const P& c, const P& p) {
	return area(a, b, c) + EPS >= area(a, b, p) + area(a, c, p) + area(b, c, p);
}

#pragma endregion

#pragma region 交点

//円同士の交点
int intersect(const C &C1, const C &C2, P* p = NULL, P *q = NULL) {
	double r1 = C1.r, r2 = C2.r;
	P p1 = C1.c, p2 = C2.c;

	double d = abs(p1 - p2);
	if (d<EPS && abs(r1 - r2)<EPS) { // C1==C2
		return -1;
	} else if (r1 + r2<d - EPS || d + EPS<abs(r1 - r2)) {
		return 0;
	} else {
		double a = (r1*r1 - r2*r2 + d*d) / (2 * d);
		double h = sqrt(max(r1*r1 - a*a, 0.0));
		P tmp1 = p1 + (p2 - p1)*a / d;
		P tmp2 = (p2 - p1)*h / d;
		if (abs(tmp2)<EPS) {
			if (p&&q) *p = *q = tmp1;
			return 1;
		} else {
			if (p&&q) {
				*p = P(tmp1.x - tmp2.y, tmp1.y + tmp2.x);
				*q = P(tmp1.x + tmp2.y, tmp1.y - tmp2.x);
			}
			return 2;
		}
	}
}

// l : ax+by+c=0 に変換
inline void calc_abc(const L &l, double &a, double &b, double &c) {
	a = l.a.y - l.b.y;
	b = l.b.x - l.a.x;
	c = l.a.x*l.b.y - l.b.x*l.a.y;
}

//PからLへの垂線の足
P perp_foot(const P &p, const L &l) {
	double a, b, c;
	calc_abc(l, a, b, c);
	return p - P(a, b) * ((a*p.x + b*p.y + c) / (a*a + b*b));
}

//円と直線の交点
int intersect(const C &c, const L &l, P *p = NULL, P *q = NULL) {
	P m = perp_foot(c.c, l);
	double d2 = abs2(c.c - m);
	if (c.r*c.r + EPS<d2)   return 0;
	else if (abs(c.r*c.r - d2)<EPS) {
		if (p&&q)    *p = *q = m;
		return 1;
	} else {
		if (p&&q) {
			P v;
			double n0 = abs2(l.a - m), n1 = abs2(l.b - m);
			if (n0<n1)    v = l.b - m, n0 = n1;
			else        v = l.a - m;
			v *= sqrt((c.r*c.r - d2) / n0);
			*p = m + v, *q = m - v;
		}
		return 2;
	}
}

//円と線分の交点
int intersect(const C &c, const S &s, P *p = NULL, P *q = NULL) {
	P pp, qq;
	int n = intersect(c, L(s.a, s.b), &pp, &qq);
	if (n == 0)    return 0;
	else if (n == 1) {
		if (dot(pp - s.a, pp - s.b)<EPS) {
			if (p&&q)    *p = *q = pp;
			return 1;
		}
		return 0;
	} else {
		bool bp = (dot(pp - s.a, pp - s.b)<EPS);
		bool bq = (dot(qq - s.a, qq - s.b)<EPS);
		if (bp&&bq) {
			if (p&&q)    *p = pp, *q = qq;
			return 2;
		}
		if (bp || bq) {
			if (p&&q)    *p = (bp ? pp : qq);
			return 1;
		}
		return 0;
	}
}

//直線の交点
P intersect(const L &L1, const L &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 + (L2.b - L2.a) * (a2 / a1);
}

//角ABC の二等分線,A + pはBC上の辺に存在する
P bisect_angle(P A, P B, P C) {
	A -= B; C -= B;
	double alen = abs(A), clen = abs(C);
	P p = (A * clen + C * alen) / (alen + clen);
	return p;
}

//三角形ABCにおいて、AからBCへの垂線の長さ
double perp_len(P A, P B, P C) {
	return 2 * area(A, B, C) / abs(B - C);
}

//三角形の内心
P inner_center(P A, P B, P C) {
	P bis1 = bisect_angle(A, B, C);
	P bis2 = bisect_angle(B, A, C);
	L l1(B, B + bis1), l2(A, A + bis2);
	return intersect(l1, l2);
}

#pragma endregion


int main() {
	int x1, x2, x3, y1, y2, y3;
	while (cin >> x1 >> y1 >> x2 >> y2 >> x3 >> y3) {
		if (!x1&&!x2&&!x3&&!y1&&!y2&&!y3) break;
		double A = hypot(x2 - x3, y2 - y3);
		double B = hypot(x3 - x1, y3 - y1);
		double C = hypot(x1 - x2, y1 - y2);
		double a1 = acos((B*B + C*C - A*A) / (2 * B*C)) / 2;
		double a2 = acos((C*C + A*A - B*B) / (2 * C*A)) / 2;
		double a3 = acos((A*A + B*B - C*C) / (2 * A*B)) / 2;
		double cotA = cos(a1) / sin(a1);
		double cotB = cos(a2) / sin(a2);
		double cotC = cos(a3) / sin(a3);

		double s = (A + B + C) / 2;
		double S = sqrt(s*(s - A)*(s - B)*(s - C));
		double r1, r2, r3;
		double l = 0, r = S / (A+B+C) * 2;
		FOR(_, 50) {
			r1 = (l + r) / 2;
			double p = r1 * cotA;
			r2 = (-sqrt(r1) + sqrt(r1 - cotB * (p - C))) / cotB;
			r2 *= r2;
			r3 = (-sqrt(r1) + sqrt(r1 - cotC * (p - B))) / cotC;
			r3 *= r3;
			double cur_A = r2*cotB + r3*cotC + 2 * sqrt(r2*r3);
			if (cur_A < A) r = r1;
			else l = r1;
		}
		printf("%.10f %.10f %.10f\n", r1, r2, r3);
	}
}