Sunake is in the form of a polygonal line consisting of n vertices (without self-intersection). First, Sunake-kun's i-th vertex is at (xi, yi). You can move continuously by translating or rotating, but you cannot deform (change the length of the polygonal line or the angle between the two line segments). y = 0 is the wall, and there is a small hole at (0, 0). Determine if you can move through this hole so that the whole thing meets y <0.

Constraints

* 2 ≤ n ≤ 1000
* 0 ≤ xi ≤ 109
* 1 ≤ yi ≤ 109
* Lines do not have self-intersections
* None of the three points are on the same straight line
* (xi, yi) ≠ (xi + 1, yi + 1)
* All inputs are integers

Input


n
x1 y1
.. ..
xn yn


Output

Output "Possible" if you can move through the hole, and "Impossible" if you can't.

Examples

Input

4
0 1
1 1
1 2
2 2


Output

Possible


Input

11
63 106
87 143
102 132
115 169
74 145
41 177
56 130
28 141
19 124
0 156
22 183


Output

Impossible
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using ld = long double;
using V = complex<ld>;
using L = pair<V, V>;
constexpr ld PI = static_cast<ld>(3.1415926535898);
constexpr ld EPS = static_cast<ld>(1e-12);

// 点をsetとかmapにつめたいとき(誤差を1e-10とか厳しくし過ぎるとバグる)
// inline bool operator<(const C a, const C b){
//     return abs(a.real()-b.real())>EPS ? a.real()<b.real()-EPS : a.imag()<b.imag()-EPS;
// }

namespace std
{
inline bool equal(const ld a, const ld b)
{
    return (-EPS < a - b and a - b < EPS);
}

inline bool operator<(const V& a, const V& b)
{
    return a.real() != b.real() ? a.real() < b.real() : a.imag() < b.imag();
}

inline bool operator==(const V& c1, const V& c2)
{
    return (equal(c1.real(), c2.real()) and equal(c1.imag(), c2.imag()));
}

inline bool operator!=(const V& a, const V& b)
{
    return !(a == b);
}
}

inline ld Sqrt(const ld x)
{
    return (x < 0 ? 0 : sqrt(x));
}

inline V normalize(const V& c)
{
    return c / abs(c);
}

inline ld arg(const V& a, const V& b)
{
    return arg(b * conj(a));
}

inline ld cross(const V& a, const V& b)
{
    return imag(conj(a) * b);
}

inline ld dot(const V& a, const V& b)
{
    return real(conj(a) * b);
}

inline int ccw(const V& a, const V& b, const V& c)
{
    if (cross(b - a, c - a) > 0) {
        return +1;  // counter clockwise
    }
    if (cross(b - a, c - a) < 0) {
        return -1;  // clockwise
    }
    if (dot(b - a, c - a) < 0) {
        return +2;  // c--a--b on line
    }
    if (norm(b - a) < norm(c - a)) {
        return -2;  // a--b--c on line
    }
    return 0;  //b--a--c on line
}

inline bool intersectLL(const L& l, const L& m)
{
    return abs(cross(l.second - l.first, m.second - m.first)) > EPS or abs(cross(l.second - l.first, m.first - l.first)) < EPS;
}

inline bool intersectLS(const L& l, const L& s)
{
    return cross(l.second - l.first, s.first - l.first) * cross(l.second - l.first, s.second - l.first) < EPS;
}

inline bool intersectLP(const L& l, const V& p)
{
    return abs(cross(l.second - p, l.first - p)) < EPS;
}

inline bool intersectSS(const L& s, const L& t)
{
    return ccw(s.first, s.second, t.first) * ccw(s.first, s.second, t.second) <= 0 and ccw(t.first, t.second, s.first) * ccw(t.first, t.second, s.second) <= 0;
}

inline bool intersectSP(const L& s, const V& p)
{
    return abs(s.first - p) + abs(s.second - p) - abs(s.second - s.first) < EPS;
}

inline V crosspointLL(const L& l, const L& m)
{
    const ld A = cross(l.second - l.first, m.second - m.first);
    const ld B = cross(l.second - l.first, l.second - m.first);
    //同一直線のとき
    if (abs(A) < EPS and abs(B) < EPS) {
        return m.first;
    }
    return m.first + (B / A) * (m.second - m.first);
}

//点pを直線l上に射影
inline V projection(const L& l, const V& p)
{
    const ld t = dot(p - l.first, l.first - l.second) / norm(l.first - l.second);
    return l.first + t * (l.first - l.second);
}

//crosspointCLに使用する関数(命名が謎です)
inline ld gettime(const V& c1, const V& c2)
{
    return (dot(c1, c2) < 0 ? -1.0 : 1.0) * abs(c2) / abs(c1);
}

