#include <bits/stdc++.h>
using namespace std;
#define rep(i, n) for (int i = 0; i < n; i++)
const int INF = 2e9;

struct unionfind {
    vector<int> parent; // 各要素の親のindex(根の場合は-1)
    vector<int> diff_weight; // 各要素の親要素との重さの差分(根の場合は0)
    unionfind(int n) {
        parent.resize(n, -1);
        diff_weight.resize(n, 0);
    }
    int root(int x) { // 要素xの属する集合の根のindex(要素xが根の場合はx)
        if (parent[x] < 0) return x;
        int r = root(parent[x]);
        diff_weight[x] += diff_weight[parent[x]];
        return parent[x] = r;
    }
    int weight(int x) { // 要素xとその親要素との重さの差分
        root(x);
        return diff_weight[x];
    }
    void merge(int x, int y) { // 要素xとyを共通の集合に結合
        x = root(x), y = root(y);
        if (x == y) return;
        if (parent[x] > parent[y]) {
            swap(x, y);
        }
        parent[x] += parent[y];
        parent[y] = x;
    }
    void merge(int x, int y, int w) { // 要素xとyを共通の集合に結合
        w += weight(x), w -= weight(y);
        x = root(x), y = root(y);
        if (x == y) return;
        if (parent[x] > parent[y]) {
            swap(x, y);
            w *= -1;
        }
        parent[x] += parent[y];
        parent[y] = x;
        diff_weight[y] = w;
    }
    bool common(int x, int y) { // 要素xとyが共通の集合に属するか
        return root(x) == root(y);
    }
    int size(int x) { // 要素xの属する集合の大きさ
        return -parent[root(x)];
    }
    int diff(int x, int y) { // 要素xとyの重さの差分
        return weight(y) - weight(x);
    }
};
struct edge {
    int from, to, cost;
};
struct graph {
    int n;
    vector<vector<edge>> G;
    vector<bool> visited;
    vector<int> indeg;
    graph(int n_) {
        n = n_;
        G.resize(n);
        visited.resize(n, false);
        indeg.resize(n, 0);
    }
    void add_edge(int from, int to, int cost) {
        G[from].push_back({from, to, cost});
        indeg[to]++;
    }
    void dfs(int s) {
        visited[s] = true;
        for (edge e : G[s]) {
            if (visited[e.to]) continue;
            dfs(e.to);
        }
    }
    void dfs(int s, int i, int _n) {
        visited[s] = true;
        if (i == _n) return;
        for (edge e : G[s]) {
            if (visited[e.to]) continue;
            dfs(e.to, i + 1, _n);
        }
    }
    void dfs(int cur, int prev, bool &closed) {
        visited[cur] = true;
        for (edge e : G[cur]) {
            if (not visited[e.to]) {
                dfs(e.to, cur, closed);
            } else if (e.to != prev) {
                closed = true;
            }
        }
    }
    void bfs(int s) {
        queue<int> q;
        q.push(s);
        visited[s] = true;
        while (not q.empty()) {
            int cur = q.front();
            for (edge e : G[cur]) {
                if (not visited[e.to]) continue;
                q.push(e.to);
                visited[e.to] = true;
            }
        }
    }
    void dijkstra(int s, vector<int> &dist) {
        using pii = pair<int, int>;
        dist.resize(n, INF);
        dist[s] = 0;
        priority_queue<pii, vector<pii>, greater<pii>> pq;
        pq.push({dist[s], s});
        while (not pq.empty()) {
            int cur = pq.top().second;
            pq.pop();
            for (edge e : G[cur]) {
                if (dist[e.to] > dist[cur] + e.cost) {
                    dist[e.to] = dist[cur] + e.cost;
                    pq.push({dist[e.to], e.to});
                }
            }
        }
    }
    void bellman_ford(int s, vector<int> &dist, bool &negative) {
        fill(visited.begin(), visited.end(), false);
        dfs(s);
        dist.resize(n, INF);
        dist[s] = 0;
        for (int i = 0; i < n; i++) {
            for (int u = 0; u < n; u++) {
                for (edge e : G[u]) {
                    if (not visited[e.to]) continue;
                    if (dist[e.to] > dist[u] + e.cost) {
                        dist[e.to] = dist[u] + e.cost;
                        if (i == n-1) {
                            negative = true;
                            return;
                        }
                    }
                }
            }
        }
    }
    void warshall_floyd(vector<vector<int>> &dist, bool &negative) {
        dist.resize(n, vector<int>(n, INF));
        for (int i = 0; i < n; i++) {
            for (edge e : G[i]) {
                dist[i][e.to] = e.cost;
            }
            dist[i][i] = 0;
        }
        for (int k = 0; k < n; k++) {
            for (int i = 0; i < n; i++) {
                for (int j = 0; j < n; j++) {
                    if (dist[i][k] == INF or dist[k][j] == INF) continue;
                    if (dist[i][j] > dist[i][k] + dist[k][j]) {
                        dist[i][j] = dist[i][k] + dist[k][j];
                    }
                    if (i == j and dist[i][j] < 0) {
                        negative = true;
                        return;
                    }
                }
            }
        }
    }
    static bool comp(const edge &e1, const edge &e2) {
        return e1.cost < e2.cost;
    }
    void kruskal(vector<edge> &edges, int &sum) {
        unionfind mst(n);
        sort(edges.begin(), edges.end(), comp);
        int m = edges.size();
        sum = 0;
        for (int i = 0; i < m; i++) {
            edge e = edges[i];
            if (not mst.common(e.from, e.to)) {
                mst.merge(e.from, e.to);
                sum += e.cost;
            }
        }
    }
    void topological(vector<int> &t) {
        queue<int> q;
        for(int i = 0; i < n; i++) {
            if (indeg[i] == 0) {
                q.push(i);
            }
        }
        while (not q.empty()) {
            int cur = q.front();
            q.pop();
            t.push_back(cur);
            for (edge e : G[cur]) {
                indeg[e.to]--;
                if (indeg[e.to] == 0) {
                    q.push(e.to);
                }
            }
        }
    }
};

