Problem:
Problem E:
Symmetry
Open Binary and Object Group organizes a programming contest every year. Mr. Hex belongs to this
group and joins the judge team of the contest. This year, he created a geometric problem with its solution
for the contest. The problem required a set of points forming a line-symmetric polygon for the input.
Preparing the input for this problem was also his task. The input was expected to cover all edge cases, so
he spent much time and attention to make them satisfactory.
However, since he worked with lots of care and for a long time, he got tired before he finished. So He
might have made mistakes - there might be polygons not meeting the condition. It was not reasonable to
prepare the input again from scratch. The judge team thus decided to find all line-asymmetric polygons
in his input and fix them as soon as possible. They asked a programmer, just you, to write a program to
find incorrect polygons.
You can assume the following:
Edges of the polygon must not cross or touch each other except for the end points of adjacent
       edges.
It is acceptable for the polygon to have adjacent three vertexes on a line, but in such a case, there
       must be the vertex symmetric to each of them.
Input
The input consists of a set of points in the following format.
N
x
1
y
1
x
2
y
2
...
x
N
y
N
The first line of the input contains an integer
N
(3 ≤
N
≤ 1000), which denotes the number of points.
The following
N
lines describe each point. The
i
-th line contains two integers
x
1
,
y
1
(-10000 ≤
x
i
,
y
i
≤ 10000), which denote the coordinates of the
i
-th point.
Note that, although the points are the vertexes of a polygon, they are given in an artibrary order, not
necessarily clockwise or counterclockwise.
Output
Output "
Yes
" in a line if the points can form a line-symmetric polygon, otherwise output "
No
".
Sample Input 1
4
0 1
1 0
0 0
1 1
Sample Output 1
Yes
Sample Input 2
4
0 1
1 -1
0 0
1 1
Sample Output 2
No
Sample Input 3
9
-1 1
0 1
1 1
-1 0
0 0
1 0
-1 -1
0 -1
1 -1
Sample Output 3
No
Sample Input 4
3
-1 -1
0 0
1 1
Sample Output 4
No
Sample Input 5
4
0 2
0 0
-1 0
1 0
Sample Output 5
Yes

Submitted solutions:

code_snippet: // AOJ #2159
// Symmetry 2025.2.10

#include <bits/stdc++.h>
using namespace std;
using ll = long long;

const double EPS = 1e-9;
 
bool dEqual(double a, double b, double eps = EPS) {
    return fabs(a-b) < eps;
}
 
double normalizeAngle(double a) {
    a = fmod(a, M_PI);
    if(a < 0) a += M_PI;
    return a;
}
 
struct Point { int x, y; };
 
ll cross_ll(ll ax, ll ay, ll bx, ll by) {
    return ax * by - ay * bx;
}
 
int main() {
    ios::sync_with_stdio(0);
    cin.tie(0);
 
    int N;
    cin >> N;
    vector<Point> pts(N);
    ll sumx = 0, sumy = 0;
    for (int i = 0; i < N; i++){
        cin >> pts[i].x >> pts[i].y;
        sumx += pts[i].x;
        sumy += pts[i].y;
    }
    double cx = (double) sumx / N;
    double cy = (double) sumy / N;
    
    bool allCollinear = true;
    int idx = -1;
    for (int i = 0; i < N; i++){
        if(!(dEqual(pts[i].x, pts[0].x) && dEqual(pts[i].y, pts[0].y))) {
            idx = i;
            break;
        }
    }
    if(idx == -1){
        cout << "No" << endl;
        return 0;
    }
    for (int i = 0; i < N; i++){
        ll dx1 = pts[idx].x - pts[0].x;
        ll dy1 = pts[idx].y - pts[0].y;
        ll dx2 = pts[i].x - pts[0].x;
        ll dy2 = pts[i].y - pts[0].y;
        if(cross_ll(dx1, dy1, dx2, dy2) != 0){
            allCollinear = false;
            break;
        }
    }
    if(allCollinear){
        cout << "No" << endl;
        return 0;
    }
 
    vector<double> cand;
    for (int i = 0; i < N; i++){
        double dx = pts[i].x - cx, dy = pts[i].y - cy;
        if(fabs(dx) < EPS && fabs(dy) < EPS) continue;
        double ang = atan2(dy, dx);
        if(ang < 0) ang += 2*M_PI;
        double cand1 = normalizeAngle(ang);
        cand.push_back(cand1);
        double cand2 = normalizeAngle(ang + M_PI/2);
        cand.push_back(cand2);
    }
    sort(cand.begin(), cand.end());
    vector<double> candUnique;
    for (double a : cand){
        if(candUnique.empty() || fabs(a - candUnique.back()) > EPS)
            candUnique.push_back(a);
    }
 
 
    bool possible = false;
    for (double theta : candUnique) {
        double ux = cos(theta), uy = sin(theta);
        double vx = -sin(theta), vy = cos(theta);
 
        vector<double> tvals(N), dvals(N);
        double t_min_all = 1e18, t_max_all = -1e18;
        int offCount = 0;
        for (int i = 0; i < N; i++){
            double dx = pts[i].x - cx, dy = pts[i].y - cy;
            double t = dx * ux + dy * uy;
            double d = dx * vx + dy * vy;
            tvals[i] = t;
            dvals[i] = d;
            t_min_all = min(t_min_all, t);
            t_max_all = max(t_max_all, t);
            if(fabs(d) > EPS) offCount++;
        }
        if(offCount == 0) continue;
 
        double T_range = t_max_all - t_min_all;
        const double TOL_t = 1e-7; 
        map<ll, pair<int,int>> groups;
        auto quantize = [&](double x) -> ll {
            return (ll) round(x / TOL_t);
        };
        bool ok = true;
        for (int i = 0; i < N; i++){
            if(fabs(dvals[i]) > EPS){
                ll key = quantize(tvals[i]);
                if(dvals[i] > EPS) groups[key].first++;
                else               groups[key].second++;
            }
        }
        for (auto &pr : groups) {
            if(pr.second.first != pr.second.second) {
                ok = false;
                break;
            }
        }
 
        if(!ok) continue;
 
        double tolT = max(1e-9, T_range * 1e-3);
        for (int i = 0; i < N; i++){
            if(fabs(dvals[i]) <= EPS){
                if( !( fabs(tvals[i] - t_min_all) <= tolT || fabs(tvals[i] - t_max_all) <= tolT ) ){
                    ok = false;
                    break;
                }
            }
        }
        if(ok) {
            possible = true;
            break;
        }
    }
    cout << (possible ? "Yes" : "No") << endl;
    return 0;
}
accuracy: 0.3076923076923077
time_ms: 190
memory_kb: 3920
final_rank: 14

code_snippet: #include<bits/stdc++.h>
using namespace std;
using ll = long long;
#define rep(i,n) for(ll i=0;i<ll(n);i++)
#define ALL(A) A.begin(),A.end()

#include<complex>
#define mod 1000000007
using ll = long long;
const int INF = 1000000000;
const ll LINF = 1001002003004005006ll;
int dx[] = { 1,0,-1,0 }, dy[] = { 0,1,0,-1 };
// ll gcd(ll a,ll b){return b?gcd(b,a%b):a;}
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 (b < a) { a = b; return true; }return false; }

struct IOSetup {
    IOSetup() {
        cin.tie(0);
        ios::sync_with_stdio(0);
        cout << fixed << setprecision(12);
    }
} iosetup;

template<typename T>
ostream& operator<<(ostream& os, const vector<T>& v) {
    for (int i = 0; i < (int)v.size(); i++) os << v[i] << (i + 1 == (int)v.size() ? "" : " ");
    return os;
}
template<typename T>
istream& operator>>(istream& is, vector<T>& v) {
    for (T& x : v)is >> x;
    return is;
}

#line 1 "Geometry/template.cpp"
// Real
using Real = double;
const Real EPS = 1e-6;
const Real pi = acosl(-1);

// Point
using Point = complex<Real>;
istream& operator>>(istream& is, Point& p) {
    Real a, b;
    is >> a >> b;
    p = Point(a, b);
    return is;
}
ostream& operator<<(ostream& os, Point& p) {
    return os << fixed << setprecision(12) << p.real() << ' ' << p.imag();
}
inline bool eq(Real a, Real b) {
    return fabs(a - b) < EPS;
}
Point operator*(const Point& p, const Real& d) {
    return Point(real(p) * d, imag(p) * d);
}

// Line
struct Line {
    Point p1, p2;
    Line() = default;
    Line(Point p1, Point p2) :p1(p1), p2(p2) {}
    //Ax + By = C
    Line(Real A, Real B, Real C) {
        if (eq(A, 0))     p1 = Point(0, C / B), p2 = Point(1, C / B);
        else if (eq(B, 0))p1 = Point(C / A, 0), p2 = Point(C / A, 1);
        else            p1 = Point(0, C / B), p2 = Point(C / A, 0);
    }
};

// Segment
struct Segment :Line {
    Segment() = default;
    Segment(Point p1, Point p2) :Line(p1, p2) {}
};

Real dot(Point a, Point b) {
    return real(a) * real(b) + imag(a) * imag(b);
}
Real cross(Point a, Point b) {
    return real(a) * imag(b) - imag(a) * real(b);
}
Point projection(Line l, Point p) {
    // ベクトルl乗に点pからおろした垂線の足
    Real k = dot(l.p1 - l.p2, p - l.p1) / norm(l.p1 - l.p2);
    return l.p1 + (l.p1 - l.p2) * k;
}
Real dis(Point a, Point b) {
    return abs(a - b);
}
Real dis(Line l, Point p) {
    return abs(p - projection(l, p));
}

vector<Point> convex_hull(vector<Point> p) {
    int n = (int)p.size(), k = 0;
    if (n <= 2)return p;
    sort(begin(p), end(p), [](Point a, Point b) {
        return real(a) != real(b) ? real(a) < real(b) : imag(a) < imag(b);
        });
    vector<Point>ch(2 * n);
    for (int i = 0; i < n; ch[k++] = p[i++]) {
        while (k >= 2 && cross(ch[k - 1] - ch[k - 2], p[i] - ch[k - 1]) < 0)k--;
    }
    for (int i = n - 2, t = k + 1; i >= 0; ch[k++] = p[i--]) {
        while (k >= t && cross(ch[k - 1] - ch[k - 2], p[i] - ch[k - 1]) < 0)k--;
    }
    ch.resize(k - 1);
    return ch;
}


int main() {
    ll N;
    cin>>N;
    vector<Point> P(N);
    set<pair<ll,ll>> S;
    for(int i=0;i<N;i++){
        cin>>P[i];
        S.insert({round(real(P[i])),round(imag(P[i]))});
    }
    vector<Point> C=convex_hull(P);
    ll CN=C.size();
    rep(j,2)rep(i,CN){
        Point Q=C[i];
        if(j==1){
            Q=(C[i]+C[(i+1)%CN])/2.0;
        }
        Point R;
        if(CN%2==0&&j==0){
            R=C[(i+(CN/2))%CN];
        }
        else{
            R=(C[(i+CN/2)%CN]+C[(i+CN/2+1)%CN])/2.0;
        }
        Line L(Q,R);
        bool OK=1;
        ll cnt=0;
        rep(i,N){
            Point G=projection(L,P[i]);
            if(dis(L,P[i])<EPS)cnt++;
            G=G*2.0-P[i];
            double x=real(G);
            double y=imag(G);
            if(abs(x-round(x))>EPS||abs(y-round(y))>EPS){
                OK=0;
                break;
            }
            if(!S.count({round(x),round(y)})){
                OK=0;
                break;
            }
        }
        if(OK&&cnt<=2){
            cout<<"Yes"<<endl;
            return 0;
        }
    }
    cout<<"No"<<endl;
}
accuracy: 1
time_ms: 320
memory_kb: 3672
final_rank: 4

code_snippet: #include<bits/stdc++.h>
using namespace std;
using ll = long long;
#define rep(i,n) for(ll i=0;i<ll(n);i++)
#define ALL(A) A.begin(),A.end()

#include<complex>
#define mod 1000000007
using ll = long long;
const int INF = 1000000000;
const ll LINF = 1001002003004005006ll;
int dx[] = { 1,0,-1,0 }, dy[] = { 0,1,0,-1 };
// ll gcd(ll a,ll b){return b?gcd(b,a%b):a;}
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 (b < a) { a = b; return true; }return false; }

struct IOSetup {
    IOSetup() {
        cin.tie(0);
        ios::sync_with_stdio(0);
        cout << fixed << setprecision(12);
    }
} iosetup;

template<typename T>
ostream& operator<<(ostream& os, const vector<T>& v) {
    for (int i = 0; i < (int)v.size(); i++) os << v[i] << (i + 1 == (int)v.size() ? "" : " ");
    return os;
}
template<typename T>
istream& operator>>(istream& is, vector<T>& v) {
    for (T& x : v)is >> x;
    return is;
}

#line 1 "Geometry/template.cpp"
// Real
using Real = double;
const Real EPS = 1e-6;
const Real pi = acosl(-1);

// Point
using Point = complex<Real>;
istream& operator>>(istream& is, Point& p) {
    Real a, b;
    is >> a >> b;
    p = Point(a, b);
    return is;
}
ostream& operator<<(ostream& os, Point& p) {
    return os << fixed << setprecision(12) << p.real() << ' ' << p.imag();
}
inline bool eq(Real a, Real b) {
    return fabs(a - b) < EPS;
}
Point operator*(const Point& p, const Real& d) {
    return Point(real(p) * d, imag(p) * d);
}

// Line
struct Line {
    Point p1, p2;
    Line() = default;
    Line(Point p1, Point p2) :p1(p1), p2(p2) {}
    //Ax + By = C
    Line(Real A, Real B, Real C) {
        if (eq(A, 0))     p1 = Point(0, C / B), p2 = Point(1, C / B);
        else if (eq(B, 0))p1 = Point(C / A, 0), p2 = Point(C / A, 1);
        else            p1 = Point(0, C / B), p2 = Point(C / A, 0);
    }
};

// Segment
struct Segment :Line {
    Segment() = default;
    Segment(Point p1, Point p2) :Line(p1, p2) {}
};

Real dot(Point a, Point b) {
    return real(a) * real(b) + imag(a) * imag(b);
}
Real cross(Point a, Point b) {
    return real(a) * imag(b) - imag(a) * real(b);
}
Point projection(Line l, Point p) {
    // ベクトルl乗に点pからおろした垂線の足
    Real k = dot(l.p1 - l.p2, p - l.p1) / norm(l.p1 - l.p2);
    return l.p1 + (l.p1 - l.p2) * k;
}
Real dis(Point a, Point b) {
    return abs(a - b);
}
Real dis(Line l, Point p) {
    return abs(p - projection(l, p));
}

vector<Point> convex_hull(vector<Point> p) {
    int n = (int)p.size(), k = 0;
    if (n <= 2)return p;
    sort(begin(p), end(p), [](Point a, Point b) {
        return real(a) != real(b) ? real(a) < real(b) : imag(a) < imag(b);
        });
    vector<Point>ch(2 * n);
    for (int i = 0; i < n; ch[k++] = p[i++]) {
        while (k >= 2 && cross(ch[k - 1] - ch[k - 2], p[i] - ch[k - 1]) < 0)k--;
    }
    for (int i = n - 2, t = k + 1; i >= 0; ch[k++] = p[i--]) {
        while (k >= t && cross(ch[k - 1] - ch[k - 2], p[i] - ch[k - 1]) < 0)k--;
    }
    ch.resize(k - 1);
    return ch;
}


int main() {
    ll N;
    cin>>N;
    vector<Point> P(N);
    set<pair<ll,ll>> S;
    for(int i=0;i<N;i++){
        cin>>P[i];
        S.insert({round(real(P[i])),round(imag(P[i]))});
    }
    vector<Point> C=convex_hull(P);
    ll CN=C.size();
    rep(i,CN){
        Point Q=C[i];
        Point R;
        if(CN%2==0){
            R=C[(i+(CN/2))%CN];
        }
        else{
            R=(C[(i+CN/2)%CN]+C[(i+CN/2+1)%CN])/2.0;
        }
        Line L(Q,R);
        bool OK=1;
        ll cnt=0;
        rep(i,N){
            Point G=projection(L,P[i]);
            if(dis(L,P[i])<EPS)cnt++;
            G=G*2.0-P[i];
            double x=real(G);
            double y=imag(G);
            if(abs(x-round(x))>EPS||abs(y-round(y))>EPS){
                OK=0;
                break;
            }
            if(!S.count({round(x),round(y)})){
                OK=0;
                break;
            }
        }
        if(OK&&cnt<=2){
            cout<<"Yes"<<endl;
            return 0;
        }
    }
    cout<<"No"<<endl;
}
accuracy: 0.3076923076923077
time_ms: 150
memory_kb: 3576
final_rank: 13

code_snippet: #include <bits/stdc++.h>
using namespace std;

int mygcd(int x, int y) {
	if (y == 0) {
		return x;
	}
	return mygcd(y, x % y);
}

int floordiv(int x, int y) {
	// for y > 0, return floor(x / y)
	return (x >= 0 ? x / y : -((-x + y - 1) / y));
}

