Problem: A convex polygon consisting of N vertices is given. The coordinates of each vertex are represented counterclockwise by (X1, Y1), (X2, Y2), ……, (XN, YN). No matter what straight line passes through the point P, find the coordinates of the point P so that the areas of the two convex polygons obtained after cutting are equal.

Constraints

* All inputs are integers

* 3 ≤ N ≤ 50

* 0 ≤ | Xi |, | Yi | ≤ 1000000

* The input polygon is a simple convex polygon.

* The output must satisfy max (| X-cX |, | Y-cY |) ≤ 0.0001 when the output coordinates are (X, Y) and the exact solution is (cX, cY).

Input

The input is given in the following format.

> N
> X1 Y1
> X2 Y2
> ……
> XN YN
>

Output

If there is a point that satisfies the condition of the problem statement, the coordinates of that point

> X Y
>

Output in the format of. If the point does not exist, output "NA" on one line.

Examples

Input

4
100 100
0 100
0 0
100 0


Output

50.00000 50.00000


Input

3
100 100
0 100
0 0


Output

NA

Solution (in CPP):

Solution:
#include "bits/stdc++.h"
using namespace std;

//#define int long long
#define DBG 1
#define dump(o) if(DBG){cerr<<#o<<" "<<(o)<<" ";}
#define dumpl(o) if(DBG){cerr<<#o<<" "<<(o)<<endl;}
#define dumpc(o) if(DBG){cerr<<#o; for(auto &e:(o))cerr<<" "<<e;cerr<<endl;}
#define rep(i,a,b) for(int i=(a);i<(b);i++)
#define rrep(i,a,b) for(int i=(b)-1;i>=(a);i--)
#define all(c) begin(c),end(c)
const int INF = sizeof(int) == sizeof(long long) ? 0x3f3f3f3f3f3f3f3fLL : 0x3f3f3f3f;
const int MOD = (int)(1e9 + 7);
template<class T> bool chmax(T &a, const T &b) { if (a < b) { a = b; return true; } return false; }
template<class T> bool chmin(T &a, const T &b) { if (a > b) { a = b; return true; } return false; }

const double EPS = 1e-8;
#define equals(a,b) (fabs((a)-(b)) < EPS)
#define next(P,i) P[(i+1)%P.size()]
#define prev(P,i) P[(i+P.size()-1)%P.size()]

//0?¬?
class Point {
public:
	double x, y;
	Point() {}
	Point(double x, double y) :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*(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 y != p.y ? y < p.y : x < p.x; // y?????? -> x??????
		return x != p.x ? x < p.x : y < p.y; // x?????? -> 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; }
};
inline ostream &operator << (ostream &os, const Point &p) { os << p.x << " " << p.y; return os; }
inline istream &operator >> (istream &is, Point &p) { double x, y; is >> x >> y; p = Point(x, y); return is; }

//1?¬?
class Vector :public Point {
public:
	using Point::Point;
	Vector(const Point &P) { x = P.x; y = P.y; }
	Vector rotate(double rad) { return Vector(x*cos(rad) - y*sin(rad), x*sin(rad) + y*cos(rad)); }
};

class Line {
public:
	Point p1, p2;
	Line() {}
	Line(Point p1, Point p2) :p1(p1), p2(p2) {}
};
class Segment :public Line {
public:
	using Line::Line;
	Segment(const Line &L) { p1 = L.p1; p2 = L.p2; }
	Vector vec() { return p2 - p1; }
};


//2?¬?
class Circle {
public:
	Point c; //center
	double r; //radius
	Circle() {}
	Circle(Point c, double r) :c(c), r(r) {}
};
using Polygon = vector<Point>;

//?????? dot product
double dot(Vector a, Vector b) { return a.x*b.x + a.y*b.y; }
//?????? cross product ?????§???????????£????????????
double cross(Vector a, Vector b) { return a.x*b.y - a.y*b.x; }

//????????¢??? radian ??? ??? degree
double rad(double deg) { return acos(-1)*deg / 180; }
//????§? argument
double arg(Vector p) { return atan2(p.y, p.x); }
//?\???¢??? polar form
Vector polar(double r, double a) { return Point(cos(a)*r, sin(a)*r); }

bool inrange(Point p, double x1, double y1, double x2, double y2) {
	return x1 <= p.x&&p.x <= x2&&y1 <= p.y&&p.y <= y2;
}

//??´?????????
bool is_orthogonal(Vector a, Vector b) { return equals(dot(a, b), 0.0); }
bool is_orthogonal(Point a1, Point a2, Point b1, Point b2) { return is_orthogonal(a1 - a2, b1 - b2); }
bool is_orthogonal(Segment s1, Segment s2) { return equals(dot(s1.p2 - s1.p1, s2.p2 - s2.p1), 0.0); }

//????????????
bool is_parallel(Vector a, Vector b) { return equals(cross(a, b), 0.0); }
bool is_parallel(Point a1, Point a2, Point b1, Point b2) { return is_parallel(a1 - a2, b1 - b2); }
bool is_parallel(Segment s1, Segment s2) { return equals(cross(s1.p2 - s1.p1, s2.p2 - s2.p1), 0.0); }

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

//??????(p0,p1)????????????p2???????????¢???
enum { ONLINE_FRONT = -2, CLOCKWISE, ON_SEGMENT, COUNTER_CLOCKWISE, ONLINE_BACK };
int ccw(Point p0, Point p1, Point p2) {
	Vector a = p1 - p0, b = p2 - p0;
	if (cross(a, b) > EPS)return COUNTER_CLOCKWISE;
	if (cross(a, b) < -EPS)return CLOCKWISE;
	if (dot(a, b) < -EPS)return ONLINE_BACK; //p2 p0 p1
	if (a.norm() < b.norm())return ONLINE_FRONT; //p0 p1 p2
	return ON_SEGMENT;
}
int ccw(Vector a, Vector b) {
	if (cross(a, b) > EPS)return COUNTER_CLOCKWISE;
	if (cross(a, b) < -EPS)return CLOCKWISE;
	if (dot(a, b) < -EPS)return ONLINE_BACK; //p2 p0 p1
	if (a.norm() < b.norm())return ONLINE_FRONT; //p0 p1 p2
	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); }
//(?????????????¶????)

//2??????????????¢
double get_distance(Point a, Point b) { return (a - b).abs(); }
//??´?????¨???????????¢
double get_distance(Line l, Point p) { return abs(cross(l.p2 - l.p1, p - l.p1) / (l.p2 - l.p1).abs()); }
//????????¨???????????¢
double get_distance(Segment s, Point p) {
	if (dot(s.p2 - s.p1, p - s.p1) < 0.0)return (p - s.p1).abs();
	if (dot(s.p1 - s.p2, p - s.p2) < 0.0)return (p - s.p2).abs();
	return get_distance(Line(s), p);
}
//????????¨??????????????¢
double get_distance(Segment s1, Segment s2) {
	if (intersect(s1, s2))return 0.0;
	return	min(
		min(get_distance(s1, s2.p1), get_distance(s1, s2.p2)),
		min(get_distance(s2, s1.p1), get_distance(s2, s1.p2))
	);
}

//?????¨??´??????????????????
bool intersect(Circle c, Line l) { return get_distance(l, c.c) <= c.r + EPS; }
//?????¨?????????????????? ??±?????\????????°
int intersect(Circle c1, Circle c2) {
	double d = get_distance(c1.c, c2.c);
	if (d > c1.r + c2.r)return 4;
	if (d == c1.r + c2.r)return 3;
	if (d + c1.r == c2.r || d + c2.r == c1.r)return 1;
	if (d + c1.r < c2.r || d + c2.r < c1.r)return 0;
	return 2;
}

//????????¨???????????????
Point get_cross_point(Segment s1, Segment s2) {
	assert(intersect(s1, s2));
	Vector base = s2.p2 - s2.p1;
	double a1 = abs(cross(base, s1.p1 - s2.p1)); //area1
	double a2 = abs(cross(base, s1.p2 - s2.p1)); //area2
	double t = a1 / (a1 + a2);
	return s1.p1 + (s1.p2 - s1.p1)*t;
}
//??´?????¨??´????????????
//Point get_cross_point(Line l1, Line l2) {}

//?????¨??´????????????
pair<Point, Point> get_cross_points(Circle c, Line l) {
	assert(intersect(c, l));
	Vector pr = project(l, c.c);
	Vector e = (l.p2 - l.p1) / (l.p2 - l.p1).abs();
	double base = sqrt(c.r*c.r - (pr - c.c).norm());
	return make_pair(pr + e*base, pr - e*base);
}
//?????¨????????????
pair<Point, Point> get_cross_points(Circle c1, Circle c2) {
	int m = intersect(c1, c2);
	assert(m != 4 && m != 0);
	double d = (c1.c - c2.c).abs();
	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));
}

