// Original C++ solution (slower):
/**

 *      purpose : 

 *      author  : kyomukyomupurin

 *      created : 

**/



// input/output

#include <iostream>

#include <fstream>

#include <sstream>

// container class

#include <array>

#include <deque>

#include <map>

#include <queue>

#include <set>

#include <stack>

#include <string>

#include <unordered_map>

#include <unordered_set>

#include <vector>

// math, algorithm

#include <algorithm>

#include <cmath>

#include <complex>

#include <numeric>

// etc

#include <bitset>

#include <cassert>

#include <cctype>

#include <cstring>

#include <chrono>

#include <iomanip>

#include <random>

#include <utility>

// using-directive

using namespace std;

// alias template

using int64 = int64_t;

using pii = pair<int, int>;

using pll = pair<int64_t, int64_t>;

// text macro replacement

#define rep(i, n) for (int i = 0; i < (int)(n); ++i)

#define all(v) (v).begin(), (v).end()

#define rall(v) (v).rbegin(), (v).rend()

#define print(x) cout << (x) << '\n'

#define debug(x) cout << #x << ": " << (x) << '\n'

// variadic template

template<typename T> inline void chmin(T &a, T b) {if (a > b) a = b; return;}

template<typename T> inline void chmax(T &a, T b) {if (a < b) a = b; return;}



const int MAX_V = 2e5;

const int64_t INF = 1e18;



struct edge {

  int64_t to, cost;

};



int n;

std::vector<edge> G[MAX_V];

int64_t dis[MAX_V];



void dijkstra(int s){

  std::priority_queue<std::pair<int64_t, int64_t>,

                      std::vector<std::pair<int64_t, int64_t>>,

                      std::greater<std::pair<int64_t, int64_t>>> pq;

  std::fill(dis, dis + n, INF);

  dis[s] = 0;

  pq.push(std::pair<int64_t, int64_t>(0, s));



  while (!pq.empty()){

    std::pair<int64_t, int64_t> p = pq.top(); pq.pop();

    int v = p.second;

    if (dis[v] < p.first) continue;

    for (int i = 0; i < (int) G[v].size(); ++i){

      edge e = G[v][i];

      if (dis[e.to] > dis[v] + e.cost){

        dis[e.to] = dis[v] + e.cost;

        pq.push(std::pair<int64_t, int64_t>(dis[e.to], e.to));

      }

    }

  }

}



int main(){

  ios_base::sync_with_stdio(false);

  cin.tie(nullptr);



  int m; cin >> n >> m;

  vector<int> a(m), b(m);

  for (int i = 0; i < m; ++i) {

    cin >> a[i] >> b[i];

    --a[i]; --b[i];

    G[a[i]].push_back({b[i], 1});

    G[b[i]].push_back({a[i], 1});

  }



  dijkstra(0);



  if (dis[n - 1] == 2) print("POSSIBLE");

  else print("IMPOSSIBLE");



  return 0;

}

// Optimized solution to the same problem (faster):
#pragma region kyomukyomupurin



/**

 *    author  : 𝒌𝒚𝒐𝒎𝒖𝒌𝒚𝒐𝒎𝒖𝒑𝒖𝒓𝒊𝒏

 *    created : 2020-04-24 21:52:31

 **/



#include <algorithm>

#include <bitset>

#include <cassert>

#include <cctype>

#include <chrono>

#include <cmath>

#include <complex>

#include <deque>

#include <iomanip>

#include <iostream>

#include <map>

#include <numeric>

#include <queue>

#include <random>

#include <set>

#include <stack>

#include <string>

#include <utility>

#include <vector>



using namespace std;



using int64 = long long;



template <class T>

using binary_heap = std::priority_queue<T, std::vector<T>, std::greater<T>>;



template <class T, class U>

std::ostream& operator<<(std::ostream& os, const std::pair<T, U>& p) {

  return os << '(' << p.first << ", " << p.second << ')';

}



template <class T>

std::ostream& operator<<(std::ostream& os, const std::vector<T>& vec) {

  int flag = 0;

  for (auto e : vec) os << (flag++ ? ", " : "{") << e;

  return os << '}';

}



template <class T>

std::ostream& operator<<(std::ostream& os, const std::set<T>& st) {

  int flag = 0;

  for (auto e : st) os << (flag++ ? ", " : "{") << e;

  return os << '}';

}



template <class T, class U>

std::ostream& operator<<(std::ostream& os, const std::map<T, U>& mp) {

  int flag = 0;

  for (auto e : mp) os << (flag++ ? ", " : "{") << e;

  return os << '}';

}



template <class T>

std::istream& operator>>(std::istream& is, std::vector<T>& vec) {

  for (T& e : vec) is >> e;

  return is;

}



#define all(_) begin(_), end(_)

#define rall(_) rbegin(_), rend(_)



#ifdef LOCAL

#define debug(...) cerr << "[" << #__VA_ARGS__ << "]: ", debug_out(__VA_ARGS__)

#else

#define debug(...)

#endif



void debug_out() { std::cerr << '\n'; }



template <class Head, class... Tail>

void debug_out(Head&& head, Tail&&... tail) {

  std::cerr << head;

  if (sizeof...(Tail) != 0) std::cerr << ", ";

  debug_out(std::forward<Tail>(tail)...);

}



#pragma endregion kyomukyomupurin



template <class _Tp>

class Dijkstra {

  template <class _Up>

  using binary_heap = std::priority_queue<_Up, std::vector<_Up>, std::greater<_Up>>;



 public:

  static constexpr _Tp kInfinity = std::numeric_limits<_Tp>::max() / static_cast<_Tp>(2);



  Dijkstra(int node_size) : node_size_(node_size), graph_(node_size) {}



  void add(int from, int to, _Tp cost) {

    assert(0 <= from && from < node_size_ && 0 <= to && to < node_size_);

    graph_[from].emplace_back((edge){to, cost});

  }



  void solve(int source) {

    assert(0 <= source && source < node_size_);

    distance_.assign(node_size_, kInfinity);

    binary_heap<std::pair<_Tp, int>> pq;

    distance_[source] = 0;

    pq.emplace(0, source);



    while (!pq.empty()) {

      std::pair<_Tp, int> cur = pq.top();

      pq.pop();

      int v = cur.second;

      if (distance_[v] < cur.first) continue;

      for (const edge& e : graph_[v]) {

        if (distance_[e.to] > distance_[v] + e.cost) {

          distance_[e.to] = distance_[v] + e.cost;

          pq.emplace(distance_[e.to], e.to);

        }

      }

    }

  }



  _Tp operator[](int to) const {

    assert(0 <= to && to < node_size_);

    return distance_[to];

  }



 private:

  struct edge {

    int to;

    _Tp cost;

  };

  int node_size_;

  std::vector<_Tp> distance_;

  std::vector<std::vector<edge>> graph_;

};



int main() {

  ios_base::sync_with_stdio(false);

  cin.tie(nullptr);



  int n, m; cin >> n >> m;

  Dijkstra<int> d(n);



  for (int i = 0; i < m; ++i) {

    int a, b; cin >> a >> b;

    --a; --b;

    d.add(a, b, 1);

    d.add(b, a, 1);

  }



  d.solve(0);



  cout << (d[n - 1] == 2 ? "POSSIBLE" : "IMPOSSIBLE") << endl;



  return 0;

}

// Fastest known solution for this problem: