Problem:
Problem C
Sibling Rivalry
You are playing a game with your elder brother.
First, a number of circles and arrows connecting some pairs of the circles are drawn on the ground. Two of the circles are marked as the
start circle
and the
goal circle
.
At the start of the game, you are on the start circle. In each
turn
of the game, your brother tells you a number, and you have to take that number of
steps
. At each step, you choose one of the arrows outgoing from the circle you are on, and move to the circle the arrow is heading to. You can visit the same circle or use the same arrow any number of times.
Your aim is to stop on the goal circle after the fewest possible turns, while your brother's aim is to prevent it as long as possible. Note that, in each single turn, you
must
take the exact number of steps your brother tells you. Even when you visit the goal circle during a turn, you have to leave it if more steps are to be taken.
If you reach a circle with no outgoing arrows before completing all the steps, then you lose the game. You also have to note that, your brother may be able to repeat turns forever, not allowing you to stop after any of them.
Your brother, mean but not too selfish, thought that being allowed to choose arbitrary numbers is not fair. So, he decided to declare three numbers at the start of the game and to use only those numbers.
Your task now is, given the configuration of circles and arrows, and the three numbers declared, to compute the smallest possible number of turns within which you can always finish the game, no matter how your brother chooses the numbers.
Input
The input consists of a single test case, formatted as follows.
$n$ $m$ $a$ $b$ $c$
$u_1$ $v_1$
...
$u_m$ $v_m$
All numbers in a test case are integers. $n$ is the number of circles $(2 \leq n \leq 50)$. Circles are numbered 1 through $n$. The start and goal circles are numbered 1 and $n$, respectively. $m$ is the number of arrows $(0 \leq m \leq n(n - 1))$. $a$, $b$, and $c$ are the three numbers your brother declared $(1 \leq a, b, c \leq 100)$. The pair, $u_i$ and $v_i$, means that there is an arrow from the circle $u_i$ to the circle $v_i$. It is ensured that $u_i \ne v_i$ for all $i$, and $u_i \ne u_j$ or $v_i \ne v_j$ if $i \ne j$.
Output
Print the smallest possible number of turns within which you can always finish the game. Print
IMPOSSIBLE
if your brother can prevent you from reaching the goal, by either making you repeat the turns forever or leading you to a circle without outgoing arrows.
Sample Input 1
3 3 1 2 4
1 2
2 3
3 1
Sample Output 1
IMPOSSIBLE
Sample Input 2
8 12 1 2 3
1 2
2 3
1 4
2 4
3 4
1 5
5 8
4 6
6 7
4 8
6 8
7 8
Sample Output 2
2
For Sample Input 1, your brother may choose 1 first, then 2, and repeat these forever. Then you can never finish.
For Sample Input 2 (Figure C.1), if your brother chooses 2 or 3, you can finish with a single turn. If he chooses 1, you will have three options.
Move to the circle 5. This is a bad idea: Your brother may
...(truncated)

Submitted solutions:

code_snippet: #include <bits/stdc++.h>
using namespace std;
#define all(a) (a).begin(), (a).end()
#define rep(i, n) for (int i = 0; i < (int)(n); i++)
#define rrep(i, n) for (int i = (int)(n); i >= 0; i--)
#define range(i, l, r) for (int i = (int)(l); i < (int)(r); i++)
using ll = long long;

template <typename T>
ostream& operator<<(ostream& os, const vector<T>& v) {
    os << "[";
    for (int i = 0; i < v.size(); i++) {
        os << v[i] << (i == (v.size() - 1) ? "" : ", ");
    }
    os << "]";
    return os;
}

template <typename T1, typename T2>
ostream& operator<<(ostream& os, const pair<T1, T2> p) {
    os << "{" << p.first << ", " << p.second << "}";
    return os;
}
template <typename T>
ostream& operator<<(ostream& os, const set<T> s) {
    if (s.empty()) {
        os << "{}";
        return os;
    }
    os << "{";
    auto it = s.begin();
    while (it != s.end()) {
        cout << *it << (++it == s.end() ? "}" : ", ");
    }
    return os;
}

int n, m, a, b, c;
vector<vector<int>> edges;
vector<int> t, cnt;

void check(int x) {
    vector<bool> dp(n, false), nxt(n, false);
    rep(i, n) if (t[i] != -1) dp[i] = true;
    rep(_, x) {
        rep(i, n) nxt[i] = false;
        rep(i, n) if (dp[i]) {
            for (auto j : edges[i]) nxt[j] = true;
        }
        swap(dp, nxt);
    }
    rep(i, n) if (dp[i]) cnt[i]++;
}

int main() {
    cin >> n >> m >> a >> b >> c;
    edges.resize(n);
    rep(i, m) {
        int u, v;
        cin >> u >> v;
        u--;
        v--;
        edges[v].push_back(u);
    }

    t.resize(n);
    cnt.resize(n);
    rep(i, n) t[i] = -1;
    t[n - 1] = 0;
    rep(i, n) {
        rep(j, n) cnt[j] = 0;
        for (auto x : {a, b, c}) {
            check(x);
        }
        rep(j, n) if (cnt[j] == 3 && t[j] == -1) t[j] = i + 1;
    }

    if (t[0] == -1) {
        cout << "IMPOSSIBLE\n";
    } else {
        cout << t[0] << endl;
    }
}
accuracy: 1
time_ms: 10
memory_kb: 3584
final_rank: 6

code_snippet: #include <iostream>
#include<math.h>
#include<vector>
# include<string.h>
#include <queue>
#include <cstdio>
using namespace std;
const int INF=10000;
const int maxn=55;
bool go[maxn][maxn][102];
int n,m,a,b,c;
int d[maxn];
int inq[3];
int step[3];

int main()
{
    //freopen("A.in","r",stdin);
    int x,y;
	scanf("%d%d%d%d%d",&n,&m,&step[0],&step[1],&step[2]);

	memset(go,0,sizeof(go));
	for(int i=1;i<=m;i++){
        scanf("%d%d",&x,&y);
        go[x][y][1]=1;
	}

	for(int k=1;k<=99;k++){
        for(int i=1;i<=n;i++){
            for(int j=1;j<=n;j++){
                if(go[i][j][k]){
                    for(int t=1;t<=n;t++){
                        if(go[j][t][1]){
                            go[i][t][k+1]=1;
                        }
                    }
                }
            }
        }
	}

    memset(d,-1,sizeof(d));
	d[n]=0;// mq.push_back(n); inq[n] = true;
	while(1){
        Loop:
        for(int i=1;i<=n;i++){
            if(d[i]!=-1) continue;

            inq[0]=inq[1]=inq[2]=INF;
            for(int j=1;j<=n;j++){
                if(d[j]==-1) continue;
                for(int k=0;k<3;k++)
                    if(go[i][j][step[k]]) inq[k]=min(inq[k],d[j]+1);
            }
            if((inq[0]!=INF)&&(inq[1]!=INF)&&(inq[2]!=INF)) {
                d[i]=max(inq[0],max(inq[1],inq[2]));goto Loop;
            }
        }
        break;
	}

	if(d[1]==-1){
        puts("IMPOSSIBLE");
	}
	else{
        printf("%d\n",d[1]);
	}


	return 0;
}
accuracy: 0.17567567567567569
time_ms: 10
memory_kb: 3868
final_rank: 19

code_snippet: #include <bits/stdc++.h>

using namespace std;

