Problem: For given two circles $c1$ and $c2$, print the coordinates of the cross points of them.

Constraints

* The given circle have at least one cross point and have different center coordinates.
* $-10,000 \leq c1x, c1y, c2x, c2y \leq 10,000$
* $1 \leq c1r, c2r \leq 10,000$

Input

The input is given in the following format.

$c1x\; c1y\; c1r$
$c2x\; c2y\; c2r$


$c1x$, $c1y$ and $c1r$ represent the coordinate and radius of the first circle. $c2x$, $c2y$ and $c2r$ represent the coordinate and radius of the second circle. All input values are given in integers.

Output

Print the coordinates ($x1$, $y1$) and ($x2$, $y2$) of the cross points $p1$ and $p2$ respectively in the following rules.

* If there is one cross point, print two coordinates with the same values.
* Print the coordinate with smaller $x$ first. In case of a tie, print the coordinate with smaller $y$ first.



The output values should be in a decimal fraction with an error less than 0.000001.

Examples

Input

0 0 2
2 0 2


Output

1.00000000 -1.73205080 1.00000000 1.73205080


Input

0 0 2
0 3 1


Output

0.00000000 2.00000000 0.00000000 2.00000000

Solution (in CPP):

Solution:
#include <bits/stdc++.h>
#define db double
using namespace std;
const double inf = 1e20;
const double eps = 1e-8;
const double pi = acos (-1);
const int N = 2e5 + 100;
int sgn (double x) {
    if (fabs (x) < eps) return 0;
    if (x < 0) return -1;
    return 1;
}
struct point {
    double x, y;
    point () {}
    point (double _x, double _y) {
        x = _x, y = _y;
    }
    void input () {
        scanf ("%lf %lf", &x, &y);
    }
    point operator - (const point &b) const {
        return point (x - b.x, y - b.y);
    }
    bool operator == (const point &b) const {
        return sgn (x - b.x) == 0 && sgn (y - b.y) == 0;
    }
    bool operator < (const point &b) const {
        if (sgn (x - b.x) == 0) return y < b.y;
        return x < b.x;
    }
    double operator * (const point &b) const {
        return x * b.x + y * b.y;
    }
    double operator ^ (const point &b) const {
        return x * b.y - y * b.x;
    }
    point operator / (const double &b) const {
        return point (x / b, y / b);
    }
    point operator * (const double &b) const {
        return point (x * b, y * b);
    }
    point operator + (const point &b) const {
        return point (x + b.x, y + b.y);
    }
    double cross (point a, point b) {
        return (point (a - *this) ^ point (b - *this));
    }
    double dot (point a, point b) {
        return (point (a - *this) * point (b - *this));
    }
    double len () {
        return hypot (x, y);
    }
    bool on_seg (point a, point b) {///点是否在线段ab上
        return sgn (cross (a, b)) == 0 && dot (a, b) <= 0;
    }
    point turn (db k) {
        return point (x * cos (k) - y * sin (k), x * sin (k) + y * cos (k));
    }
} s, e;
///两线段的交点
point spp (point s1, point e1, point s, point e) {
    if (s.dot (e, s1) > s.dot (e, e1)) swap (s1, e1);
    point p = e - s;
    double len = p.len ();
    double a = fabs (s.cross (e, s1)) / len;
    double b = fabs (s.cross (e, e1)) / len;
    double a1 = s.dot (e, s1) / len;
    double b1 = s.dot (e, e1) / len;
    double k = a1 + fabs(a1 - b1) / (a + b) * a;
    p = p / len, p = p * k, p = p + s;
    return p;
}
///两线段是否相交
bool seg (point a, point b, point c, point d) {
    if (a.on_seg (c, d)) return true;
    if (a.cross (b, d) * a.cross (b, c) < 0 && c.cross (d, b) * c.cross (d, a) < 0) return true;
    return false;
}
/// 点的投影是否在线段ab上
bool check (point p, point a, point b) {
    point x = b - a;
    double k = x.len ();
    double u = a.dot (p, b) / k;
    x = (x / k) * u;
    x = x + a;
    if (x.on_seg (a, b)) return true;
    return false;
}
struct line {
    point s, e;
    line () {}
    line (point _s, point _e) {
        s = _s, e = _e;
    }

};
//struct polygon {
//    int n;
//    point ps[N];
//    void input () {
//        cin >> n;
//        for (int i = 0; i < n; i++) ps[i].input ();
//    }
//    ///排序规则
//    struct cmp {
//        point p;
//        cmp (point _p) {
//            p = _p;
//        }
//        bool operator () (const point &aa, const point &bb) {
//            point a = aa, b = bb;
//            int d = sgn (p.cross (a, b));
//            if (d == 0) return point (a - p).len () < point (b - p).len ();
//            else return d > 0;
//        }
//    };
//    ///排序
//    void norm () {
//        point mi = ps[0];
//        for (int i = 0; i < n; i++) mi = min (mi, ps[i]);
//        sort (ps, ps + n, cmp (mi));
//    }
//    ///求凸包
////    void getconvex (polygon &convex) {
////        sort (ps, ps + n);
////        int &top = convex.n;
////        top = 0;
////        convex.ps[top++] = ps[0];
////        for (int i = 1; i < n; i++) {
////            while (top >= 2 && convex.ps[top - 2].cross (convex.ps[top - 1], ps[i]) < 0) top--;
////            convex.ps[top++] = ps[i];
////        }
////        int t = 0;
////        for (int i = n - 2; i >= 0; i--) {
////            while (t && convex.ps[top - 2].cross (convex.ps[top - 1], ps[i]) < 0) top--, t--;
////            if (!i) break;
////            convex.ps[top++] = ps[i];
////            t++;
////        }
////    }
//    ///几何面积
//    double mianji () {
//        if (n < 2) return 0;
//        double ans = 0;
//        ps[n] = ps[0];
//        for (int i = 1; i <= n; i++) ans += point (0, 0).cross (ps[i - 1], ps[i]);
//        return ans;
//    }
//} dd, ans;
struct circle {
    point p;
    double r;
    circle () {}
    circle (point _p, double _r) {
        p = _p, r = _r;
    }
    void input () {
        p.input ();
        scanf ("%lf", &r);
    }
} cr1, cr2;
int main () {
    cr1.input (), cr2.input ();
    double len = point (cr1.p - cr2.p).len ();
    double k = (cr1.r * cr1.r + len * len - cr2.r * cr2.r) / (2 * cr1.r * len);
    k = acos (k);
    db len1 = point (cr1.p - cr2.p).len ();
    s = point (cr2.p - cr1.p).turn (k);
    e = point (cr2.p - cr1.p).turn (-k);
    s = s / len1 * cr1.r;
    e = e / len1 * cr1.r;
    s = s + cr1.p;
    e = e + cr1.p;
    if (e < s) swap (s, e);
    printf ("%.8f %.8f %.8f %.8f\n", s.x, s.y, e.x, e.y);
    return 0;
}