int main() {
	// step #1. input
	int N;
	cin >> N;
	vector<int> X(N), Y(N);
	for (int i = 0; i < N; i++) {
		cin >> X[i] >> Y[i];
		X[i] *= 2;
		Y[i] *= 2;
	}

	// step #2. check function (line: (cx, cy) + t * (vx, vy))
	auto symmetric = [&](const vector<int>& v) -> bool {
		vector<int> sv = v;
		sort(sv.begin(), sv.end());
		for (int i = 0; i < int(sv.size()); i++) {
			if (sv[i] + sv[sv.size() - i - 1] != 0) {
				return false;
			}
		}
		return true;
	};
	auto check = [&](int cx, int cy, int vx, int vy) -> bool {
		vector<array<int, 2> > p(N);
		for (int i = 0; i < N; i++) {
			p[i][0] = vx * (X[i] - cx) + vy * (Y[i] - cy); // dot
			p[i][1] = vx * (Y[i] - cy) - vy * (X[i] - cx); // cross
		}
		sort(p.begin(), p.end());
		if (p[0][0] == p[N - 1][0]) {
			return false; // all are in straight lines
		}
		int pre = 0, center = 0;
		for (int i = 1; i <= N; i++) {
			if (i == N || p[i][0] != p[i - 1][0]) {
				vector<int> v(i - pre);
				for (int j = 0; j < i - pre; j++) {
					v[j] = p[j + pre][1];
				}
				if (!symmetric(v)) {
					return false; // not symmetric
				}
				center += (i - pre) % 2;
				pre = i;
			}
		}
		if (center >= 3) {
			return false; // too many central points
		}
		return true;
	};

	// step #3. find "gravity point"
	int gx = 0, gy = 0;
	for (int i = 0; i < N; i++) {
		gx += X[i];
		gy += Y[i];
	}

	// step #4. enumerate all possible lines
	vector<array<int, 4> > lines;
	for (int i = 0; i < N; i++) {
		for (int j = i + 1; j < N; j++) {
			int mx = (X[i] + X[j]) / 2;
			int my = (Y[i] + Y[j]) / 2;
			int vx = -(Y[j] - Y[i]);
			int vy = (X[j] - X[i]);
			if (vx < 0 || (vx == 0 && vy < 0)) {
				vx *= -1;
				vy *= -1;
			}
			int g = mygcd(abs(vx), abs(vy));
			vx /= g;
			vy /= g;
			int d;
			if (vx > 0) {
				d = floordiv(mx, vx);
			}
			else {
				d = floordiv(my, vy);
			}
			mx -= d * vx;
			my -= d * vy;
			if (1LL * (gx - mx * N) * vy - 1LL * (gy - my * N) * vx == 0) {
				lines.push_back({ mx, my, vx, vy }); // passes the gravity point
			}
		}
	}
	sort(lines.begin(), lines.end());
	lines.erase(unique(lines.begin(), lines.end()), lines.end());

	// step #3. brute force (there are at most 2N lines)
	bool ans = false;
	for (array<int, 4> l : lines) {
		if (check(l[0], l[1], l[2], l[3])) {
			ans = true;
		}
	}
	
	// step #4. output
	cout << (ans ? "Yes" : "No") << endl;

	return 0;
}
accuracy: 1
time_ms: 120
memory_kb: 3764
final_rank: 2

code_snippet: #include <bits/stdc++.h>
using namespace std;
using ll = long long;
#define rep(i, s, t) for (int i = (int)(s); i < (int)(t); ++i)
#define revrep(i, t, s) for (int i = (int)(t)-1; i >= (int)(s); --i)
#define all(x) begin(x), end(x)
template <typename T> bool chmax(T& a, const T& b) { return a < b ? (a = b, 1) : 0; }
template <typename T> bool chmin(T& a, const T& b) { return a > b ? (a = b, 1) : 0; }

template <typename T, typename U>
ostream& operator<<(ostream& os, const pair<T, U>& p) {
    os << "(" << p.first << ", " << p.second << ")";
    return os;
}

int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(nullptr);
    cout << fixed << setprecision(15);

    int N;
    cin >> N;
    vector<pair<ll, ll>> pts(N);
    for (auto& p : pts) cin >> p.first >> p.second;
    map<tuple<ll, ll, ll>, int> cnt;
    // collinear
    set<pair<ll, ll>> st;
    rep(i,1,N) {
        auto [x0, y0] = pts[0];
        auto [xi, yi] = pts[i];
        ll dx = xi-x0, dy = yi-y0;
        if (dy < 0 || (dy == 0 && dx < 0)) dx *= -1, dy *= -1;
        ll g = gcd(dx, dy);
        dx /= g;
        dy /= g;
        st.insert({dx, dy});
    }
    if (st.size() == 1) {
        cout << "No" << endl;
        return 0;
    }
    rep(i,0,N) rep(j,i+1,N) {
        auto [xi, yi] = pts[i];
        auto [xj, yj] = pts[j];
        ll dx = xj-xi, dy = yj-yi;
        if (dy < 0 || (dy == 0 && dx < 0)) dx *= -1, dy *= -1;
        ll g = gcd(dx, dy);
        dx /= g;
        dy /= g;
        ++cnt[{dx*2, dy*2, dx*(xi+xj)+dy*(yi+yj)}];
    }
    bool ans = false;
    for (auto& p : cnt) {
        if (N-2*p.second <= 2) {
            auto [a, b, c] = p.first;
            int cnt = 0;
            for (auto [x, y] : pts) {
                if (a*x+b*y==c) {
                    ++cnt;
                }
            }
            if (2*p.second + cnt == N) {
                ans = true;
                break;
            }
        }
    }
    cout << (ans ? "Yes" : "No") << endl;
}
accuracy: 1
time_ms: 290
memory_kb: 42440
final_rank: 7

code_snippet: #include <bits/stdc++.h>
using namespace std;
using ll = long long;
#define rep(i, s, t) for (int i = (int)(s); i < (int)(t); ++i)
#define revrep(i, t, s) for (int i = (int)(t)-1; i >= (int)(s); --i)
#define all(x) begin(x), end(x)
template <typename T> bool chmax(T& a, const T& b) { return a < b ? (a = b, 1) : 0; }
template <typename T> bool chmin(T& a, const T& b) { return a > b ? (a = b, 1) : 0; }

template <typename T, typename U>
ostream& operator<<(ostream& os, const pair<T, U>& p) {
    os << "(" << p.first << ", " << p.second << ")";
    return os;
}

int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(nullptr);
    cout << fixed << setprecision(15);

    int N;
    cin >> N;
    vector<pair<ll, ll>> pts(N);
    for (auto& p : pts) cin >> p.first >> p.second;
    map<tuple<ll, ll, ll>, int> cnt;
    // collinear
    set<pair<ll, ll>> st;
    rep(i,1,N) {
        auto [x0, y0] = pts[0];
        auto [xi, yi] = pts[i];
        ll dx = xi-x0, dy = yi-y0;
        if (dy < 0 || (dy == 0 && dx < 0)) dx *= -1, dy *= -1;
        ll g = gcd(dx, dy);
        dx /= g;
        dy /= g;
        st.insert({dx, dy});
    }
    if (st.size() == 1) {
        cout << "No" << endl;
        return 0;
    }
    rep(i,0,N) rep(j,i+1,N) {
        auto [xi, yi] = pts[i];
        auto [xj, yj] = pts[j];
        ll dx = xj-xi, dy = yj-yi;
        if (dy < 0 || (dy == 0 && dx < 0)) dx *= -1, dy *= -1;
        ll g = gcd(dx, dy);
        dx /= g;
        dy /= g;
        ++cnt[{dx*2, dy*2, dx*(xi+xj)+dy*(yi+yj)}];
    }
    bool ans = false;
    for (auto& p : cnt) {
        auto [a, b, c] = p.first;
        int cnt = 0;
        for (auto [x, y] : pts) {
            if (a*x+b*y==c) {
                ++cnt;
            }
        }
        if (2*p.second + cnt == N) {
            ans = true;
            break;
        }
    }
    cout << (ans ? "Yes" : "No") << endl;
}
accuracy: 0.3269230769230769
time_ms: 220
memory_kb: 23728
final_rank: 12

code_snippet: #include <bits/stdc++.h>
using namespace std;
using ll = long long;
#define rep(i, s, t) for (int i = (int)(s); i < (int)(t); ++i)
#define revrep(i, t, s) for (int i = (int)(t)-1; i >= (int)(s); --i)
#define all(x) begin(x), end(x)
template <typename T> bool chmax(T& a, const T& b) { return a < b ? (a = b, 1) : 0; }
template <typename T> bool chmin(T& a, const T& b) { return a > b ? (a = b, 1) : 0; }

template <typename T, typename U>
ostream& operator<<(ostream& os, const pair<T, U>& p) {
    os << "(" << p.first << ", " << p.second << ")";
    return os;
}

int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(nullptr);
    cout << fixed << setprecision(15);

    int N;
    cin >> N;
    vector<pair<ll, ll>> pts(N);
    for (auto& p : pts) cin >> p.first >> p.second;
    map<tuple<ll, ll, ll>, int> cnt;
    // collinear
    set<pair<ll, ll>> st;
    rep(i,1,N) {
        auto [x0, y0] = pts[0];
        auto [xi, yi] = pts[i];
        ll dx = xi-x0, dy = yi-y0;
        if (dy < 0) dx *= -1, dy *= -1;
        ll g = gcd(dx, dy);
        dx /= g;
        dy /= g;
        st.insert({dx, dy});
    }
    if (st.size() == 1) {
        cout << "No" << endl;
        return 0;
    }
    rep(i,0,N) rep(j,i+1,N) {
        auto [xi, yi] = pts[i];
        auto [xj, yj] = pts[j];
        ll dx = xj-xi, dy = yj-yi;
        if (dy < 0) dx *= -1, dy *= -1;
        ll g = gcd(dx, dy);
        dx /= g;
        dy /= g;
        ++cnt[{dx*2, dy*2, dx*(xi+xj)+dy*(yi+yj)}];
    }
    bool ans = false;
    for (auto& p : cnt) {
        auto [a, b, c] = p.first;
        int cnt = 0;
        for (auto [x, y] : pts) {
            if (a*x+b*y==c) {
                ++cnt;
            }
        }
        if (2*p.second + cnt == N) {
            ans = true;
            break;
        }
    }
    cout << (ans ? "Yes" : "No") << endl;
}
accuracy: 0.3076923076923077
time_ms: 310
memory_kb: 23656
final_rank: 19

code_snippet: #include <bits/stdc++.h>
using namespace std;
using ll = long long;
#define rep(i, s, t) for (int i = (int)(s); i < (int)(t); ++i)
#define revrep(i, t, s) for (int i = (int)(t)-1; i >= (int)(s); --i)
#define all(x) begin(x), end(x)
template <typename T> bool chmax(T& a, const T& b) { return a < b ? (a = b, 1) : 0; }
template <typename T> bool chmin(T& a, const T& b) { return a > b ? (a = b, 1) : 0; }

template <typename T, typename U>
ostream& operator<<(ostream& os, const pair<T, U>& p) {
    os << "(" << p.first << ", " << p.second << ")";
    return os;
}

int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(nullptr);
    cout << fixed << setprecision(15);

    int N;
    cin >> N;
    vector<pair<ll, ll>> pts(N);
    for (auto& p : pts) cin >> p.first >> p.second;
    map<tuple<ll, ll, ll>, int> cnt;
    // collinear
    set<pair<ll, ll>> st;
    rep(i,1,N) {
        auto [x0, y0] = pts[0];
        auto [xi, yi] = pts[i];
        ll dx = xi-x0, dy = yi-y0;
        if (dy < 0) dx *= -1, dy *= -1;
        ll g = gcd(dx, dy);
        dx /= g;
        dy /= g;
        st.insert({dx, dy});
    }
    if (st.size() == 1) {
        cout << "No" << endl;
        return 0;
    }
    rep(i,0,N) rep(j,i+1,N) {
        auto [xi, yi] = pts[i];
        auto [xj, yj] = pts[j];
        ll dx = xj-xi, dy = yj-yi;
        assert(dx != 0 || dy != 0);
        if (dy < 0) dx *= -1, dy *= -1;
        ll g = gcd(dx, dy);
        dx /= g;
        dy /= g;
        ++cnt[{dx*2, dy*2, dx*(xi+xj)+dy*(yi+yj)}];
    }
    bool ans = false;
    for (auto& p : cnt) {
        if (N % 2 == 0) {
            if (p.second == N/2) {
                ans = true;
                break;
            } else if (p.second == (N-2)/2) {
                auto [a, b, c] = p.first;
                int cnt = 0;
                for (auto [x, y] : pts) {
                    if (a*x+b*y==c) {
                        ++cnt;
                    }
                }
                if (cnt >= 2) {
                    ans = true;
                    break;
                }
            }
        } else {
            if (p.second == (N-1)/2) {
                auto [a, b, c] = p.first;
                int cnt = 0;
                for (auto [x, y] : pts) {
                    if (a*x+b*y==c) {
                        ++cnt;
                    }
                }
                if (cnt >= 1) {
                    ans = true;
                    break;
                }
            }

        }
    }
    cout << (ans ? "Yes" : "No") << endl;
}
accuracy: 0.3076923076923077
time_ms: 130
memory_kb: 23676
final_rank: 17

code_snippet: #include <bits/stdc++.h>
using namespace std;
using ll = long long;
#define rep(i, s, t) for (int i = (int)(s); i < (int)(t); ++i)
#define revrep(i, t, s) for (int i = (int)(t)-1; i >= (int)(s); --i)
#define all(x) begin(x), end(x)
template <typename T> bool chmax(T& a, const T& b) { return a < b ? (a = b, 1) : 0; }
template <typename T> bool chmin(T& a, const T& b) { return a > b ? (a = b, 1) : 0; }

template <typename T, typename U>
ostream& operator<<(ostream& os, const pair<T, U>& p) {
    os << "(" << p.first << ", " << p.second << ")";
    return os;
}

int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(nullptr);
    cout << fixed << setprecision(15);

    int N;
    cin >> N;
    vector<pair<ll, ll>> pts(N);
    for (auto& p : pts) cin >> p.first >> p.second;
    map<tuple<ll, ll, ll>, int> cnt;
    // collinear
    set<pair<ll, ll>> st;
    rep(i,1,N) {
        auto [x0, y0] = pts[0];
        auto [xi, yi] = pts[i];
        ll dx = xi-x0, dy = yi-y0;
        if (dy < 0) dx *= -1, dy *= -1;
        assert(dx != 0 || dy != 0);
        ll g = gcd(dx, dy);
        dx /= g;
        dy /= g;
        st.insert({dx, dy});
    }
    if (st.size() == 1) {
        cout << "No" << endl;
        return 0;
    }
    rep(i,0,N) rep(j,i+1,N) {
        auto [xi, yi] = pts[i];
        auto [xj, yj] = pts[j];
        ll dx = xj-xi, dy = yj-yi;
        if (dy < 0) dx *= -1, dy *= -1;
        ll g = gcd(dx, dy);
        dx /= g;
        dy /= g;
        ++cnt[{dx*2, dy*2, dx*(xi+xj)+dy*(yi+yj)}];
    }
    bool ans = false;
    for (auto& p : cnt) {
        if (N % 2 == 0) {
            if (p.second == N/2) {
                ans = true;
                break;
            } else if (p.second == (N-2)/2) {
                auto [a, b, c] = p.first;
                int cnt = 0;
                for (auto [x, y] : pts) {
                    if (a*x+b*y==c) {
                        ++cnt;
                    }
                }
                if (cnt >= 2) {
                    ans = true;
                    break;
                }
            }
        } else {
            if (p.second == (N-1)/2) {
                auto [a, b, c] = p.first;
                int cnt = 0;
                for (auto [x, y] : pts) {
                    if (a*x+b*y==c) {
                        ++cnt;
                    }
                }
                if (cnt >= 1) {
                    ans = true;
                    break;
                }
            }

        }
    }
    cout << (ans ? "Yes" : "No") << endl;
}
accuracy: 0.3076923076923077
time_ms: 130
memory_kb: 23696
final_rank: 18

code_snippet: #include <bits/stdc++.h>
using namespace std;
using ll = long long;
#define rep(i, s, t) for (int i = (int)(s); i < (int)(t); ++i)
#define revrep(i, t, s) for (int i = (int)(t)-1; i >= (int)(s); --i)
#define all(x) begin(x), end(x)
template <typename T> bool chmax(T& a, const T& b) { return a < b ? (a = b, 1) : 0; }
template <typename T> bool chmin(T& a, const T& b) { return a > b ? (a = b, 1) : 0; }

template <typename T, typename U>
ostream& operator<<(ostream& os, const pair<T, U>& p) {
    os << "(" << p.first << ", " << p.second << ")";
    return os;
}

