Problem:
H: Aggressive Traveller
You are very eager to travel to many countries. There are $N$ countries in the world. $M$ distinct pairs of the countries have a travel route
between the two countries. All the $M$ routes are one-way: if there is a route from $A$ to $B$, you can move from country $A$ to country $B$,
but not from $B$ to $A$ unless there is another route from $B$ to $A$. Now you are in country $S$ and set the goal of your travel to country $T$.
From $S$ to $T$, you want to visit the countries as many times as possible.
However, there are some restrictions. There are $K$ countries which have strict security checks before you enter these countries. The flow
of the security check of the $i$-th restricted country $c_i$ is as follows:
You show your passport to an officer.
The officer checks your passport. If at least one of the following two conditions is satisfied, your entrance is rejected:
Your passport has two or more stamps of the same country.
Your passport has more than $r_i$ stamps.
Otherwise your entrance is accepted. The officer stamps your passport with a stamp of country $c_i$.
You enter the country $c_i$.
Note that in $N - K$ countries other than $K$ restricted countries, passport checking is skipped so you can freely enter these countries but
you must get a stamp of a country you enter. Also notice that you may be able to enter $c_i$ at most twice, because you get a stamp
after
passport checking. Initially your passport has only a single stamp of country $S$.
As an aggressive traveller, you want to maximize the number of stamps on your passport. You are going to start your travel from country
and $S$ eventually finish the travel at country $T$. Write a program that outputs the maximum number of stamps you can get on your
passport when you reach $T$. This number includes the stamps of countries $S$ and $T$. If you cannot reach $T$ from $S$, output
'UNREACHABLE' instead. Also, if you can indefinitely repeat to visit countries and then eventually reach $T$, output 'INFINITY' instead.
Note that you don't have to stop your travel when reaching $T$ and can visit $T$ multiple times.
Input
The input consists of a single test case in the format below.
$N$ $M$ $K$ $S$ $T$
$u_1$ $v_1$
:
$u_M$ $v_M$
$c_1$ $r_1$
:
$c_K$ $r_K$
The first line contains five integers $N$ ($3 \leq N \leq 1,000$), $M$ ($2 \leq M \leq 10,000$), $K$ ($1 \leq K \leq N$), $S$ ($1 \leq S \leq N$), $T$ ($1 \leq T \leq N$). $N$ is the number of countries. $M$ is the number of routes between pairs of countries. $K$ is the number of restricted countries. $S$ and $T$ are the countries you start your travel from and want to reach, respectively. The $i$-th of following $M$ lines is the information of the $i$-th route:
you can move from countries $u_i$ to country $v_i$ ($1 \leq u_i, v_i \leq N$). The $j$-th of further following $K$ lines is the information of the $j$-th
restricted country: country $c_j$ ($1 \leq c_j \leq N$) has the limit $r_i$ ($1 \leq r_j \leq 5$) of the number 
...(truncated)

Submitted solutions:

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
 */

namespace Random {
mt19937_64 randgen(chrono::steady_clock::now().time_since_epoch().count());
using u64 = unsigned long long;
u64 get() {
    return randgen();
}
template <typename T> T get(T L) { // [0,L]

    return get() % (L + 1);
}
template <typename T> T get(T L, T R) { // [L,R]

    return get(R - L) + L;
}
}