//円と直線の交点
inline vector<V> crosspointCL(const V& c1, const ld r1, const L& l)
{
    const V a = l.first;
    const V b = l.second;
    vector<V> res;
    const V target = projection(L(a, b), c1);
    const V base = normalize(b - a);
    const ld h = abs(c1 - target);
    if (r1 + EPS < h) {
        return res;
    }
    const ld w = Sqrt(r1 * r1 - h * h);
    const ld LL = gettime(normalize(b - a), target - a) - w;
    const ld RR = LL + w * 2.0;
    res.push_back(a + base * LL);
    if (equal(LL, RR)) {
        return res;
    }
    res.push_back(a + base * RR);
    return res;
}

//円と線分の交点
inline vector<V> crosspointCS(const V& c1, const ld r1, const L& s)
{
    vector<V> tmp = crosspointCL(c1, r1, s);
    vector<V> res;
    for (int i = 0; i < tmp.size(); i++) {
        if (abs(s.second - s.first) == abs(s.first - tmp[i]) + abs(s.second - tmp[i])) {
            res.push_back(tmp[i]);
        }
    }
    return res;
}

//円どうしの交点
inline L crosspointCC(const V& c1, const ld r1, const V& c2, const ld r2)
{
    const V a = conj(c2 - c1);
    const V b = (r2 * r2 - r1 * r1 - (c2 - c1) * conj(c2 - c1));
    const V c = r1 * r1 * (c2 - c1);
    const V d = b * b - (ld)4.0 * a * c;
    const V z1 = (-b + sqrt(d)) / ((ld)2.0 * a) + c1;
    const V z2 = (-b - sqrt(d)) / ((ld)2.0 * a) + c1;
    return L(z1, z2);
}

//点pを直線lを軸として対称移動
inline V reflection(const L& l, const V& p)
{
    return p + (projection(l, p) - p) * (ld)2.0;
}

//点と直線の距離
inline ld distanceLP(const L& l, const V& p)
{
    return abs(p - projection(l, p));
}

//直線と直線の距離
inline ld distanceLL(const L& l, const L& m)
{
    return intersectLL(l, m) ? 0 : distanceLP(l, m.first);
}

//直線と線分の距離
inline ld distanceLS(const L& l, const L& s)
{
    if (intersectLS(l, s)) {
        return 0;
    }
    return min(distanceLP(l, s.first), distanceLP(l, s.second));
}
//線分と点の距離
inline ld distanceSP(const L& s, const V& p)
{
    const V r = projection(s, p);
    if (intersectSP(s, r)) {
        return abs(r - p);
    }
    return min(abs(s.first - p), abs(s.second - p));
}

//線分と線分の距離
inline ld distanceSS(const L& s, const L& t)
{
    if (intersectSS(s, t)) {
        return 0;
    }
    return min(min(distanceSP(s, t.first), distanceSP(s, t.second)), min(distanceSP(t, s.first), distanceSP(t, s.second)));
}

inline ld getarea(const V& c1, const ld r1, const V& a, const V& b)
{
    const V va = c1 - a;
    const V vb = c1 - b;
    const ld A = abs(va);
    const ld B = abs(vb);
    const ld f = cross(va, vb);
    const ld d = distanceSP(L(a, b), c1);
    ld res = 0;
    if (equal(f, (ld)0.0)) {
        return 0;
    }
    if (A < r1 + EPS and B < r1 + EPS) {
        return f * (ld)0.5;
    }
    if (d > r1 - EPS) {
        return r1 * r1 * M_PI * arg(va, vb) / ((ld)2.0 * M_PI);
    }
    vector<V> u = crosspointCS(c1, r1, L(a, b));
    u.insert(u.begin(), a);
    u.push_back(b);
    for (int i = 0; i + 1 < (int)u.size(); i++) {
        res += getarea(c1, r1, u[i], u[i + 1]);
    }
    return res;
}

//円と多角形の共通部分の面積
inline ld getcrossarea(const vector<V>& t, const V& c1, const ld r1)
{
    const int n = t.size();
    if (n < 3) {
        return 0;
    }
    ld res = 0;
    for (int i = 0; i < n; i++) {
        const V a = t[i];
        const V b = t[(i + 1) % n];
        res += getarea(c1, r1, a, b);
    }
    return res;
}