#define rep(i, a, b) for (int i = (int)(a); i < (int)(b); i++)
#define rrep(i, a, b) for (int i = (int)(b)-1; i >= (int)(a); i--)
#define ALL(v) (v).begin(), (v).end()
#define UNIQUE(v) sort(ALL(v)), (v).erase(unique(ALL(v)), (v).end())
#define SZ(v) (int)v.size()
#define MIN(v) *min_element(ALL(v))
#define MAX(v) *max_element(ALL(v))
#define LB(v, x) int(lower_bound(ALL(v), (x)) - (v).begin())
#define UB(v, x) int(upper_bound(ALL(v), (x)) - (v).begin())

using uint = unsigned int;
using ll = long long int;
using ull = unsigned long long;
using i128 = __int128_t;
using u128 = __uint128_t;
const int inf = 0x3fffffff;
const ll INF = 0x1fffffffffffffff;

template <typename T> inline bool chmax(T &a, T b) {
    if (a < b) {
        a = b;
        return 1;
    }
    return 0;
}
template <typename T> inline bool chmin(T &a, T b) {
    if (a > b) {
        a = b;
        return 1;
    }
    return 0;
}
template <typename T, typename U> T ceil(T x, U y) {
    assert(y != 0);
    if (y < 0)
        x = -x, y = -y;
    return (x > 0 ? (x + y - 1) / y : x / y);
}
template <typename T, typename U> T floor(T x, U y) {
    assert(y != 0);
    if (y < 0)
        x = -x, y = -y;
    return (x > 0 ? x / y : (x - y + 1) / y);
}
template <typename T> int popcnt(T x) {
    return __builtin_popcountll(x);
}
template <typename T> int topbit(T x) {
    return (x == 0 ? -1 : 63 - __builtin_clzll(x));
}
template <typename T> int lowbit(T x) {
    return (x == 0 ? -1 : __builtin_ctzll(x));
}

template <class T, class U>
ostream &operator<<(ostream &os, const pair<T, U> &p) {
    os << "P(" << p.first << ", " << p.second << ")";
    return os;
}
template <typename T> ostream &operator<<(ostream &os, const vector<T> &vec) {
    os << "{";
    for (int i = 0; i < vec.size(); i++) {
        os << vec[i] << (i + 1 == vec.size() ? "" : ", ");
    }
    os << "}";
    return os;
}
template <typename T, typename U>
ostream &operator<<(ostream &os, const map<T, U> &map_var) {
    os << "{";
    for (auto itr = map_var.begin(); itr != map_var.end(); itr++) {
        os << "(" << itr->first << ", " << itr->second << ")";
        itr++;
        if (itr != map_var.end())
            os << ", ";
        itr--;
    }
    os << "}";
    return os;
}
template <typename T> ostream &operator<<(ostream &os, const set<T> &set_var) {
    os << "{";
    for (auto itr = set_var.begin(); itr != set_var.end(); itr++) {
        os << *itr;
        ++itr;
        if (itr != set_var.end())
            os << ", ";
        itr--;
    }
    os << "}";
    return os;
}
#ifdef LOCAL
#define show(...) _show(0, #__VA_ARGS__, __VA_ARGS__)
#else
#define show(...) true
#endif
template <typename T> void _show(int i, T name) {
    cerr << '\n';
}
template <typename T1, typename T2, typename... T3>
void _show(int i, const T1 &a, const T2 &b, const T3 &...c) {
    for (; a[i] != ',' && a[i] != '\0'; i++)
        cerr << a[i];
    cerr << ":" << b << " ";
    _show(i + 1, a, c...);
}

/**
 * @brief template
 */

int main() {
    int N, M, A[3];
    cin >> N >> M >> A[0] >> A[1] >> A[2];
    vector<vector<bool>> G(N,vector<bool>(N,false));
    rep(i,0,M) {
        int U, V;
        cin >> U >> V;
        U--, V--;
        G[U][V] = 1;
    }
    vector<vector<vector<bool>>> X(3,vector<vector<bool>>(N,vector<bool>(N,false)));
    rep(i,0,3) {
        rep(j,0,N) X[i][j][j] = true;
        rep(j,0,A[i]) {
            vector<vector<bool>> Next(N,vector<bool>(N,false));
            rep(k,0,N) {
                rep(l,0,N) {
                    rep(m,0,N) {
                        if (X[i][k][l] && G[l][m]) Next[k][m] = true;
                    }
                }
            }
            rep(k,0,N) {
                rep(l,0,N) {
                    X[i][k][l] = Next[k][l];
                }
            }
        }
    }
    vector<int> ANS(N,inf);
    vector<int> CanGoal(N,0);
    queue<int> Q;
    ANS[N-1] = 0, CanGoal[N-1] = 7, Q.push(N-1);
    while(!Q.empty()) {
        int P = Q.front();
        Q.pop();
        rep(i,0,3) {
            rep(j,0,N) {
                if (X[i][j][P]) {
                    CanGoal[j] |= (1<<i);
                    if (CanGoal[j] == 7 && ANS[j] == inf) {
                        int MAX = 0;
                        rep(k,0,3) {
                            int MIN = inf;
                            rep(l,0,N) {
                                if (X[k][j][l] && ANS[l] < inf) {
                                    chmin(MIN,ANS[l]);
                                }
                            }
                            chmax(MAX,MIN);
                        }
                        ANS[j] = MAX+1;
                        Q.push(j);
                    }
                }
            }
        }
    }
    if (ANS[0] == inf) cout << "IMPOSSIBLE" << endl;
    else cout << ANS[0] << endl;
}
accuracy: 1
time_ms: 30
memory_kb: 3464
final_rank: 3

code_snippet: #include <iostream>
using namespace std;
int N, M;
int A[3];
int G[51][51];
bool used[51];
bool dp[101][51][51];
int main() {
  cin >> N >> M;
  for (int i = 0; i < 3; i++)
    cin >> A[i];
  for (int i = 0; i < N; i++)
    for (int j = 0; j < N; j++)
      G[i][j] = -1;
  for (int i = 0; i < M; i++) {
    int f, t;
    cin >> f >> t;
    f--;
    t--;
    G[f][t] = true;
  }
  for (int i = 0; i < N; i++)
    dp[0][i][i] = true;
  for (int i = 1; i < 101; i++) {
    for (int j = 0; j < N; j++) {
      for (int k = 0; k < N; k++) {
        if (dp[i - 1][j][k]) {
          for (int to = 0; to < N; to++) {
            if (G[k][to] != -1) {
              dp[i][j][to] = true;
            }
          }
        }
      }
    }
  }
  used[N - 1] = true;
  for (int ite = 1;; ite++) {
    bool ok = false;
    bool new_used[51] = {false};
    for (int i = 0; i < N; i++) {
      if (used[i])
        continue;
      int cnt = 0;
      for (int j = 0; j < 3; j++) {
        int a = A[j];
        for (int k = 0; k < N; k++) {
          if (dp[a][i][k] && used[k]) {
            cnt++;
            break;
          }
        }
      }
      if (cnt == 3) {
        ok = true;
        new_used[i] = true;
      }
    }
    if (ok) {
      for (int i = 0; i < N; i++) {
        if (new_used[i]) {
          used[i] = true;
        }
      }
      if (used[0]) {
        cout << ite << endl;
        return 0;
      }
    } else {
      break;
    }
  }
  cout << "IMPOSSIBLE" << endl;
  return 0;
}
accuracy: 1
time_ms: 10
memory_kb: 3692
final_rank: 8

code_snippet: #include <bits/stdc++.h>
using namespace std;

int N, M;
int A[3];
vector<int> G[51];
bitset<51> used;
bitset<101*51*51> dp;