int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(nullptr);
    cout << fixed << setprecision(15);

    int N;
    cin >> N;
    vector<pair<ll, ll>> pts(N);
    for (auto& p : pts) cin >> p.first >> p.second;
    map<tuple<ll, ll, ll>, int> cnt;
    // collinear
    set<pair<ll, ll>> st;
    rep(i,1,N) {
        auto [x0, y0] = pts[0];
        auto [xi, yi] = pts[i];
        ll dx = xi-x0, dy = yi-y0;
        if (dy < 0) dx *= -1, dy *= -1;
        ll g = gcd(dx, dy);
        dx /= g;
        dy /= g;
        st.insert({dx, dy});
    }
    if (st.size() == 1) {
        cout << "No" << endl;
        return 0;
    }
    rep(i,0,N) rep(j,i+1,N) {
        auto [xi, yi] = pts[i];
        auto [xj, yj] = pts[j];
        ll dx = xj-xi, dy = yj-yi;
        if (dy < 0) dx *= -1, dy *= -1;
        ll g = gcd(dx, dy);
        dx /= g;
        dy /= g;
        ++cnt[{dx*2, dy*2, dx*(xi+xj)+dy*(yi+yj)}];
    }
    bool ans = false;
    for (auto& p : cnt) {
        if (N % 2 == 0) {
            if (p.second == N/2) {
                ans = true;
                break;
            } else if (p.second == (N-2)/2) {
                auto [a, b, c] = p.first;
                int cnt = 0;
                for (auto [x, y] : pts) {
                    if (a*x+b*y==c) {
                        ++cnt;
                    }
                }
                if (cnt >= 2) {
                    ans = true;
                    break;
                }
            }
        } else {
            if (p.second == (N-1)/2) {
                auto [a, b, c] = p.first;
                int cnt = 0;
                for (auto [x, y] : pts) {
                    if (a*x+b*y==c) {
                        ++cnt;
                    }
                }
                if (cnt >= 1) {
                    ans = true;
                    break;
                }
            }

        }
    }
    cout << (ans ? "Yes" : "No") << endl;
}
accuracy: 0.3076923076923077
time_ms: 130
memory_kb: 23540
final_rank: 16

code_snippet: #include <bits/stdc++.h>
using namespace std;
using ll = long long;
#define rep(i, s, t) for (int i = (int)(s); i < (int)(t); ++i)
#define revrep(i, t, s) for (int i = (int)(t)-1; i >= (int)(s); --i)
#define all(x) begin(x), end(x)
template <typename T> bool chmax(T& a, const T& b) { return a < b ? (a = b, 1) : 0; }
template <typename T> bool chmin(T& a, const T& b) { return a > b ? (a = b, 1) : 0; }

template <typename T, typename U>
ostream& operator<<(ostream& os, const pair<T, U>& p) {
    os << "(" << p.first << ", " << p.second << ")";
    return os;
}

int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(nullptr);
    cout << fixed << setprecision(15);

    int N;
    cin >> N;
    vector<pair<int, int>> pts(N);
    for (auto& p : pts) cin >> p.first >> p.second;
    map<tuple<int, int, int>, int> cnt;
    // collinear
    set<pair<int, int>> st;
    rep(i,1,N) {
        auto [x0, y0] = pts[0];
        auto [xi, yi] = pts[i];
        int dx = xi-x0, dy = yi-y0;
        if (dy < 0) dx *= -1, dy *= -1;
        int g = gcd(dx, dy);
        dx /= g;
        dy /= g;
        st.insert({dx, dy});
    }
    if (st.size() == 1) {
        cout << "No" << endl;
        return 0;
    }
    rep(i,0,N) rep(j,i+1,N) {
        auto [xi, yi] = pts[i];
        auto [xj, yj] = pts[j];
        int dx = xj-xi, dy = yj-yi;
        if (dy < 0) dx *= -1, dy *= -1;
        int g = gcd(dx, dy);
        dx /= g;
        dy /= g;
        ++cnt[{dx*2, dy*2, dx*(xi+xj)+dy*(yi+yj)}];
    }
    bool ans = false;
    for (auto& p : cnt) {
        if (N % 2 == 0) {
            if (p.second == N/2) {
                ans = true;
                break;
            } else if (p.second == (N-2)/2) {
                auto [a, b, c] = p.first;
                int cnt = 0;
                for (auto [x, y] : pts) {
                    if (a*x+b*y==c) {
                        ++cnt;
                    }
                }
                if (cnt >= 2) {
                    ans = true;
                    break;
                }
            }
        } else {
            if (p.second == (N-1)/2) {
                auto [a, b, c] = p.first;
                int cnt = 0;
                for (auto [x, y] : pts) {
                    if (a*x+b*y==c) {
                        ++cnt;
                    }
                }
                if (cnt >= 1) {
                    ans = true;
                    break;
                }
            }

        }
    }
    cout << (ans ? "Yes" : "No") << endl;
}
accuracy: 0.3076923076923077
time_ms: 110
memory_kb: 19604
final_rank: 15

code_snippet: #include <bits/stdc++.h>

#include <limits>
#include <type_traits>

namespace suisen {
// ! utility
template <typename ...Types>
using constraints_t = std::enable_if_t<std::conjunction_v<Types...>, std::nullptr_t>;
template <bool cond_v, typename Then, typename OrElse>
constexpr decltype(auto) constexpr_if(Then&& then, OrElse&& or_else) {
    if constexpr (cond_v) {
        return std::forward<Then>(then);
    } else {
        return std::forward<OrElse>(or_else);
    }
}

// ! function
template <typename ReturnType, typename Callable, typename ...Args>
using is_same_as_invoke_result = std::is_same<std::invoke_result_t<Callable, Args...>, ReturnType>;
template <typename F, typename T>
using is_uni_op = is_same_as_invoke_result<T, F, T>;
template <typename F, typename T>
using is_bin_op = is_same_as_invoke_result<T, F, T, T>;

template <typename Comparator, typename T>
using is_comparator = std::is_same<std::invoke_result_t<Comparator, T, T>, bool>;

// ! integral
template <typename T, typename = constraints_t<std::is_integral<T>>>
constexpr int bit_num = std::numeric_limits<std::make_unsigned_t<T>>::digits;
template <typename T, unsigned int n>
struct is_nbit { static constexpr bool value = bit_num<T> == n; };
template <typename T, unsigned int n>
static constexpr bool is_nbit_v = is_nbit<T, n>::value;

// ?
template <typename T>
struct safely_multipliable {};
template <>
struct safely_multipliable<int> { using type = long long; };
template <>
struct safely_multipliable<long long> { using type = __int128_t; };
template <>
struct safely_multipliable<unsigned int> { using type = unsigned long long; };
template <>
struct safely_multipliable<unsigned long int> { using type = __uint128_t; };
template <>
struct safely_multipliable<unsigned long long> { using type = __uint128_t; };
template <>
struct safely_multipliable<float> { using type = float; };
template <>
struct safely_multipliable<double> { using type = double; };
template <>
struct safely_multipliable<long double> { using type = long double; };
template <typename T>
using safely_multipliable_t = typename safely_multipliable<T>::type;

} // namespace suisen

// ! type aliases
using i128 = __int128_t;
using u128 = __uint128_t;

template <typename T>
using pq_greater = std::priority_queue<T, std::vector<T>, std::greater<T>>;
template <typename T, typename U>
using umap = std::unordered_map<T, U>;

// ! macros (capital: internal macro)
#define OVERLOAD2(_1,_2,name,...) name
#define OVERLOAD3(_1,_2,_3,name,...) name
#define OVERLOAD4(_1,_2,_3,_4,name,...) name

#define REP4(i,l,r,s)  for(std::remove_reference_t<std::remove_const_t<decltype(r)>>i=(l);i<(r);i+=(s))
#define REP3(i,l,r)    REP4(i,l,r,1)
#define REP2(i,n)      REP3(i,0,n)
#define REPINF3(i,l,s) for(std::remove_reference_t<std::remove_const_t<decltype(l)>>i=(l);;i+=(s))
#define REPINF2(i,l)   REPINF3(i,l,1)
#define REPINF1(i)     REPINF2(i,0)
#define RREP4(i,l,r,s) for(std::remove_reference_t<std::remove_const_t<decltype(r)>>i=(l)+fld((r)-(l)-1,s)*(s);i>=(l);i-=(s))
#define RREP3(i,l,r)   RREP4(i,l,r,1)
#define RREP2(i,n)     RREP3(i,0,n)

#define rep(...)    OVERLOAD4(__VA_ARGS__, REP4   , REP3   , REP2   )(__VA_ARGS__)
#define rrep(...)   OVERLOAD4(__VA_ARGS__, RREP4  , RREP3  , RREP2  )(__VA_ARGS__)
#define repinf(...) OVERLOAD3(__VA_ARGS__, REPINF3, REPINF2, REPINF1)(__VA_ARGS__)

#define CAT_I(a, b) a##b
#define CAT(a, b) CAT_I(a, b)
#define UNIQVAR(tag) CAT(tag, __LINE__)
#define loop(n) for (std::remove_reference_t<std::remove_const_t<decltype(n)>> UNIQVAR(loop_variable) = n; UNIQVAR(loop_variable) --> 0;)

#define all(iterable) std::begin(iterable), std::end(iterable)
#define input(type, ...) type __VA_ARGS__; read(__VA_ARGS__)

#ifdef LOCAL
#  define debug(...) debug_internal(#__VA_ARGS__, __VA_ARGS__)

template <class T, class... Args>
void debug_internal(const char* s, T&& first, Args&&... args) {
    constexpr const char* prefix = "[\033[32mDEBUG\033[m] ";
    constexpr const char* open_brakets = sizeof...(args) == 0 ? "" : "(";
    constexpr const char* close_brakets = sizeof...(args) == 0 ? "" : ")";
    std::cerr << prefix << open_brakets << s << close_brakets << ": " << open_brakets << std::forward<T>(first);
    ((std::cerr << ", " << std::forward<Args>(args)), ...);
    std::cerr << close_brakets << "\n";
}

#else
#  define debug(...) void(0)
#endif

// ! I/O utilities

// pair
template <typename T, typename U>
std::ostream& operator<<(std::ostream& out, const std::pair<T, U> &a) {
    return out << a.first << ' ' << a.second;
}
// tuple
template <unsigned int N = 0, typename ...Args>
std::ostream& operator<<(std::ostream& out, const std::tuple<Args...> &a) {
    if constexpr (N >= std::tuple_size_v<std::tuple<Args...>>) {
        return out;
    } else {
        out << std::get<N>(a);
        if constexpr (N + 1 < std::tuple_size_v<std::tuple<Args...>>) {
            out << ' ';
        }
        return operator<<<N + 1>(out, a);
    }
}
// vector
template <typename T>
std::ostream& operator<<(std::ostream& out, const std::vector<T> &a) {
    for (auto it = a.begin(); it != a.end();) {
        out << *it;
        if (++it != a.end()) out << ' ';
    }
    return out;
}
// array
template <typename T, size_t N>
std::ostream& operator<<(std::ostream& out, const std::array<T, N> &a) {
    for (auto it = a.begin(); it != a.end();) {
        out << *it;
        if (++it != a.end()) out << ' ';
    }
    return out;
}
inline void print() { std::cout << '\n'; }
template <typename Head, typename... Tail>
inline void print(const Head &head, const Tail &...tails) {
    std::cout << head;
    if (sizeof...(tails)) std::cout << ' ';
    print(tails...);
}
template <typename Iterable>
auto print_all(const Iterable& v, std::string sep = " ", std::string end = "\n") -> decltype(std::cout << *v.begin(), void()) {
    for (auto it = v.begin(); it != v.end();) {
        std::cout << *it;
        if (++it != v.end()) std::cout << sep;
    }
    std::cout << end;
}

// pair
template <typename T, typename U>
std::istream& operator>>(std::istream& in, std::pair<T, U> &a) {
    return in >> a.first >> a.second;
}
// tuple
template <unsigned int N = 0, typename ...Args>
std::istream& operator>>(std::istream& in, std::tuple<Args...> &a) {
    if constexpr (N >= std::tuple_size_v<std::tuple<Args...>>) {
        return in;
    } else {
        return operator>><N + 1>(in >> std::get<N>(a), a);
    }
}
// vector
template <typename T>
std::istream& operator>>(std::istream& in, std::vector<T> &a) {
    for (auto it = a.begin(); it != a.end(); ++it) in >> *it;
    return in;
}
// array
template <typename T, size_t N>
std::istream& operator>>(std::istream& in, std::array<T, N> &a) {
    for (auto it = a.begin(); it != a.end(); ++it) in >> *it;
    return in;
}
template <typename ...Args>
void read(Args &...args) {
    ( std::cin >> ... >> args );
}

// ! integral utilities

// Returns pow(-1, n)
template <typename T>
constexpr inline int pow_m1(T n) {
    return -(n & 1) | 1;
}
// Returns pow(-1, n)
template <>
constexpr inline int pow_m1<bool>(bool n) {
    return -int(n) | 1;
}

// Returns floor(x / y)
template <typename T>
constexpr inline T fld(const T x, const T y) {
    return (x ^ y) >= 0 ? x / y : (x - (y + pow_m1(y >= 0))) / y;
}
template <typename T>
constexpr inline T cld(const T x, const T y) {
    return (x ^ y) <= 0 ? x / y : (x + (y + pow_m1(y >= 0))) / y;
}

template <typename T, suisen::constraints_t<suisen::is_nbit<T, 16>> = nullptr>
constexpr inline int popcount(const T x) { return __builtin_popcount(x); }
template <typename T, suisen::constraints_t<suisen::is_nbit<T, 32>> = nullptr>
constexpr inline int popcount(const T x) { return __builtin_popcount(x); }
template <typename T, suisen::constraints_t<suisen::is_nbit<T, 64>> = nullptr>
constexpr inline int popcount(const T x) { return __builtin_popcountll(x); }
template <typename T, suisen::constraints_t<suisen::is_nbit<T, 16>> = nullptr>
constexpr inline int count_lz(const T x) { return x ? __builtin_clz(x)   : suisen::bit_num<T>; }
template <typename T, suisen::constraints_t<suisen::is_nbit<T, 32>> = nullptr>
constexpr inline int count_lz(const T x) { return x ? __builtin_clz(x)   : suisen::bit_num<T>; }
template <typename T, suisen::constraints_t<suisen::is_nbit<T, 64>> = nullptr>
constexpr inline int count_lz(const T x) { return x ? __builtin_clzll(x) : suisen::bit_num<T>; }
template <typename T, suisen::constraints_t<suisen::is_nbit<T, 16>> = nullptr>
constexpr inline int count_tz(const T x) { return x ? __builtin_ctz(x)   : suisen::bit_num<T>; }
template <typename T, suisen::constraints_t<suisen::is_nbit<T, 32>> = nullptr>
constexpr inline int count_tz(const T x) { return x ? __builtin_ctz(x)   : suisen::bit_num<T>; }
template <typename T, suisen::constraints_t<suisen::is_nbit<T, 64>> = nullptr>
constexpr inline int count_tz(const T x) { return x ? __builtin_ctzll(x) : suisen::bit_num<T>; }
template <typename T>
constexpr inline int floor_log2(const T x) { return suisen::bit_num<T> - 1 - count_lz(x); }
template <typename T>
constexpr inline int ceil_log2(const T x)  { return floor_log2(x) + ((x & -x) != x); }
template <typename T>
constexpr inline int kth_bit(const T x, const unsigned int k) { return (x >> k) & 1; }
template <typename T>
constexpr inline int parity(const T x) { return popcount(x) & 1; }

struct all_subset {
    struct all_subset_iter {
        const int s; int t;
        constexpr all_subset_iter(int s) : s(s), t(s + 1) {}
        constexpr auto operator*() const { return t; }
        constexpr auto operator++() {}
        constexpr auto operator!=(std::nullptr_t) { return t ? (--t &= s, true) : false; }
    };
    int s;
    constexpr all_subset(int s) : s(s) {}
    constexpr auto begin() { return all_subset_iter(s); }
    constexpr auto end()   { return nullptr; }
};

// ! container

template <typename T, typename Comparator, suisen::constraints_t<suisen::is_comparator<Comparator, T>> = nullptr>
auto priqueue_comp(const Comparator comparator) {
    return std::priority_queue<T, std::vector<T>, Comparator>(comparator);
}

template <typename Iterable>
auto isize(const Iterable &iterable) -> decltype(int(iterable.size())) {
    return iterable.size();
}

template <typename T, typename Gen, suisen::constraints_t<suisen::is_same_as_invoke_result<T, Gen, int>> = nullptr>
auto generate_vector(int n, Gen generator) {
    std::vector<T> v(n);
    for (int i = 0; i < n; ++i) v[i] = generator(i);
    return v;
}
template <typename T>
auto generate_range_vector(T l, T r) {
    return generate_vector(r - l, [l](int i) { return l + i; });
}
template <typename T>
auto generate_range_vector(T n) {
    return generate_range_vector(0, n);
}

template <typename T>
void sort_unique_erase(std::vector<T> &a) {
    std::sort(a.begin(), a.end());
    a.erase(std::unique(a.begin(), a.end()), a.end());
}

template <typename InputIterator, typename BiConsumer>
auto foreach_adjacent_values(InputIterator first, InputIterator last, BiConsumer f) -> decltype(f(*first++, *last), void()) {
    if (first != last) for (auto itr = first, itl = itr++; itr != last; itl = itr++) f(*itl, *itr);
}
template <typename Container, typename BiConsumer>
auto foreach_adjacent_values(Container c, BiConsumer f) -> decltype(c.begin(), c.end(), void()){
    foreach_adjacent_values(c.begin(), c.end(), f);
}

// ! other utilities