void Solve() {
    int N, M, K, S, T;
    cin >> N >> M >> K >> S >> T, S--, T--;
    vector<vector<int>> G(N), RG(N);
    rep(i,0,M) {
        int a, b;
        cin >> a >> b;
        a--, b--;
        G[a].push_back(b);
        RG[b].push_back(a);
    }
    vector<int> R(N, -1);
    rep(i,0,K) {
        int c, r;
        cin >> c >> r;
        c--;
        R[c] = r;
    }
    vector<vector<bool>> B(N, vector<bool>(6, false));
    auto Examine = [&]() -> void {
        vector<int> A(N);
        rep(i,0,N) A[i] = Random::get(0,4);
        vector<vector<bool>> DP(N, vector<bool>(1<<5, false));
        queue<pair<int,int>> Q;
        DP[S][0] = true;
        Q.push({S,0});
        while(!Q.empty()) {
            auto [p, mask] = Q.front();
            Q.pop();
            for (int np : G[p]) {
                if (mask & (1<<A[p])) continue;
                int nmask = mask | (1<<A[p]);
                if (!DP[np][nmask]) {
                    DP[np][nmask] = true;
                    Q.push({np,nmask});
                }
            }
        }
        rep(i,0,N) {
            rep(j,0,1<<5) {
                if (DP[i][j]) B[i][popcnt(j)] = true;
            }
        }
    };
    const int try_number = 1000;
    rep(i,0,try_number) Examine();
    vector<int> V(N, -1);
    vector<bool> canReach(N, false);
    {
        queue<int> Q;
        vector<bool> DP(N, false);
        rep(i,0,N) {
            if (R[i] == -1) continue;
            rep(j,0,R[i]+1) {
                if (B[i][j]) {
                    V[i] = j;
                    DP[i] = true;
                    Q.push(i);
                }
            }
        }
        if (R[S] == -1) {
            Q.push(S);
            DP[S] = true;
        }
        while(!Q.empty()) {
            int p = Q.front();
            Q.pop();
            for (int np : G[p]) {
                if (!DP[np] && R[np] == -1) {
                    DP[np] = true;
                    Q.push(np);
                }
            }
        }
        if (!DP[T]) {
            cout << "UNREACHABLE" << endl;
            return;
        }
        rep(i,0,N) if (DP[i]) canReach[i] = true;
        rep(i,0,N) DP[i] = false;
        Q.push(T);
        DP[T] = true;
        while(!Q.empty()) {
            int p = Q.front();
            Q.pop();
            if (R[p] != -1) continue;
            for (int np : RG[p]) {
                if (!DP[np]) {
                    DP[np] = true;
                    Q.push(np);
                }
            }
        }
        rep(i,0,N) if (!DP[i]) canReach[i] = false;
    }
    int VC = 0;
    rep(i,0,N) if (canReach[i]) VC++;
    vector<vector<int>> H(N);
    vector<int> COUNT(N, 0);
    rep(i,0,N) {
        if (!canReach[i]) continue;
        for (int ni : G[i]) {
            if (R[ni] != -1) continue;
            if (!canReach[ni]) continue;
            H[i].push_back(ni);
            COUNT[ni]++;
        }
    }
    vector<int> ord;
    {
        queue<int> Q;
        rep(i,0,N) {
            if (!canReach[i]) continue;
            if (COUNT[i] == 0) {
                Q.push(i);
            }
        }
        while(!Q.empty()) {
            int p = Q.front();
            Q.pop();
            ord.push_back(p);
            for (int np : H[p]) {
                COUNT[np]--;
                if (COUNT[np] == 0) {
                    Q.push(np);
                }
            }
        }
    }
    if (SZ(ord) != VC) {
        cout << "INFINITY" << endl;
        return;
    }
    vector<int> ANS(N, -inf);
    ANS[S] = 0;
    rep(i,0,N) {
        if (V[i] >= 0) chmax(ANS[i], V[i]);
    }
    for (int i : ord) {
        for (int ni : H[i]) {
            chmax(ANS[ni], ANS[i]+1);
        }
    }
    cout << ANS[T]+1 << endl;
}

int main() {
int _ = 1;
//cin >> _;
while(_--) {
    Solve();
}
}
accuracy: 1
time_ms: 460
memory_kb: 3772
final_rank: 2

code_snippet: // clang-format off
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
const ll INF = 1ll << 60;
#define REP(i, n) for (ll i=0; i<ll(n); i++)
template <class T> using V = vector<T>;
template<class A, class B>
bool chmax(A &a, B b) { return a < b && (a = b, true); }
template<class A, class B>
bool chmin(A &a, B b) { return b < a && (a = b, true); }

void solve(){
    int n, m, k, s, t; cin >> n >> m >> k >> s >> t; s--; t--;
    V<V<int>> g(n);
    REP(i, m) {
        int u, v; cin >> u >> v; u--; v--;
        g[u].push_back(v);
    }
    V<int> c(n, -1);
    REP(i, k) {
        int ci, r; cin >> ci >> r; ci--;
        c[ci] = r;
    }
    c[s] = 0;
    constexpr int MAX_C = 5;
    V<V<char>> reachable(MAX_C+1, V<char>(n));
    mt19937 mt(0);
    REP(tr, 2000) {
        V<int> colors(n);
        REP(i, n) colors[i] = mt() % MAX_C;
        V<V<char>> cs(1<<MAX_C, V<char>(n));
        cs[1<<colors[s]][s] = 1;
        reachable[0][s] = 1;
        REP(i, 1<<MAX_C) REP(j, n) {
            if(!cs[i][j]) continue;
            // if(tr == 0) cerr << "! " << i << ' ' << j << endl;
            int steps = popcount((unsigned)i);
            for(int nj : g[j]) {
                if(c[nj] > 0 && steps <= c[nj]) reachable[steps][nj] = 1;
                if((i & (1 << colors[nj])) == 0) cs[i | 1<<colors[nj]][nj] = 1;
            }
        }
    }
    V<V<int>> rg(n);
    REP(u, n) for(int v : g[u]) rg[v].push_back(u);
    V<int> dist(n, -10);
    dist[t] = 0;
    REP(_, n) {
        REP(u, n) {
            if(dist[u] == -10) continue;
            if(c[u] > 0) continue;
            for(int v : rg[u]) {
                chmax(dist[v], dist[u]+1);
            }
        }
    }
    V<int> upd(n);
    REP(_, n) {
        REP(u, n) {
            if(dist[u] == -10) continue;
            if(c[u] > 0) continue;
            for(int v : rg[u]) {
                if(chmax(dist[v], dist[u]+1)) upd[v] = 1;
            }
        }
    }
    int ans = -1;
    REP(j, n) {
        REP(i, MAX_C+1) {
            if(reachable[i][j]) {
                if(upd[j]) {
                    cout << "INFINITY\n";
                    return;
                }
                chmax(ans, i+dist[j]+1);
            }
        }
    }
    if(ans == -1) cout << "UNREACHABLE\n";
    else cout << ans << '\n';
}

int main() {
    cin.tie(0)->sync_with_stdio(0);
    solve();
}
accuracy: 1
time_ms: 450
memory_kb: 3840
final_rank: 3

code_snippet: // clang-format off
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
const ll INF = 1ll << 60;
#define REP(i, n) for (ll i=0; i<ll(n); i++)
template <class T> using V = vector<T>;
template<class A, class B>
bool chmax(A &a, B b) { return a < b && (a = b, true); }
template<class A, class B>
bool chmin(A &a, B b) { return b < a && (a = b, true); }

void solve(){
    int n, m, k, s, t; cin >> n >> m >> k >> s >> t; s--; t--;
    V<V<int>> g(n);
    REP(i, m) {
        int u, v; cin >> u >> v; u--; v--;
        g[u].push_back(v);
    }
    V<int> c(n, -1);
    REP(i, k) {
        int ci, r; cin >> ci >> r; ci--;
        c[ci] = r;
    }
    c[s] = 0;
    constexpr int MAX_C = 5;
    V<V<char>> reachable(MAX_C+1, V<char>(n));
    mt19937 mt(0);
    REP(tr, 3000) {
        V<int> colors(n);
        REP(i, n) colors[i] = mt() % MAX_C;
        V<V<char>> cs(1<<MAX_C, V<char>(n));
        cs[1<<colors[s]][s] = 1;
        reachable[0][s] = 1;
        REP(i, 1<<MAX_C) REP(j, n) {
            if(!cs[i][j]) continue;
            // if(tr == 0) cerr << "! " << i << ' ' << j << endl;
            int steps = popcount((unsigned)i);
            for(int nj : g[j]) {
                if(c[nj] != -1 && steps <= c[nj]) reachable[steps][nj] = 1;
                if((i & (1 << colors[nj])) == 0) cs[i | 1<<colors[nj]][nj] = 1;
            }
        }
    }
    int ans = -1;
    REP(j, n) {
        V<int> dist(n, -10);
        dist[j] = 0;
        REP(_, n+10) {
            REP(u, n) {
                if(dist[u] == -10) continue;
                for(int v : g[u]) {
                    if(c[v] > 0) continue;
                    chmax(dist[v], dist[u]+1);
                }
            }
        }
        bool upd = false;
        REP(_, n+10) {
            REP(u, n) {
                if(dist[u] == -10) continue;
                for(int v : g[u]) {
                    if(c[v] > 0) continue;
                    if(chmax(dist[v], dist[u]+1) && v == t) upd = true;
                }
            }
        }
        if(upd) {
            cout << "INFINITY\n";
            return;
        }
        REP(i, MAX_C+1) {
            if(reachable[i][j]) chmax(ans, i+dist[t]+1);
        }
    }
    if(ans == -1) cout << "UNREACHABLE\n";
    else cout << ans << '\n';
}

int main() {
    cin.tie(0)->sync_with_stdio(0);
    solve();
}
accuracy: 0.75
time_ms: 890
memory_kb: 3712
final_rank: 6

code_snippet: // clang-format off
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
const ll INF = 1ll << 60;
#define REP(i, n) for (ll i=0; i<ll(n); i++)
template <class T> using V = vector<T>;
template<class A, class B>
bool chmax(A &a, B b) { return a < b && (a = b, true); }
template<class A, class B>
bool chmin(A &a, B b) { return b < a && (a = b, true); }

void solve(){
    int n, m, k, s, t; cin >> n >> m >> k >> s >> t; s--; t--;
    V<V<int>> g(n);
    REP(i, m) {
        int u, v; cin >> u >> v; u--; v--;
        g[u].push_back(v);
    }
    V<int> c(n, -1);
    REP(i, k) {
        int ci, r; cin >> ci >> r; ci--;
        c[ci] = r;
    }
    c[s] = 0;
    constexpr int MAX_C = 5;
    V<V<char>> reachable(MAX_C+1, V<char>(n));
    mt19937 mt(0);
    REP(tr, 2000) {
        V<int> colors(n);
        REP(i, n) colors[i] = mt() % MAX_C;
        V<V<char>> cs(1<<MAX_C, V<char>(n));
        cs[1<<colors[s]][s] = 1;
        reachable[0][s] = 1;
        REP(i, 1<<MAX_C) REP(j, n) {
            if(!cs[i][j]) continue;
            // if(tr == 0) cerr << "! " << i << ' ' << j << endl;
            int steps = popcount((unsigned)i);
            for(int nj : g[j]) {
                if(c[nj] != -1 && steps <= c[nj]) reachable[steps][nj] = 1;
                if((i & (1 << colors[nj])) == 0) cs[i | 1<<colors[nj]][nj] = 1;
            }
        }
    }
    int ans = -1;
    REP(j, n) {
        V<int> dist(n, -10);
        dist[j] = 0;
        REP(_, n+10) {
            REP(u, n) {
                if(dist[u] == -10) continue;
                for(int v : g[u]) {
                    if(c[v] > 0) continue;
                    chmax(dist[v], dist[u]+1);
                }
            }
        }
        bool upd = false;
        REP(_, n+10) {
            REP(u, n) {
                if(dist[u] == -10) continue;
                for(int v : g[u]) {
                    if(c[v] > 0) continue;
                    if(chmax(dist[v], dist[u]+1) && v == t) upd = true;
                }
            }
        }
        if(upd) {
            cout << "INFINITY\n";
            return;
        }
        REP(i, MAX_C+1) {
            if(reachable[i][j]) chmax(ans, i+dist[t]+1);
        }
    }
    if(ans == -1) cout << "UNREACHABLE\n";
    else cout << ans << '\n';
}

int main() {
    cin.tie(0)->sync_with_stdio(0);
    solve();
}
accuracy: 0.75
time_ms: 870
memory_kb: 3712
final_rank: 5

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