int main() {
  scanf("%d%d", &N, &M);
  for (int i = 0; i < 3; i++)
    scanf("%d", &A[i]);
  for (int i = 0; i < M; i++) {
    int f, t;
    scanf("%d%d", &f, &t);
    f--;
    t--;
    G[f].push_back(t);
  }
  for (int i = 0; i < N; i++)
    dp[i*N + i] = true;
  for (int i = 1; i < 101; i++) {
    for (int j = 0; j < N; j++) {
      for (int k = 0; k < N; k++) {
        if (dp[(i - 1)*N*N + j*N + k]) {
          for (int to : G[k]) {
            dp[i*N*N + j*N + to] = true;
          }
        }
      }
    }
  }
  used[N - 1] = true;
  for (int ite = 1;; ite++) {
    vector<int> idx;
    for (int i = 0; i < N; i++) {
      if (used[i])
        continue;
      int cnt = 0;
      for (int j = 0; j < 3; j++) {
        int a = A[j];
        for (int k = 0; k < N; k++) {
          if (dp[a*N*N + i*N + k] && used[k]) {
            cnt++;
            break;
          }
        }
      }
      if (cnt == 3) {
        idx.push_back(i);
      }
    }
    if (!idx.empty()) {
      for (int i : idx) {
        used[i] = true;
      }
      if (used[0]) {
        printf("%d\n", ite);
        return 0;
      }
    } else {
      break;
    }
  }
  printf("IMPOSSIBLE\n");
  return 0;
}
accuracy: 1
time_ms: 10
memory_kb: 3596
final_rank: 7

code_snippet: #include <iostream>
#include <vector>
#include <bitset>
using namespace std;

const int MAXN = 51;
const int MAXM = 101;
int N, M;
int A[3];
vector<int> G[MAXN];
bitset<MAXN> used = 0;
bitset<MAXM> dp[MAXM][MAXN];

int main() {
    cin >> N >> M;
    for (int i = 0; i < 3; i++)
        cin >> A[i];
    for (int i = 0; i < M; i++) {
        int f, t;
        cin >> f >> t;
        f--; t--;
        G[f].push_back(t);
    }
    for (int i = 0; i < N; i++)
        dp[0][i][i] = 1;
    for (int i = 1; i < MAXM; i++) {
        for (int j = 0; j < N; j++) {
            for (int k = 0; k < N; k++) {
                if (dp[i - 1][j][k]) {
                    for (int to : G[k]) {
                        dp[i][j][to] = 1;
                    }
                }
            }
        }
    }
    used[N - 1] = 1;
    for (int ite = 1;; ite++) {
        bool ok = false;
        vector<int> idx;
        idx.clear();
        for (int i = 0; i < N; i++) {
            if (used[i])
                continue;
            int cnt = 0;
            for (int j = 0; j < 3; j++) {
                int a = A[j];
                for (int k = 0; k < N; k++) {
                    if (dp[a][i][k] && used[k]) {
                        cnt++;
                        break;
                    }
                }
                if (cnt == 3) {
                    ok = true;
                    idx.push_back(i);
                    break;
                }
            }
        }
        if (ok) {
            for (int i : idx) {
                used[i] = 1;
            }
            if (used[0]) {
                cout << ite << endl;
                return 0;
            }
        } else {
            break;
        }
    }
    cout << "IMPOSSIBLE" << endl;
    return 0;
}
accuracy: 1
time_ms: 10
memory_kb: 3524
final_rank: 4

code_snippet: #include <bits/stdc++.h>
// #include <atcoder/modint>
#define rng(a) a.begin(),a.end()
#define rrng(a) a.rbegin(),a.rend()
#define INF 2000000000000000000
#define ll long long
#define ull unsigned long long
#define ld long double
#define pll pair<ll, ll>
using namespace std;
template<class T>bool chmax(T &a, const T &b) { if (a<b) { a=b; return 1; } return 0; }
template<class T>bool chmin(T &a, const T &b) { if (b<a) { a=b; return 1; } return 0; }
const double PI = 3.141592653589793;

void erase_continuous(vector<ll> &A) {
  sort(rng(A));
  A.erase(unique(rng(A)), A.end());
}

int main() {
  ios::sync_with_stdio(false);
  cin.tie(nullptr);
  ll N, M, A, B, C;
  cin >> N >> M >> A >> B >> C;
  vector<vector<ll>> connection(N);
  vector<vector<ll>> rev(N);
  for (int i = 0; i < M; i++) {
    ll u, v;
    cin >> u >> v;
    u -= 1, v -= 1;
    connection.at(u).push_back(v);
    rev.at(v).push_back(u);
  }
  vector<bool> won(N, false);
  won.at(N - 1) = true;
  for (int i = 0; i < 110; i++) {
    // for (int j = 0; j < N; j++) {
    //   if (won.at(j)) {
    //     cout << j + 1 << ' ';
    //   }
    // }
    // cout << endl;
    vector<set<ll>> st(N);
    vector<ll> now;
    for (int j = 0; j < N; j++) {
      if (won.at(j)) {
        st.at(j).insert(0);
        now.push_back(j);
      }
    }
    for (int temp = 1; temp < 110; temp++) {
      vector<ll> nexts;
      for (int j = 0; j < now.size(); j++) {
        for (int k = 0; k < rev.at(now.at(j)).size(); k++) {
          ll next = rev.at(now.at(j)).at(k);
          st.at(next).insert(temp);
          nexts.push_back(next);
        }
      }
      erase_continuous(nexts);
      now = nexts;
    }
    for (int j = 0; j < N; j++) {
      bool ok = true;
      if (st.at(j).find(A) == st.at(j).end()) {
        ok = false;
      }
      if (st.at(j).find(B) == st.at(j).end()) {
        ok = false;
      }
      if (st.at(j).find(C) == st.at(j).end()) {
        ok = false;
      }
      if (ok) {
        won.at(j) = true;
        if (j == 0) {
          cout << i + 1 << endl;
          return 0;
        }
      }
    }
  }
  cout << "IMPOSSIBLE" << endl;
}
accuracy: 1
time_ms: 90
memory_kb: 3832
final_rank: 12

code_snippet: #include<bits/stdc++.h>

using namespace std;

using ll=long long;
using ld=long double;

int main(){
    int n,m,a,b,c;cin>>n>>m>>a>>b>>c;
    vector g(vector(n+1,vector<vector<int>>(101,vector<int>())));
    for(int i=0;i<m;i++){
        int u,v;
        cin>>u>>v;
        u--;v--;
        g[v][1].emplace_back(u);
    }
    for(int cnt=2;cnt<=100;cnt++){
        for(int at=0;at<n;at++){
            vector<int>cand;
            vector<int>used(n);
            for(auto to:g[at][cnt-1]){
                for(auto v:g[to][1]){
                    if(used[v])continue;
                    used[v]=1;
                    cand.emplace_back(v);
                }
            }
            g[at][cnt]=cand;
        }
    }
    const int INF=1001001001;
    vector<array<int,3>>x(n,{INF,INF,INF});
    x[n-1]={0,0,0};
    vector<int>ans(n,INF);
    ans[n-1]=0;
    queue<int>q;
    q.emplace(n-1);
    vector<int>K={a,b,c};
    auto add=[&](int at){
        int ret=0;
        for(auto z:x[at])ret=max(ret,z);
        if(ret==INF)return;
        if(ans[at]>ret){
            ans[at]=ret;
            q.emplace(at);
        }
    };
    while(q.size()){
        auto at=q.front();q.pop();
        for(int k=0;k<3;k++){
            for(auto to:g[at][K[k]]){
                x[to][k]=min(x[to][k],ans[at]+1);
                add(to);
            }
        }
    }
    if(ans[0]==INF){
        puts("IMPOSSIBLE");
    }
    else{
        cout<<ans[0]<<endl;
    }
}
accuracy: 1
time_ms: 10
memory_kb: 4568
final_rank: 14

