Problem: Read a set of coordinates of three different points P1 (x1, y1), P2 (x2, y2), Q (xq, yq) on the plane, and line symmetry with point Q with the straight line passing through point P1 point P2 as the axis of symmetry. Create a program that outputs the point R (x, y) at the position of. Note that the point Q is not on its axis of symmetry.

<image>



input

The input consists of multiple datasets. Each dataset is given in the following format:


x1, y1, x2, y2, xq, yq


x1, y1, x2, y2, xq, yq (real numbers between -100 and 100) are given on one line separated by commas.

The number of datasets does not exceed 50.

output

Print x, y on a single line, separated by blanks, for each dataset. The output may contain an error of 0.0001 or less in real numbers.

Example

Input

1.0,0.0,-1.0,0.0,1.0,1.0
1.0,0.0,0.0,-1.0,3.0,0.0
0.0,1.0,0.0,-1.0,1.0,1.0


Output

1.000000 -1.000000
1.000000 2.000000
-1.000000 1.000000

Solution (in CPP):

Solution:
#include <iostream>
#include <algorithm>
#include <iomanip>
#include <map>
#include <set>
#include <queue>
#include <stack>
#include <numeric>
#include <bitset>
#include <cmath>

static const int MOD = 1000000007;
using ll = long long;
using u32 = uint32_t;
using namespace std;

template<class T> constexpr T INF = ::numeric_limits<T>::max()/32*15+208;

using real = double;
real EPS = 1e-10;
struct Point {
    real x, y;
    Point& operator+=(const Point a) { x += a.x; y += a.y;  return *this; }
    Point& operator-=(const Point a) { x -= a.x; y -= a.y;  return *this; }
    Point& operator*=(const real k) { x *= k; y *= k;  return *this; }
    Point& operator/=(const real k) { x /= k; y /= k;  return *this; }
    Point operator+(const Point a) const {return Point(*this) += a; }
    Point operator-(const Point a) const {return Point(*this) -= a; }
    Point operator*(const real k) const {return Point(*this) *= k; }
    Point operator/(const real k) const {return Point(*this) /= k; }
    bool operator<(const Point &a) const { return (x != a.x ? x < a.x : y < a.y); }
    explicit Point(real a = 0, real b = 0) : x(a), y(b) {};
};

istream& operator>> (istream& s, Point& P){
    s >> P.x >> P.y;
    return s;
}

inline real dot(Point a, Point b){ return a.x*b.x + a.y*b.y; }
inline real cross(Point a, Point b){ return a.x*b.y - a.y*b.x; }
inline real abs(Point a){ return sqrt(dot(a, a)); }

static constexpr int COUNTER_CLOCKWISE = 1;
static constexpr int CLOCKWISE = -1;
static constexpr int ONLINE_BACK = 2;
static constexpr int ONLINE_FRONT = -2;
static constexpr int ON_SEGMENT = 0;

int ccw(Point a, Point b, Point c){
    b -= a; c -= a;
    if(cross(b, c) > EPS) return COUNTER_CLOCKWISE;
    if(cross(b, c) < -EPS) return CLOCKWISE;
    if(dot(b, c) < 0) return ONLINE_BACK;
    if(abs(b) < abs(c)) return ONLINE_FRONT;
    return ON_SEGMENT;
}
struct Segment {
    Point a, b;
    Segment(Point x, Point y) : a(x), b(y) {};
};

double distance(Segment l, Point c){
    if(dot(l.b-l.a, c-l.a) < EPS) return abs(c-l.a);
    if(dot(l.a-l.b, c-l.b) < EPS) return abs(c-l.b);
    return abs(cross(l.b-l.a, c-l.a)) / abs(l.a-l.b);
}

bool intersect(Segment l1, Segment l2){
    return (ccw(l1.a, l1.b, l2.a)*ccw(l1.a, l1.b, l2.b) <= 0 &&
            ccw(l2.a, l2.b, l1.a)*ccw(l2.a, l2.b, l1.b) <= 0);
}

Point crossPoint(Segment l1, Segment l2){
    real d1 = abs(cross(l1.b-l1.a, l2.b-l2.a));
    real d2 = abs(cross(l1.b-l1.a, l1.b-l2.a));
    if(d1 < EPS && d2 < EPS) return l2.a;
    return l2.a+(l2.b-l2.a)*d2/d1;
}

Point project(Segment s, Point p){
    Point Q = s.b-s.a;
    return s.a + Q*(dot(p-s.a, Q) / dot(Q, Q));
}

Point refrect(Segment s, Point p){
    Point Q = project(s, p);
    return Q*2-p;
}


int main(){
    double x1, y1, x2, y2, xq, yq;
    while(scanf("%lg,%lg,%lg,%lg,%lg,%lg", &x1, &y1, &x2, &y2, &xq, &yq) != EOF){
        Point a(x1, y1), b(x2, y2), P(xq, yq);
        Segment s(a, b);
        Point ans = refrect(s, P);
        printf("%.10lf %.10lf\n", ans.x, ans.y);
    }
    return 0;
}