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
#include <iostream>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <algorithm>
#include <functional>
#include <vector>
#include <list>
#include <queue>
#include <deque>
#include <stack>
#include <map>
#include <set>
#include <bitset>
#include <tuple>
#include <complex>
#include <cassert>
#include <exception>
#include <iomanip>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<ll,ll> P;
typedef vector<int> vi;
typedef vector<ll> vll;
typedef vector<char> vc;
typedef vector<string> vs;
typedef vector<P> vp;
#define rep(i,a,n) for(ll i = (a);i < (n);i++)
#define per(i,a,n) for(ll i = (a);i > (n);i--)
#define lep(i,a,n) for(ll i = (a);i <= (n);i++)
#define pel(i,a,n) for(ll i = (a);i >= (n);i--)
#define clr(a,b) memset((a),(b),sizeof(a))
#define pb push_back
#define all(c) (c).begin(),(c).end()
#define sz size()
#define print(X) cout << (X) << "\n"
#define input(X) getline(cin,X)
static const int INF = 1e+9+7;
static const ll INFL = 1e+18+7;
ll n,m,l;
int p;
string s,t;
ll d[200010],dp[300][300];
char field[200][200];
namespace Geometry{
  #define equals(a,b) (fabs((a) - (b)) < EPS)
  #define BOTTOM 0
  #define LEFT 1
  #define RIGHT 2
  #define TOP 3
  #define gprint(X) cout << fixed << setprecision(8) << (X) << endl
  #define gprints(X,Y) cout << fixed << setprecision(8) << (X) << " " << (Y) << endl
  const double EPS = 1e-10;
  static const int COUNTER_CLOCKWISE = 1;
  static const int CLOCKWISE = -1;
  static const int ONLINE_BACK = 2;
  static const int ONLINE_FRONT = -2;
  static const int ON_SEGMENT = 0;
  
  class Point{
  public:
    double x,y;
    Point(double x = 0,double y = 0): x(x),y(y){}
    Point operator + (Point p){ return Point(x + p.x , y + p.y); }
    Point operator - (Point p){ return Point(x - p.x , y - p.y); }
    Point operator += (Point p){ return Point(x += p.x,y += p.y); }
    Point operator -= (Point p){ return Point(x -= p.x,y -= p.y); }
    Point operator * (double a){ return Point(a * x , a * y); }
    Point operator / (double a){ return Point(x / a , y / a); }
    bool operator < (const Point &p) const{ return x != p.x ? x < p.x : y < p.y; }
    bool operator == (const Point &p) const{ return equals(x,p.x) && equals(y,p.y); }

    double abs(){ return sqrt(norm()); }
    double norm(){ return x * x + y * y; }
    friend ostream& operator << (ostream &os,Point &p){ return os << p.x << " " << p.y; }
    friend istream& operator >> (istream &is,Point &p){ return is >> p.x >> p.y; }
  };

  struct Segment{
    Point p1,p2;
    Segment(){};
    Segment(Point p1,Point p2): p1(p1) , p2(p2){};
    friend ostream& operator << (ostream &os,Segment &seg){ return os << seg.p1 << " " << seg.p2; }
    friend istream& operator >> (istream &is,Segment &seg){ return is >> seg.p1 >> seg.p2; }
  };

  class Circle{
  public:
    Point c;
    double r;
    Circle(Point c = Point(),double r = 0.0): c(c),r(r){}
    friend ostream& operator << (ostream &os,Circle &c){ return os << c.c << " " << c.r; }
    friend istream& operator >> (istream &is,Circle &c){ return is >> c.c >> c.r; }
  };

  typedef Point Vector;
  typedef Segment Line;
  typedef vector<Point> Polygon;

  double norm(Vector a){ return  a.x * a.x + a.y * a.y; }
  double abs(Vector a){ return sqrt(norm(a)); }
  double dot(Vector a,Vector b){ return a.x * b.x + a.y * b.y; }
  double cross(Vector a,Vector b){ return a.x * b.y - a.y * b.x; }
  bool Orthogonal(Vector a,Vector b){ return equals(dot(a,b),0.0); }
  bool Orthogonal(Point a1,Point a2,Point b1,Point b2){ return Orthogonal(a1 - a2,b1 - b2); }
  bool Orthogonal(Segment s1,Segment s2){ return equals(dot(s1.p2 - s1.p1,s2.p2 - s2.p1) , 0.0); }
  bool Parallel(Vector a,Vector b){ return equals(cross(a,b),0.0); }
  bool Parallel(Point a1,Point a2,Point b1,Point b2){ return Parallel(a1 - a2 , b1 - b2); }
  bool Parallel(Segment s1,Segment s2){ return equals(cross(s1.p2 - s1.p1 , s2.p2 - s2.p1),0.0); }
  bool less(const Point &a,const Point &b){ return (a.x != b.x) ? a.x < b.x : a.y < b.y; }
  bool greater(const Point &a,const Point b){ return !less(a,b); }

