Example

Input

3 3 1 2 4
1 2
2 3
3 1


Output

IMPOSSIBLE
#include "bits/stdc++.h"
#include<unordered_map>
#include<unordered_set>
#pragma warning(disable:4996)
using namespace std;
using ld = long double;
template<class T>
using Table = vector<vector<T>>;
const ld eps=1e-9;

//// < "D:\D_Download\Visual Studio 2015\Projects\programing_contest_c++\Debug\a.txt"


struct Realedge {
  vector<set<int>>tos;
};

int main() {
  
  int N, M, A, B, C; cin >> N >> M >> A >> B >> C;
  vector<int>memo(N, -1);
  memo[N - 1] = 0;
  vector<int>nums = { A,B,C };
  vector<vector<int>>edges(N);
  for (int i = 0; i < M; ++i) {
    int u, v; cin >> u >> v;
    u--; v--;
    edges[u].push_back(v);
  }
  vector<Realedge>res(N);
  for (int i = 0; i < 3; ++i) {
    for (int start = 0; start < N; ++start) {
      const int time = nums[i];
      set<int>froms;
      froms.emplace(start);
      for (int t = 0; t < time; ++t) {
        set<int>tos;
        for (auto f : froms) {
          for (auto e : edges[f]) {
            tos.emplace(e);
          }
        }
        froms = tos;
      }
      res[start].tos.push_back(froms);
    }
  }
  queue<int> que;
  que.push(N - 1);
  int ans = -1;
  while (!que.empty()) {
    if (que.front() == 0) {
      ans = memo[0];
      break;
    }
    que.pop();
    for (int i = 0; i < res.size(); ++i) {
      int maxtime = -1;
      for (int j = 0; j < 3; ++j) {
        set<int>aset(res[i].tos[j]);
        int mintime = 1e9;
        for (auto n : aset) {
          if (memo[n]!=-1&&memo[n] < mintime) {
            mintime = memo[n];
          }
        }
        maxtime = max(maxtime, mintime+1);
      }
      if (maxtime >= 1e9) {

      }
      else {
        if (memo[i]==-1||maxtime < memo[i]) {

          memo[i] = maxtime;
          que.push(i);
        }
      }
    }
  }
  if (ans == -1) {

    cout << "IMPOSSIBLE" << endl;
  }
  else {
    cout << ans << endl;
  }
  return 0;
}