code_snippet: #include<bits/stdc++.h>
#define rep(i,a,...) for(int i = (a)*(strlen(#__VA_ARGS__)!=0);i<(int)(strlen(#__VA_ARGS__)?__VA_ARGS__:(a));++i)
#define per(i,a,...) for(int i = (strlen(#__VA_ARGS__)?__VA_ARGS__:(a))-1;i>=(int)(strlen(#__VA_ARGS__)?(a):0);--i)
#define foreach(i, n) for(auto &i:(n))
#define all(x) (x).begin(), (x).end()
#define bit(x) (1ll << (x))
#define lambda(RES_TYPE, ...) (function<RES_TYPE(__VA_ARGS__)>)[&](__VA_ARGS__) -> RES_TYPE
#define method(FUNC_NAME, RES_TYPE, ...) function<RES_TYPE(__VA_ARGS__)> FUNC_NAME = lambda(RES_TYPE, __VA_ARGS__)
using namespace std;
using ll = long long;
using pii = pair<int,int>;
using pll = pair<ll,ll>;
//const ll MOD = (ll)1e9+7;
const ll MOD = 998244353;
const int INF = (ll)1e9+7;
const ll INFLL = (ll)1e18;
template<class t>
using vvector = vector<vector<t>>;
template<class t>
using vvvector = vector<vector<vector<t>>>;
template<class t>
using priority_queuer = priority_queue<t, vector<t>, greater<t>>;
template<class t, class u> bool chmax(t &a, u b){if(a<b){a=b;return true;}return false;}
template<class t, class u> bool chmin(t &a, u b){if(a>b){a=b;return true;}return false;}
#ifdef DEBUG
#define debug(x) cout<<"LINE "<<__LINE__<<": "<<#x<<" = "<<x<<endl;
#else
#define debug(x) (void)0
#endif

namespace templates{
    ll modpow(ll x, ll b,ll mod=MOD){
        ll res = 1;
        while(b){
            if(b&1)res = res * x % mod;
            x = x * x % mod;
            b>>=1;
        }
        return res;
    }

    ll modinv(ll x){
        return modpow(x, MOD-2);
    }

    bool was_output = false;

    void print();
    template <class t> void print(const vector<t> &);
    template <class t, class u> void print(const pair<t, u> &);
    template <class t> void print(const t&);
    template <class Head, class... Tail> void print(const Head&, const Tail&...);

    template <class t> void println(const vector<vector<t>>&);
    template <class t> void println(const vector<t>&);
    template <class t> void println(const t&);
    template <class Head, class... Tail> void println(const Head&, const Tail&...);
    void println();
    void newline();

    void print(){
        return;
    }

    template <class t>
    void print(const vector<t>&x){
        for(const t&i:x)print(i);
    }
    template <class t, class u>
    void print(const pair<t,u>&p){
        print(p.first);
        print(p.second);
    }
    template <class t>
    void print(const t&x){
        if(was_output)cout<<" ";
        cout<<x;
        was_output = true;
    }
    template <class Head, class... Tail>
    void print(const Head&head,const Tail&...tail){
        print(head);
        print(tail...);
    }

    template<class t>
    void println(const vector<vector<t>>&x){
        for(vector<t> i:x)println(i);
    }
    template<class t>
    void println(const vector<t>&x){
        for(const t&i:x)print(i);
        println();
    }
    template <class t>
    void println(const t&x){
        print(x);
        println();
    }
    void println(){
        if(was_output){
            cout << endl;
            was_output = false;
        }
    }
    template <class Head, class... Tail>
    void println(const Head&head,const Tail&...tail){
        print(head);
        println(tail...);
    }

    void newline(){
        was_output = true;
        println();
    }

    template<class t>
    istream& operator>>(istream&is, vector<t>&x){
        for(auto &i:x)is >> i;
        return is;
    }

    template<class t, class u>
    istream& operator>>(istream&is, pair<t, u>&x){
        is >> x.first >> x.second;
        return is;
    }

    template<class t>
    ostream& operator<<(ostream&os, vector<t> &v){
        os << "{";
        for(t &i:v){
            os << i << ", ";
        }
        os << "}";
        return os;
    }

    template<class t = long long>
    t in(){
        t res; cin >> res; return res;
    }

    template<class t>
    vector<t> sorted(vector<t> line,function<bool(t,t)> comp=[](t a,t b){return a<b;}){
        sort(line.begin(),line.end(),comp);
        return line;
    }

    template<class t>
    vector<t> reversed(vector<t> line){
        reverse(line.begin(),line.end());
        return line;
    }
    string reversed(string str){
        reverse(str.begin(),str.end());
        return str;
    }

    long long gcd(long long a,long long b){
        while(b){
            a %= b;
            swap(a,b);
        }
        return a;
    }

    long long lcm(long long a,long long b){
        return a / gcd(a,b) * b;
    }

    class output_initializer{
    public:
        output_initializer(){
            ios::sync_with_stdio(false);
            cin.tie(nullptr);
            cout << setprecision(20);
        }
    };output_initializer OUTPUT_INITIALIZER_INSTANCE = output_initializer();
}

using namespace templates;

string func(){
    int n = in();
    int m = in();
    vector<int> nums(3);
    foreach(i,nums)i=in();
    vvector<int> edges(n);
    rep(i,m){
        int a = in()-1;
        int b = in()-1;
        edges[a].emplace_back(b);
    }
    vvector<set<int>> move_to(n,vector<set<int>>(3));
    rep(p,n){
        rep(k,3){
            set<int> s{p};
            rep(_,nums[k]){
                set<int> next;
                foreach(i,s){
                    foreach(e,edges[i])next.emplace(e);
                }
                s = next;
            }
            move_to[p][k] = s;
        }
    }
    vvector<int> dp(n,vector<int>(n,-1));
    method(rec,int,int p,int t){
        if(p == n - 1)return t;
        if(t==n)return INF;
        int &it = dp[p][t];
        if(it >= 0)return it;
        it = 0;
        foreach(moves,move_to[p]){
            int mins = INF;
            foreach(move,moves){
                chmin(mins,rec(move,t+1));
            }
            chmax(it,mins);
        }
        return it;
    };
    int ans = rec(0,0);
    if(ans>=INF)return "IMPOSSIBLE";
    return to_string(ans);
}

int main(){
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    println(func());
    return 0;
}
accuracy: 1
time_ms: 120
memory_kb: 3908
final_rank: 13

code_snippet: #include <bits/stdc++.h>
using namespace std;

vector<vector<bool>> matmul(const vector<vector<bool>>& a, const vector<vector<bool>>& b) {
    assert(a[0].size() == b.size());
    size_t n = a.size(), m = b[0].size();
    vector<vector<bool>> c(n, vector<bool>(m, false));
    for (size_t i = 0; i < n; i++) {
        for (size_t j = 0; j < m; j++) {
            for (size_t k = 0; k < a[0].size(); k++) {
                if (a[i][k] & b[k][j]) {
                    c[i][j] = true;
                }
            }
        }
    }
    return c;
}