  Point project(Segment s,Point p){
    Vector base = s.p2 - s.p1;
    double r = dot(p - s.p1 , base) / norm(base);
    return s.p1 + base * r;
  }

  Point reflect(Segment s,Point p){
    return p + (project(s,p) - p) * 2.0;
  }

  int ccw(Point &p0,Point p1,Point p2){
    p1 -= p0;
    p2 -= p0;
    if(cross(p1,p2) > EPS)return COUNTER_CLOCKWISE;
    if(cross(p1,p2) < -EPS)return CLOCKWISE;
    if(dot(p1,p2) < -EPS)return ONLINE_BACK;
    if(p1.norm() < p2.norm())return ONLINE_FRONT;
    return ON_SEGMENT;
  }

  bool intersect(Point p1,Point p2,Point p3,Point p4){
    return (ccw(p1,p2,p3) * ccw(p1,p2,p4) <= 0 && 
            ccw(p3,p4,p1) * ccw(p3,p4,p2) <= 0);
  }
  bool intersect(Segment s1,Segment s2){ return intersect(s1.p1 , s1.p2 , s2.p1 , s2.p2); }

  double getDistance(Vector a,Vector b){ return abs(a - b); }
  double getDistance(Segment s1){ return getDistance(s1.p1,s1.p2); }
  double getDistanceLP(Line l,Point p){ return abs(cross(l.p2 - l.p1 , p - l.p1) / abs(l.p2 - l.p1)); }
  double getDistanceSP(Segment s,Point p){
    if(dot(s.p2 - s.p1,p - s.p1) < 0.0) return abs(p - s.p1);
    if(dot(s.p1 - s.p2,p - s.p2) < 0.0) return abs(p - s.p2);
    return getDistanceLP(s,p);
  }
  double getDistance(Segment s1,Segment s2){
    if(intersect(s1,s2))return 0.0;
    return min(min(getDistanceSP(s1,s2.p1),getDistanceSP(s1,s2.p2)),
               min(getDistanceSP(s2,s1.p1),getDistanceSP(s2,s1.p2)));
  }

  Point getCrossPoint(Segment s1,Segment s2){
    Vector base = s2.p2 - s2.p1;
    double d1 = abs(cross(base,s1.p1 - s2.p1));
    double d2 = abs(cross(base,s1.p2 - s2.p1));
    double t = d1 / (d1 + d2);
    return s1.p1 + (s1.p2 - s1.p1) * t;
  }

  pair<Point,Point> getCrossPoints(Circle c,Line l){
    Vector pr = project(l,c.c);
    Vector e = (l.p2 - l.p1) / abs(l.p2 - l.p1);
    double base = sqrt(c.r * c.r - norm(pr - c.c));
    return make_pair(pr + e * base , pr - e * base);
  }

  double arg(Vector p){ return atan2(p.y,p.x); }
  Vector polar(double a,double r){ return Point(cos(r) * a, sin(r) * a); }

  pair<Point,Point> getCrossPoints(Circle c1,Circle c2){
    double d = abs(c1.c - c2.c);
    double a = acos((c1.r * c1.r + d * d - c2.r * c2.r) / (2 * c1.r * d));
    double t = arg(c2.c - c1.c);
    return make_pair(c1.c + polar(c1.r,t + a),c1.c + polar(c1.r,t - a));
  }
  
  int contains(Polygon g,Point p){
    int n = g.size();
    bool x = false;
    for(int i = 0;i < n;i++){
      Point a = g[i] - p, b = g[(i + 1) % n] - p;
      if(abs(cross(a,b)) < EPS && dot(a,b) < EPS)return 1;
      if(a.y > b.y)swap(a,b);
      if(a.y < EPS && EPS < b.y && cross(a,b) > EPS)x = !x;
    }
    return (x ? 2 : 0);
  }

  //=====================================================//
  //==================== Andrew Scan ====================//
  //=====================================================//
 
  int Accw(Point p0,Point p1,Point p2){
    Vector a = p1 - p0;
    Vector b = p2 - p0;
    if(cross(a,b) > EPS)return 1;
    return -1;
  }
 