// x <- min(x, y). returns true iff `x` has chenged.
template <typename T>
inline bool chmin(T &x, const T &y) {
    if (y >= x) return false;
    x = y;
    return true;
}
// x <- max(x, y). returns true iff `x` has chenged.
template <typename T>
inline bool chmax(T &x, const T &y) {
    if (y <= x) return false;
    x = y;
    return true;
}

namespace suisen {}
using namespace suisen;
using namespace std;

struct io_setup {
    io_setup(int precision = 20) {
        std::ios::sync_with_stdio(false);
        std::cin.tie(nullptr);
        std::cout << std::fixed << std::setprecision(precision);
    }
} io_setup_{};

// ! code from here

#include <utility>

namespace suisen {
template <typename T, typename U>
std::pair<T, U>& operator+=(std::pair<T, U> &p1, const std::pair<T, U> &p2) {
    p1.first += p2.first, p1.second += p2.second;
    return p1;
}
template <typename T, typename U>
std::pair<T, U> operator+(const std::pair<T, U> &p1, const std::pair<T, U> &p2) {
    return {p1.first + p2.first, p1.second + p2.second};
}
template <typename T, typename U>
std::pair<T, U>& operator-=(std::pair<T, U> &p1, const std::pair<T, U> &p2) {
    p1.first -= p2.first, p1.second -= p2.second;
    return p1;
}
template <typename T, typename U>
std::pair<T, U> operator-(const std::pair<T, U> &p1, const std::pair<T, U> &p2) {
    return {p1.first - p2.first, p1.second - p2.second};
}
template <typename T, typename U, typename V>
std::pair<T, U>& operator*=(std::pair<T, U> &p, const V m) {
    p.first *= m, p.second *= m;
    return p;
}
template <typename T, typename U, typename V>
std::pair<T, U> operator*(const std::pair<T, U> &p, const V m) {
    return {p.first * m, p.second * m};
}
template <typename T, typename U, typename V>
std::pair<T, U> operator*(const V m, const std::pair<T, U> &p) {
    return {p.first * m, p.second * m};
}
} // namespace suisen

using Point = pair<long long, long long>;

tuple<long long, long long, long long> sui(const Point& p0, const Point& p1) {
    auto [x0, y0] = p0;
    auto [x1, y1] = p1;

    long long a = (x1 - x0) >> 1;
    long long b = (y1 - y0) >> 1;
    long long c = (x0 * x0 + y0 * y0 - x1 * x1 - y1 * y1) >> 2;

    return { a, b, c };
}

long long crs(const Point& p0, const Point& p1) {
    auto [x0, y0] = p0;
    auto [x1, y1] = p1;
    return x0 * y1 - x1 * y0;
}

constexpr int M = 40000;

int main() {
    input(int, n);

    vector<pair<int, int>> ps(n);
    read(ps);

    vector<vector<int>> yl(M + 1);

    for (auto& [x, y] : ps) {
        x += 10000;
        y += 10000;

        x *= 2;
        y *= 2;

        yl[x].push_back(y);
    }

    for (auto& ys : yl) {
        sort(all(ys));
    }

    {
        bool online = true;
        rep(j, 2, n) {
            Point p1 = ps[1] - ps[0];
            Point p2 = ps[j] - ps[0];
            online &= crs(p1, p2) == 0;
        }
        if (online) {
            print("No");
            return 0;
        }
    }

    rep(i, n) rep(j, i) {
        auto [a, b, c] = sui(ps[i], ps[j]);

        const long long den = a * a + b * b;

        auto pm = ps[i] + ps[j];
        pm.first >>= 1;
        pm.second >>= 1;

        Point v{ -b, a };

        int dif = 0;

        bool ok = true;
        int online = 0;
        rep(k, n) {
            auto p = ps[k] - pm;
            long long c = crs(p, v);
            if (c > 0) {
                ++dif;
                continue;
            }
            if (c == 0) {
                if (++online == 3) break;
                continue;
            }
            --dif;

            long long t = a * p.first + b * p.second;

            long long qa = 2 * t * a / den, ra = 2 * t * a % den;
            long long qb = 2 * t * b / den, rb = 2 * t * b % den;
            if (ra or rb) {
                ok = false;
                break;
            }

            long long x1 = p.first - qa + pm.first;
            long long y1 = p.second - qb + pm.second;
            if (x1 < 0 or x1 > M or not binary_search(all(yl[x1]), y1)) {
                ok = false;
                break;
            }
        }
        ok &= dif == 0;
        if (not ok or online == 3) continue;

        print("Yes");
        return 0;
    }

    print("No");
    return 0;
}
accuracy: 1
time_ms: 40
memory_kb: 4132
final_rank: 1

code_snippet: #include <bits/stdc++.h>

using namespace std;

#define eps 1e-9
#define INF 2000000000              // 2e9
#define LLINF 2000000000000000000ll // 2e18 (llmax:9e18)
#define all(x) (x).begin(), (x).end()
#define sq(x) ((x) * (x))

#define rep(i, x) for (int i = 0; i < (int)(x); i++)
#define drep(i, x) for (int i = ((int)(x)-1); i >= 0; i--)

#define popcount __builtin_popcount
#define next __next
#define prev __prev

#ifndef LOCAL
#define dmp(...) ;
#else
#define dmp(...)                                                               \
  cerr << "[ " << #__VA_ARGS__ << " ] : " << dump_str(__VA_ARGS__) << endl
#endif

// ---------------- Utility ------------------

template <class T>
bool chmin(T &a, const T &b) {
  if (a <= b) return false;
  a = b;
  return true;
}

template <class T>
bool chmax(T &a, const T &b) {
  if (a >= b) return false;
  a = b;
  return true;
}

template <class T>
using MaxHeap = priority_queue<T>;

template <class T>
using MinHeap = priority_queue<T, vector<T>, greater<T>>;

template <class T>
vector<T> vect(int len, T elem) {
  return vector<T>(len, elem);
}

// ----------------- Input -------------------

template <class T, class U>
istream &operator>>(istream &is, pair<T, U> &p) {
  return is >> p.first >> p.second;
}

template <class T>
istream &operator>>(istream &is, vector<T> &vec) {
  for (int i = 0; i < vec.size(); i++) is >> vec[i];
  return is;
}

// ----------------- Output ------------------

template <class T, class U>
ostream &operator<<(ostream &os, const pair<T, U> &p) {
  return os << p.first << ',' << p.second;
}

template <class T>
ostream &operator<<(ostream &os, const vector<T> &v) {
  for (const T &e : v) os << e << " ";
  return os;
}

template <class T>
ostream &operator<<(ostream &os, const deque<T> &d) {
  for (const T &e : d) os << e << " ";
  return os;
}

template <class T>
ostream &operator<<(ostream &os, const set<T> &s) {
  os << "{ ";
  for (const T &e : s) os << e << " ";
  return os << "}";
}

template <class T, class U>
ostream &operator<<(ostream &os, const map<T, U> &m) {
  os << "{ ";
  for (const auto &[key, val] : m) os << "( " << key << " -> " << val << " ) ";
  return os << "}";
}

template <class TupleTy, size_t... I>
void dump_tuple(ostream &os, const TupleTy t, std::index_sequence<I...>) {
  (..., (os << (I == 0 ? "" : ",") << std::get<I>(t)));
}

template <class... Args>
ostream &operator<<(ostream &os, const tuple<Args...> &t) {
  os << "(";
  dump_tuple(os, t, std::make_index_sequence<sizeof...(Args)>());
  return os << ")";
}

void dump_str_rec(ostringstream &) {}

template <class Head, class... Tail>
void dump_str_rec(ostringstream &oss, Head &&head, Tail &&... tail) {
  oss << ", " << head;
  dump_str_rec(oss, forward<Tail>(tail)...);
}

template <class T, class... U>
string dump_str(T &&arg, U &&... args) {
  ostringstream oss;
  oss << arg;
  dump_str_rec(oss, forward<U>(args)...);
  return oss.str();
}

// --------------- Fast I/O ------------------

void fastio() {
  cin.tie(0);
  ios::sync_with_stdio(0);
  cout << fixed << setprecision(20);
}

// ------------------ ACL --------------------

// #include <atcoder/modint>
// constexpr int MOD = 998244353;
// constexpr int MOD = 1000000007;
// using mint = atcoder::static_modint<MOD>;
// ostream &operator<<(ostream &os, const mint &v) {
//   return os << v.val();
// }

// ------------ End of template --------------

// Geometry Library
// written by okuraofvegetable

#define pb push_back
#define DOUBLE_INF 1e50
#define Points vector<Point>

#define EQ(a, b) (abs((a) - (b)) < eps)
#define GT(a, b) ((a) > (b))
#define GE(a, b) (GT(a, b) || EQ(a, b))
#define LT(a, b) ((a) < (b))
#define LE(a, b) (LT(a, b) || EQ(a, b))

inline double add(double a, double b) {
  if (abs(a + b) < eps * (abs(a) + abs(b))) return 0;
  return a + b;
}

// --------------------- Point -----------------------

#define Vector Point
struct Point {
  double x, y;
  Point() {}
  Point(double x, double y) : x(x), y(y) {}
  Point operator+(Point p) { return Point(add(x, p.x), add(y, p.y)); }
  Point operator-(Point p) { return Point(add(x, -p.x), add(y, -p.y)); }
  Point operator*(double d) { return Point(x * d, y * d); }
  Point operator/(double d) { return Point(x / d, y / d); }
  double dot(Point p) { return add(x * p.x, y * p.y); }
  double det(Point p) { return add(x * p.y, -y * p.x); }
  double norm() { return sqrt(x * x + y * y); }
  double norm2() { return x * x + y * y; }
  double dist(Point p) { return ((*this) - p).norm(); }
  double dist2(Point p) { return sq(x - p.x) + sq(y - p.y); }
  double arg() { return atan2(y, x); }             // [-PI,PI]
  double arg(Vector v) { return v.arg() - arg(); } // henkaku
  double angle(Vector v) {                         // [0,PI]
    return acos(cos(arg(v)));
  }
  Vector normalize() { return (*this) * (1.0 / norm()); }
  Point vert() { return Point(y, -x); }

  // Signed area of triange (0,0) (x,y) (p.x,p.y)
  double area(Point p) { return (x * p.y - p.x * y) / 2.0; }
  friend istream &operator>>(istream &is, Point &p) { return is >> p.x >> p.y; }
  friend ostream &operator<<(ostream &os, const Point &p) {
    return os << '(' << p.x << ',' << p.y << ')';
  }
};

Point divide_rate(Point a, Point b, double A, double B) {
  assert(!EQ(A + B, 0.0));
  return (a * B + b * A) * (1.0 / (A + B));
}

Vector polar(double len, double arg) {
  return Vector(cos(arg) * len, sin(arg) * len);
}

// Direction a -> b -> c
// verified AOJ CGL_1_C
enum { COUNTER_CLOCKWISE, CLOCKWISE, ONLINE_BACK, ONLINE_FRONT, ON_SEGMENT };
int ccw(Point a, Point b, Point c) {
  Vector p = b - a;
  Vector q = c - a;
  if (p.det(q) > 0.0) return COUNTER_CLOCKWISE; // counter clockwise
  if (p.det(q) < 0.0) return CLOCKWISE;         // clockwise
  if (p.dot(q) < 0.0) return ONLINE_BACK;       // c--a--b online_back
  if (p.norm() < q.norm()) return ONLINE_FRONT; // a--b--c online_front
  return ON_SEGMENT;                            // a--c--b on_segment
}

// --------------------- Line ------------------------
struct Line {
  Point a, b;
  Line() {}
  Line(Point a, Point b) : a(a), b(b) {}
  bool on(Point q) {
    dmp((a - q).det(b - q));
    return EQ((a - q).det(b - q), 0.0);
  }
  // following 2 functions verified AOJ CGL_2_A
  bool is_parallel(Line l) { return EQ((a - b).det(l.a - l.b), 0.0); }
  bool is_orthogonal(Line l) { return EQ((a - b).dot(l.a - l.b), 0.0); }
  Point intersection(Line l) {
    assert(!is_parallel(l));
    return a + (b - a) * ((l.b - l.a).det(l.a - a) / (l.b - l.a).det(b - a));
  }
  // Projection of p to this line
  // verified AOJ CGL_1_A
  Point projection(Point p) {
    return (b - a) * ((b - a).dot(p - a) / (b - a).norm2()) + a;
  }
  double distance(Point p) {
    Point q = projection(p);
    return p.dist(q);
  }
  // Reflection point of p onto this line
  // verified AOJ CGL_1_B
  Point refl(Point p) {
    Point proj = projection(p);
    return p + ((proj - p) * 2.0);
  }
  bool left(Point p) {
    if ((p - a).det(b - a) > 0.0)
      return true;
    else
      return false;
  }
  friend istream &operator>>(istream &is, Line &l) { return is >> l.a >> l.b; }
  friend ostream &operator<<(ostream &os, const Line &l) {
    return os << l.a << " -> " << l.b;
  }
};

#define endl "\n"
using ll = long long;
using pii = pair<int, int>;

const bool multitest = false;

void solve() {
  int N;
  cin >> N;
  vector<pii> ps(N);
  vector<Point> qs(N);
  cin >> ps;
  set<pii> s;
  for (int i = 0; i < N; i++) {
    ps[i].first *= 2;
    ps[i].second *= 2;
    s.insert(ps[i]);
    qs[i] = Point(ps[i].first, ps[i].second);
  }

  {
    Line l(qs[0], qs[1]);
    bool flag = true;
    for (int i = 0; i < N; i++) {
      if (!l.on(qs[i])) flag = false;
    }
    if (flag) {
      cout << "No" << endl;
      return;
    }
  }

  map<tuple<int, int, int, int>, int> cnt;
  for (int i = 0; i < N; i++) {
    for (int j = 0; j < N; j++) {
      if (i == j) continue;
      int x = (ps[i].first + ps[j].first) / 2;
      int y = (ps[i].second + ps[j].second) / 2;
      int dx = ps[i].second - ps[j].second;
      int dy = ps[j].first - ps[i].first;
      int g = gcd(dx, dy);
      dx /= g, dy /= g;
      if (dx < 0) {
        dx *= -1;
        dy *= -1;
      }
      if (dx == 0) {
        if (dy < 0) dy *= -1;
      }
      if (dx == 0) {
        y = 0;
      } else {
        int p = x / dx + 2;
        x -= p * dx, y -= p * dy;
        while (x < 0) x += dx, y += dy;
      }
      tuple<int, int, int, int> l(x, y, dx, dy);
      dmp(i, j, x, y, dx, dy);
      cnt[l]++;
    }
  }

  auto check = [&](tuple<int, int, int, int> l) {
    auto [x, y, dx, dy] = l;
    Line line(Point(x, y), Point(x + dx, y + dy));
    dmp(x, y, dx, dy);
    int on_cnt = 0;
    for (int i = 0; i < N; i++) {
      if (line.on(qs[i])) on_cnt++;
      Point p = line.refl(qs[i]);
      int X = std::floor(p.x + eps);
      int X_ = std::floor(p.x - eps);
      dmp(X, X_);
      if (X == X_) return false;

      int Y = std::floor(p.y + eps);
      int Y_ = std::floor(p.y - eps);
      dmp(Y, Y_);
      if (Y == Y_) return false;

      if (!s.count(pii(X, Y))) return false;
    }
    if (on_cnt > 2) return false;
    return true;
  };

  for (auto [l, c] : cnt) {
    auto [x, y, dx, dy] = l;
    dmp(x, y, dx, dy, c);
    if (c >= N - 2) {
      if (check(l)) {
        cout << "Yes" << endl;
        return;
      }
    }
  }

  cout << "No" << endl;

  return;
}

int main() {
  fastio();
  if (!multitest) {
    solve();
  } else {
    cerr << "[Warning] Multi testcase mode on" << endl;
    int t;
    cin >> t;
    while (t--) solve();
  }
  return 0;
}
accuracy: 1
time_ms: 460
memory_kb: 34672
final_rank: 9

code_snippet: #pragma GCC ta g("avx2")
#pragma GCC optimize("Ofast")
#pragma GCC optimize("unroll-loops")
#include <bits/stdc++.h>
using namespace std;
#define DEBUG
#ifdef DEBUG
template <class T, class U>
ostream &operator<<(ostream &os, const pair<T, U> &p) {
    os << '(' << p.first << ',' << p.second << ')';
    return os;
}
template <class T> ostream &operator<<(ostream &os, const vector<T> &v) {
    os << '{';
    for(int i = 0; i < (int)v.size(); i++) {
        if(i) { os << ','; }
        os << v[i];
    }
    os << '}';
    return os;
}
void debugg() { cerr << endl; }
template <class T, class... Args>
void debugg(const T &x, const Args &... args) {
    cerr << " " << x;
    debugg(args...);
}
#define debug(...)                                                             \
    cerr << __LINE__ << " [" << #__VA_ARGS__ << "]: ", debugg(__VA_ARGS__)