int main() {
    cin.tie(0);
    ios::sync_with_stdio(false);
    int n, m, a, b, c;
    cin >> n >> m >> a >> b >> c;
    vector<vector<bool>> G(n, vector<bool>(n, false));
    for (; m--;) {
        int u, v;
        cin >> u >> v;
        G[--v][--u] = true;
    }

    auto calc = [&](int s, int d) {
        vector<vector<bool>> mat(n, vector<bool>(n, false));
        mat[s][s] = true;
        for (int i = 0; i < d; i++) mat = matmul(mat, G);
        vector<bool> res(n);
        for (int i = 0; i < n; i++) res[i] = mat[s][i];
        return res;
    };
    vector<int> A = {a, b, c};
    vector<vector<int>> go(n, vector<int>(n, 0));

    for (int i = 0; i < n; i++) {
        for (int j = 0; j < 3; j++) {
            auto res = calc(i, A[j]);
            for (int k = 0; k < n; k++) go[i][k] |= res[k] << j;
        }
    }

    vector<int> ok(n, 0), dp(n);
    ok[n - 1] = 7;
    dp[n - 1] = 0;
    queue<int> que;
    que.emplace(n - 1);

    while (!que.empty()) {
        int v = que.front();
        que.pop();
        for (int u = 0; u < n; u++) {
            if (ok[u] == 7) continue;
            ok[u] |= go[v][u];
            dp[u] = dp[v] + 1;
            if (ok[u] == 7) que.emplace(u);
        }
    }

    if (ok[0] != 7)
        cout << "IMPOSSIBLE" << '\n';
    else
        cout << dp[0] << '\n';
    return 0;
}
accuracy: 1
time_ms: 1460
memory_kb: 3472
final_rank: 17

code_snippet: #define LOCAL
#include <bits/stdc++.h>
using namespace std;
#pragma region Macros
typedef long long ll;
typedef __int128_t i128;
typedef unsigned int uint;
typedef unsigned long long ull;
#define ALL(x) (x).begin(), (x).end()

template <typename T> istream& operator>>(istream& is, vector<T>& v) {
    for (T& x : v) is >> x;
    return is;
}
template <typename T> ostream& operator<<(ostream& os, const vector<T>& v) {
    for (int i = 0; i < (int)v.size(); i++) {
        os << v[i] << (i + 1 == (int)v.size() ? "" : " ");
    }
    return os;
}
template <typename T, typename U> ostream& operator<<(ostream& os, const pair<T, U>& p) {
    os << '(' << p.first << ',' << p.second << ')';
    return os;
}
template <typename T, typename U> ostream& operator<<(ostream& os, const map<T, U>& m) {
    os << '{';
    for (auto itr = m.begin(); itr != m.end();) {
        os << '(' << itr->first << ',' << itr->second << ')';
        if (++itr != m.end()) os << ',';
    }
    os << '}';
    return os;
}
template <typename T, typename U> ostream& operator<<(ostream& os, const unordered_map<T, U>& m) {
    os << '{';
    for (auto itr = m.begin(); itr != m.end();) {
        os << '(' << itr->first << ',' << itr->second << ')';
        if (++itr != m.end()) os << ',';
    }
    os << '}';
    return os;
}
template <typename T> ostream& operator<<(ostream& os, const set<T>& s) {
    os << '{';
    for (auto itr = s.begin(); itr != s.end();) {
        os << *itr;
        if (++itr != s.end()) os << ',';
    }
    os << '}';
    return os;
}
template <typename T> ostream& operator<<(ostream& os, const multiset<T>& s) {
    os << '{';
    for (auto itr = s.begin(); itr != s.end();) {
        os << *itr;
        if (++itr != s.end()) os << ',';
    }
    os << '}';
    return os;
}
template <typename T> ostream& operator<<(ostream& os, const unordered_set<T>& s) {
    os << '{';
    for (auto itr = s.begin(); itr != s.end();) {
        os << *itr;
        if (++itr != s.end()) os << ',';
    }
    os << '}';
    return os;
}
template <typename T> ostream& operator<<(ostream& os, const deque<T>& v) {
    for (int i = 0; i < (int)v.size(); i++) {
        os << v[i] << (i + 1 == (int)v.size() ? "" : " ");
    }
    return os;
}

template <int i, typename T> void print_tuple(ostream&, const T&) {}
template <int i, typename T, typename H, class... Args> void print_tuple(ostream& os, const T& t) {
    if (i) os << ',';
    os << get<i>(t);
    print_tuple<i + 1, T, Args...>(os, t);
}
template <typename... Args> ostream& operator<<(ostream& os, const tuple<Args...>& t) {
    os << '{';
    print_tuple<0, tuple<Args...>, Args...>(os, t);
    return os << '}';
}

void debug_out() { cerr << '\n'; }
template <class Head, class... Tail> void debug_out(Head&& head, Tail&&... tail) {
    cerr << head;
    if (sizeof...(Tail) > 0) cerr << ", ";
    debug_out(move(tail)...);
}
#ifdef LOCAL
#define debug(...)                                                                   \
    cerr << " ";                                                                     \
    cerr << #__VA_ARGS__ << " :[" << __LINE__ << ":" << __FUNCTION__ << "]" << '\n'; \
    cerr << " ";                                                                     \
    debug_out(__VA_ARGS__)
#else
#define debug(...) 42
#endif

template <typename T> T gcd(T x, T y) { return y != 0 ? gcd(y, x % y) : x; }
template <typename T> T lcm(T x, T y) { return x / gcd(x, y) * y; }

int topbit(signed t) { return t == 0 ? -1 : 31 - __builtin_clz(t); }
int topbit(long long t) { return t == 0 ? -1 : 63 - __builtin_clzll(t); }
int botbit(signed a) { return a == 0 ? 32 : __builtin_ctz(a); }
int botbit(long long a) { return a == 0 ? 64 : __builtin_ctzll(a); }
int popcount(signed t) { return __builtin_popcount(t); }
int popcount(long long t) { return __builtin_popcountll(t); }
bool ispow2(int i) { return i && (i & -i) == i; }

template <class T> T ceil(T x, T y) {
    assert(y >= 1);
    return (x > 0 ? (x + y - 1) / y : x / y);
}
template <class T> T floor(T x, T y) {
    assert(y >= 1);
    return (x > 0 ? x / y : (x - y + 1) / y);
}

template <class T1, class T2> inline bool chmin(T1& a, T2 b) {
    if (a > b) {
        a = b;
        return true;
    }
    return false;
}
template <class T1, class T2> inline bool chmax(T1& a, T2 b) {
    if (a < b) {
        a = b;
        return true;
    }
    return false;
}
#pragma endregion

const int INF = 1e9;
const long long IINF = 1e18;
const int dx[4] = {1, 0, -1, 0}, dy[4] = {0, 1, 0, -1};
const char dir[4] = {'D', 'R', 'U', 'L'};
const long long MOD = 1000000007;
// const long long MOD = 998244353;

vector<vector<bool>> matmul(const vector<vector<bool>>& a, const vector<vector<bool>>& b) {
    assert(a[0].size() == b.size());
    size_t n = a.size(), m = b[0].size();
    vector<vector<bool>> c(n, vector<bool>(m, false));
    for (size_t i = 0; i < n; i++) {
        for (size_t j = 0; j < m; j++) {
            for (size_t k = 0; k < a[0].size(); k++) {
                if (a[i][k] & b[k][j]) {
                    c[i][j] = true;
                }
            }
        }
    }
    return c;
}