//凸包を求める(O(nlogn))
inline vector<V> convex_hull(vector<V> ps)
{
    const int n = (int)ps.size();
    int k = 0;
    sort(ps.begin(), ps.end());
    vector<V> ch(2 * n);
    for (int i = 0; i < n; ch[k++] = ps[i++]) {
        while (k >= 2 and ccw(ch[k - 2], ch[k - 1], ps[i]) <= 0) {
            k--;
        }
    }
    for (int i = n - 2, t = k + 1; i >= 0; ch[k++] = ps[i--]) {
        while (k >= t and ccw(ch[k - 2], ch[k - 1], ps[i]) <= 0) {
            k--;
        }
    }
    ch.resize(k - 1);
    return ch;
}

//凸性判定
inline bool isconvex(const vector<V>& ps)
{
    for (int i = 0; i < ps.size(); i++) {
        if (ccw(ps[(i + ps.size() - 1) % ps.size()], ps[i], ps[(i + 1) % ps.size()])) {
            return false;
        }
    }
    return true;
}

//多角形の符号付き面積(左回りが正)
inline ld area(const vector<V>& ps)
{
    ld A = 0;
    for (int i = 0; i < ps.size(); i++) {
        A += cross(ps[i], ps[(i + 1) % ps.size()]);
    }
    return A / (ld)2.0;
}

//凸多角形を直線で切断した時の左側の図形
vector<V> convex_cut(const vector<V>& ps, const L& l)
{
    vector<V> Q;
    for (int i = 0; i < ps.size(); i++) {
        const V A = ps[i];
        const V B = ps[(i + 1) % ps.size()];
        if (ccw(l.first, l.second, A) != -1) {
            Q.push_back(A);
        }
        if (ccw(l.first, l.second, A) * ccw(l.first, l.second, B) < 0) {
            Q.push_back(crosspointLL(L(A, B), l));
        }
    }
    return Q;
}

//点が多角形に包含されているか(0は含まれない,1は辺上,2は含まれる)
int contains(const vector<V>& ps, const V& p)
{
    bool flag = false;
    for (int i = 0; i < ps.size(); i++) {
        V a = ps[i] - p;
        V b = ps[(i + 1) % ps.size()] - p;
        if (imag(a) > imag(b)) {
            swap(a, b);
        }
        if (imag(a) <= 0 and 0 < imag(b)) {
            if (cross(a, b) < 0) {
                flag = not flag;
            }
        }
        if (cross(a, b) == 0 and dot(a, b) <= 0)
            return 1;
    }
    return flag ? 2 : 0;
}

//凸多角形の交差
vector<V> convex_intersection(const vector<V>& ps, const vector<V>& qs)
{
    vector<V> rs;
    const int a = ps.size();
    const int b = qs.size();
    for (int i = 0; i < a; i++) {
        if (contains(qs, ps[i])) {
            rs.push_back(ps[i]);
        }
    }
    for (int i = 0; i < b; i++) {
        if (contains(ps, qs[i])) {
            rs.push_back(qs[i]);
        }
    }
    for (int i = 0; i < a; i++) {
        for (int j = 0; j < b; j++) {
            const L l1(ps[i], ps[(i + 1) % a]);
            const L l2(qs[j], qs[(j + 1) % b]);
            if (intersectSS(l1, l2)) {
                rs.push_back(crosspointLL(l1, l2));
            }
        }
    }
    sort(rs.begin(), rs.end());
    rs.erase(unique(rs.begin(), rs.end()), rs.end());
    if (rs.size() <= 1) {
        return rs;
    }
    return convex_hull(rs);
}

//凸多角形の直径を求める(キャリパー法)
//maxi,maxjが最遠点対となる
inline ld convex_diameter(const vector<V>& ps)
{
    const int n = ps.size();
    int is = 0;
    int js = 0;
    for (int i = 1; i < n; ++i) {
        if (imag(ps[i]) > imag(ps[is])) {
            is = i;
        }
        if (imag(ps[i]) < imag(ps[js])) {
            js = i;
        }
    }
    ld maxd = abs(ps[is] - ps[js]);
    int i;
    int maxi;
    int j;
    int maxj;
    i = maxi = is;
    j = maxj = js;
    do {
        if (cross(ps[(i + 1) % ps.size()] - ps[i], ps[(j + 1) % ps.size()] - ps[j]) >= 0)
            j = (j + 1) % n;
        else
            i = (i + 1) % n;
        if (abs(ps[i] - ps[j]) > maxd) {
            maxd = abs(ps[i] - ps[j]);
            maxi = i;
            maxj = j;
        }
    } while (i != is or j != js);
    return maxd;
}

inline bool compyx(const V& c1, const V& c2)
{
    return c1.imag() != c2.imag() ? c1.imag() < c2.imag() : c1.real() < c2.real();
}

