Example

Input

3 3 1 2 4
1 2
2 3
3 1


Output

IMPOSSIBLE
#include<iostream>
#include<vector>
#include<cmath>
#include<iomanip>
#include<algorithm>
using namespace std;
// Brute Force Attack!
int main(int argc, char *argv[])
{
  int n, m, a, b ,c;
  cin >> n >> m >> a >> b >> c;
  vector<int> abc = {a, b, c};
  sort(abc.begin(), abc.end());
  vector<vector<bool>> step(n, vector<bool>(n, false));
  for(int i = 0; i < m; i++) {
    int u, v;
    cin >> u >> v;
    step[u-1][v-1] = true;
  }
  a = abc[0];
  b = abc[1];
  c = abc[2];
  vector<vector<bool>> arch(n,vector<bool>(n));
  vector<vector<bool>> brch(n,vector<bool>(n));
  vector<vector<bool>> crch(n,vector<bool>(n));
  for(int i = 0; i < n; i++) {
    for(int j = 0; j < n; j++) {
      arch[i][j] = i == j;
      brch[i][j] = i == j;
      crch[i][j] = i == j;
    }
  }
  auto mul = [](int n, vector<vector<bool>> &z, vector<vector<bool>> &y) {
    bool t[n][n];
    for(int i = 0; i < n; i++) {
      for(int j = 0; j < n; j++) {
        bool c = false;
        for(int k = 0; k < n; k++) {
          c = c || (z[i][k] && y[k][j]);
        }
        t[i][j] = c;
      }
    }
    for(int i = 0; i < n; i++) {
      for(int j = 0; j < n; j++) {
        z[i][j] = t[i][j];
      }
    }
  };
  // c is the biggest
  while(c != 0) {
    if(a & 1) { // arch *= step
      mul(n, arch, step);
    }
    if(b & 1) { // brch *= step
      mul(n, brch, step);
    }
    if(c & 1) { // crch *= step
      mul(n, crch, step);
    }
    mul(n, step, step);
    a >>= 1;
    b >>= 1;
    c >>= 1;
  }
  
  // arch: a-step reachable
  // brch: b-step reachable
  // crch: c-step reachable

  vector<int> ok(n, -1);
  ok[n-1] = 0; // the goal is ok

  auto reachable = [&ok,&n](const vector<vector<bool>> &rch, int i){
    for(int j = 0; j < n; j++) {
      if(rch[i][j] && (ok[j] >= 0)) return true;
    }
    return false;
  };
  
  auto search = [&]() {
    bool done = false;
    int ss = 0;
    while(!done) {
      ss++;
      done = true;
      vector<int> ok2(n, -1);
      for(int i = 0; i < n; i++) {
        // if i has a-reachable ok, b-reachable ok, and c-reachable ok vertives,
        // then i is also ok
        if(ok[i] < 0 && reachable(arch, i) && reachable(brch, i) && reachable(crch, i)) {
          ok2[i] = ss;
          if(i == 0) {
            ok[i] = ok2[i];
            return;
          }
          done = false;
        }
      }
      for(int i = 0; i < n; i++) {
        ok[i] = ok2[i] >= 0 ? ok2[i] : ok[i];
      }
    }
  };
  search();
  if(ok[0] < 0) cout << "IMPOSSIBLE" << endl;
  else cout << ok[0] << endl;
  return 0;
}