int main() {
    cin.tie(0);
    ios::sync_with_stdio(false);
    int n, m, a, b, c;
    cin >> n >> m >> a >> b >> c;
    vector<vector<bool>> G(n, vector<bool>(n, false));
    for (; m--;) {
        int u, v;
        cin >> u >> v;
        G[--v][--u] = true;
    }

    auto calc = [&](int s, int d) {
        vector<vector<bool>> mat(n, vector<bool>(n, false));
        mat[s][s] = true;
        for (int i = 0; i < d; i++) mat = matmul(mat, G);
        vector<bool> res(n);
        for (int i = 0; i < n; i++) res[i] = mat[s][i];
        return res;
    };
    vector<int> A = {a, b, c};
    vector<vector<int>> go(n, vector<int>(n, 0));

    for (int i = 0; i < n; i++) {
        for (int j = 0; j < 3; j++) {
            auto res = calc(i, A[j]);
            for (int k = 0; k < n; k++) go[i][k] |= res[k] << j;
        }
    }

    vector<int> ok(n, 0), dp(n);
    ok[n - 1] = 7;
    dp[n - 1] = 0;
    queue<int> que;
    que.emplace(n - 1);

    while (!que.empty()) {
        int v = que.front();
        que.pop();
        for (int u = 0; u < n; u++) {
            if (ok[u] == 7) continue;
            ok[u] |= go[v][u];
            dp[u] = dp[v] + 1;
            if (ok[u] == 7) que.emplace(u);
        }
    }

    if (ok[0] != 7)
        cout << "IMPOSSIBLE" << '\n';
    else
        cout << dp[0] << '\n';
    return 0;
}
accuracy: 1
time_ms: 1460
memory_kb: 3480
final_rank: 18

code_snippet: #include <bits/stdc++.h>

using namespace std ;

const int inf = 1e9 ;
const int MAX = 50 + 5 ;

int arr[3] ;
int n , m ;

int dp[MAX][MAX][102] ;

vector< vector<int> >adj(MAX) ;

int solve(int node , int dep , int rem)
{
	if(dep >= n)
		return inf ;
	if(!rem && node == n)
		return dep ;
	int &ret = dp[node][dep][rem] ;
	if(ret != -1)
		return ret ;
	if(rem)
	{
		ret = inf ;
		for(auto &child : adj[node])
			ret = min(ret , solve(child , dep , rem-1)) ;
	}
	else
	{
		ret = 0 ;
		for(int i = 0 ; i < 3 ; ++i)
		{
			int Min = inf ;
			for(auto &child : adj[node])
				Min = min(Min , solve(child , dep+1 , arr[i]-1)) ;
			ret = max(ret , Min) ;
		}
	}
	return ret ;
}

int main()
{
	memset(dp , -1 , sizeof(dp)) ;
	ios_base::sync_with_stdio(0) ;
	cin.tie(0) ;
	cin>>n>>m>>arr[0]>>arr[1]>>arr[2] ;
	for(int i = 0 ; i < m ; ++i)
	{
		int x , y ;
		cin>>x>>y ;
		adj[x].push_back(y) ;
	}
	int ans = solve(1 , 0 , 0) ;
	if(ans == inf)
		cout<<"IMPOSSIBLE\n" ;
	else
		cout<<ans<<"\n" ;
	return 0 ;
}
accuracy: 1
time_ms: 10
memory_kb: 5040
final_rank: 15

code_snippet: #include <bits/stdc++.h>
using namespace std;

using ll = long long;
using PII = pair<ll, ll>;

#define FOR(i, a, n) for (ll i = (ll)a; i < (ll)n; ++i)
#define REP(i, n) FOR(i, 0, n)
#define ALL(x) x.begin(), x.end()
#define POPCOUNT(x) __builtin_popcount(x)
template <typename T> void chmin(T &a, const T &b) { a = min(a, b); }
template <typename T> void chmax(T &a, const T &b) { a = max(a, b); }

const ll INF = 1LL << 60;

struct FastIO {
    FastIO() {
        cin.tie(0);
        ios::sync_with_stdio(0);
    }
} fastiofastio;

bool can[101][50][50];
int ans[50];

int main() {
    int n, m, a, b, c;
    cin >> n >> m >> a >> b >> c;
    for (int i = 0; i < m; i++) {
        int u, v;
        cin >> u >> v;
        u--;
        v--;
        can[1][u][v] = 1;
    }
    for (int i = 1; i < 100; i++) {
        for (int j = 0; j < n; j++) {
            for (int k = 0; k < n; k++) {
                for (int l = 0; l < n; l++) {
                    if (can[i][j][l] && can[1][l][k])
                        can[i + 1][j][k] = 1;
                }
            }
        }
    }
    fill(ans, ans + n, 1 << 30);
    ans[n - 1] = 0;
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < n; j++) {
            int ma = 0;
            int mi = 1 << 30;
            for (int k = 0; k < n; k++) {
                if (can[a][j][k])
                    mi = min(mi, ans[k]);
            }
            ma = max(ma, mi);
            mi = 1 << 30;
            for (int k = 0; k < n; k++) {
                if (can[b][j][k])
                    mi = min(mi, ans[k]);
            }
            ma = max(ma, mi);
            mi = 1 << 30;
            for (int k = 0; k < n; k++) {
                if (can[c][j][k])
                    mi = min(mi, ans[k]);
            }
            ma = max(ma, mi);
            if (ma != 1 << 30)
                ans[j] = min(ans[j], ma + 1);
        }
    }
    if (ans[0] == 1 << 30)
        cout << "IMPOSSIBLE" << endl;
    else
        cout << ans[0] << endl;
}
accuracy: 1
time_ms: 10
memory_kb: 3748
final_rank: 10

code_snippet: #include<iostream>
#include<iomanip>
#include<cassert>
#include<math.h>
#include<complex>
#include<algorithm>
#include<utility>
#include<queue>
#include<string.h>
#include<string>
#include<set>
#include<map>
#include<unordered_map>
#include<functional>
#include<vector>
using namespace std;
typedef long long ll;
typedef pair<ll,ll> L_L;
const ll INF=2e18;
const ll MOD=1e9+7;

ll n,m;
ll cost[3];
int main(){
 	cin>>n>>m>>cost[0]>>cost[1]>>cost[2];
	vector<vector<ll>> edgeList(n+1);
	bool isReachable[51][51][101]={};
	for(ll i=0;i<m;i++){
		ll u,v;
		cin>>u>>v;
		edgeList[u].push_back(v);
	}
	for(ll start=1;start<=n;start++){
		isReachable[start][start][0]=true;
		queue<L_L> Q;
		Q.push(L_L(start,0));
		while(!Q.empty()){
			ll now=Q.front().first;
			ll nowC=Q.front().second;
			Q.pop();
			if(nowC==100)continue;
			for(auto e:edgeList[now]){
				if(isReachable[start][e][nowC+1])continue;
				isReachable[start][e][nowC+1]=true;
				Q.push(L_L(e,nowC+1));
			}
		}
	}
	vector<vector<ll>> d(n+1,vector<ll>(3,INF));
	queue<ll> Q;
	Q.push(n);
	for(ll i=0;i<3;i++) d[n][i]=0;
	while(!Q.empty()){
		ll now = Q.front();
		Q.pop();
		for(ll i=1;i<=n;i++){
			for(ll j=0;j<3;j++){
				if( isReachable[i][now][cost[j]] && d[i][j]==INF){
					d[i][j]=max({d[now][0],d[now][1],d[now][2]})+1;
					if(d[i][0]!=INF && d[i][1]!=INF && d[i][2]!=INF){
						Q.push(i);
					}
				}
			}
		}
	}
	ll ans=0;
	for(ll i=0;i<3;i++){
		ans=max(ans,d[1][i]);
	}
	if(ans==INF) cout<<"IMPOSSIBLE"<<endl;
	else cout<<ans<<endl;
    return 0;
}
accuracy: 1
time_ms: 10
memory_kb: 3444
final_rank: 2