inline ld closest_pair(const vector<V>::iterator a, const int n)
{
    if (n <= 1) {
        return 1e100;
    }
    int m = n / 2;
    ld x = a[m].real();
    ld d = min(closest_pair(a, m), closest_pair(a + m, n - m));
    inplace_merge(a, a + m, a + n, compyx);
    vector<V> b;
    for (int i = 0; i < n; i++) {
        if (abs(x - a[i].real()) >= d) {
            continue;
        }
        for (int j = 0; j < b.size(); j++) {
            V dp = a[i] - b[b.size() - 1 - j];
            if (dp.imag() >= d) {
                break;
            }
            d = min(d, abs(dp));
        }
        b.push_back(a[i]);
    }
    return d;
}

//最近点対を求める
inline ld compute_shortest(const vector<V>::iterator a, const int n)
{
    sort(a, a + n);
    return closest_pair(a, n);
}

//2円の位置関係を示す(返り値は2円の間の共通接線の数)
inline int getstateCC(const V& c1, const ld r1, const V& c2, const ld r2)
{
    ld d = abs(c1 - c2);
    if (d > r1 + r2 + EPS) {
        return 4;
    }
    if (d > r1 + r2 - EPS) {
        return 3;
    }
    if (d > abs(r1 - r2) + EPS) {
        return 2;
    }
    if (d > abs(r1 - r2) - EPS) {
        return 1;
    }
    return 0;
}

//点から円へ接線を引いた時の接点
inline V gettangentCP_(const V& c1, const ld r1, const V& p, const int flg)
{
    const V base = c1 - p;
    const ld w = Sqrt(norm(base) - r1 * r1);
    const V s = p + base * V(w, r1 * flg) / norm(base) * w;
    return s;
}

//点から円への接線
inline vector<L> gettangentCP(const V& c1, const ld r1, const V& p)
{
    vector<L> res;
    const V s = gettangentCP_(c1, r1, p, 1);
    const V t = gettangentCP_(c1, r1, p, -1);
    //点が円の周上にある場合
    if (s == t) {
        res.push_back(L(s, s + (c1 - p) * V(0, 1)));
    } else {
        res.push_back(L(p, s));
        res.push_back(L(p, t));
    }
    return res;
}

//2円の共通内接線を求める
inline L getintangent(const V& c1, const ld r1, const V& c2, const ld r2, const ld flg)
{
    const V base = c2 - c1;
    const ld w = r1 + r2;
    const ld h = Sqrt(norm(base) - w * w);
    const V k = base * V(w, h * flg) / norm(base);
    return L(c1 + k * r1, c2 - k * r2);
}

//2円の共通外接線を求める
inline L getouttangent(const V& c1, const ld r1, const V& c2, const ld r2, const ld flg)
{
    const V base = c2 - c1;
    const ld h = r2 - r1;
    const ld w = Sqrt(norm(base) - h * h);
    const V k = base * V(w, h * flg) / norm(base) * V(0, flg);
    return L(c1 + k * r1, c2 + k * r2);
}

//2円の共通接線を求める(各直線の２点はそれぞれの円の接点)
inline vector<L> gettangentCC(const V& c1, const ld r1, const V& c2, const ld r2)
{
    vector<L> res;
    const ld d = abs(c1 - c2);
    if (d > r1 + r2 + EPS) {
        res.push_back(getintangent(c1, r1, c2, r2, 1));
    }
    if (d > r1 + r2 - EPS) {
        res.push_back(getintangent(c1, r1, c2, r2, -1));
    }
    if (d > abs(r1 - r2) + EPS) {
        res.push_back(getouttangent(c1, r1, c2, r2, 1));
    }
    if (d > abs(r1 - r2) - EPS) {
        res.push_back(getouttangent(c1, r1, c2, r2, -1));
    }
    return res;
}

int main()
{
    int N;
    cin >> N;
    vector<V> v(N);
    vector<vector<V>> cv(N);
    for (int i = 0; i < N; i++) {
        ld x, y;
        cin >> x >> y;
        v[i] = {x, y};
    }
    for (int i = 0; i < N; i++) {
        cv[i] = convex_hull(vector<V>(v.begin(), v.begin() + i + 1));
    }
    for (int i = 1; i < N; i++) {
        if (contains(cv[i - 1], v[i]) == 2) {
            cout << "Impossible" << endl;
            return 0;
        }
    }
    reverse(v.begin(), v.end());
    for (int i = 0; i < N; i++) {
        cv[i] = convex_hull(vector<V>(v.begin(), v.begin() + i + 1));
    }
    for (int i = 1; i < N; i++) {
        if (contains(cv[i - 1], v[i]) == 2) {
            cout << "Impossible" << endl;
            return 0;
        }
    }
    cout << "Possible" << endl;
    return 0;
}