#define dump(x) cerr << __LINE__ << " " << #x << " = " << (x) << endl
#else
#define debug(...) (void(0))
#define dump(x) (void(0))
#endif
using namespace std;
typedef long long ll;
typedef vector<ll> vl;
typedef vector<vl> vvl;
typedef vector<char> vc;
typedef vector<string> vs;
typedef vector<bool> vb;
typedef vector<double> vd;
typedef pair<ll,ll> P;
typedef pair<int,int> pii;
typedef vector<P> vpl;
typedef tuple<ll,ll,ll> tapu;
#define rep(i,n) for(int i=0; i<(n); i++)
#define REP(i,a,b) for(int i=(a); i<(b); i++)
#define all(x) (x).begin(), (x).end()
#define rall(x) (x).rbegin(), (x).rend()
template<typename T1,typename T2> inline bool chmin(T1 &a,T2 b){
	if(a>b){
		a = b; return true;
	}
	else return false;
}
template<typename T1,typename T2> inline bool chmax(T1 &a,T2 b){
	if(a<b){
		a = b; return true;
	}
	else return false;
}
template<typename T> inline void print(T &a){
    int sz = a.size();
    for(auto itr = a.begin(); itr != a.end(); itr++){
		cout << *itr;
        sz--;
        if(sz) cout << " ";
	}
    cout << "\n";
}
template<typename T1,typename T2> inline void print2(T1 a, T2 b){
	cout << a << " " << b << "\n";
}
template<typename T1,typename T2,typename T3> inline void print3(T1 a, T2 b, T3 c){
	cout << a << " " << b << " " << c << "\n";
}
void mark() {cout << "#" << "\n";}
ll pcount(ll x) {return __builtin_popcountll(x);}
//#include <atcoder/maxflow>
//using namespace atcoder;
const int inf = (1<<30)-1;
const ll linf = 1LL<<61;
const int MAX = 510000;
int dy[8] = {0,1,0,-1,1,-1,-1,1};
int dx[8] = {-1,0,1,0,1,-1,1,-1};
const double pi = acos(-1);
const double eps = 1e-9;
//const int mod = 1e9 + 7;
const int mod = 998244353;

ll GCD(ll a, ll b){
	if(b==0) return a;
	else return GCD(b,a%b);
}

int main(){
	int n; cin >> n;
	vl x(n),y(n);
	rep(i,n) cin >> x[i] >> y[i], x[i] *= 2, y[i] *= 2;
	map<array<ll,3>,int> mp;
	rep(i,n) rep(j,n){
		if(i == j) continue;
		ll A = x[j] - x[i];
		ll B = y[j] - y[i];
		if(A == 0 && B == 0){
			cout << "No\n";
			return 0;
		}
		swap(A,B);
		B = -B;
		ll g = GCD(abs(A),abs(B));
		A /= g, B /= g;
		if(A < 0){
			A = -A, B = -B;
		}
		if(A == 0) B = abs(B);
		if(B == 0) A = abs(A);
		ll my = (y[i] + y[j]) / 2;
		ll mx = (x[i] + x[j]) / 2;
		ll C = A*my - B*mx;
		mp[{A,B,C}]++;
	}
	set<array<ll,3>> se;
	rep(i,n) rep(j,n){
		if(i == j) continue;
		ll A = x[j] - x[i];
		ll B = y[j] - y[i];
		if(A == 0 && B == 0){
			cout << "No\n";
			return 0;
		}
		ll g = GCD(abs(A),abs(B));
		A /= g, B /= g;
		if(A < 0){
			A = -A, B = -B;
		}
		if(A == 0) B = abs(B);
		if(B == 0) A = abs(A);
		ll my = (y[i] + y[j]) / 2;
		ll mx = (x[i] + x[j]) / 2;
		ll C = A*my - B*mx;
		se.insert({A,B,C});
	}
	if(se.size() == 1){
		cout << "No\n";
		return 0;
	}
	if(n & 1){
		for(auto t : mp){
			if(t.second == n-1){
				rep(i,n){
					if(t.first[0]*y[i]-t.first[1]*x[i]==t.first[2]){
						cout << "Yes\n";
						return 0;
					}
				}
			}
		}
		cout << "No\n";
	}else{
		for(auto t : mp){
			if(t.second == n){
				cout << "Yes\n";
				return 0;
			}
			if(t.second == n-2){
				int cnt = 0;
				rep(i,n){
					if(t.first[0]*y[i]-t.first[1]*x[i]==t.first[2]) cnt++;
				}
				if(cnt == 2){
					cout << "Yes\n";
					return 0;
				}
			}
		}
		cout << "No\n";
	}
}
accuracy: 1
time_ms: 990
memory_kb: 73640
final_rank: 11

code_snippet: /*	author:  Kite_kuma
	created: 2021.10.16 20:44:57 */

// #ifdef LOCAL
// #define _GLIBCXX_DEBUG
// #endif
#include <bits/stdc++.h>
using namespace std;

#pragma region macros

#define foa(s, v) for(auto &s : v)
#define all(v) (v).begin(), (v).end()
#define rall(v) (v).rbegin(), (v).rend()
#define popcnt(n) __builtin_popcountll((long long)n)

#define REPname(a, b, c, d, e, ...) e
#define rep(...) REPname(__VA_ARGS__, REP3, REP2, REP1, REP0)(__VA_ARGS__)
#define REP0(x) for(int Counter_in_rep_macro = 0; Counter_in_rep_macro < (x); ++Counter_in_rep_macro)
#define REP1(i, x) for(int i = 0; i < (x); ++i)
#define REP2(i, l, r) for(int i = (l); i < (r); ++i)
#define REP3(i, l, r, c) for(int i = (l); i < (r); i += (c))

#define DREPname(a, b, c, d, e, ...) e
#define drep(...) DREPname(__VA_ARGS__, DREP3, DREP2, DREP1)(__VA_ARGS__)
#define DREP1(i, x) for(int i = (x)-1; i >= 0; --i)
#define DREP2(i, l, r) for(int i = (r)-1; i >= (l); --i)
#define DREP3(i, l, r, c) for(int i = (r)-1; i >= (l); i -= (c))

#pragma endregion

#pragma region aliases

using ll = long long;
using ld = long double;
using ull = unsigned long long;
using vi = std::vector<int>;
using vvi = std::vector<std::vector<int>>;
using vvvi = std::vector<std::vector<std::vector<int>>>;
using vll = std::vector<ll>;
using vvll = std::vector<vll>;
using vvvll = std::vector<vvll>;
using pii = std::pair<int, int>;
using pll = std::pair<long long, long long>;
template <class T = ll>
using V = std::vector<T>;
template <class T = ll>
using VV = V<V<T>>;
template <class T = ll>
using VVV = V<V<V<T>>>;
template <class T = ll>
using pqup = std::priority_queue<T, std::vector<T>, std::greater<T>>;
template <class T = ll>
using pqdn = std::priority_queue<T>;

#pragma endregion

#pragma region constants

const int inf = 1e9;
const long long INF = 1e18;
const long double pi = acos(-1);
const char dl = '\n';
const char sp = ' ';
int dx[8] = {1, 0, -1, 0, 1, -1, -1, 1};
int dy[8] = {0, 1, 0, -1, 1, 1, -1, -1};

const int mod_1000000007 = 1000000007;
const int mod_998244353 = 998244353;

#pragma endregion

#pragma region basic_operation

template <class T0, class T1, class T2>
inline bool in_range(T0 x, T1 lef, T2 rig) {
	return ((lef <= x) && (x < rig));
}

template <class T>
inline bool chmin(T &a, T b) {
	if(a > b) {
		a = b;
		return true;
	}
	return false;
}
template <class T>
inline bool chmax(T &a, T b) {
	if(a < b) {
		a = b;
		return true;
	}
	return false;
}

void Yes(bool f = 1) { std::cout << (f ? "Yes" : "No") << '\n'; }
void No() { std::cout << "No\n"; }
void YES(bool f = 1) { std::cout << (f ? "YES" : "NO") << '\n'; }
void NO() { std::cout << "NO\n"; }

template <class T>
void drop(T answer) {
	std::cout << answer << '\n';
	exit(0);
}

void err(bool flag = true) {
	if(!flag) return;
	std::cout << -1 << '\n';
	exit(0);
}

template <class T>
void vout(std::vector<T> const &v, bool vertically = 0) {
	if(vertically) {
		for(auto const &a : v) {
			std::cout << a << '\n';
		}
		return;
	}
	for(auto it = v.begin(); it != v.end(); it++) {
		std::cout << (*it);
		if(it != v.end() - 1) {
			std::cout << ' ';
		}
	}
	std::cout << '\n';
	return;
}

inline void print() { std::cout << '\n'; }
template <class T>
inline void print(T x) {
	std::cout << x << '\n';
	return;
}
template <typename Head, typename... Tail>
void print(Head H, Tail... T) {
	std::cout << H << " ";
	print(T...);
}

template <class T>
void add(std::vector<T> &v, T val) {
	for(auto &a : v) a += val;
	return;
}

template <class T>
T dup(T a, T b) {
	assert(b != 0);
	return (a + b - 1) / b;
}

template <class T>
T greatest_lower_multiple(T x, T d) {
	if(d == 0) return 0;
	if(d < 0) d *= -1;
	T y = x % d;
	if(y < 0) y += d;
	return x - y;
}

template <class T>
T least_upper_multiple(T x, T d) {
	return -greatest_lower_multiple(-x, d);
}

long long POW(long long a, long long n) {
	long long res = 1;
	while(n > 0) {
		if(n & 1) res = res * a;
		a = a * a;
		n >>= 1;
	}
	return res;
}

long long modpow(long long a, long long n, long long mod) {	 // a^n mod
	assert(n >= 0 && mod);
	if(mod == 1) return 0LL;
	long long res = 1;
	a %= mod;
	while(n > 0) {
		if(n & 1) res = res * a % mod;
		a = a * a % mod;
		n >>= 1;
	}
	return res < 0 ? res + mod : res;
}

// return x which satisfies a * x % mod == gcd(a, mod)
// not (mod | a)
long long modinv(long long a, long long mod) {
	long long b = mod, u = 1, v = 0;
	while(b) {
		long long t = a / b;
		a -= t * b;
		std::swap(a, b);
		u -= t * v;
		std::swap(u, v);
	}
	u %= mod;
	if(u < 0) u += mod;
	return u;
}

template <class T>
int lb(const std::vector<T> &a, const T x) {
	return std::distance(a.begin(), std::lower_bound(a.begin(), a.end(), x));
}
template <class T>
int ub(const std::vector<T> &a, const T x) {
	return std::distance(a.begin(), std::upper_bound(a.begin(), a.end(), x));
}
template <class T>
void unq_sort(std::vector<T> &a) {
	std::sort(a.begin(), a.end());
	a.erase(std::unique(a.begin(), a.end()), a.end());
}
template <class T>
std::vector<int> press(std::vector<T> &a) {
	auto vec = a;
	unq_sort(vec);
	std::vector<int> ret;
	for(auto &v : a) ret.push_back(lb(vec, v));
	return ret;
}

#pragma endregion

#pragma region input
#define VEC(type, name, size) \
	vector<type> name(size);  \
	scanner::INPUT(name)
#define VVEC(type, name, h, w)                     \
	vector<vector<type>> name(h, vector<type>(w)); \
	scanner::INPUT(name)
#define INT(...)     \
	int __VA_ARGS__; \
	scanner::INPUT(__VA_ARGS__)
#define LL(...)            \
	long long __VA_ARGS__; \
	scanner::INPUT(__VA_ARGS__)
#define STR(...)        \
	string __VA_ARGS__; \
	scanner::INPUT(__VA_ARGS__)
#define CHR(...)      \
	char __VA_ARGS__; \
	scanner::INPUT(__VA_ARGS__)
#define DBL(...)        \
	double __VA_ARGS__; \
	scanner::INPUT(__VA_ARGS__)
#define LD(...)              \
	long double __VA_ARGS__; \
	scanner::INPUT(__VA_ARGS__)
#define TPL3(type0, type1, type2, name)   \
	std::tuple<type0, type1, type2> name; \
	scanner::INPUT(name);
#define TPL4(type0, type1, type2, type3, name)   \
	std::tuple<type0, type1, type2, type3> name; \
	scanner::INPUT(name);

namespace scanner {
template <class T>
void scan(T &a) {
	std::cin >> a;
}

template <class T, class L>
void scan(std::pair<T, L> &p) {
	scan(p.first);
	scan(p.second);
}

template <class T0, class T1, class T2>
void scan(std::tuple<T0, T1, T2> &p) {
	T0 t0;
	T1 t1;
	T2 t2;
	scan(t0);
	scan(t1);
	scan(t2);
	p = std::make_tuple(t0, t1, t2);
}

template <class T0, class T1, class T2, class T3>
void scan(std::tuple<T0, T1, T2, T3> &p) {
	T0 t0;
	T1 t1;
	T2 t2;
	T3 t3;
	scan(t0);
	scan(t1);
	scan(t2);
	scan(t3);
	p = std::make_tuple(t0, t1, t2, t3);
}

template <class T>
void scan(std::vector<T> &a) {
	for(auto &i : a) scan(i);
}

void INPUT() {}
template <class Head, class... Tail>
void INPUT(Head &head, Tail &... tail) {
	scan(head);
	INPUT(tail...);
}
}  // namespace scanner

template <typename T1, typename T2>
std::istream &operator>>(std::istream &is, std::pair<T1, T2> &p) {
	is >> p.first >> p.second;
	return is;
}
#pragma endregion

#pragma region debug

#pragma region output
template <typename T1, typename T2>
std::ostream &std::operator<<(std::ostream &os, const std::pair<T1, T2> &p) {
	os << p.first << " " << p.second;
	return os;
}
template <class T>
std::ostream &std::operator<<(std::ostream &os, const std::vector<T> &v) {
	for(int i = 0; i < (int)v.size(); i++) {
		if(i) os << " ";
		os << v[i];
	}
	return os;
}
#pragma endregion

#pragma region view

namespace viewer {
void view(const long long e) {
	if(e == INF)
		std::cerr << "INF";
	else if(e == -INF)
		std::cerr << "-INF";
	else
		std::cerr << e;
}

void view(const int e) {
	if(e == inf)
		std::cerr << "inf";
	else if(e == -inf)
		std::cerr << "-inf";
	else
		std::cerr << e;
}

template <typename T>
void view(const T e) {
	std::cerr << e;
}

template <typename T, typename U>
void view(const std::pair<T, U> &p) {
	std::cerr << "(";
	view(p.first);
	std::cerr << ", ";
	view(p.second);
	std::cerr << ")";
}

template <class T0, class T1, class T2>
void view(const std::tuple<T0, T1, T2> &p) {
	std::cerr << "(";
	view(std::get<0>(p));
	std::cerr << ", ";
	view(std::get<1>(p));
	std::cerr << ", ";
	view(std::get<2>(p));
	std::cerr << ")";
}

template <class T0, class T1, class T2, class T3>
void view(const std::tuple<T0, T1, T2, T3> &p) {
	std::cerr << "(";
	view(std::get<0>(p));
	std::cerr << ", ";
	view(std::get<1>(p));
	std::cerr << ", ";
	view(std::get<2>(p));
	std::cerr << ", ";
	view(std::get<3>(p));
	std::cerr << ")";
}

template <typename T>
void view(const std::set<T> &s) {
	if(s.empty()) {
		std::cerr << "{ }";
		return;
	}
	std::cerr << "{ ";
	for(auto &t : s) {
		view(t);
		std::cerr << ", ";
	}
	std::cerr << "\b\b }";
}

template <typename T>
void view(const std::unordered_set<T> &s) {
	if(s.empty()) {
		std::cerr << "{ }";
		return;
	}
	std::cerr << "{ ";
	for(auto &t : s) {
		view(t);
		std::cerr << ", ";
	}
	std::cerr << "\b\b }";
}

template <typename T>
void view(const std::vector<T> &v) {
	if(v.empty()) {
		std::cerr << "{ }";
		return;
	}
	std::cerr << "{ ";
	for(const auto &e : v) {
		view(e);
		std::cerr << ", ";
	}
	std::cerr << "\b\b }";
}

template <typename T>
void view(const std::vector<std::vector<T>> &vv) {
	std::cerr << "{\n";
	for(const auto &v : vv) {
		std::cerr << "\t";
		view(v);
		std::cerr << '\n';
	}
	std::cerr << "}";
}

template <typename T, typename U>
void view(const std::vector<std::pair<T, U>> &v) {
	std::cerr << "{\n";
	for(const auto &c : v) {
		std::cerr << "\t(";
		view(c.first);
		std::cerr << ", ";
		view(c.second);
		std::cerr << ")\n";
	}
	std::cerr << "}";
}

template <class T0, class T1, class T2>
void view(const std::vector<std::tuple<T0, T1, T2>> &v) {
	if(v.empty()) {
		std::cerr << "{ }";
		return;
	}
	std::cerr << '{';
	for(const auto &t : v) {
		std::cerr << "\n\t";
		view(t);
		std::cerr << ",";
	}
	std::cerr << "\n}";
}

template <class T0, class T1, class T2, class T3>
void view(const std::vector<std::tuple<T0, T1, T2, T3>> &v) {
	if(v.empty()) {
		std::cerr << "{ }";
		return;
	}
	std::cerr << '{';
	for(const auto &t : v) {
		std::cerr << "\n\t";
		view(t);
		std::cerr << ",";
	}
	std::cerr << "\n}";
}

template <typename T, typename U>
void view(const std::map<T, U> &m) {
	std::cerr << "{\n";
	for(const auto &t : m) {
		std::cerr << "\t[";
		view(t.first);
		std::cerr << "] : ";
		view(t.second);
		std::cerr << '\n';
	}
	std::cerr << "}";
}

template <typename T, typename U>
void view(const std::unordered_map<T, U> &m) {
	std::cerr << "{\n";
	for(const auto &t : m) {
		std::cerr << "\t[";
		view(t.first);
		std::cerr << "] : ";
		view(t.second);
		std::cerr << '\n';
	}
	std::cerr << "}";
}
}  // namespace viewer