  Polygon andrewScan(Polygon s){
    Polygon ans;
    Polygon u,l;
    if(s.size() < 3)return s;
    sort(s.begin(),s.end());
    u.push_back(s[0]);
    u.push_back(s[1]);
    l.push_back(s[s.size()-1]);
    l.push_back(s[s.size()-2]);
    for(int i = 2;i < s.size();i++){
      for(int n = u.size();n >= 2 && Accw(u[n-2],u[n-1],s[i]) != -1;n--){
        u.pop_back();
      }
      u.push_back(s[i]);
    }
 
    for(int i = s.size() - 3;i >= 0;i--){
      for(int n = l.size();n >= 2 && Accw(l[n-2],l[n-1],s[i]) != -1;n--){
        l.pop_back();
      }
      l.push_back(s[i]);
    }
    reverse(l.begin(),l.end());
    for(int i = u.size() - 2;i >= 1;i--){
      l.push_back(u[i]);
    }
    int f = 0;
    for(int i = 1;i < l.size();i++){
      if(l[f].y > l[i].y || (l[f].y == l[i].y && l[f].x > l[i].x)){
        f = i;
      }
    }
    for(int i = 0;i < l.size();i++){
      ans.push_back(Point((int)l[(i + f)%l.size()].x,(int)l[(i + f)%l.size()].y));
    }
    return ans;
  }

  //=====================================================//
  //======================== END ========================//
  //=====================================================//

  class EndPoint{
  public:
    Point p;
    int seg,st;
    EndPoint(){}
    EndPoint(Point p,int seg,int st): p(p),seg(seg),st(st){}

    bool operator < (const EndPoint &ep) const{
      if(p.y == ep.p.y){
        return st < ep.st;
      }else{
        return p.y < ep.p.y;
      }
    }
  };

  EndPoint EP[2 * 100000];

  int manhattanIntersection(vector<Segment> S){
    int n = S.size();
    for(int i = 0,k = 0;i < n;i++){
      if(S[i].p1.y == S[i].p2.y){
        if(S[i].p1.x > S[i].p2.x)swap(S[i].p1,S[i].p2);
      }else if(S[i].p1.y > S[i].p2.y){
        swap(S[i].p1,S[i].p2);
      }

      if(S[i].p1.y == S[i].p2.y){
        EP[k++] = EndPoint(S[i].p1,i,LEFT);
        EP[k++] = EndPoint(S[i].p2,i,RIGHT);
      }else{
        EP[k++] = EndPoint(S[i].p1,i,BOTTOM);
        EP[k++] = EndPoint(S[i].p2,i,TOP);
      }
    }

    sort(EP,EP + (2 * n));

    set<int> BT;
    BT.insert(1000000001);
    int cnt = 0;
    for(int i = 0;i < 2 * n;i++){
      if(EP[i].st == TOP){
        BT.erase(EP[i].p.x);
      }else if(EP[i].st == BOTTOM){
        BT.insert(EP[i].p.x);
      }else if(EP[i].st == LEFT){
        set<int>::iterator b = lower_bound(BT.begin(),BT.end(),S[EP[i].seg].p1.x);
        set<int>::iterator e = upper_bound(BT.begin(),BT.end(),S[EP[i].seg].p2.x);
        cnt += distance(b,e);
      }
    }
    return cnt;
  }
};

using namespace Geometry;

int main(){
  Point a,b,c;
  while(cin >> a >> b >> c,(a.abs() + b.abs() + c.abs()) != 0){
    // Area Size
    double segA = getDistance(b,c);
    double segB = getDistance(a,c);
    double segC = getDistance(b,a);
    double area1 = (segA + segB + segC) / 2;
    double area2 = sqrt(area1 * (area1 - segA) * (area1 - segB) * (area1 - segC));
    double radius = area2 / area1;
    // cout << "total : " << (segA * radius / 2) + (segB * radius / 2) + (segC * radius / 2) << endl;
    Point p = Point((segA*a.x + segB*b.x + segC*c.x)/(segA + segB + segC),(segA*a.y + segB*b.y + segC*c.y)/(segA + segB + segC));

    double difA = getDistance(p,a);
    double difB = getDistance(p,b);
    double difC = getDistance(p,c);

    // ans
    double r1 = radius / (2 * (area1 - segA)) * (area1 + difA - radius - difB - difC);
    double r2 = radius / (2 * (area1 - segB)) * (area1 + difB - radius - difA - difC);
    double r3 = radius / (2 * (area1 - segC)) * (area1 + difC - radius - difB - difA);
    cout << fixed << setprecision(6) << r1 << " " << r2 << " " << r3 << endl;
  }
  return 0;
}
