#include using namespace std; typedef struct { long long nume; long long deno; } frac; long long target; int n; frac num[10]; long long gcd(long long p, long long q) { return q ? gcd(q, p % q) : p; } void fr_op(frac t0, frac t1, frac *ans, int op) { long long deno, nume, d; switch(op) { case 0://足し算 deno = t0.deno * t1.deno; nume = t0.nume * t1.deno + t1.nume * t0.deno; break; case 1://掛け算 deno = t0.deno * t1.deno; nume = t0.nume * t1.nume; break; case 2://割り算1 deno = t0.deno * t1.nume; nume = t0.nume * t1.deno; break; case 3://割り算2 deno = t0.nume * t1.deno; nume = t0.deno * t1.nume; break; case 4://引き算 if(t0.deno * t1.nume < t0.nume * t1.deno) { deno = t0.deno * t1.deno; nume = t0.nume * t1.deno - t1.nume * t0.deno; } else { deno = t0.deno * t1.deno; nume = t1.nume * t0.deno - t0.nume * t1.deno; } break; //0が発生するのは引き算の結果のみ //その直前には等式ができているのでその場合を分けてもいい } //約分 d = gcd(deno, nume); if(d == 0)d = 1; //t0,t1がともに0だと割り算1,2の結果deno,numeがどちらも0になる (*ans).nume = nume / d; (*ans).deno = deno / d; return; } int check(frac *num, int count) { int i, j, k, op; frac next[10], temp0, temp1; if(num[0].nume == target && num[0].deno == 1)return 1; //num[0]が求める値になっていればOK if(count == 1)return 0; //そうでなく要素数が1ならダメ for(i = 0; i < count - 1; i++) for(j = i + 1; j < count; j++) { //1.numから2数を取る //2.選んだ2数に四則のいずれかを施す //3.その結果をnum[0]に戻して再帰 for(k = 0; k < count; k++)next[k] = num[k]; temp0 = next[i]; temp1 = next[j]; next[i] = next[0]; next[j] = next[count - 1]; for(op = 0; op < 5; op++) { fr_op(temp0, temp1, &next[0], op); if(check(next, count - 1))return 1; } } return 0; } bool check(int N, int M) { for(int i = 0; i < N; i++) num[i].nume = i + 1; for(int i = 0; i < N; i++) num[i].deno = 1; num[N].nume = M; num[N].deno = 1; n = N + 1; return (check(num, N)); } int main() { int N, M; cin >> N >> M; if(N >= 8 || (N <= 5 && check(N, M))) { cout << "Possible" << endl; } else { cout << "Impossible" << endl; } }