#pragma endregion

// when debugging : g++ foo.cpp -DLOCAL
#ifdef LOCAL
void debug_out() {}
template <typename Head, typename... Tail>
void debug_out(Head H, Tail... T) {
	viewer::view(H);
	std::cerr << ", ";
	debug_out(T...);
}
#define debug(...)                                                \
	do {                                                          \
		std::cerr << __LINE__ << " [" << #__VA_ARGS__ << "] : ["; \
		debug_out(__VA_ARGS__);                                   \
		std::cerr << "\b\b]\n";                                   \
	} while(0)
#define dump(x)                                      \
	do {                                             \
		std::cerr << __LINE__ << " " << #x << " : "; \
		viewer::view(x);                             \
		std::cerr << '\n';                           \
	} while(0)

#else
#define debug(...) (void(0))
#define dump(x) (void(0))
#endif

#pragma endregion

#pragma region geometry_light

using Real = long double;
using R = Real;
using Point = std::complex<Real>;
using Vec = Point;
const Real EPS = 1e-10, PI = acos(-1);

inline bool eq(const Real &a, const Real &b) { return fabs(b - a) < EPS; }
inline bool eq(const Point &a, const Point &b) { return fabs(b - a) < EPS; }
/*
	-1: a < b
	0 : a == b
	1 : a > b
*/
inline int compare(const Real &a, const Real &b) { return eq(a, b) ? 0 : a < b ? -1 : 1; }
inline int sign(const Real &a) { return fabs(a) < EPS ? 0 : a < 0 ? -1 : 1; }

namespace std {
const Point operator*(const Point &p, const Real &d) { return Point(real(p) * d, imag(p) * d); }
}  // namespace std

std::istream &operator>>(std::istream &is, Point &p) {
	Real a, b;
	is >> a >> b;
	p = Point(a, b);
	return is;
}
std::ostream &operator<<(std::ostream &os, Point &p) { return os << std::fixed << std::setprecision(10) << p.real() << " " << p.imag(); }

// rotate point 'p' for counter clockwise direction
const Point rotate(const Real &theta, const Point &p) {
	return Point(cos(theta) * p.real() - sin(theta) * p.imag(), sin(theta) * p.real() + cos(theta) * p.imag());
}

const Real radian_to_degree(const Real &r) { return (r * 180.0 / PI); }

const Real degree_to_radian(const Real &d) { return (d * PI / 180.0); }

// get angle a-b-c (<pi)
const Real get_angle(const Point &a, const Point &b, const Point &c) {
	const Point v(a - b), w(c - b);
	Real theta = fabs(atan2(w.imag(), w.real()) - atan2(v.imag(), v.real()));
	return std::min(theta, 2 * PI - theta);
}

namespace std {
bool operator<(const Point &a, const Point &b) { return a.real() != b.real() ? a.real() < b.real() : a.imag() < b.imag(); }
}  // namespace std

struct Line {
	Point a, b;

	Line() = default;

	Line(Point a, Point b) : a(a), b(b) {}

	Line(Real A, Real B, Real C)  // Ax + By = C
	{
		if(eq(A, 0))
			a = Point(0, C / B), b = Point(1, C / B);
		else if(eq(B, 0))
			b = Point(C / A, 0), b = Point(C / A, 1);
		else
			a = Point(0, C / B), b = Point(C / A, 0);
	}

	friend std::ostream &operator<<(std::ostream &os, Line &p) { return os << p.a << " -- " << p.b; }

	friend std::istream &operator>>(std::istream &is, Line &a) { return is >> a.a >> a.b; }
};

struct Segment : Line {
	Segment() = default;

	Segment(Point a, Point b) : Line(a, b) {}
};

struct Circle {
	Point p;
	Real r;

	Circle() = default;

	Circle(Point p, Real r) : p(p), r(r) {}
};

using Points = std::vector<Point>;
using Polygon = std::vector<Point>;
using Segments = std::vector<Segment>;
using Lines = std::vector<Line>;
using Circles = std::vector<Circle>;

const Real cross(const Point &a, const Point &b) { return real(a) * imag(b) - imag(a) * real(b); }
const Real dot(const Point &a, const Point &b) { return real(a) * real(b) + imag(a) * imag(b); }

// http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=CGL_1_C
const int ccw(const Point &a, Point b, Point c) {
	b = b - a, c = c - a;
	if(cross(b, c) > EPS) return +1;		// "COUNTER_CLOCKWISE"
	if(cross(b, c) < -EPS) return -1;		// "CLOCKWISE"
	if(dot(b, c) < -EPS) return +2;			// "ONLINE_BACK"
	if(norm(b) + EPS < norm(c)) return -2;	// "ONLINE_FRONT"
	return 0;								// "ON_SEGMENT"
}

// http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=CGL_2_A
bool parallel(const Line &a, const Line &b) { return eq(cross(a.b - a.a, b.b - b.a), 0.0); }

// http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=CGL_2_A
bool orthogonal(const Line &a, const Line &b) { return eq(dot(a.a - a.b, b.a - b.b), 0.0); }

// http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=CGL_1_A
Point projection(const Line &l, const Point &p) {
	double t = dot(p - l.a, l.a - l.b) / norm(l.a - l.b);
	return l.a + (l.a - l.b) * t;
}

Point projection(const Segment &l, const Point &p) {
	double t = dot(p - l.a, l.a - l.b) / norm(l.a - l.b);
	return l.a + (l.a - l.b) * t;
}

// http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=CGL_1_B
Point reflection(const Line &l, const Point &p) { return projection(l, p) * 2.0 - p; }

int intersect(const Line &l, const Point &p) { return int(abs(ccw(l.a, l.b, p)) != 1); }

int intersect(const Line &l, const Line &m) {
	if(intersect(l, m.a) && intersect(l, m.b)) return -1;
	return int(abs(cross(l.b - l.a, m.b - m.a)) > EPS);
}

int intersect(const Segment &s, const Point &p) { return int(ccw(s.a, s.b, p) == 0); }

int intersect(const Line &l, const Segment &s) {
	if(intersect(l, s.a) && intersect(l, s.b)) return -1;
	return cross(l.b - l.a, s.a - l.a) * cross(l.b - l.a, s.b - l.a) < EPS;
}

Real distance(const Line &l, const Point &p);

int intersect(const Circle &c, const Line &l) {
	Real d = c.r - distance(l, c.p);
	return fabs(d) < EPS ? 1 : d > 0. ? 2 : 0;
}

int intersect(const Circle &c, const Point &p) { return int(abs(abs(p - c.p) - c.r) < EPS); }

// http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=CGL_2_B
int intersect(const Segment &s, const Segment &t) {
	if(eq(s.a, s.b)) return intersect(t, s.a);
	if(intersect(Line(s), t.a) && intersect(Line(s), t.b) &&
	   std::max(std::min(s.a, s.b), std::min(t.a, t.b)) < std::min(std::max(s.a, s.b), std::max(t.a, t.b)))
		return -1;
	return int(ccw(s.a, s.b, t.a) * ccw(s.a, s.b, t.b) <= 0 && ccw(t.a, t.b, s.a) * ccw(t.a, t.b, s.b) <= 0);
}

int intersect(const Circle &c, const Segment &l) {
	const Point h = projection(l, c.p);
	if(norm(h - c.p) - c.r * c.r > EPS) return 0;
	auto d1 = abs(c.p - l.a), d2 = abs(c.p - l.b);
	if(compare(d1, c.r) == -1 && compare(d2, c.r) == -1) return 0;
	if(d1 < c.r - EPS && d2 > c.r - EPS || d1 > c.r - EPS && d2 < c.r - EPS) return 1;
	return dot(l.a - h, l.b - h) < 0 ? 2 : 0;
}

Real distance(const Point &a, const Point &b);

int number_of_common_tangents(const Circle &c1, const Circle &c2) {
	Real r1 = std::min(c1.r, c2.r), r2 = std::max(c1.r, c2.r), d = distance(c1.p, c2.p);
	int com = compare(r1 + r2, d);
	return com == 1 ? compare(d + r1, r2) + 1 : 3 - com;
	// if(c1.r < c2.r) swap(c1, c2);
	// Real d = abs(c1.p - c2.p);
	// if(compare(c1.r + c2.r, d) == -1) return 4;
	// if(eq(c1.r + c2.r, d)) return 3;
	// if(compare(c1.r - c2.r, d) == -1) return 2;
	// return int(eq(c1.r - c2.r, d));
}

// http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=CGL_7_A&lang=jp
int intersect(const Circle &c1, const Circle &c2) { return 2 - abs(2 - number_of_common_tangents(c1, c2)); }

Real distance(const Point &a, const Point &b) { return abs(a - b); }

Real distance(const Line &l, const Point &p) { return abs(p - projection(l, p)); }

Real distance(const Line &l, const Line &m) { return intersect(l, m) ? 0 : distance(l, m.a); }

Real distance(const Segment &s, const Point &p) {
	Point r = projection(s, p);
	return intersect(s, r) ? distance(r, p) : std::min(abs(s.a - p), abs(s.b - p));
}

// http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=CGL_2_D
Real distance(const Segment &a, const Segment &b) {
	if(intersect(a, b)) return 0;
	return std::min({distance(a, b.a), distance(a, b.b), distance(b, a.a), distance(b, a.b)});
}

Real distance(const Line &l, const Segment &s) {
	if(intersect(l, s)) return 0;
	return std::min(distance(l, s.a), distance(l, s.b));
}

Point crosspoint(const Line &l, const Line &m) {
	Real A = cross(l.b - l.a, m.b - m.a);
	Real B = cross(l.b - l.a, l.b - m.a);
	if(eq(abs(A), 0.0) && eq(abs(B), 0.0)) return m.a;
	return m.a + (m.b - m.a) * B / A;
}

// http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=CGL_2_C
Point crosspoint(const Segment &l, const Segment &m) { return crosspoint(Line(l), Line(m)); }

// http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=CGL_7_D
std::pair<Point, Point> crosspoint(const Circle &c, const Line l) {
	Point pr = projection(l, c.p);
	if(eq(distance(l, c.p), c.r)) return {pr, pr};
	Vec v = (l.b - l.a) / abs(l.b - l.a) * sqrt(c.r * c.r - norm(pr - c.p));
	return make_pair(pr - v, pr + v);
	// Vec e = (l.b - l.a) / abs(l.b - l.a);
	// double base = sqrt(c.r * c.r - norm(pr - c.p));
	// return {pr - e * base, pr + e * base};
}

std::pair<Point, Point> crosspoint(const Circle &c, const Segment &l) {
	if(intersect(c, l) == 2) return crosspoint(c, Line(l.a, l.b));
	auto ret = crosspoint(c, Line(l.a, l.b));
	if(dot(l.a - ret.first, l.b - ret.first) < EPS)
		ret.second = ret.first;
	else
		ret.first = ret.second;
	return ret;
}

// http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=CGL_7_E
std::pair<Point, Point> crosspoint(const Circle &c1, const Circle &c2) {
	Real d = abs(c1.p - c2.p);
	Real a = acos((c1.r * c1.r + d * d - c2.r * c2.r) / (2 * c1.r * d));  // cosine theorem
	Real t = atan2(c2.p.imag() - c1.p.imag(), c2.p.real() - c1.p.real());
	Point p1 = c1.p + Point(cos(t + a) * c1.r, sin(t + a) * c1.r);
	Point p2 = c1.p + Point(cos(t - a) * c1.r, sin(t - a) * c1.r);
	return make_pair(p1, p2);
}

// http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=CGL_7_F
// "点 p を通る円 c の接線"の接点2つ
std::pair<Point, Point> tangent(const Circle &c1, const Point &p2) {
	return crosspoint(c1, Circle(p2, sqrt(norm(c1.p - p2) - c1.r * c1.r)));
}

// http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=CGL_7_G
// 円 c1, c2 の共通接線
Lines tangent(Circle c1, Circle c2) {
	Lines ret;
	if(c1.r < c2.r) std::swap(c1, c2);
	Real g = norm(c1.p - c2.p);
	if(eq(g, 0)) return ret;
	Vec u = (c2.p - c1.p) / Real(sqrt(g));
	Vec v = rotate(PI * 0.5, u);
	for(int s : {-1, 1}) {
		Real h = (c1.r + s * c2.r) / sqrt(g);
		if(eq(1 - h * h, 0)) {
			ret.emplace_back(c1.p + u * c1.r, c1.p + (u + v) * c1.r);
		} else if(1 - h * h > 0) {
			Point uu = u * h, vv = v * sqrt(1 - h * h);
			ret.emplace_back(c1.p + (uu + vv) * c1.r, c2.p - (uu + vv) * c2.r * s);
			ret.emplace_back(c1.p + (uu - vv) * c1.r, c2.p - (uu - vv) * c2.r * s);
		}
	}
	return ret;
}

#pragma endregion

bool solve(int n) {
	Points pts(n);
	foa(p, pts) cin >> p;
	const Point g = accumulate(all(pts), Point(0, 0), [](const Point &p, const Point &q) { return p + q; }) / Point(n, 0);
	std::transform(pts.begin(), pts.end(), pts.begin(), [&g](const Point &p) { return p - g; });

	debug(pts);

	auto is_sym = [&](R angle) {
		std::transform(pts.begin(), pts.end(), pts.begin(), [&angle](const Point &p) { return p * polar(R(1), R(-angle)); });
		auto tmp = pts;
		sort(all(tmp));

		debug(tmp);

		int on_border = 0;
		for(auto it = tmp.begin(); it != tmp.end();) {
			V<R> ys;
			R x = it->real();
			while(it != tmp.end() && eq(x, it->real())) {
				ys.push_back(it->imag());
				it++;
				debug(ys);
				debug(x, it->real());
			}
			sort(all(ys));
			int s = ys.size();
			debug(ys);
			rep(i, s) {
				int j = s - 1 - i;
				if(!eq(ys[i] + ys[j], 0)) {
					debug(ys, i, j);
					debug(ys[i] + ys[j]);
					return false;
				}
			}
			if(s & 1) on_border++;

			debug(ys, "ok");
		}
		debug(on_border);
		if(on_border <= 2) {
			debug(tmp);
			return true;
		}
		return false;
	};

	auto this_pt = [&](Point p) {
		if(eq(p, Point(0, 0))) return false;
		// debug(pts, p);
		return is_sym(arg(p));
	};

	sort(all(pts), [](const Point &a, const Point &b) {
		if(eq(abs(a), abs(b))) return arg(a) < arg(b);
		return abs(a) < abs(b);
	});

	rep(i, n) {
		if(this_pt(pts[i])) return true;
		int j = (i + 1) % n;
		if(this_pt((pts[i] + pts[j]) * 0.5)) return true;
	}

	return false;
}

int main() {
	std::ios::sync_with_stdio(false);
	std::cin.tie(nullptr);
	std::cout << std::fixed << std::setprecision(15);
	srand((unsigned)time(NULL));

	// auto c = polar(1., 1.);
	// cout << c.real() << sp << c.imag() << dl;

	int n;
	while(cin >> n && n) {
		ld time = clock();
		Yes(solve(n));
		debug((clock() - time) / CLOCKS_PER_SEC);
	}

	return 0;
}
accuracy: 1
time_ms: 420
memory_kb: 3976
final_rank: 5

code_snippet: #include <bits/stdc++.h>
using namespace std;
typedef long long ll;
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 (b<a) { a=b; return true; } return false; }
#define all(x) (x).begin(),(x).end()
#define fi first
#define se second
#define mp make_pair
#define si(x) int(x.size())
const int mod=1000000007,MAX=205,INF=1<<29;

#define double long double

//幾何ライブラリ
// define double ll をするときは Point の < と == も書き換えよう！

const double eps=1e-8;
const double pi=acos((double)-1.0L);
#define equals(a,b) (fabs((a)-(b))<eps)

double torad(double deg) {return (double)(deg)*pi/180.0;}
double todeg(double ang) {return ang*180.0/pi;}

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 * (double a){return Point(a*x,a*y);}
    Point operator / (double a){return Point(x/a,y/a);}
    
    double abs(){return sqrt(norm());}
    double norm(){return x*x+y*y;}
    
    bool operator < (const Point &p)const{
        return x+eps<p.x||(equals(x,p.x)&&y+eps<p.y);
    }
    
    bool operator == (const Point &p)const{
        return fabs(x-p.x)<eps/100000&&fabs(y-p.y)<eps/100000;
    }
};

typedef Point Vector;

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;
}

struct Segment{
    Point p1,p2;
};

bool isOrthogonal(Vector a,Vector b){
    return equals(dot(a,b),0.0);
}

bool isOrthogonal(Point a1,Point a2,Point b1,Point b2){
    return isOrthogonal(a1-a2,b1-b2);
}

bool isOrthogonal(Segment s1,Segment s2){
    return equals(dot(s1.p2-s1.p1,s2.p2-s2.p1),0.0);
}