//????????????
enum { OUT = 0, ON, IN };
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 ON;
		if (a.y > b.y)swap(a, b);
		if (a.y < EPS&&EPS<b.y&&cross(a, b)>EPS)x = !x;
	}
	return (x ? IN : OUT);
}

int contains(Circle c, Point p) {
	double d = get_distance(c.c, p);
	if (equals(d, c.r))return ON;
	if (d < c.r)return IN;
	return OUT;
}

//????§???¢?????¢???
double area(Polygon g) {
	double a = 0;
	for (size_t i = 0; i < g.size(); i++)
		a += cross(g[i], g[(i + 1) % g.size()]);
	return a / 2.0;
}

//?????§????????????????¨??????????
bool is_convex(Polygon g) {
	for (size_t i = 0; i < g.size(); i++)
		if (ccw(g[i], g[(i + 1) % g.size()], g[(i + 2) % g.size()]) == CLOCKWISE)
			return false;
	return true;
}

//??????
//Graham scan https://en.wikipedia.org/wiki/Graham_scan
//???????????????????????????
Polygon convex_hull(Polygon P) {
	sort(P.begin(), P.end());
	Polygon up;
	for (Point &p : P) {
		while (up.size() > 1 && ccw(up[up.size() - 2], up[up.size() - 1], p) != CLOCKWISE)up.pop_back();
		up.emplace_back(p);
	}
	Polygon down;
	for (Point &p : P) {
		while (down.size() > 1 && ccw(down[down.size() - 2], down[down.size() - 1], p) != COUNTER_CLOCKWISE)down.pop_back();
		down.emplace_back(p);
	}
	reverse(up.begin(), up.end()); // ???????¨??????????
	down.insert(down.end(), up.begin() + 1, up.end() - 1);
	return down;
}

//??????
//Graham scan https://en.wikipedia.org/wiki/Graham_scan
//?????????????????????
Polygon convex_hull_with_points_online(Polygon P) {
	sort(P.begin(), P.end());
	Polygon up;
	for (Point &p : P) {
		int _ccw;
		while (up.size() > 1 && (_ccw = ccw(up[up.size() - 2], up[up.size() - 1], p)) != CLOCKWISE &&_ccw != ONLINE_FRONT)
			up.pop_back();
		up.emplace_back(p);
	}
	Polygon down;
	for (Point &p : P) {
		int _ccw;
		while (down.size() > 1 && (_ccw = ccw(down[down.size() - 2], down[down.size() - 1], p)) != COUNTER_CLOCKWISE && _ccw != ONLINE_FRONT)
			down.pop_back();
		down.emplace_back(p);
	}
	reverse(up.begin(), up.end()); // ???????¨??????????
	down.insert(down.end(), up.begin() + 1, up.end() - 1);
	return down;
}

//???????§???¢??????????????????????????¢
//calipers https://en.wikipedia.org/wiki/Rotating_calipers
double diameter(Polygon P) {
	P = convex_hull(P);
	auto mima = minmax_element(P.begin(), P.end());
	int I = mima.first - P.begin();
	int J = mima.second - P.begin();
	double maxd = get_distance(P[I], P[J]);

	int maxi, maxj, i, j;
	i = maxi = I;
	j = maxj = J;
	do {
		if (ccw(next(P, i) - P[i], next(P, j) - P[j]) == COUNTER_CLOCKWISE)
			j = (j + 1) % P.size();
		else
			i = (i + 1) % P.size();
		if (maxd < get_distance(P[i], P[j])) {
			maxd = get_distance(P[i], P[j]);
			maxi = i, maxj = j;
		}
	} while (!(i == I&&j == J));
	return maxd;
}

//????§???¢???(0,0)???????????¨???????????¢
Polygon rotate(const Polygon &P, double rad) {
	Polygon ret;
	for (auto &p : P)
		ret.emplace_back(p.x*cos(rad) - p.y*sin(rad), p.x*sin(rad) + p.y*cos(rad));
	return ret;
}

//????§???¢?????????
Point center(const Polygon &P) {
	Point ret(0, 0);
	for (auto &p : P)ret = ret + p;
	ret = ret / P.size();
	return ret;
}

signed main() {
	cout << fixed << setprecision(6);
	int N; cin >> N;
	Polygon P(N);
	rep(i, 0, N)cin >> P[i];
	Point c = center(P);
	for (auto &p : P)p = p - c;
	Polygon Q = rotate(P, rad(180));
	sort(all(P));
	sort(all(Q));
	if (P == Q)cout << c << endl;
	else cout << "NA" << endl;
	return 0;
}