Language: C++

#include <vector>
#include <queue>
#include <iostream>

using namespace std;

using ll = long long;
using dd = double;
using vi = vector<int>;
using vl = vector<ll>;
using vd = vector<dd>;
using vb = vector<bool>;

template <class T, class V>
istream& operator>>(istream& in, pair<T, V>& pair) {
    return in >> pair.first >> pair.second;
}

template <class T>
istream& operator>>(istream& in, vector<T>& elements) {
    for (size_t i = 0; i < elements.size(); ++i) {
        in >> elements[i];
    }
    return in;
}

template <class Container, class Element>
bool Contains(const Container& container, const Element& element) {
    return container.find(element) != container.end();
}

template <class T>
ostream& operator<<(ostream& out, const vector<T>& elements) {
    for (const T& element : elements) {
        out << element << ' ';
    }
    return out;
}

template <class T, class V>
ostream& operator<<(ostream& out, const pair<T, V>& pair) {
    out << pair.first << ' ' << pair.second;
}

#define FOR(i,n) for(size_t i=0, i##_len=(n); i<i##_len; ++i)
#define SORT(c) sort((c).begin(), (c).end())

using Graph = vector<vector<int>>;

vector<vector<vector<int>>> passes;

vector<int> GetKenKenPas(const Graph& g, int v, int depth = 3) {
    if (!passes[v][depth].empty()) {
        return passes[v][depth];
    }
    if (depth == 1) {
        return g[v];
    }
    vector<int> result = g[v];
    for (int i = 2; i <= 3; ++i) {
        vector<int> next_result;
        for (int el : result) {
            for (int nel : g[el]) {
                next_result.push_back(nel);
            }
        }
        result = move(next_result);
    }
    passes[v][depth] = move(result);
    return passes[v][depth];
}

int Eval(int n, int m, const Graph& g, int s, int t) {
    vb used(n);
    vi dist(n, -1);
    
    used[s] = true;
    dist[s] = 0;
    
    queue<int> q;
    q.push(s);
    
    while (!q.empty()) {
        int v = q.front();
        q.pop();
        
        assert(used[v]);
        for (int next : GetKenKenPas(g, v)) {
            if (used[next]) {
                continue;
            }
            used[next] = true;
            dist[next] = dist[v] + 1;
            q.push(next);
            if (next == t) {
                return dist[t];
            }
        }
    }
    return dist[t];
}

int main() {
    ios_base::sync_with_stdio(false);
    
    int n, m;
    cin >> n >> m;
    
    passes = vector<vector<vector<int>>>(n);
    FOR(i, n) {
        passes[i] = vector<vector<int>>(4);
    }
    
    Graph g(n);
    FOR(i, m) {
        int u, v;
        cin >> u >> v;
        --u; --v;
        
        g[u].push_back(v);
    }
    
    int s, t;
    cin >> s >> t;
    --s; --t;
    
    cout << Eval(n, m, g, s, t) << endl;
    
    return 0;
}


Compiler output:
a.cc: In function 'std::ostream& operator<<(std::ostream&, const std::pair<_T1, _T2>&)':
a.cc:43:1: warning: no return statement in function returning non-void [-Wreturn-type]
   43 | }
      | ^
a.cc: In function 'int Eval(int, int, const Graph&, int, int)':
a.cc:87:9: error: 'assert' was not declared in this scope
   87 |         assert(used[v]);
      |         ^~~~~~
a.cc:4:1: note: 'assert' is defined in header '<cassert>'; this is probably fixable by adding '#include <cassert>'
    3 | #include <iostream>
  +++ |+#include <cassert>
    4 |