bool isParallel(Vector a,Vector b){
    return equals(cross(a,b),0.0);
}

bool isParallel(Point a1,Point a2,Point b1,Point b2){
    return isParallel(a1-a2,b1-b2);
}

bool isParallel(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)/norm(base);
    return s.p1+base*r;
}

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

Point turn(Point p,Point c,double pi){
    double q=atan2(p.y-c.y,p.x-c.x);
    q+=pi;
    p=c+Point{cos(q)*abs(p-c),sin(q)*abs(p-c)};
    
    return p;
}
//pをcを中心としてpi回転させる(1周で2π)
//p=cのときnan

//p0,p1,p2の順に見たときどうなるか？

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;

int ccw(Point p0,Point p1,Point p2){
    Vector a=p1-p0;
    Vector 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;
    if(a.norm()<b.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);
}

bool overlap(Segment s1,Segment s2){
    int a=ccw(s1.p1,s1.p2,s2.p1),b=ccw(s1.p1,s1.p2,s2.p2);
    if(a&1||b&1) return 0;
    if(a==2){
        if(b==-2||(b==0&&!(s2.p2==s1.p1))) return 1;
        else return 0;
    }
    if(a==-2){
        if(b==2||(b==0&&!(s2.p2==s1.p2))) return 1;
        else return 0;
    }
    if(a==0){
        if(s1.p1==s2.p1){
            if(b!=2) return 1;
            else return 0;
        }
        else if(s1.p2==s2.p1){
            if(b!=-2) return 1;
            else return 0;
        }
        else return 1;
    }
    return 0;
}
//s1とs2の共通の線分(長さ0より大きい)があるかどうか

typedef Segment Line;

double getDistance(Point a,Point b){
    return abs(a-b);
}

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({getDistanceSP(s1,s2.p1),getDistanceSP(s1,s2.p2),getDistanceSP(s2,s1.p1),getDistanceSP(s2,s1.p2)});
}

Point getCrossPointS(Segment s1,Segment s2){
    //if(ccw(s1.p1,s1.p2,s2.p1)==0&&ccw(s1.p1,s1.p2,s2.p2)==0) return s1.p1;
    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;
}//同じ時壊れます

Point getCrossPointL(Line l1,Line l2){
    //if(ccw(s1.p1,s1.p2,s2.p1)==0&&ccw(s1.p1,s1.p2,s2.p2)==0) return s1.p1;
    
    Vector v1=l1.p2-l1.p1,v2=l2.p2-l2.p1;
    
    return l1.p1+v1*cross(v2,l2.p1-l1.p1)/cross(v2,v1);
}

Segment ParallelSegment(Segment s,double d){
    Vector v={-(s.p2-s.p1).y,(s.p2-s.p1).x};
    v=v/abs(v);
    
    s.p1=s.p1+v*d;
    s.p2=s.p2+v*d;
    
    return s;
}

Point naisin(Point p1,Point p2,Point p3){
    if(p1==p2&&p2==p3&&p3==p1) return p1;
    
    return (p1*abs(p2-p3)+p2*abs(p1-p3)+p3*abs(p1-p2))/(abs(p2-p3)+abs(p1-p3)+abs(p1-p2));
}

Point naisin(Line l1,Line l2,Line l3){
    //平行でない前提
    
    Point p1=getCrossPointL(l1,l2),p2=getCrossPointL(l1,l3),p3=getCrossPointL(l2,l3);
    return naisin(p1,p2,p3);
}

//ネットの適当を書いたのであってるか全く知りません→あってそう

class Circle{
public:
    Point c;
    double r;
    Circle(Point c=Point(),double r=0.0):c(c),r(r){}
};

Point CircleCenter(Point a,Point b,Point c){
    Point u=a-b,v=a-c;
    double m1=(norm(a)-norm(b))/2.0,m2=(norm(a)-norm(c))/2.0;
    
    Point res;
    if(cross(u,v)==0.0){
        res.x=1e9;
        res.y=1e9;
        
        return res;
    }
    res.x=(m1*v.y-m2*u.y)/cross(u,v);
    res.y=(m1*v.x-m2*u.x)/cross(v,u);
    
    return res;
}
//3点を通る円の中心を返す

//交わる 0
// c1がc2のinside 1
// c1がc2のoutside 2
// 交わらない 3

int not_intersect(Circle c1,Circle c2){
    double d=getDistance(c1.c,c2.c);
    double r1=c1.r,r2=c2.r;
    if(r1<r2){
        if(d<(r2-r1)) return 1;
    }
    if(r1>r2){
        if(d<(r1-r2)) return 2;
    }
    if(d<=r1+r2) return 0;
    else return 3;
}