code_snippet: #include<cstdio>
#include<vector>
#include<algorithm>
using namespace std;
constexpr int INF = 10000000;

int n, m, a, b, c, u, v, memo[50][101];
vector<int> e[50], re[50];
bool ok[50], tmp[50][101];

int main() {
  scanf("%d%d%d%d%d", &n, &m, &a, &b, &c);
  for (int i = 0; i < m; i++) {
    scanf("%d%d", &u, &v);
    u--; v--;
    e[u].push_back(v);
    re[v].push_back(u);
  }
  ok[n-1] = true;
  for (int i = 1; i <= 100; i++) {
    for (int j = 0; j < n; j++) {
      for (int k = 0; k <= 100; k++) tmp[j][k] = false;
      if (ok[j]) tmp[j][0] = true;
    }
    for (int j = 1; j <= 100; j++) {
      for (int k = 0; k < n; k++) {
        for (int l : re[k]) if (tmp[k][j-1]) tmp[l][j] = true;
      }
    }
    for (int j = 0; j < n; j++) if (tmp[j][a] && tmp[j][b] && tmp[j][c]) ok[j] = true;
    if (ok[0]) {
      printf("%d\n", i);
      return 0;
    }
  }
  printf("IMPOSSIBLE\n");
}

/*
int solve(int x);

int dfs(int x, int t) {
  if (t == 0) return solve(x);
  if (memo[x][t] != -1) return memo[x][t];
  memo[x][t] = INF;
  for (int i : e[x]) memo[x][t] = min(memo[x][t], dfs(i, t-1));
  return memo[x][t];
}

int solve(int x) {
  if (memo[x][0] == -1) {
    memo[x][0] = INF; // ?????????????
    memo[x][0] = max({dfs(x, a), dfs(x, b), dfs(x, c)}) + 1;
  }
  return memo[x][0];
}

int main() {
  scanf("%d%d%d%d%d", &n, &m, &a, &b, &c);
  for (int i = 0; i < m; i++) {
    scanf("%d%d", &u, &v);
    u--; v--;
    e[u].push_back(v);
  }
  for (int i = 0; i < n; i++) for (int j = 0; j <= 100; j++) memo[i][j] = -1;
  memo[n-1][0] = 0;
  int ans = solve(0);
  if (ans < INF) printf("%d\n", ans);
  else printf("IMPOSSIBLE\n");
}
*/
accuracy: 1
time_ms: 10
memory_kb: 2824
final_rank: 1

code_snippet: #include "iostream"
#include "climits"
#include "list"
#include "queue"
#include "stack"
#include "set"
#include "functional"
#include "algorithm"
#include "string"
#include "map"
#include "unordered_map"
#include "unordered_set"
#include "iomanip"
#include "cmath"
#include "random"
#include "bitset"
#include "cstdio"
#include "numeric"
#include "cassert"
#include "ctime"

using namespace std;

constexpr long long int MOD = 1000000007;
//constexpr int MOD = 1000000007;
//constexpr int MOD = 998244353;
//constexpr long long int MOD = 998244353;
constexpr double EPS = 1e-12;

//int N, M, K, T, H, W, L, R;
long long int N, M, K, T, H, W, L, R;


int main() {
	ios::sync_with_stdio(false);
	cin.tie(0);

	int a, b, c;
	cin >> N >> M >> a >> b >> c;
	vector<vector<int>>edge(N);
	for (int i = 0; i < M; i++) {
		cin >> L >> R;
		L--, R--;
		edge[L].push_back(R);
	}
	vector<vector<vector<int>>>dp(N, vector<vector<int>>(101, vector<int>(N)));
	for (int i = 0; i < N; i++)dp[i][0][i] = 1;
	for (int i = 0; i < N; i++) {
		for (int j = 0; j < 100; j++) {
			for (int k = 0; k < N; k++) {
				if (!dp[i][j][k])continue;
				for (auto l : edge[k]) {
					dp[i][j + 1][l] = 1;
				}
			}
		}
	}
	vector<int>dis(N, MOD);
	dis.back() = 0;
	for (int loop = 0; loop < N; loop++) {
		for (int i = 0; i < N; i++) {
			for (int j = 0; j < N; j++) {
				if (dis[j] == MOD)continue;
				for (int k = 0; k < N; k++) {
					if (dis[k] == MOD)continue;
					for (int l = 0; l < N; l++) {
						if (dis[l] == MOD)continue;
						if (dp[i][a][j] && dp[i][b][k] && dp[i][c][l])dis[i] = min(dis[i], max({ dis[j],dis[k],dis[l] }) + 1);
					}
				}
			}
		}
	}
	if (dis.front() == MOD) {
		cout << "IMPOSSIBLE\n";
		return 0;
	}
	cout << dis.front() << endl;
}
accuracy: 1
time_ms: 820
memory_kb: 4224
final_rank: 16

code_snippet: #include "iostream"
#include "climits"
#include "list"
#include "queue"
#include "stack"
#include "set"
#include "functional"
#include "algorithm"
#include "string"
#include "map"
#include "unordered_map"
#include "unordered_set"
#include "iomanip"
#include "cmath"
#include "random"
#include "bitset"
#include "cstdio"
#include "numeric"
#include "cassert"
#include "ctime"

using namespace std;

constexpr long long int MOD = 1000000007;
//constexpr int MOD = 1000000007;
//constexpr int MOD = 998244353;
//constexpr long long int MOD = 998244353;
constexpr double EPS = 1e-12;

//int N, M, K, T, H, W, L, R;
long long int N, M, K, T, H, W, L, R;


int main() {
	ios::sync_with_stdio(false);
	cin.tie(0);

	int a, b, c;
	cin >> N >> M >> a >> b >> c;
	vector<vector<int>>edge(N);
	for (int i = 0; i < M; i++) {
		cin >> L >> R;
		L--, R--;
		edge[L].push_back(R);
	}
	vector<vector<vector<int>>>dp(N, vector<vector<int>>(101, vector<int>(N)));
	for (int i = 0; i < N; i++)dp[i][0][i] = 1;
	for (int i = 0; i < N; i++) {
		for (int j = 0; j < 100; j++) {
			for (int k = 0; k < N; k++) {
				if (!dp[i][j][k])continue;
				for (auto l : edge[k]) {
					dp[i][j + 1][l] = 1;
				}
			}
		}
	}
	vector<int>dis(N, MOD);
	dis.back() = 0;
	for (int loop = 0; loop < N; loop++) {
		for (int i = 0; i < N; i++) {
			if (dis[i] != MOD)continue;
			for (int j = 0; j < N; j++) {
				if (dis[j] == MOD)continue;
				for (int k = 0; k < N; k++) {
					if (dis[k] == MOD)continue;
					for (int l = 0; l < N; l++) {
						if (dis[l] == MOD)continue;
						if (dp[i][a][j] && dp[i][b][k] && dp[i][c][l])dis[i] = min(dis[i], max({ dis[j],dis[k],dis[l] }) + 1);
					}
				}
			}
		}
	}
	if (dis.front() == MOD) {
		cout << "IMPOSSIBLE\n";
		return 0;
	}
	cout << dis.front() << endl;
}
accuracy: 0.17567567567567569
time_ms: 30
memory_kb: 4220
final_rank: 20