int main() {
    int n, m;
    cin >> n >> m;
    // int r;
    // cin >> r;
    graph G(n);
    // vector<edge> edges(m);
    rep(i, m) {
        int from, to, cost = 0;
        cin >> from >> to;
        from--; to--;
        // cin >> cost;
        G.add_edge(from, to, cost);
        // edges[i] = {from, to, cost};
    }
    // 単一始点最短経路(ダイクストラ)
    // vector<int> dist;
    // G.dijkstra(r, dist);
    // for (int x : dist) {
    //     if (x == INF) printf("INF\n");
    //     else printf("%d\n", x);
    // }
    // 単一始点最短経路(ベルマンフォード)
    // vector<int> dist;
    // bool negative = false;
    // G.bellman_ford(r, dist, negative);
    // if (negative) printf("NEGATIVE CYCLE\n");
    // else {
    //     for (int x : dist) {
    //         if (x == INF) printf("INF\n");
    //         else printf("%d\n", x);
    //     }
    // }
    // 全点対間最短経路(ワーシャルフロイド)
    // vector<vector<int>> dist;
    // bool negative = false;
    // G.warshall_floyd(dist, negative);
    // if (negative) printf("NEGATIVE CYCLE\n");
    // else {
    //     rep(i, n) {
    //         rep(j, n) {
    //             if (dist[i][j] == INF) printf("INF");
    //             else printf("%d", dist[i][j]);
    //             if (j == n-1) printf("\n");
    //             else printf(" ");
    //         }
    //     }
    // }
    // 最小全域木(クラスカル)
    // int sum = 0;
    // G.kruskal(edges, sum);
    // printf("%d\n", sum);
    // トポロジカルソート
    // vector<int> t;
    // G.topological(t);
    // for (int x : t) {
    //     printf("%d\n", x);
    // }
    G.dfs(0, 0, 2);
    cout << (G.visited[n-1] ? "POSSIBLE" : "IMPOSSIBLE") << endl;
}

Measured memory_bytes: 13008