int main() {

    cin.tie(nullptr);
    ios::sync_with_stdio(false);

    clock_t start=clock(),end=clock();
    int N,M,K,S,T;
    cin>>N>>M>>K>>S>>T;
    vector<vector<int>> G(N),IG(N);
    S--;T--;
    for(int i=0;i<M;i++){
        int u,v;
        cin>>u>>v;
        u--;v--;
        G[u].push_back(v);
        IG[v].push_back(u);
    }
    vector<int> B(N,-1);
    for(int k=0;k<K;k++){
        int c,r;
        cin>>c>>r;
        B[c-1]=r;
    }
    vector<int> D(N,-1000);
    {
        queue<int> Q;
        Q.push(T);
        D[T]=1;
        while(!Q.empty()){
            int p=Q.front();
            Q.pop();
            if(B[p]>0)continue;
            for(int v:IG[p]){
                if(D[v]<0){
                    D[v]=D[p]+1;
                    Q.push(v);
                }
                if(D[p]==2*N+10){
                    if(D[v]!=2*N+10){
                        D[v]=D[p];
                        Q.push(v);
                    }
                }
                else if(D[v]<D[p]+1){
                    D[v]=D[p]+1;
                    Q.push(v);
                }
            }
        }
    }
    // for(int i=0;i<N;i++)cout<<D[i]<<" \n"[i==N-1];
    vector<vector<bool>> P(N,vector<bool>(6,0));
    P[S][0]=1;
    {
        end=clock();
        vector<int> col(N);
        while(double(end-start)/CLOCKS_PER_SEC<1.6){
            for(int i=0;i<N;i++)col[i]=rand()%5;
            vector<vector<bool>> seen(N,vector<bool>(1<<5,0));
            queue<pair<int,int>> Q;
            Q.push({S,1<<col[S]});
            while(!Q.empty()){
                auto [n,bit]=Q.front();
                Q.pop();
                if(seen[n][bit])continue;
                seen[n][bit]=1;
                for(int v:G[n]){
                    if(B[v]>0&&B[v]<__builtin_popcount(bit))continue;
                    P[v][__builtin_popcount(bit)]=1;
                    if(bit&(1<<col[v]))continue;
                    int nbit=bit+(1<<col[v]);
                    if(seen[v][nbit])continue;
                    Q.push({v,nbit});
                }
            } 
            end=clock();
        }
    }
    int an=-5;
    B[S]=N+10;
    for(int i=0;i<N;i++){
        for(int j=0;j<6;j++){
            if(B[i]>=j&&P[i][j]){
                an=max(an,j+D[i]);
            }
        }
    }
    if(an<0)cout<<"UNREACHABLE"<<endl;
    else if(an>=N*2+10)cout<<"INFINITY"<<endl;
    else cout<<an<<endl;
}
accuracy: 1
time_ms: 1600
memory_kb: 4368
final_rank: 4

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

int main() {

    cin.tie(nullptr);
    ios::sync_with_stdio(false);

    clock_t start=clock(),end=clock();
    int N,M,K,S,T;
    cin>>N>>M>>K>>S>>T;
    vector<vector<int>> G(N),IG(N);
    S--;T--;
    for(int i=0;i<M;i++){
        int u,v;
        cin>>u>>v;
        u--;v--;
        G[u].push_back(v);
        IG[v].push_back(u);
    }
    vector<int> B(N,-1);
    for(int k=0;k<K;k++){
        int c,r;
        cin>>c>>r;
        B[c-1]=r;
    }
    vector<int> D(N,-1000);
    {
        queue<int> Q;
        Q.push(T);
        D[T]=1;
        while(!Q.empty()){
            int p=Q.front();
            Q.pop();
            if(B[p]>0)continue;
            for(int v:IG[p]){
                if(D[v]<0){
                    D[v]=D[p]+1;
                    Q.push(v);
                }
                if(D[p]==2*N+10){
                    if(D[v]!=2*N+10){
                        D[v]=D[p];
                        Q.push(v);
                    }
                }
                else if(D[v]<D[p]+1){
                    D[v]=D[p]+1;
                    Q.push(v);
                }
            }
        }
    }
    // for(int i=0;i<N;i++)cout<<D[i]<<" \n"[i==N-1];
    vector<vector<bool>> P(N,vector<bool>(6,0));
    P[0][0]=1;
    {
        end=clock();
        vector<int> col(N);
        while(double(end-start)/CLOCKS_PER_SEC<1.6){
            for(int i=0;i<N;i++)col[i]=rand()%5;
            vector<vector<bool>> seen(N,vector<bool>(1<<5,0));
            queue<pair<int,int>> Q;
            Q.push({S,1<<col[S]});
            while(!Q.empty()){
                auto [n,bit]=Q.front();
                Q.pop();
                if(seen[n][bit])continue;
                seen[n][bit]=1;
                for(int v:G[n]){
                    P[v][__builtin_popcount(bit)]=1;
                    if(bit&(1<<col[v]))continue;
                    int nbit=bit+(1<<col[v]);
                    if(seen[v][nbit])continue;
                    Q.push({v,nbit});
                }
            } 
            end=clock();
        }
    }
    int an=-5;
    B[S]=N+10;
    for(int i=0;i<N;i++){
        for(int j=0;j<6;j++){
            if(B[i]>=j&&P[i][j]){
                an=max(an,j+D[i]);
            }
        }
    }
    if(an<0)cout<<"UNREACHABLE"<<endl;
    else if(an>=N*2+10)cout<<"INFINITY"<<endl;
    else cout<<an<<endl;
}
accuracy: 0.475
time_ms: 1600
memory_kb: 3460
final_rank: 7