pair<Point,Point> segCrossPpoints(Circle c,Line l){
    //assert(intersect(c,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);}

//inside(outside)

pair<Point,Point> getCrossPoints(Circle c1,Circle c2){
    //assert(intersect(c1,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));
}

vector<Line> Commontangent(Circle c1,Circle c2){
    vector<Line> res;
    Point p=c2.c-c1.c;
    
    if(abs(p)>=(c1.r+c2.r)){
        Point a,b;
        a.x=c1.r*(p.x*(c1.r+c2.r)+p.y*sqrt(norm(p)-(c1.r+c2.r)*(c1.r+c2.r)))/norm(p);
        a.y=c1.r*(p.y*(c1.r+c2.r)-p.x*sqrt(norm(p)-(c1.r+c2.r)*(c1.r+c2.r)))/norm(p);
        
        b.x=c1.r*(p.x*(c1.r+c2.r)-p.y*sqrt(norm(p)-(c1.r+c2.r)*(c1.r+c2.r)))/norm(p);
        b.y=c1.r*(p.y*(c1.r+c2.r)+p.x*sqrt(norm(p)-(c1.r+c2.r)*(c1.r+c2.r)))/norm(p);
        
        res.push_back(Line{a+c1.c,a+c1.c+Point{-a.y,a.x}});
        if(!(a==b)){
            res.push_back(Line{b+c1.c,b+c1.c+Point{-b.y,b.x}});
        }
    }
    
    if(abs(p)>=abs(c1.r-c2.r)){
        Point a,b;
        a.x=c1.r*(p.x*(c1.r-c2.r)+p.y*sqrt(norm(p)-(c1.r-c2.r)*(c1.r-c2.r)))/norm(p);
        a.y=c1.r*(p.y*(c1.r-c2.r)-p.x*sqrt(norm(p)-(c1.r-c2.r)*(c1.r-c2.r)))/norm(p);
        
        b.x=c1.r*(p.x*(c1.r-c2.r)-p.y*sqrt(norm(p)-(c1.r-c2.r)*(c1.r-c2.r)))/norm(p);
        b.y=c1.r*(p.y*(c1.r-c2.r)+p.x*sqrt(norm(p)-(c1.r-c2.r)*(c1.r-c2.r)))/norm(p);
        
        res.push_back(Line{a+c1.c,a+c1.c+Point{-a.y,a.x}});
        if(!(a==b)){
            res.push_back(Line{b+c1.c,b+c1.c+Point{-b.y,b.x}});
        }
    }
    
    return res;
}

typedef vector<Point> Polygon;

/*
 IN 2
 ON 1
 OUT 0
 */

int contains(Polygon g,Point p){
    int n=int(g.size());
    bool x=false;
    for(int i=0;i<n;i++){
        Point a=g[i]-p,b=g[(i+1)%n]-p;
        if(a.y>b.y) swap(a,b);
        if(a.y<eps&&0<b.y&&cross(a,b)<0) x=!x;
        if(abs(cross(a,b))<eps&&dot(a,b)<eps) return 1;
    }
    return (x?2:0);
}

Polygon andrewScan(Polygon s,bool ok){
    Polygon u,l;
    sort(all(s));
    
    if(int(s.size())<3) return s;
    int n=int(s.size());
    
    u.push_back(s[0]);
    u.push_back(s[1]);
    
    l.push_back(s[n-1]);
    l.push_back(s[n-2]);
    
    if(ok){
        for(int i=2;i<n;i++){
            for(int j=int(u.size());j>=2&&ccw(u[j-2],u[j-1],s[i])==counter_clockwise;j--){
                u.pop_back();
            }
            u.push_back(s[i]);
        }
        
        for(int i=int(s.size())-3;i>=0;i--){
            for(int j=int(l.size());j>=2&&ccw(l[j-2],l[j-1],s[i])==counter_clockwise;j--){
                l.pop_back();
            }
            l.push_back(s[i]);
        }
    }
    
    if(!ok){
        for(int i=2;i<n;i++){
            for(int j=int(u.size());j>=2&&ccw(u[j-2],u[j-1],s[i])!=clockwise;j--){
                u.pop_back();
            }
            u.push_back(s[i]);
        }
        
        for(int i=int(s.size())-3;i>=0;i--){
            for(int j=int(l.size());j>=2&&ccw(l[j-2],l[j-1],s[i])!=clockwise;j--){
                l.pop_back();
            }
            l.push_back(s[i]);
        }
    }
    
    reverse(all(l));
    
    for(int i=int(u.size())-2;i>=1;i--) l.push_back(u[i]);
    
    return l;
}//ok==1なら辺の上も含める

Polygon convex_cut(const Polygon& P, const Line& l) {
    Polygon Q;
    for(int i=0;i<si(P);i++){
        Point A=P[i],B=P[(i+1)%si(P)];
        if(ccw(l.p1,l.p2,A)!=-1)Q.push_back(A);
        if(ccw(l.p1,l.p2,A)*ccw(l.p1,l.p2,B)<0) Q.push_back(getCrossPointL(Line{A,B},l));
    }
    return Q;
}

double area(Point a,Point b,Point c){
    b=b-a;
    c=c-a;
    return abs(b.x*c.y-b.y*c.x)/2.0;
}

double area(Polygon &P){
    if(si(P)==0) return 0.0;
    double res=0;
    Point c={0.0,0.0};
    for(int i=0;i<si(P);i++){
        c=c+P[i];
    }
    c=c/si(P);
    
    for(int i=0;i<si(P);i++){
        res+=area(c,P[i],P[(i+1)%si(P)]);
    }
    
    return res;
}

ll gcd(ll a,ll b){
    if(b==0) return a;
    return gcd(b,a%b);
}

pair<Point,Vector> perpendicular_bisector(Point a,Point b){
    Point c=(a+b)/2;
    Vector v=b-c;
    swap(v.x,v.y);
    v.x*=-1;
    
    Point p=c;
    if(v.x==0){
        v.y=1;
        p.y=0;
    }
    else if(v.y==0){
        v.x=1;
        p.x=0;
    }
    else{
        if(v.x<0){
            v.x*=-1;
            v.y*=-1;
        }
        ll g=gcd(abs(ll(v.x)),abs(ll(v.y)));
        v.x/=g;
        v.y/=g;
        if(p.x>=0){
            ll d=p.x/v.x;
            p=p-v*d;
        }else{
            ll d=abs(p.x)/v.x;
            p=p+v*d;
            
            if(p.x<0){
                p=p+v;
            }
        }
    }
    
    return mp(p,v);
}
//2倍するなりして整数にしておくこと

int main(){
    
    std::ifstream in("text.txt");
    std::cin.rdbuf(in.rdbuf());
    cin.tie(0);
    ios::sync_with_stdio(false);
    
    int N;cin>>N;
    vector<Point> P(N);
    for(int i=0;i<N;i++){
        cin>>P[i].x>>P[i].y;
        P[i].x*=2;
        P[i].y*=2;
    }
    
    sort(all(P));
    bool g=false;
    for(int i=2;i<N;i++){
        if(abs(ccw(P[0],P[1],P[i]))&1) g=true;
    }
    if(!g){
        cout<<"No"<<endl;
        return 0;
    }
    map<pair<pair<double,double>,pair<double,double>>,int> MA;
    
    for(int i=0;i<N;i++){
        for(int j=i+1;j<N;j++){
            auto m=perpendicular_bisector(P[i],P[j]);
            MA[mp(mp(m.fi.x,m.fi.y),mp(m.se.x,m.se.y))]++;
        }
    }
    
    for(auto m:MA){
        if(m.se<N/2-2) continue;
        int oncnt=0;
        vector<Point> Q(N);
        for(int i=0;i<N;i++){
            Point a,b,c=P[i];
            a={m.fi.fi.fi,m.fi.fi.se};
            b={m.fi.se.fi,m.fi.se.se};
            b=b+a;
            if(abs(ccw(a,b,c))%2==0) oncnt++;
            Q[i]=reflect({a,b},c);
        }
        sort(all(Q));
        if(P==Q&&oncnt<3){
            cout<<"Yes"<<endl;
            return 0;
        }
    }
    
    cout<<"No"<<endl;
    
}
accuracy: 1
time_ms: 350
memory_kb: 65944
final_rank: 10

code_snippet: #include <bits/stdc++.h>
using namespace std;
long long gcd(long long a, long long b){
  if (b == 0){
    return a;
  } else {
    return gcd(b, a % b);
  }
}
/*
struct line{
  long long a, b, c;
  line(point A, point B){
    a = A.y - B.y;
    b = B.x - A.x;
    c = A.x * B.y - B.x * A.y;
    long long g = gcd(a, gcd(b, c));
    a /= g;
    b /= g;
    c /= g;
  }
};
line(point A, point B){

}
*/
int main(){
  int N;
  cin >> N;
  vector<long long> x(N), y(N);
  for (int i = 0; i < N; i++){
    cin >> x[i] >> y[i];
    x[i] *= 2;
    y[i] *= 2;
  }
  bool ok1 = false;
  for (int i = 0; i < N; i++){
    if ((x[1] - x[0]) * (y[i] - y[0]) != (y[1] - y[0]) * (x[i] - x[0])){
      ok1 = true;
    }
  }
  if (!ok1){
    cout << "No" << endl;
  } else {
    map<tuple<int, int, int>, int> mp;
    for (int i = 0; i < N; i++){
      for (int j = i + 1; j < N; j++){
        long long mx = (x[i] + x[j]) / 2;
        long long my = (y[i] + y[j]) / 2;
        long long a = x[j] - x[i];
        long long b = y[j] - y[i];
        long long c = -(a * mx + b * my);
        long long g = gcd(a, gcd(b, c));
        a /= g;
        b /= g;
        c /= g;
        mp[make_tuple(a, b, c)]++;
      }
    }
    bool ok2 = false;
    for (auto P : mp){
      long long a = get<0>(P.first);
      long long b = get<1>(P.first);
      long long c = get<2>(P.first);
      long long cnt = P.second;
      if (N % 2 == 0){
        if (cnt == N / 2){
          ok2 = true;
        }
        if (cnt == N / 2 - 1){
          int cnt2 = 0;
          for (int i = 0; i < N; i++){
            if (a * x[i] + b * y[i] + c == 0){
              cnt2++;
            }
          }
          if (cnt2 == 2){
            ok2 = true;
          }
        }
      }
      if (N % 2 == 1){
        if (cnt == N / 2){
          for (int i = 0; i < N; i++){
            if (a * x[i] + b * y[i] + c == 0){
              ok2 = true;
            }
          }
        }
      }
    }
    if (ok2){
      cout << "Yes" << endl;
    } else {
      cout << "No" << endl;
    }
  }
}
accuracy: 1
time_ms: 330
memory_kb: 34312
final_rank: 6

code_snippet: #include<iostream>
#include<string>
#include<cstdio>
#include<vector>
#include<cmath>
#include<algorithm>
#include<functional>
#include<iomanip>
#include<queue>
#include<ciso646>
#include<random>
#include<map>
#include<set>
#include<bitset>
#include<stack>
#include<unordered_map>
#include<utility>
#include<cassert>
#include<complex>
#include<numeric>
#include<array>
using namespace std;

//#define int long long
typedef long long ll;

typedef unsigned long long ul;
typedef unsigned int ui;
constexpr ll mod = 1000000007;
const ll INF = mod * mod;
typedef pair<int, int>P;
#define stop char nyaa;cin>>nyaa;
#define rep(i,n) for(int i=0;i<n;i++)
#define per(i,n) for(int i=n-1;i>=0;i--)
#define Rep(i,sta,n) for(int i=sta;i<n;i++)
#define rep1(i,n) for(int i=1;i<=n;i++)
#define per1(i,n) for(int i=n;i>=1;i--)
#define Rep1(i,sta,n) for(int i=sta;i<=n;i++)
#define all(v) (v).begin(),(v).end()
typedef pair<ll, ll> LP;
typedef long double ld;
typedef pair<ld, ld> LDP;
const ld eps = 1e-8;
const ld pi = acosl(-1.0);

ll mod_pow(ll x, ll n, ll m = mod) {
	ll res = 1;
	while (n) {
		if (n & 1)res = res * x % m;
		x = x * x % m; n >>= 1;
	}
	return res;
}
struct modint {
	ll n;
	modint() :n(0) { ; }
	modint(ll m) :n(m) {
		if (n >= mod)n %= mod;
		else if (n < 0)n = (n % mod + mod) % mod;
	}
	operator int() { return n; }
};
bool operator==(modint a, modint b) { return a.n == b.n; }
modint operator+=(modint& a, modint b) { a.n += b.n; if (a.n >= mod)a.n -= mod; return a; }
modint operator-=(modint& a, modint b) { a.n -= b.n; if (a.n < 0)a.n += mod; return a; }
modint operator*=(modint& a, modint b) { a.n = ((ll)a.n * b.n) % mod; return a; }
modint operator+(modint a, modint b) { return a += b; }
modint operator-(modint a, modint b) { return a -= b; }
modint operator*(modint a, modint b) { return a *= b; }
modint operator^(modint a, ll n) {
	if (n == 0)return modint(1);
	modint res = (a * a) ^ (n / 2);
	if (n % 2)res = res * a;
	return res;
}

ll inv(ll a, ll p) {
	return (a == 1 ? 1 : (1 - p * inv(p % a, a)) / a + p);
}
modint operator/(modint a, modint b) { return a * modint(inv(b, mod)); }

const int max_n = 1 << 19;
modint fact[max_n], factinv[max_n];
void init_f() {
	fact[0] = modint(1);
	for (int i = 0; i < max_n - 1; i++) {
		fact[i + 1] = fact[i] * modint(i + 1);
	}
	factinv[max_n - 1] = modint(1) / fact[max_n - 1];
	for (int i = max_n - 2; i >= 0; i--) {
		factinv[i] = factinv[i + 1] * modint(i + 1);
	}
}
modint comb(int a, int b) {
	if (a < 0 || b < 0 || a < b)return 0;
	return fact[a] * factinv[b] * factinv[a - b];
}

typedef complex<ld> Point;
ld dot(Point a, Point b) { return real(conj(a) * b); }
ld cross(Point a, Point b) { return imag(conj(a) * b); }
namespace std {
	bool operator<(const Point& lhs, const Point& rhs) {
		return lhs.real() == rhs.real() ? lhs.imag() < rhs.imag() : lhs.real() < rhs.real();
	}
}
struct Line {
	Point a, b;
};
struct Circle {
	Point p; ld r;
};
int ccw(Point a, Point b, Point c) {
	b -= a; c -= a;
	if (cross(b, c) > eps)return 1;//counter clockwise
	if (cross(b, c) < -eps)return -1;//clock wise
	if (dot(b, c) < 0)return 2;//c--a--b on line
	if (norm(b) < norm(c))return -2;//a--b--c on line
	return 0; //a--c--b on line
}
bool isis_ss(Line s, Line t) {
	return(cross(s.b - s.a, t.a - s.a) * cross(s.b - s.a, t.b - s.a) < -eps && cross(t.b - t.a, s.a - t.a) * cross(t.b - t.a, s.b - t.a) < -eps);
}
Point is_ll(Line s, Line t) {
	Point sv = s.b - s.a; Point tv = t.b - t.a;
	return s.a + sv * cross(tv, t.a - s.a) / cross(tv, sv);
}
bool eq(ld a, ld b) {
	return abs(a - b) < eps;
}
//2直線の交差判定
bool isis_ll(Line l, Line m) {
	return !eq(cross(l.b - l.a, m.b - m.a), 0);
}
//点が直線上に存在するか
bool isis_lp(Line l, Point p) {
	return (abs(cross(l.b - p, l.a - p)) < eps);
}
Line mid_line(Point a, Point b) {
	ld mx = (real(a) + real(b)) / 2.0, my = (imag(a) + imag(b)) / 2.0;
	ld dx = real(b) - real(a), dy = imag(b) - imag(a);
	swap(dx, dy); dx = -dx;
	Point le = { mx + dx,my + dy }, ri = { mx - dx,my - dy };
	return { le,ri };
}
//点から直線への垂線の足
Point proj(Line l, Point p) {
	ld t = dot(p - l.a, l.a - l.b) / norm(l.a - l.b);
	return l.a + t * (l.a - l.b);
}
//直線と点の距離
ld dist_lp(Line l, Point p) {
	return abs(p - proj(l, p));
}
Point inv_with_line(Point a, Line l) {
	ld dx = real(l.b) - real(l.a);
	ld dy = imag(l.b) - imag(l.a);
	swap(dx, dy); dx *= -1;
	ld r = sqrtl(dx * dx + dy * dy);
	dx /= r, dy /= r;
	ld dist = dist_lp(l,a);
	Point z = dist * Point{ dx,dy } + a;
	if (!isis_lp(l, z)) {
		z += (-3 * dist) * Point { dx, dy };
		return z;
	}
	else {
		z += dist * Point{ dx,dy };
		return z;
	}
}
void solve() {
	int n; cin >> n;
	vector<Point> p(n);
	map<P, bool> exi;
	rep(i, n) {
		int x, y; cin >> x >> y;
		exi[{x, y}] = true;
		p[i] = { (ld)x,(ld)y };
	}
	vector<P> vs;
	for (pair<P,bool> p : exi)vs.push_back(p.first);
	sort(all(vs));
	bool f = false;
	rep1(i, n - 2) {
		int lx = vs[i].first - vs[i - 1].first;
		int ly = vs[i].second - vs[i - 1].second;
		int rx = vs[i + 1].first - vs[i].first;
		int ry = vs[i + 1].second - vs[i].second;
		if (ly * rx != lx * ry) {
			f = true;
		}
	}
	if (!f) {
		cout << "No\n"; return;
	}
	auto okline = [&](Line l)->bool {
		int cnt = 0;
		rep(j, n) {
			if (isis_lp(l, p[j]))cnt++;
			else {
				Point t = inv_with_line(p[j], l);
				int x, y;
				if (real(t) > 0)x = real(t) + eps;
				else x = real(t) - eps;
				if (imag(t) > 0)y = imag(t) + eps;
				else y = imag(t) - eps;
				ld dif = abs(Point{ (ld)x,(ld)y } - t);
				//cout << "nande " <<j<<" "<< t << "\n";
				if (dif < eps) {
					if (!exi[{x, y}])return false;
				}
				else return false;
			}
		}
		if (cnt <= 2)return true;
		else return false;
	};
	rep(i, n) {
		rep(to, n)if(i!=to) {
			Line l = mid_line(p[i], p[to]);
			if (okline(l)) {
				cout << "Yes\n"; return;
			}
			l = { p[0],p[to] };
			if (okline(l)) {
				cout << "Yes\n"; return;
			}
		}
	}
	cout << "No\n";
}

signed main() {
	ios::sync_with_stdio(false);
	cin.tie(0);
	//cout << fixed << setprecision(15);
	//init_f();
	//init();
	//expr();
	//int t; cin >> t; rep(i, t)
	solve();
	return 0;
}
accuracy: 1
time_ms: 770
memory_kb: 12156
final_rank: 8

code_snippet: #include<iostream>
#include<string>
#include<cstdio>
#include<vector>
#include<cmath>
#include<algorithm>
#include<functional>
#include<iomanip>
#include<queue>
#include<ciso646>
#include<random>
#include<map>
#include<set>
#include<bitset>
#include<stack>
#include<unordered_map>
#include<utility>
#include<cassert>
#include<complex>
#include<numeric>
#include<array>
using namespace std;

//#define int long long
typedef long long ll;

typedef unsigned long long ul;
typedef unsigned int ui;
constexpr ll mod = 1000000007;
const ll INF = mod * mod;
typedef pair<int, int>P;
#define stop char nyaa;cin>>nyaa;
#define rep(i,n) for(int i=0;i<n;i++)
#define per(i,n) for(int i=n-1;i>=0;i--)
#define Rep(i,sta,n) for(int i=sta;i<n;i++)
#define rep1(i,n) for(int i=1;i<=n;i++)
#define per1(i,n) for(int i=n;i>=1;i--)
#define Rep1(i,sta,n) for(int i=sta;i<=n;i++)
#define all(v) (v).begin(),(v).end()
typedef pair<ll, ll> LP;
typedef long double ld;
typedef pair<ld, ld> LDP;
const ld eps = 1e-12;
const ld pi = acosl(-1.0);

ll mod_pow(ll x, ll n, ll m = mod) {
	ll res = 1;
	while (n) {
		if (n & 1)res = res * x % m;
		x = x * x % m; n >>= 1;
	}
	return res;
}
struct modint {
	ll n;
	modint() :n(0) { ; }
	modint(ll m) :n(m) {
		if (n >= mod)n %= mod;
		else if (n < 0)n = (n % mod + mod) % mod;
	}
	operator int() { return n; }
};
bool operator==(modint a, modint b) { return a.n == b.n; }
modint operator+=(modint& a, modint b) { a.n += b.n; if (a.n >= mod)a.n -= mod; return a; }
modint operator-=(modint& a, modint b) { a.n -= b.n; if (a.n < 0)a.n += mod; return a; }
modint operator*=(modint& a, modint b) { a.n = ((ll)a.n * b.n) % mod; return a; }
modint operator+(modint a, modint b) { return a += b; }
modint operator-(modint a, modint b) { return a -= b; }
modint operator*(modint a, modint b) { return a *= b; }
modint operator^(modint a, ll n) {
	if (n == 0)return modint(1);
	modint res = (a * a) ^ (n / 2);
	if (n % 2)res = res * a;
	return res;
}

ll inv(ll a, ll p) {
	return (a == 1 ? 1 : (1 - p * inv(p % a, a)) / a + p);
}
modint operator/(modint a, modint b) { return a * modint(inv(b, mod)); }

const int max_n = 1 << 19;
modint fact[max_n], factinv[max_n];
void init_f() {
	fact[0] = modint(1);
	for (int i = 0; i < max_n - 1; i++) {
		fact[i + 1] = fact[i] * modint(i + 1);
	}
	factinv[max_n - 1] = modint(1) / fact[max_n - 1];
	for (int i = max_n - 2; i >= 0; i--) {
		factinv[i] = factinv[i + 1] * modint(i + 1);
	}
}
modint comb(int a, int b) {
	if (a < 0 || b < 0 || a < b)return 0;
	return fact[a] * factinv[b] * factinv[a - b];
}

typedef complex<ld> Point;
ld dot(Point a, Point b) { return real(conj(a) * b); }
ld cross(Point a, Point b) { return imag(conj(a) * b); }
namespace std {
	bool operator<(const Point& lhs, const Point& rhs) {
		return lhs.real() == rhs.real() ? lhs.imag() < rhs.imag() : lhs.real() < rhs.real();
	}
}
struct Line {
	Point a, b;
};
struct Circle {
	Point p; ld r;
};
int ccw(Point a, Point b, Point c) {
	b -= a; c -= a;
	if (cross(b, c) > eps)return 1;//counter clockwise
	if (cross(b, c) < -eps)return -1;//clock wise
	if (dot(b, c) < 0)return 2;//c--a--b on line
	if (norm(b) < norm(c))return -2;//a--b--c on line
	return 0; //a--c--b on line
}
bool isis_ss(Line s, Line t) {
	return(cross(s.b - s.a, t.a - s.a) * cross(s.b - s.a, t.b - s.a) < -eps && cross(t.b - t.a, s.a - t.a) * cross(t.b - t.a, s.b - t.a) < -eps);
}
Point is_ll(Line s, Line t) {
	Point sv = s.b - s.a; Point tv = t.b - t.a;
	return s.a + sv * cross(tv, t.a - s.a) / cross(tv, sv);
}
bool eq(ld a, ld b) {
	return abs(a - b) < eps;
}
//2直線の交差判定
bool isis_ll(Line l, Line m) {
	return !eq(cross(l.b - l.a, m.b - m.a), 0);
}
//点が直線上に存在するか
bool isis_lp(Line l, Point p) {
	return (abs(cross(l.b - p, l.a - p)) < eps);
}
Line mid_line(Point a, Point b) {
	ld mx = (real(a) + real(b)) / 2.0, my = (imag(a) + imag(b)) / 2.0;
	ld dx = real(b) - real(a), dy = imag(b) - imag(a);
	swap(dx, dy); dx = -dx;
	Point le = { mx + dx,my + dy }, ri = { mx - dx,my - dy };
	return { le,ri };
}
//点から直線への垂線の足
Point proj(Line l, Point p) {
	ld t = dot(p - l.a, l.a - l.b) / norm(l.a - l.b);
	return l.a + t * (l.a - l.b);
}
//直線と点の距離
ld dist_lp(Line l, Point p) {
	return abs(p - proj(l, p));
}
Point inv_with_line(Point a, Line l) {
	ld dx = real(l.b) - real(l.a);
	ld dy = imag(l.b) - imag(l.a);
	swap(dx, dy); dx *= -1;
	ld r = sqrtl(dx * dx + dy * dy);
	dx /= r, dy /= r;
	ld dist = dist_lp(l,a);
	Point z = dist * Point{ dx,dy } + a;
	if (!isis_lp(l, z)) {
		z += (-3 * dist) * Point { dx, dy };
		return z;
	}
	else {
		z += dist * Point{ dx,dy };
		return z;
	}
}
void solve() {
	int n; cin >> n;
	vector<Point> p(n);
	map<P, bool> exi;
	rep(i, n) {
		int x, y; cin >> x >> y;
		exi[{x, y}] = true;
		p[i] = { (ld)x,(ld)y };
	}
	vector<P> vs;
	for (pair<P,bool> p : exi)vs.push_back(p.first);
	sort(all(vs));
	bool f = false;
	rep1(i, n - 2) {
		int lx = vs[i].first - vs[i - 1].first;
		int ly = vs[i].second - vs[i - 1].second;
		int rx = vs[i + 1].first - vs[i].first;
		int ry = vs[i + 1].second - vs[i].second;
		if (ly * rx != lx * ry) {
			f = true;
		}
	}
	if (!f) {
		cout << "No\n"; return;
	}
	auto okline = [&](Line l)->bool {
		int cnt = 0;
		rep(j, n) {
			if (isis_lp(l, p[j]))cnt++;
			else {
				Point t = inv_with_line(p[j], l);
				int x, y;
				if (real(t) > 0)x = real(t) + eps;
				else x = real(t) - eps;
				if (imag(t) > 0)y = imag(t) + eps;
				else y = imag(t) - eps;
				ld dif = abs(Point{ (ld)x,(ld)y } - t);
				//cout << "nande " <<j<<" "<< t << "\n";
				if (dif < eps) {
					if (!exi[{x, y}])return false;
				}
				else return false;
			}
		}
		if (cnt <= 2)return true;
		else return false;
	};
	rep(i, n) {
		rep(to, n)if(i!=to) {
			Line l = mid_line(p[0], p[to]);
			if (okline(l)) {
				cout << "Yes\n"; return;
			}
			l = { p[0],p[to] };
			if (okline(l)) {
				cout << "Yes\n"; return;
			}
		}
	}
	cout << "No\n";
}

signed main() {
	ios::sync_with_stdio(false);
	cin.tie(0);
	//cout << fixed << setprecision(15);
	//init_f();
	//init();
	//expr();
	//int t; cin >> t; rep(i, t)
	solve();
	return 0;
}
accuracy: 0.09615384615384616
time_ms: 20
memory_kb: 11484
final_rank: 20

code_snippet: #include <iostream>
#include <iomanip>
#include <complex>
#include <vector>
#include <algorithm>
#include <cmath>
#include <array>
#include <set>
using namespace std;

const double EPS = 1e-8;
const double INF = 1e12;
const double PI = acos(-1);
#define EQ(n,m) (abs((n)-(m)) < EPS)
#define X real()
#define Y imag()

typedef complex<double> P;
typedef vector<P> VP;
struct L : array<P, 2>{
    L(const P& a, const P& b){ at(0)=a; at(1)=b; }
    L(){}
};

namespace std{
    bool operator < (const P& a, const P& b){
        return !EQ(a.X,b.X) ? a.X<b.X : a.Y+EPS<b.Y;
    }
    bool operator == (const P& a, const P& b){
        return abs(a-b) < EPS;
    }
}

double dot(P a, P b){
    return (conj(a)*b).X;
}
double cross(P a, P b){
    return (conj(a)*b).Y;
}

bool intersectLP(const L& l, const P& p){
    return abs(cross(l[1]-p, l[0]-p)) < EPS;
}

P projection(const L& l, const P& p) {
    double t = dot(p-l[0], l[0]-l[1]) / norm(l[0]-l[1]);
    return l[0] + t*(l[0]-l[1]);
}
P reflection(const L& l, const P& p) {
    return p + 2.0*(projection(l, p) -p);
}

int main(){
    int n;
    cin >> n;
    set<P> poly;
    for(int i=0; i<n; i++){
        int x,y;
        cin >> x >> y;
        poly.insert(P(x, y));
    }

    P g(0, 0);
    for(auto p: poly){
        g += p;
    }
    g /= (double)n;

    vector<L> cand;
    for(auto p: poly){
        if(g != p){
            cand.emplace_back(g, p);
        }
        for(auto q: poly){
            if(p == q) continue;
            P mid = (p+q) /2.0;
            if(g == mid) continue;
            if(reflection(L(g, mid), p) == q){
                cand.emplace_back(g, mid);
            }
        }
    }
    bool ok = false;
    for(auto l: cand){
        int on_line = 0;
        bool symmetry = true;
        for(auto p: poly){
            if(intersectLP(l, p)){
                on_line++;
            }
            if(poly.find(reflection(l, p)) == poly.end()){
                symmetry = false;
                break;
            }
        }
        if(symmetry and on_line <= 2){
            ok = true;
            break;
        }
    }
    if(ok){
        cout << "Yes" << endl;
    }else{
        cout << "No" << endl;
    }

    return 0;
}
accuracy: 1
time_ms: 120
memory_kb: 4948
final_rank: 3