code_snippet: #include <bits/stdc++.h>
using namespace std;
int main(){
  int n, m, a, b, c;
  cin >> n >> m >> a >> b >> c;
  vector<vector<int>> E(n);
  for (int i = 0; i < m; i++){
    int u, v;
    cin >> u >> v;
    u--;
    v--;
    E[v].push_back(u);
  }
  vector<vector<vector<bool>>> next(n, vector<vector<bool>>(101, vector<bool>(n, false)));
  for (int i = 0; i < n; i++){
    next[i][0][i] = true;
    for (int j = 0; j < 100; j++){
      for (int k = 0; k < n; k++){
        if (next[i][j][k]){
          for (int l : E[k]){
            next[i][j + 1][l] = true;
          }
        }
      }
    }
  }
  vector<bool> A(n, false), B(n, false), C(n, false);
  A[n - 1] = true;
  B[n - 1] = true;
  C[n - 1] = true;
  vector<int> t(n, -1);
  t[n - 1] = 0;
  queue<int> Q;
  Q.push(n - 1);
  while (!Q.empty()){
    int v = Q.front();
    Q.pop();
    for (int i = 0; i < n; i++){
      if (!A[i] && next[v][a][i]){
        A[i] = true;
        if (A[i] && B[i] && C[i]){
          t[i] = t[v] + 1;
          Q.push(i);
        }
      }
    }
    for (int i = 0; i < n; i++){
      if (!B[i] && next[v][b][i]){
        B[i] = true;
        if (A[i] && B[i] && C[i]){
          t[i] = t[v] + 1;
          Q.push(i);
        }
      }
    }
    for (int i = 0; i < n; i++){
      if (!C[i] && next[v][c][i]){
        C[i] = true;
        if (A[i] && B[i] && C[i]){
          t[i] = t[v] + 1;
          Q.push(i);
        }
      }
    }
  }
  if (t[0] == -1){
    cout << "IMPOSSIBLE" << endl;
  } else {
    cout << t[0] << endl;
  }
}
accuracy: 1
time_ms: 10
memory_kb: 3560
final_rank: 5

code_snippet: #include <bits/stdc++.h>
using namespace std;
typedef long long ll;
template<class T>bool chmax(T &a, const T &b) { if (a<b) { a=b; return true; } return false; }
template<class T>bool chmin(T &a, const T &b) { if (b<a) { a=b; return true; } return false; }
#define all(x) (x).begin(),(x).end()
#define fi first
#define se second
#define mp make_pair
#define si(x) int(x.size())
const int mod=1000000007,MAX=105,INF=1<<27;
vector<int> G[MAX],G2[MAX];
bool can[MAX][MAX][MAX],check[MAX],ok[MAX];
int N,M;
int dp[MAX];

void BFS(int u){
    for(int t=0;t<100;t++){
        for(int i=0;i<N;i++){
            for(int to:G[i]){
                can[u][to][t+1]|=can[u][i][t];
            }
        }
        
        if(check[t+1]){
            for(int i=0;i<N;i++){
                ok[i]&=can[u][i][t+1];
            }
        }
    }
    
    if(ok[N-1]) chmin(dp[u],1);
}

int main(){
    
    std::ifstream in("text.txt");
    std::cin.rdbuf(in.rdbuf());
    cin.tie(0);
    ios::sync_with_stdio(false);
    
    cin>>N>>M;
    vector<int> A(3);
    for(int i=0;i<3;i++){
        int x;cin>>x;
        check[x]=1;
        A[i]=x;
    }
    for(int i=0;i<M;i++){
        int a,b;cin>>a>>b;
        a--;b--;
        G[a].push_back(b);
    }
    
    for(int i=0;i<N;i++) dp[i]=INF;
    dp[N-1]=0;
    
    for(int i=0;i<N;i++){
        for(int j=0;j<N;j++) ok[j]=1;
        can[i][i][0]=1;
        
        BFS(i);
    }
    
    for(int t=0;t<100;t++){
        for(int i=0;i<N;i++){
            int ma=0;
            for(int j=0;j<3;j++){
                int mi=INF;
                for(int x=0;x<N;x++){
                    if(can[i][x][A[j]]) chmin(mi,dp[x]);
                }
                chmax(ma,mi);
            }
            chmin(dp[i],ma+1);
        }
    }
    
    if(dp[0]==INF) cout<<"IMPOSSIBLE"<<endl;
    else cout<<dp[0]<<endl;
}
accuracy: 1
time_ms: 10
memory_kb: 3704
final_rank: 9

code_snippet: #include <bits/stdc++.h>
using namespace std;
using ll = long long;
using vi = vector<int>;
using vvi = vector<vi>;
using vll = vector<ll>;
using vvll = vector<vll>;
using P = pair<int, int>;
const double eps = 1e-8;
const ll MOD = 1000000007;
const int INF = INT_MAX / 2;
const ll LINF = LLONG_MAX / 2;
template <typename T1, typename T2>
void chmax(T1 &a, const T2 &b) {
  if(a < b) a = b;
}
template <typename T1, typename T2>
void chmin(T1 &a, const T2 &b) {
  if(a > b) a = b;
}
template<typename T>
void printv(const vector<T>& s) {
  for(int i=0;i<(int)(s.size());++i) {
    cout << s[i];
    if(i != (int)(s.size())-1) cout << " ";
  }
  cout << "\n";
}
template<typename T1, typename T2>
ostream& operator<<(ostream &os, const pair<T1, T2> p) {
  os << p.first << ":" << p.second;
  return os;
}
int main() {
  cin.tie(0);
  ios::sync_with_stdio(false);
  cout << fixed << setprecision(10);
  int n, m; vi v(3); cin >> n >> m >> v[0] >> v[1] >> v[2];
  vvi g(n);
  for(int i=0;i<m;++i) {
    int a, b; cin >> a >> b;
    a--; b--;
    g[a].push_back(b);
  }
  vector<vector<set<int>>> V(3, vector<set<int>>(n));
  vector<set<int>> tmp(n);
  for(int i=0;i<n;++i) {
    tmp[i].insert(i);
  }
  int now = 0;
  while(now <= max(v[0], max(v[1], v[2]))) {
    vector<set<int>> nxt(n);
    for(int i=0;i<n;++i) {
      for(auto &e: tmp[i]) {
        for(int j=0;j<(int)(g[e].size());++j) {
          nxt[i].insert(g[e][j]);
        }
      }
    }
    now++;
    if(now == v[0]) {
      V[0] = nxt;
    }
    if(now == v[1]) {
      V[1] = nxt;
    }
    if(now == v[2]) {
      V[2] = nxt;
    }
    tmp = nxt;
  }
  vector<int> d(n, -1);
  d[n-1] = 0;
  for(int i=0;i<n;++i) {
    vi nxt(n, -1);
    for(int j=0;j<n;++j) {
      for(int k=0;k<3;++k) {
        int tmp = INF;
        for(auto &e: V[k][j]) {
          if(d[e] == -1) continue;
          chmin(tmp, d[e] + 1);
        }
        chmax(nxt[j], tmp);
      }
      if(nxt[j] == -1) nxt[j] = d[j];
      else if(d[j] != -1) chmin(nxt[j], d[j]);
      if(nxt[j] == INF) nxt[j] = -1;
    }
    d = nxt;
  }
  if(d[0] == -1) {
    cout << "IMPOSSIBLE" << endl;
  } else {
    cout << d[0] << endl;
  }
}
accuracy: 1
time_ms: 30
memory_kb: 3752
final_rank: 11