code_snippet: #include <iostream>
#include <vector>
#include <algorithm>
#include <queue>
#include <string>
#include <random>
#include <climits>
using namespace std;

namespace{
const string INF = "INFINITY";

vector<vector<int>> G, rG, srG;
vector<int> lims;

vector<int> state;
vector<int> loop;
vector<int> cnt;
void dfs1(int u){
	if(lims[u] >= 0){ return; }
	state[u] = 1;
	for(int v : rG[u]){
		if(state[v] == 1){
			loop.push_back(v);
		}
		else if(state[v] == 0){
			dfs1(v);
		}
	}
	state[u] = 2;
}

vector<int> distg;
vector<vector<char>> vis;
vector<char> isinf;

void dfs2(int u){
	if(lims[u] >= 0 || isinf[u] || state[u] != 0){ return; }
	state[u] = 1;
	for(int v : rG[u]){
		++cnt[v];
		srG[u].push_back(v);
		dfs2(v);
	}
}

int ans = -1;
void dfs3(int clr, int u, int d){
	if(lims[u] >= 0 && d > lims[u]){ return; }
	++d;
	if(isinf[u]){ throw __LINE__; }
	if(distg[u] >= 0){
		ans = max(ans, d + distg[u]);
	}
	if(clr & state[u]){ return; }
	clr |= state[u];
	if(vis[clr][u]){ return; }
	vis[clr][u] = 1;
	for(int v : G[u]){
		dfs3(clr, v, d);
	}
}

string solve() try{
	int n, m, k, start, goal;
	cin >> n >> m >> k >> start >> goal;
	--start;
	--goal;
	G.resize(n);
	rG.resize(n);
	srG.resize(n);
	cnt.assign(n, 0);
	for(int i = 0; i < m; ++i){
		int a, b;
		cin >> a >> b;
		--a;
		--b;
		G[a].push_back(b);
		rG[b].push_back(a);
	}
	lims.assign(n, -1);
	for(int i = 0; i < k; ++i){
		int v, u;
		cin >> v >> u;
		lims[v - 1] = u;
	}
	
	state.assign(n, 0);
	dfs1(goal);
	
	isinf.assign(n, 0);
	queue<int> q;
	for(int u : loop){
		isinf[u] = 1;
		q.push(u);
	}
	while(!q.empty()){
		int u = q.front();
		q.pop();
		if(lims[u] == -1){
			for(int v : rG[u]){
				if(!isinf[v]){
					isinf[v] = 1;
					q.push(v);
				}
			}
		}
	}
	if(isinf[start]){ return INF; }
	
	state.assign(n, 0);
	dfs2(goal);

	distg.assign(n, -1);
	q.push(goal);
	q.push(-1);
	int tm = 0;
	while(q.size() > 1){
		int u = q.front();
		q.pop();
		if(u == -1){
			q.push(-1);
			++tm;
		}
		else{
			distg[u] = tm;
			for(int v : srG[u]){
				if(--cnt[v] == 0){
					q.push(v);
				}
			}
		}
	}

	int maxu = max(0, *max_element(lims.begin(), lims.end()) - 1);
	mt19937 mt(20210225);
	uniform_int_distribution<> uid(0, maxu);

	for(int zzz = 1000; zzz--; ){
		for(int &x : state){ x = 1 << uid(mt); }
		vis.assign(2 << maxu, vector<char>(n));
		dfs3(0, start, 0);
	}
	if(ans < 0){ return "UNREACHABLE"; }
	return to_string(ans);
}catch(int){ return INF; }
}

int main(){
	ios::sync_with_stdio(false);
	string ans = solve();
	cout << ans << '\n';
}
accuracy: 1
time_ms: 250
memory_kb: 3448
final_rank: 1