Problem:
I: Irreversible Reactions
Life is ephemeral. What is done sometimes cannot be irreversible. In terms of this, chemical reaction networks are similar to life.
For brevity, we model a chemical reaction network as follows. There are $N$ states in a chemical reaction network. The reaction starts with
the state $S$. $M$ distinct pairs ($u_i, v_i$) of states have a relation such that $u_i$ can be transited to $v_i$. For each unit of time, a state is transited to
other states if there is at least one state that can be transited from the state. If there are no such states, the state does not change. If there
are two or more states to which the current state can be transited, the next state is selected at uniformly random from these states.
In an experiment of the chemical reaction network, we stop the experiment when the current state does not change. In addition, after
transitions, it might reach a state from which it's impossible to return back to $S$ by repeating transitions. In such cases we also stop the
experiment. Your task as a bioinformatics researcher is to write a program to compute the expected time until we stop the experiment. If
the expected time is infinite, output $-1$ instead.
A more precise description of the experiment termination criteria is the following. If there are no states that can be transited from the
current state, we stop the experiment immediately. Otherwise, the experiment does not stop, if it is possible to return back to $S$ from the
current state by repeating zero or more transitions. In other words, the state $S$ itself is always considered as a state that can return to $S$ in
this case.
Input
The input consists of a single test case in the format below.
$N$ $M$ $S$
$u_1$ $v_1$
:
$u_M$ $v_M$
The first line contains three integers $N$ ($2 \leq N \leq 200$), $M$ ($1 \leq M \leq \min(N(N-1), 1000)$), $S$ ($1 \leq S \leq N$). $N$ is the number of
states in a chemical reaction network. $M$ is the number of transitions between states. $S$ is the initial state. The $i$-th of the following $M$ 
lines represents the $i$-th transition, which means a state $u_i$ can be transited to $v_i$ ($1 \leq u_i, v_i \leq N, u_i \ne v_i$). Note that it does not
necessarily imply $v_i$ can be transitioned to $u_i$. It is guaranteed that the pairs $u_i$ and $v_i$ are distinct. That is, for $1 \leq i < j \leq M$, either $u_i \ne u_j$ or $v_i \ne v_j$ holds.
Output
Output the expected time to reach one of the states from which it's impossible to return back to the initial state $S$. The expected time can
be huge, thus outputs the expected time modulo $10^9 + 7$. More precisely, if it is finite, the expected time can be represented as an
irreducible fraction $b/a$, and you should output the minimum non-negative integer $x$ which satisfies $ax \equiv b$ mod $10^9 + 7$. You may
assume that such $x$ exists for the given input.
If the expected time is infinity, output $-1$ instead.
Examples
Input 1
3 3 1
1 2
2 1
2 3
Output 1
4
Input 2
5 7 1
1 2
2 1

...(truncated)

Submitted solutions:

code_snippet: #include <bits/stdc++.h>
using namespace std;
using ll = long long;
#define rep(i, n) for (ll i = 0; i < n; ++i)
#define rrep(i, n) for (ll i = n-1; i >=0; i--)
#define loop(i,m,n)for(ll i=m;i<=n;i++)
#define vl vector<ll>
#define vvl vector<vl>
#define inf 1000000000000000000LL


struct SCC
{
    private:
    long long n;
    vector<vector<long long>> G, rG;

    vector<long long> order;

    vector<long long> component;
    vector<long long> components_size;
    long long component_count = 0;

    vector<vector<long long>> component_elements;
    vector<vector<long long>> rebuildedG;

    void topological_sort(){
        vector<bool> used(n, false);
        auto dfs = [&used, this](auto dfs, long long v) -> void {
            used[v] = 1;
            for (auto nv : G[v]) {
                if (!used[nv]) dfs(dfs, nv);
            }
            order.push_back(v);
        };

        for (long long v = 0; v < n; ++v){
            if (!used[v]) dfs(dfs, v);
        }

        reverse(order.begin(), order.end());
    }

    void search_components() {
        auto dfs = [this](auto dfs, long long v, long long k) -> void {
            component[v] = k;
            components_size[k]++;
            component_elements[k].push_back(v);
            for (auto nv : rG[v]) {
                if (component[nv] == -1) dfs(dfs, nv, k);
            }
        };

        for (auto v : order) {
            if (component[v] == -1){
                components_size.push_back(0);
                component_elements.push_back(vector<long long>());
                dfs(dfs, v, component_count++);
            }
        }
    }

    void rebuild() {
        rebuildedG.resize(component_count);

        set<pair<long long, long long>> connected;
        for (long long v = 0; v < n; v++){
            for (auto nv : G[v]) {
                long long v_comp = component[v];
                long long nv_comp = component[nv];
                pair<long long, long long> p = {v_comp, nv_comp};
                if (!is_same(v, nv) && !connected.count(p)) {
                    rebuildedG[v_comp].push_back(nv_comp);
                    connected.insert(p);
                }
            }
        }
    }

    public:
    SCC(vector<vector<long long>> &_G) : n(_G.size()), G(_G), rG(vector<vector<long long>>(n)), component(vector<long long>(n, -1)) {
        for (long long v = 0; v < n; v++){
            for (auto nv : G[v]){
                rG[nv].push_back(v);
            }
        }

        topological_sort();
        search_components();
        rebuild();
    }

    size_t size() const { return component_count; }

    long long get_component(long long v) const {
        assert(0 <= v && v < n);
        return component[v];
    }
    
    long long get_component_size(long long component) const {
        assert(0 <= component && component < size());
        return components_size[component];
    }
    
    vector<long long> get_component_elements(long long component) const {
        assert(0 <= component && component < size());
        return component_elements[component];
    }

    vector<long long>& operator[](long long component) {
        assert(0 <= component && component < size());
        return rebuildedG[component];
    }

    operator vector<vector<long long>>() const { return rebuildedG; }

    bool is_same(long long u, long long v) { return component[u] == component[v]; }
};

struct mint
{
    private:
    long long n;
    long long mod;

    public:
    static long long default_mod;

    mint() : n(0), mod(default_mod == 0 ? 998244353 : default_mod) {}
    mint(const mint &m) {
        n = m.n;
        mod = m.mod;
    }
    mint(long long n, long long mod = default_mod){
        if (default_mod == 0) {
            default_mod = mod == 0 ? 998244353 : mod;
            mod = default_mod;
        }
        assert(1 <= mod);

        this->n = (n % mod + mod) % mod;
        this-> mod = mod;
    }

    mint inv() const {
        assert(gcd(n, mod) == 1);
        auto ext_gcd = [&](auto f, ll a, ll b, ll &x, ll &y) -> long long {
            if(b == 0) {
                x = 1;
                y = 0;
                return a;
            }
            ll d = f(f, b, a % b, y, x);
            y -= a / b * x;
            return d;
        };

        long long x, y;
        ext_gcd(ext_gcd, n, mod, x, y);
        return mint((x % mod + mod) % mod, mod);
    }

    mint pow(ll exp) const {
        bool inverse = exp < 0;
        if (inverse) exp = -exp;

        ll a = n;
        ll res = 1;
        while (exp > 0) {
            if (exp & 1) res = res * a % mod;
            a = a * a % mod;
            exp >>= 1;
        }
        return (inverse ? mint(res, mod).inv() : mint(res, mod));
    }

    mint &operator=(const mint &o) {
        n = o.n;
        mod = o.mod;
        return *this;
    }

    mint operator+() const {return *this; }
    mint operator-() const {return 0 - *this; }

    mint &operator++() {
        n++;
        if (n == mod) n = 0;
        return *this;
    }
    mint &operator--() {
        if(n == 0) n = mod;
        n--;
        return *this;
    }
    mint operator++(int) {
        mint res = *this;
        ++*this;
        return res;
    }
    mint operator--(int) {
        mint res = *this;
        --*this;
        return res;
    }

    mint &operator+=(const mint &o) {
        assert(mod == o.mod);
        n += o.n;
        if (n >= mod) n -= mod;
        return *this;
    }
    mint &operator-=(const mint &o) {
        assert(mod == o.mod);
        n += mod - o.n;
        if (n >= mod) n -= mod;
        return *this;
    }
    mint &operator*=(const mint &o) {
        assert(mod == o.mod);
        n = n * o.n % mod;
        return *this;
    }
    mint &operator/=(const mint &o) {
        assert(mod == o.mod);
        n = n * o.inv().n % mod;
        return *this;
    }
    friend mint operator+(const mint &a, const mint &b){
        return mint(a) += b;
    }
    friend mint operator-(const mint &a, const mint &b){
        return mint(a) -= b;
    }
    friend mint operator*(const mint &a, const mint &b){
        return mint(a) *= b;
    }
    friend mint operator/(const mint &a, const mint &b){
        return mint(a) /= b;
    }

    friend bool operator==(const mint &a, const mint &b) {
        return a.n == b.n && a.mod == b.mod;
    }
    friend bool operator!=(const mint &a, const mint &b) {
        return a.n != b.n || a.mod != b.mod;
    }

    friend ostream &operator<<(ostream &os, const mint &m) {
        os << m.n;
        return os;
    }
};

long long mint::default_mod = 1000000007;

//拡大係数行列を与えると、連立1次方程式の解を返す。
template <typename T>
vector<T> hakidasi(vector<vector<T>> a){
	ll n=a.size();
	//下三角行列を0、対角行列を1にする
	rep(i,n){
		//i,iが0なら別の行とswap;
		if(a[i][i]==0){
			loop(j,i+1,n-1){
				if(a[j][i]!=0){
					swap(a[i],a[j]);
					break;
				}
			}
		}

		//i行目をa[i][i]で割る
		loop(j,i+1,n){
			a[i][j]/=a[i][i];
		}
		a[i][i]=1;

		//i行目より下の行を前の部分を0にする
		loop(j,i+1,n-1){
			//j行目のi番目を0にする
			loop(k,i+1,n){
				a[j][k]-=a[j][i]*a[i][k];
			}
			a[j][i]=0;
		}
	}
	vector<T> ans(n);
	//復元する。
	rrep(i,n){
		//i番目の答えを求める
		T tmp=a[i][n];
		loop(j,i+1,n-1){
			tmp-=a[i][j]*ans[j];
		}
		ans[i]=tmp;
	}
	return ans;
}

int main(){
    ll n, m, s; cin >> n >> m >> s;
    --s;
    vvl g(n);
    rep(i, m) {
        ll u, v; cin >> u >> v;
        --u, --v;
        g[u].push_back(v);
    }

    if (g[s].size() == 0) {
        cout << 0 << endl;
        return 0;
    }

    SCC scc(g);
    if (scc[scc.get_component(s)].size() == 0) {
        cout << -1 << endl;
        return 0;
    }

    set<ll> sgroup;
    for (ll v : scc.get_component_elements(scc.get_component(s))) {
        sgroup.insert(v);
    }

    vvl ng(sgroup.size() + 1);
    vector<bool> visited(sgroup.size() + 1, false);
    map<ll, ll> nidx;
    auto dfs = [&](auto dfs, ll v) -> void {
        if (!nidx.count(v)) nidx[v] = nidx.size();
        if (visited[nidx[v]]) return;
        visited[nidx[v]] = true;

        for (ll to : g[v]) {
            if (sgroup.count(to)) {
                dfs(dfs, to);
                ng[nidx[v]].push_back(nidx[to]);
            }
            else {
                ng[nidx[v]].push_back(sgroup.size());
            }
        }
    };
    dfs(dfs, s);

    vector<vector<mint>> mat(sgroup.size(), vector<mint>(sgroup.size() + 1, 0));
    for (ll v : sgroup) {
        ll i = nidx[v];
        mat[i][i] = 1;
        mat[i][sgroup.size()] = 1;
        mint p = (mint)1 / ng[i].size();
        for (ll to : ng[i]) {
            if (to == sgroup.size()) continue;
            mat[i][to] = -p;
        }
    }

    vector<mint> ans = hakidasi<mint>(mat);
    cout << ans[nidx[s]] << endl;

    return 0;
}
accuracy: 1
time_ms: 20
memory_kb: 4260
final_rank: 5

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 fastio {
static constexpr uint32_t SZ = 1 << 17;
char ibuf[SZ];
char obuf[SZ];
char out[100];
// pointer of ibuf, obuf


uint32_t pil = 0, pir = 0, por = 0;

struct Pre {
    char num[10000][4];
    constexpr Pre() : num() {
        for (int i = 0; i < 10000; i++) {
            int n = i;
            for (int j = 3; j >= 0; j--) {
                num[i][j] = n % 10 | '0';
                n /= 10;
            }
        }
    }
} constexpr pre;

inline void load() {
    memmove(ibuf, ibuf + pil, pir - pil);
    pir = pir - pil + fread(ibuf + pir - pil, 1, SZ - pir + pil, stdin);
    pil = 0;
    if (pir < SZ)
        ibuf[pir++] = '\n';
}

inline void flush() {
    fwrite(obuf, 1, por, stdout);
    por = 0;
}

void rd(char &c) {
    do {
        if (pil + 1 > pir)
            load();
        c = ibuf[pil++];
    } while (isspace(c));
}

void rd(string &x) {
    x.clear();
    char c;
    do {
        if (pil + 1 > pir)
            load();
        c = ibuf[pil++];
    } while (isspace(c));
    do {
        x += c;
        if (pil == pir)
            load();
        c = ibuf[pil++];
    } while (!isspace(c));
}

template <typename T> void rd_real(T &x) {
    string s;
    rd(s);
    x = stod(s);
}

template <typename T> void rd_integer(T &x) {
    if (pil + 100 > pir)
        load();
    char c;
    do
        c = ibuf[pil++];
    while (c < '-');
    bool minus = 0;
    if constexpr (is_signed<T>::value || is_same_v<T, i128>) {
        if (c == '-') {
            minus = 1, c = ibuf[pil++];
        }
    }
    x = 0;
    while ('0' <= c) {
        x = x * 10 + (c & 15), c = ibuf[pil++];
    }
    if constexpr (is_signed<T>::value || is_same_v<T, i128>) {
        if (minus)
            x = -x;
    }
}

void rd(int &x) {
    rd_integer(x);
}
void rd(ll &x) {
    rd_integer(x);
}
void rd(i128 &x) {
    rd_integer(x);
}
void rd(uint &x) {
    rd_integer(x);
}
void rd(ull &x) {
    rd_integer(x);
}
void rd(u128 &x) {
    rd_integer(x);
}
void rd(double &x) {
    rd_real(x);
}
void rd(long double &x) {
    rd_real(x);
}

template <class T, class U> void rd(pair<T, U> &p) {
    return rd(p.first), rd(p.second);
}
template <size_t N = 0, typename T> void rd_tuple(T &t) {
    if constexpr (N < std::tuple_size<T>::value) {
        auto &x = std::get<N>(t);
        rd(x);
        rd_tuple<N + 1>(t);
    }
}
template <class... T> void rd(tuple<T...> &tpl) {
    rd_tuple(tpl);
}

template <size_t N = 0, typename T> void rd(array<T, N> &x) {
    for (auto &d : x)
        rd(d);
}
template <class T> void rd(vector<T> &x) {
    for (auto &d : x)
        rd(d);
}

void read() {}
template <class H, class... T> void read(H &h, T &...t) {
    rd(h), read(t...);
}

void wt(const char c) {
    if (por == SZ)
        flush();
    obuf[por++] = c;
}
void wt(const string s) {
    for (char c : s)
        wt(c);
}
void wt(const char *s) {
    size_t len = strlen(s);
    for (size_t i = 0; i < len; i++)
        wt(s[i]);
}

template <typename T> void wt_integer(T x) {
    if (por > SZ - 100)
        flush();
    if (x < 0) {
        obuf[por++] = '-', x = -x;
    }
    int outi;
    for (outi = 96; x >= 10000; outi -= 4) {
        memcpy(out + outi, pre.num[x % 10000], 4);
        x /= 10000;
    }
    if (x >= 1000) {
        memcpy(obuf + por, pre.num[x], 4);
        por += 4;
    } else if (x >= 100) {
        memcpy(obuf + por, pre.num[x] + 1, 3);
        por += 3;
    } else if (x >= 10) {
        int q = (x * 103) >> 10;
        obuf[por] = q | '0';
        obuf[por + 1] = (x - q * 10) | '0';
        por += 2;
    } else
        obuf[por++] = x | '0';
    memcpy(obuf + por, out + outi + 4, 96 - outi);
    por += 96 - outi;
}

template <typename T> void wt_real(T x) {
    ostringstream oss;
    oss << fixed << setprecision(15) << double(x);
    string s = oss.str();
    wt(s);
}

void wt(int x) {
    wt_integer(x);
}
void wt(ll x) {
    wt_integer(x);
}
void wt(i128 x) {
    wt_integer(x);
}
void wt(uint x) {
    wt_integer(x);
}
void wt(ull x) {
    wt_integer(x);
}
void wt(u128 x) {
    wt_integer(x);
}
void wt(double x) {
    wt_real(x);
}
void wt(long double x) {
    wt_real(x);
}

template <class T, class U> void wt(const pair<T, U> val) {
    wt(val.first);
    wt(' ');
    wt(val.second);
}
template <size_t N = 0, typename T> void wt_tuple(const T t) {
    if constexpr (N < std::tuple_size<T>::value) {
        if constexpr (N > 0) {
            wt(' ');
        }
        const auto x = std::get<N>(t);
        wt(x);
        wt_tuple<N + 1>(t);
    }
}
template <class... T> void wt(tuple<T...> tpl) {
    wt_tuple(tpl);
}
template <class T, size_t S> void wt(const array<T, S> val) {
    auto n = val.size();
    for (size_t i = 0; i < n; i++) {
        if (i)
            wt(' ');
        wt(val[i]);
    }
}
template <class T> void wt(const vector<T> val) {
    auto n = val.size();
    for (size_t i = 0; i < n; i++) {
        if (i)
            wt(' ');
        wt(val[i]);
    }
}

void print() {
    wt('\n');
}
template <class Head, class... Tail> void print(Head &&head, Tail &&...tail) {
    wt(head);
    if (sizeof...(Tail))
        wt(' ');
    print(forward<Tail>(tail)...);
}
void __attribute__((destructor)) _d() {
    flush();
}
} // namespace fastio


using fastio::flush;
using fastio::print;
using fastio::read;

inline void first(bool i = true) {
    print(i ? "first" : "second");
}
inline void Alice(bool i = true) {
    print(i ? "Alice" : "Bob");
}
inline void Takahashi(bool i = true) {
    print(i ? "Takahashi" : "Aoki");
}
inline void yes(bool i = true) {
    print(i ? "yes" : "no");
}
inline void Yes(bool i = true) {
    print(i ? "Yes" : "No");
}
inline void No() {
    print("No");
}
inline void YES(bool i = true) {
    print(i ? "YES" : "NO");
}
inline void NO() {
    print("NO");
}
inline void Yay(bool i = true) {
    print(i ? "Yay!" : ":(");
}
inline void Possible(bool i = true) {
    print(i ? "Possible" : "Impossible");
}
inline void POSSIBLE(bool i = true) {
    print(i ? "POSSIBLE" : "IMPOSSIBLE");
}

/**
 * @brief Fast IO
 */

template <unsigned mod = 1000000007> struct fp {
    unsigned v;
    static constexpr int get_mod() {
        return mod;
    }
    constexpr unsigned inv() const {
        assert(v != 0);
        int x = v, y = mod, p = 1, q = 0, t = 0, tmp = 0;
        while (y > 0) {
            t = x / y;
            x -= t * y, p -= t * q;
            tmp = x, x = y, y = tmp;
            tmp = p, p = q, q = tmp;
        }
        if (p < 0)
            p += mod;
        return p;
    }
    constexpr fp(ll x = 0) : v(x >= 0 ? x % mod : (mod - (-x) % mod) % mod) {}
    fp operator-() const {
        return fp() - *this;
    }
    fp pow(ull t) {
        fp res = 1, b = *this;
        while (t) {
            if (t & 1)
                res *= b;
            b *= b;
            t >>= 1;
        }
        return res;
    }
    fp &operator+=(const fp &x) {
        if ((v += x.v) >= mod)
            v -= mod;
        return *this;
    }
    fp &operator-=(const fp &x) {
        if ((v += mod - x.v) >= mod)
            v -= mod;
        return *this;
    }
    fp &operator*=(const fp &x) {
        v = ull(v) * x.v % mod;
        return *this;
    }
    fp &operator/=(const fp &x) {
        v = ull(v) * x.inv() % mod;
        return *this;
    }
    fp operator+(const fp &x) const {
        return fp(*this) += x;
    }
    fp operator-(const fp &x) const {
        return fp(*this) -= x;
    }
    fp operator*(const fp &x) const {
        return fp(*this) *= x;
    }
    fp operator/(const fp &x) const {
        return fp(*this) /= x;
    }
    bool operator==(const fp &x) const {
        return v == x.v;
    }
    bool operator!=(const fp &x) const {
        return v != x.v;
    }
    friend istream &operator>>(istream &is, fp &x) {
        return is >> x.v;
    }
    friend ostream &operator<<(ostream &os, const fp &x) {
        return os << x.v;
    }
};

template <unsigned mod> void rd(fp<mod> &x) {
    fastio::rd(x.v);
}
template <unsigned mod> void wt(fp<mod> x) {
    fastio::wt(x.v);
}

template <typename T> T Inv(ll n) {
    static const int md = T::get_mod();
    static vector<T> buf({0, 1});
    assert(n > 0);
    n %= md;
    while (SZ(buf) <= n) {
        int k = SZ(buf), q = (md + k - 1) / k;
        buf.push_back(buf[k * q - md] * q);
    }
    return buf[n];
}

template <typename T> T Fact(ll n, bool inv = 0) {
    static const int md = T::get_mod();
    static vector<T> buf({1, 1}), ibuf({1, 1});
    assert(n >= 0 and n < md);
    while (SZ(buf) <= n) {
        buf.push_back(buf.back() * SZ(buf));
        ibuf.push_back(ibuf.back() * Inv<T>(SZ(ibuf)));
    }
    return inv ? ibuf[n] : buf[n];
}

template <typename T> T nPr(int n, int r, bool inv = 0) {
    if (n < 0 || n < r || r < 0)
        return 0;
    return Fact<T>(n, inv) * Fact<T>(n - r, inv ^ 1);
}
template <typename T> T nCr(int n, int r, bool inv = 0) {
    if (n < 0 || n < r || r < 0)
        return 0;
    return Fact<T>(n, inv) * Fact<T>(r, inv ^ 1) * Fact<T>(n - r, inv ^ 1);
}
template <typename T> T nHr(int n, int r, bool inv = 0) {
    return nCr<T>(n + r - 1, r, inv);
}

/**
 * @brief Modint
 */

template <class T> struct Matrix {
    int h, w;
    vector<vector<T>> val;
    T det;
    Matrix() {}
    Matrix(int n) : h(n), w(n), val(vector<vector<T>>(n, vector<T>(n))) {}
    Matrix(int n, int m)
        : h(n), w(m), val(vector<vector<T>>(n, vector<T>(m))) {}
    vector<T> &operator[](const int i) {
        return val[i];
    }
    Matrix &operator+=(const Matrix &m) {
        assert(h == m.h and w == m.w);
        rep(i, 0, h) rep(j, 0, w) val[i][j] += m.val[i][j];
        return *this;
    }
    Matrix &operator-=(const Matrix &m) {
        assert(h == m.h and w == m.w);
        rep(i, 0, h) rep(j, 0, w) val[i][j] -= m.val[i][j];
        return *this;
    }
    Matrix &operator*=(const Matrix &m) {
        assert(w == m.h);
        Matrix<T> res(h, m.w);
        rep(i, 0, h) rep(j, 0, m.w) rep(k, 0, w) res.val[i][j] +=
            val[i][k] * m.val[k][j];
        *this = res;
        return *this;
    }
    Matrix operator+(const Matrix &m) const {
        return Matrix(*this) += m;
    }
    Matrix operator-(const Matrix &m) const {
        return Matrix(*this) -= m;
    }
    Matrix operator*(const Matrix &m) const {
        return Matrix(*this) *= m;
    }
    Matrix pow(ll k) {
        Matrix<T> res(h, h), c = *this;
        rep(i, 0, h) res.val[i][i] = 1;
        while (k) {
            if (k & 1)
                res *= c;
            c *= c;
            k >>= 1;
        }
        return res;
    }
    vector<int> gauss(int c = -1) {
        det = 1;
        if (val.empty())
            return {};
        if (c == -1)
            c = w;
        int cur = 0;
        vector<int> res;
        rep(i, 0, c) {
            if (cur == h)
                break;
            rep(j, cur, h) if (val[j][i] != 0) {
                swap(val[cur], val[j]);
                if (cur != j)
                    det *= -1;
                break;
            }
            det *= val[cur][i];
            if (val[cur][i] == 0)
                continue;
            rep(j, 0, h) if (j != cur) {
                T z = val[j][i] / val[cur][i];
                rep(k, i, w) val[j][k] -= val[cur][k] * z;
            }
            res.push_back(i);
            cur++;
        }
        return res;
    }
    Matrix inv() {
        assert(h == w);
        Matrix base(h, h * 2), res(h, h);
        rep(i, 0, h) rep(j, 0, h) base[i][j] = val[i][j];
        rep(i, 0, h) base[i][h + i] = 1;
        base.gauss(h);
        det = base.det;
        rep(i, 0, h) rep(j, 0, h) res[i][j] = base[i][h + j] / base[i][i];
        return res;
    }
    bool operator==(const Matrix &m) {
        assert(h == m.h and w == m.w);
        rep(i, 0, h) rep(j, 0, w) if (val[i][j] != m.val[i][j]) return false;
        return true;
    }
    bool operator!=(const Matrix &m) {
        assert(h == m.h and w == m.w);
        rep(i, 0, h) rep(j, 0, w) if (val[i][j] == m.val[i][j]) return false;
        return true;
    }
    friend istream &operator>>(istream &is, Matrix &m) {
        rep(i, 0, m.h) rep(j, 0, m.w) is >> m[i][j];
        return is;
    }
    friend ostream &operator<<(ostream &os, Matrix &m) {
        rep(i, 0, m.h) {
            rep(j, 0, m.w) os << m[i][j]
                              << (j == m.w - 1 and i != m.h - 1 ? '\n' : ' ');
        }
        return os;
    }
};

/**
 * @brief Matrix
 */

struct SCC{
    int n,m,cur;
    vector<vector<int>> g;
    vector<int> low,ord,id;
    SCC(int _n=0):n(_n),m(0),cur(0),g(_n),low(_n),ord(_n,-1),id(_n){}
    void resize(int _n){
        n=_n;
        g.resize(n);
        low.resize(n);
        ord.resize(n,-1);
        id.resize(n);
    }
    void add_edge(int u,int v){g[u].emplace_back(v);}
    void dfs(int v,vector<int>& used){
        ord[v]=low[v]=cur++;
        used.emplace_back(v);
        for(auto& nxt:g[v]){
            if(ord[nxt]==-1){
                dfs(nxt,used); chmin(low[v],low[nxt]);
            }
            else{
                chmin(low[v],ord[nxt]);
            }
        }
        if(ord[v]==low[v]){
            while(1){
                int add=used.back(); used.pop_back();
                ord[add]=n; id[add]=m;
                if(v==add)break;
            }
            m++;
        }
    }
    void run(){
        vector<int> used;
        rep(v,0,n)if(ord[v]==-1)dfs(v,used);
        for(auto& x:id)x=m-1-x;
    }
};

/**
 * @brief Strongly Connected Components
 */

using Fp = fp<1000000007>;

int main() {
    int N, M, S;
    cin >> N >> M >> S;
    S--;
    vector<int> A(M), B(M);
    vector<vector<int>> C(N);
    SCC G(N);
    rep(i,0,M) {
        cin >> A[i] >> B[i];
        A[i]--, B[i]--;
        C[A[i]].push_back(B[i]);
        G.add_edge(A[i],B[i]);
    }
    if (C[S].size() == 0) {
        cout << 0 << endl;
        return 0;
    }
    G.run();
    Matrix<Fp> X(N+1);
    bool check = false;
    rep(i,0,N) {
        if (G.id[i] == G.id[S]) {
            Fp D = C[i].size();
            D = (Fp)1 / D;
            for (int NP : C[i]) {
                if (G.id[NP] != G.id[S]) check = true;
                X[i][NP] += D;
            }
            X[i][i] -= (Fp)1;
            X[i][N] = 1;
        }
        else {
            X[i][i] = 1;
        }
    }
    if (!check) {
        cout << -1 << endl;
        return 0;
    }
    X[N][N] = 1;
    X = X.inv();
    cout << X[S][N] << endl;
}
accuracy: 1
time_ms: 20
memory_kb: 3816
final_rank: 4

code_snippet: #include <bits/stdc++.h>
using namespace std;
#define rep(i, m, n) for (auto i = (m); i < (n); i++)
#define rept(i, n) rep(i, 0, n)
#define repr(i, m, n) for (auto i = (m); i-- > (n);)
#define reptr(i, n) repr(i, 0, n)
#define all(x) begin(x), end(x)
#define sz(x) (int)size(x)
using ll = long long;
using ull = unsigned long long;
using vi = vector<int>;
using vvi = vector<vector<int>>;
using vll = vector<ll>;
using vc = vector<char>;
using pii = pair<int, int>;

constexpr ull MOD = 1e9+7;

ull mpow(ull b, ull e) {
	ull res = 1;
	for (b %= MOD; e; e /= 2, b = b*b % MOD) {
		if (e % 2) res = res*b % MOD;
	}
	return res;
}

ull mdiv(ull a, ull b) {
	assert(b != 0);
	return a * mpow(b, MOD - 2) % MOD;
}

constexpr int MaxN = 200;
int n, m, start;
vi G[MaxN], revG[MaxN];
ull M[MaxN][MaxN+1];
bool reachable[MaxN];

void dfs(int v, int p) {
	reachable[v] = true;
	for (auto u : revG[v]) if (u != p && !reachable[u]) dfs(u, v);
}

void mul(int i, ll alpha) {
	rept(j, n+1) {
		M[i][j] = M[i][j] * alpha % MOD;
	}
}

void sub(int i0, int i1, ll alpha) {
	rept(j, n+1) {
		M[i1][j] -= M[i0][j] * alpha % MOD;
		M[i1][j] += (M[i1][j] >= MOD) * MOD;
	}
}

void solve() {
	scanf("%d%d%d", &n, &m, &start), start--;
	while (m--) {
		int u, v; scanf("%d%d", &u, &v);
		u--, v--;
		G[u].push_back(v);
		revG[v].push_back(u);
	}
	dfs(start, -1);

	rept(i, n) M[i][i] = 1;
	rept(u, n) if (reachable[u] && !G[u].empty()) {
		M[u][n] = 1;
		ull p = mdiv(1, G[u].size());
		for (auto v : G[u]) M[u][v] = (M[u][v] + MOD - p) % MOD;
	}

	rept(i, n) {
		if (M[i][i] == 0) return printf("-1\n"), void();
		mul(i, mdiv(1, M[i][i]));
		rept(i1, n) if (i1 != i) sub(i, i1, M[i1][i]);
	}
	rept(i, n) rept(j, n) assert(M[i][j] == (i == j));
	printf("%lld\n", M[start][n]);
}

int main() {
	int n = 1;
	// scanf("%d", &n);
	while (n--) solve();
}
accuracy: 1
time_ms: 10
memory_kb: 3856
final_rank: 2

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

#ifndef ATCODER_MODINT_HPP
#define ATCODER_MODINT_HPP 1
#ifndef ATCODER_INTERNAL_MATH_HPP
#define ATCODER_INTERNAL_MATH_HPP 1

#include <utility>

namespace atcoder {

namespace internal {

// @param m `1 <= m`
// @return x mod m
constexpr long long safe_mod(long long x, long long m) {
    x %= m;
    if (x < 0) x += m;
    return x;
}

// Fast modular multiplication by barrett reduction
// Reference: https://en.wikipedia.org/wiki/Barrett_reduction
// NOTE: reconsider after Ice Lake
struct barrett {
    unsigned int _m;
    unsigned long long im;

    // @param m `1 <= m < 2^31`
    barrett(unsigned int m) : _m(m), im((unsigned long long)(-1) / m + 1) {}

    // @return m
    unsigned int umod() const { return _m; }

    // @param a `0 <= a < m`
    // @param b `0 <= b < m`
    // @return `a * b % m`
    unsigned int mul(unsigned int a, unsigned int b) const {
        // [1] m = 1
        // a = b = im = 0, so okay

        // [2] m >= 2
        // im = ceil(2^64 / m)
        // -> im * m = 2^64 + r (0 <= r < m)
        // let z = a*b = c*m + d (0 <= c, d < m)
        // a*b * im = (c*m + d) * im = c*(im*m) + d*im = c*2^64 + c*r + d*im
        // c*r + d*im < m * m + m * im < m * m + 2^64 + m <= 2^64 + m * (m + 1) < 2^64 * 2
        // ((ab * im) >> 64) == c or c + 1
        unsigned long long z = a;
        z *= b;
#ifdef _MSC_VER
        unsigned long long x;
        _umul128(z, im, &x);
#else
        unsigned long long x =
            (unsigned long long)(((unsigned __int128)(z)*im) >> 64);
#endif
        unsigned int v = (unsigned int)(z - x * _m);
        if (_m <= v) v += _m;
        return v;
    }
};

// @param n `0 <= n`
// @param m `1 <= m`
// @return `(x ** n) % m`
constexpr long long pow_mod_constexpr(long long x, long long n, int m) {
    if (m == 1) return 0;
    unsigned int _m = (unsigned int)(m);
    unsigned long long r = 1;
    unsigned long long y = safe_mod(x, m);
    while (n) {
        if (n & 1) r = (r * y) % _m;
        y = (y * y) % _m;
        n >>= 1;
    }
    return r;
}

// Reference:
// M. Forisek and J. Jancina,
// Fast Primality Testing for Integers That Fit into a Machine Word
// @param n `0 <= n`
constexpr bool is_prime_constexpr(int n) {
    if (n <= 1) return false;
    if (n == 2 || n == 7 || n == 61) return true;
    if (n % 2 == 0) return false;
    long long d = n - 1;
    while (d % 2 == 0) d /= 2;
    constexpr long long bases[3] = {2, 7, 61};
    for (long long a : bases) {
        long long t = d;
        long long y = pow_mod_constexpr(a, t, n);
        while (t != n - 1 && y != 1 && y != n - 1) {
            y = y * y % n;
            t <<= 1;
        }
        if (y != n - 1 && t % 2 == 0) {
            return false;
        }
    }
    return true;
}
template <int n> constexpr bool is_prime = is_prime_constexpr(n);

// @param b `1 <= b`
// @return pair(g, x) s.t. g = gcd(a, b), xa = g (mod b), 0 <= x < b/g
constexpr std::pair<long long, long long> inv_gcd(long long a, long long b) {
    a = safe_mod(a, b);
    if (a == 0) return {b, 0};

    // Contracts:
    // [1] s - m0 * a = 0 (mod b)
    // [2] t - m1 * a = 0 (mod b)
    // [3] s * |m1| + t * |m0| <= b
    long long s = b, t = a;
    long long m0 = 0, m1 = 1;

    while (t) {
        long long u = s / t;
        s -= t * u;
        m0 -= m1 * u;  // |m1 * u| <= |m1| * s <= b

        // [3]:
        // (s - t * u) * |m1| + t * |m0 - m1 * u|
        // <= s * |m1| - t * u * |m1| + t * (|m0| + |m1| * u)
        // = s * |m1| + t * |m0| <= b

        auto tmp = s;
        s = t;
        t = tmp;
        tmp = m0;
        m0 = m1;
        m1 = tmp;
    }
    // by [3]: |m0| <= b/g
    // by g != b: |m0| < b/g
    if (m0 < 0) m0 += b / s;
    return {s, m0};
}

// Compile time primitive root
// @param m must be prime
// @return primitive root (and minimum in now)
constexpr int primitive_root_constexpr(int m) {
    if (m == 2) return 1;
    if (m == 167772161) return 3;
    if (m == 469762049) return 3;
    if (m == 754974721) return 11;
    if (m == 998244353) return 3;
    int divs[20] = {};
    divs[0] = 2;
    int cnt = 1;
    int x = (m - 1) / 2;
    while (x % 2 == 0) x /= 2;
    for (int i = 3; (long long)(i)*i <= x; i += 2) {
        if (x % i == 0) {
            divs[cnt++] = i;
            while (x % i == 0) {
                x /= i;
            }
        }
    }
    if (x > 1) {
        divs[cnt++] = x;
    }
    for (int g = 2;; g++) {
        bool ok = true;
        for (int i = 0; i < cnt; i++) {
            if (pow_mod_constexpr(g, (m - 1) / divs[i], m) == 1) {
                ok = false;
                break;
            }
        }
        if (ok) return g;
    }
}
template <int m> constexpr int primitive_root = primitive_root_constexpr(m);

}  // namespace internal

}  // namespace atcoder

#endif  // ATCODER_INTERNAL_MATH_HPP
#ifndef ATCODER_INTERNAL_TYPE_TRAITS_HPP
#define ATCODER_INTERNAL_TYPE_TRAITS_HPP 1

#include <cassert>
#include <numeric>
#include <type_traits>

namespace atcoder {

namespace internal {

#ifndef _MSC_VER
template <class T>
using is_signed_int128 =
    typename std::conditional<std::is_same<T, __int128_t>::value ||
                                  std::is_same<T, __int128>::value,
                              std::true_type,
                              std::false_type>::type;

template <class T>
using is_unsigned_int128 =
    typename std::conditional<std::is_same<T, __uint128_t>::value ||
                                  std::is_same<T, unsigned __int128>::value,
                              std::true_type,
                              std::false_type>::type;

template <class T>
using make_unsigned_int128 =
    typename std::conditional<std::is_same<T, __int128_t>::value,
                              __uint128_t,
                              unsigned __int128>;

template <class T>
using is_integral = typename std::conditional<std::is_integral<T>::value ||
                                                  is_signed_int128<T>::value ||
                                                  is_unsigned_int128<T>::value,
                                              std::true_type,
                                              std::false_type>::type;

template <class T>
using is_signed_int = typename std::conditional<(is_integral<T>::value &&
                                                 std::is_signed<T>::value) ||
                                                    is_signed_int128<T>::value,
                                                std::true_type,
                                                std::false_type>::type;

template <class T>
using is_unsigned_int =
    typename std::conditional<(is_integral<T>::value &&
                               std::is_unsigned<T>::value) ||
                                  is_unsigned_int128<T>::value,
                              std::true_type,
                              std::false_type>::type;

template <class T>
using to_unsigned = typename std::conditional<
    is_signed_int128<T>::value,
    make_unsigned_int128<T>,
    typename std::conditional<std::is_signed<T>::value,
                              std::make_unsigned<T>,
                              std::common_type<T>>::type>::type;

#else

template <class T> using is_integral = typename std::is_integral<T>;

template <class T>
using is_signed_int =
    typename std::conditional<is_integral<T>::value && std::is_signed<T>::value,
                              std::true_type,
                              std::false_type>::type;

template <class T>
using is_unsigned_int =
    typename std::conditional<is_integral<T>::value &&
                                  std::is_unsigned<T>::value,
                              std::true_type,
                              std::false_type>::type;

template <class T>
using to_unsigned = typename std::conditional<is_signed_int<T>::value,
                                              std::make_unsigned<T>,
                                              std::common_type<T>>::type;

#endif

template <class T>
using is_signed_int_t = std::enable_if_t<is_signed_int<T>::value>;

template <class T>
using is_unsigned_int_t = std::enable_if_t<is_unsigned_int<T>::value>;

template <class T> using to_unsigned_t = typename to_unsigned<T>::type;

}  // namespace internal

}  // namespace atcoder

#endif  // ATCODER_INTERNAL_TYPE_TRAITS_HPP

#include <cassert>
#include <numeric>
#include <type_traits>

#ifdef _MSC_VER
#include <intrin.h>
#endif

namespace atcoder {

namespace internal {

struct modint_base {};
struct static_modint_base : modint_base {};

template <class T> using is_modint = std::is_base_of<modint_base, T>;
template <class T> using is_modint_t = std::enable_if_t<is_modint<T>::value>;

}  // namespace internal

template <int m, std::enable_if_t<(1 <= m)>* = nullptr>
struct static_modint : internal::static_modint_base {
    using mint = static_modint;

  public:
    static constexpr int mod() { return m; }
    static mint raw(int v) {
        mint x;
        x._v = v;
        return x;
    }

    static_modint() : _v(0) {}
    template <class T, internal::is_signed_int_t<T>* = nullptr>
    static_modint(T v) {
        long long x = (long long)(v % (long long)(umod()));
        if (x < 0) x += umod();
        _v = (unsigned int)(x);
    }
    template <class T, internal::is_unsigned_int_t<T>* = nullptr>
    static_modint(T v) {
        _v = (unsigned int)(v % umod());
    }
    static_modint(bool v) { _v = ((unsigned int)(v) % umod()); }

    unsigned int val() const { return _v; }

    mint& operator++() {
        _v++;
        if (_v == umod()) _v = 0;
        return *this;
    }
    mint& operator--() {
        if (_v == 0) _v = umod();
        _v--;
        return *this;
    }
    mint operator++(int) {
        mint result = *this;
        ++*this;
        return result;
    }
    mint operator--(int) {
        mint result = *this;
        --*this;
        return result;
    }

    mint& operator+=(const mint& rhs) {
        _v += rhs._v;
        if (_v >= umod()) _v -= umod();
        return *this;
    }
    mint& operator-=(const mint& rhs) {
        _v -= rhs._v;
        if (_v >= umod()) _v += umod();
        return *this;
    }
    mint& operator*=(const mint& rhs) {
        unsigned long long z = _v;
        z *= rhs._v;
        _v = (unsigned int)(z % umod());
        return *this;
    }
    mint& operator/=(const mint& rhs) { return *this = *this * rhs.inv(); }

    mint operator+() const { return *this; }
    mint operator-() const { return mint() - *this; }

    mint pow(long long n) const {
        assert(0 <= n);
        mint x = *this, r = 1;
        while (n) {
            if (n & 1) r *= x;
            x *= x;
            n >>= 1;
        }
        return r;
    }
    mint inv() const {
        if (prime) {
            assert(_v);
            return pow(umod() - 2);
        } else {
            auto eg = internal::inv_gcd(_v, m);
            assert(eg.first == 1);
            return eg.second;
        }
    }

    friend mint operator+(const mint& lhs, const mint& rhs) {
        return mint(lhs) += rhs;
    }
    friend mint operator-(const mint& lhs, const mint& rhs) {
        return mint(lhs) -= rhs;
    }
    friend mint operator*(const mint& lhs, const mint& rhs) {
        return mint(lhs) *= rhs;
    }
    friend mint operator/(const mint& lhs, const mint& rhs) {
        return mint(lhs) /= rhs;
    }
    friend bool operator==(const mint& lhs, const mint& rhs) {
        return lhs._v == rhs._v;
    }
    friend bool operator!=(const mint& lhs, const mint& rhs) {
        return lhs._v != rhs._v;
    }

  private:
    unsigned int _v;
    static constexpr unsigned int umod() { return m; }
    static constexpr bool prime = internal::is_prime<m>;
};

template <int id> struct dynamic_modint : internal::modint_base {
    using mint = dynamic_modint;

  public:
    static int mod() { return (int)(bt.umod()); }
    static void set_mod(int m) {
        assert(1 <= m);
        bt = internal::barrett(m);
    }
    static mint raw(int v) {
        mint x;
        x._v = v;
        return x;
    }

    dynamic_modint() : _v(0) {}
    template <class T, internal::is_signed_int_t<T>* = nullptr>
    dynamic_modint(T v) {
        long long x = (long long)(v % (long long)(mod()));
        if (x < 0) x += mod();
        _v = (unsigned int)(x);
    }
    template <class T, internal::is_unsigned_int_t<T>* = nullptr>
    dynamic_modint(T v) {
        _v = (unsigned int)(v % mod());
    }
    dynamic_modint(bool v) { _v = ((unsigned int)(v) % mod()); }

    unsigned int val() const { return _v; }

    mint& operator++() {
        _v++;
        if (_v == umod()) _v = 0;
        return *this;
    }
    mint& operator--() {
        if (_v == 0) _v = umod();
        _v--;
        return *this;
    }
    mint operator++(int) {
        mint result = *this;
        ++*this;
        return result;
    }
    mint operator--(int) {
        mint result = *this;
        --*this;
        return result;
    }

    mint& operator+=(const mint& rhs) {
        _v += rhs._v;
        if (_v >= umod()) _v -= umod();
        return *this;
    }
    mint& operator-=(const mint& rhs) {
        _v += mod() - rhs._v;
        if (_v >= umod()) _v -= umod();
        return *this;
    }
    mint& operator*=(const mint& rhs) {
        _v = bt.mul(_v, rhs._v);
        return *this;
    }
    mint& operator/=(const mint& rhs) { return *this = *this * rhs.inv(); }

    mint operator+() const { return *this; }
    mint operator-() const { return mint() - *this; }

    mint pow(long long n) const {
        assert(0 <= n);
        mint x = *this, r = 1;
        while (n) {
            if (n & 1) r *= x;
            x *= x;
            n >>= 1;
        }
        return r;
    }
    mint inv() const {
        auto eg = internal::inv_gcd(_v, mod());
        assert(eg.first == 1);
        return eg.second;
    }

    friend mint operator+(const mint& lhs, const mint& rhs) {
        return mint(lhs) += rhs;
    }
    friend mint operator-(const mint& lhs, const mint& rhs) {
        return mint(lhs) -= rhs;
    }
    friend mint operator*(const mint& lhs, const mint& rhs) {
        return mint(lhs) *= rhs;
    }
    friend mint operator/(const mint& lhs, const mint& rhs) {
        return mint(lhs) /= rhs;
    }
    friend bool operator==(const mint& lhs, const mint& rhs) {
        return lhs._v == rhs._v;
    }
    friend bool operator!=(const mint& lhs, const mint& rhs) {
        return lhs._v != rhs._v;
    }

  private:
    unsigned int _v;
    static internal::barrett bt;
    static unsigned int umod() { return bt.umod(); }
};
template <int id> internal::barrett dynamic_modint<id>::bt = 998244353;

using modint998244353 = static_modint<998244353>;
using modint1000000007 = static_modint<1000000007>;
using modint = dynamic_modint<-1>;

namespace internal {

template <class T>
using is_static_modint = std::is_base_of<internal::static_modint_base, T>;

template <class T>
using is_static_modint_t = std::enable_if_t<is_static_modint<T>::value>;

template <class> struct is_dynamic_modint : public std::false_type {};
template <int id>
struct is_dynamic_modint<dynamic_modint<id>> : public std::true_type {};

template <class T>
using is_dynamic_modint_t = std::enable_if_t<is_dynamic_modint<T>::value>;

}  // namespace internal

}  // namespace atcoder

#endif  // ATCODER_MODINT_HPP

using namespace atcoder;
using mint = modint1000000007;

template <class T>
struct Matrix {
  vector<vector<T> > val;
  Matrix(int n, int m, T x = 0) : val(n, vector<T>(m, x)) {}
  void init(int n, int m, T x = 0) { val.assign(n, vector<T>(m, x)); }
  size_t size() const { return val.size(); }
  inline vector<T>& operator[](int i) { return val[i]; }
};

template <class T>
int GaussJordan(Matrix<T>& A, bool is_extended = false) {
  int m = A.size(), n = A[0].size();
  int rank = 0;
  for (int col = 0; col < n; ++col) {
    // 拡大係数行列の場合は最後の列は掃き出ししない
    if (is_extended && col == n - 1) break;

    // ピボットを探す
    int pivot = -1;
    T ma = 0;
    for (int row = rank; row < m; ++row) {
      if (A[row][col] != 0) {
        ma = A[row][col];
        pivot = row;
      }
    }
    // ピボットがなかったら次の列へ
    if (pivot == -1) continue;

    // まずは行を swap
    swap(A[pivot], A[rank]);

    // ピボットの値を 1 にする
    auto fac = A[rank][col];
    for (int col2 = 0; col2 < n; ++col2) A[rank][col2] /= fac;

    // ピボットのある列の値がすべて 0 になるように掃き出す
    for (int row = 0; row < m; ++row) {
      if (row != rank && A[row][col] != 0) {
        auto fac = A[row][col];
        for (int col2 = 0; col2 < n; ++col2) {
          A[row][col2] -= A[rank][col2] * fac;
        }
      }
    }
    ++rank;
  }
  return rank;
}

template <class T>
vector<T> linear_equation(Matrix<T> A, vector<T> b) {
  // extended
  int m = A.size(), n = A[0].size();
  Matrix<T> M(m, n + 1);
  for (int i = 0; i < m; ++i) {
    for (int j = 0; j < n; ++j) M[i][j] = A[i][j];
    M[i][n] = b[i];
  }
  int rank = GaussJordan(M, true);

  // check if it has no solution
  vector<T> res;
  for (int row = rank; row < m; ++row)
    if (M[row][n] != 0) return res;

  // answer
  res.assign(n, 0);
  for (int i = 0; i < rank; ++i) res[i] = M[i][n];
  return res;
}

int main() {
    int N, M, S; cin >> N >> M >> S;
    S--;
    Matrix<mint> mat(N, N, 0);
    vector<int> deg(N, 0);
    vector<vector<int>> graph(N);
    for (int i = 0; i < M; ++i) {
        int u, v; cin >> u >> v;
        u--, v--;
        deg[u] += 1;
        mat[u][v] = 1;
        graph[u].emplace_back(v);
    }
    vector<bool> reach(N, false);
    for (int i = 0; i < N; ++i) {
        vector<bool> tmp(N, false);
        tmp[i] = true;
        queue<int> que;
        que.push(i);
        
        while (que.size()) {
            int v = que.front();
            que.pop();
            for (auto nv : graph[v]) {
                if (tmp[nv]) continue;
                tmp[nv] = true;
                que.push(nv);
            }
        }
        
        if (tmp[S]) reach[i] = true;
        else reach[i] = false;
    }
    
    
    for (int u = 0; u < N; ++u) {
        if (reach[u] && deg[u] > 0) {
            mint inv = (mint)1 / deg[u];
            for (int v = 0; v < N; ++v) mat[u][v] *= inv;
        }
        else {
            for (int v = 0; v < N; ++v) mat[u][v] = 0;
        }
        mat[u][u] -= 1;
    }
    
    vector<mint> m1(N, mint(-1));
    for (int i = 0; i < N; ++i) {
        if (reach[i] && deg[i] > 0) m1[i] = mint(-1);
        else m1[i] = 0;
    }
    // vector<mint> ans(N, 0);
    // int rank = linear_equation(mat, m1, ans);
    vector<mint> ans = linear_equation(mat, m1);
    
    if (ans.size() == 0) {
        cout << -1 << endl;
    }
    else {
        // for (int i = 0; i < ans.size(); ++i) {
        //     cout << i << " " << ans[i].val() << endl;
        // }
        cout << ans[S].val() << endl;
    }
    
    return 0;
}
accuracy: 1
time_ms: 10
memory_kb: 3956
final_rank: 3

code_snippet: #include<bits/stdc++.h>
using namespace std;
using ll = long long;
using vll = vector<ll>;
using vvll = vector<vll>;
#define rep(i,n) for(ll i=0;i<ll(n);i++)

const ll mod = 1e9 + 7;
ll modpow(ll a, ll n) {
    if (n == 0)return 1;
    if (n % 2 == 1)return (a * modpow(a, n - 1)) % mod;
    ll t = modpow(a, n / 2);
    return (t * t) % mod;
}

unordered_map<ll, ll> INV;
ll inv(ll n) {
    if (!INV.count(n))INV[n] = modpow(n, mod - 2);
    return INV[n];
}

vvll invmat(vvll A) {
    ll n = A.size();
    vvll res(n, vll(n, 0));
    rep(i, n)res[i][i] = 1;
    rep(i, n) {
        bool EX = 0;
        for (ll j = i; j < n; j++) {
            if (A[j][i] == 0)continue;
            swap(A[j], A[i]);
            swap(res[j], res[i]);
            ll d = inv(A[i][i]);
            for (ll k = 0; k < n; k++) {
                if (k == i)continue;
                ll e = (A[k][i] * d) % mod;

                for (ll m = 0; m < n; m++) {
                    A[k][m] -= A[i][m] * e;
                    res[k][m] -= res[i][m] * e;
                    A[k][m] %= mod;
                    if (A[k][m] < 0)A[k][m] += mod;
                    res[k][m] %= mod;
                    if (res[k][m] < 0)res[k][m] += mod;
                }
            }
            for (ll m = 0; m < n; m++) {
                res[i][m] *= d;
                A[i][m] *= d;
                res[i][m] %= mod;
                A[i][m] %= mod;
            }
            EX = 1;
            break;
        }
    }
    return res;
}

int main() {
    ll N, M, S;
    cin >> N >> M >> S;
    S--;
    vvll D(N, vll(N, 1e18));
    vll EN(N, 0);
    rep(i, M) {
        ll U, V;
        cin >> U >> V;
        U--; V--;
        D[U][V] = 1;
        EN[U]++;
    }
    vvll E = D;
    if (EN[S] == 0) {
        cout << 0 << endl;
        return 0;
    }
    rep(k, N)rep(i, N)rep(j, N)D[i][j] = min(D[i][j], D[i][k] + D[k][j]);
    map<ll, ll> MP;
    vector<bool> US(N, 0);
    rep(i, N) {
        if (i==S||(D[S][i] < 1e17 && D[i][S] < 1e17)) {
            MP[i] = MP.size();
            US[i] = 1;
        }
    }
    ll MN = MP.size();
    vvll P(MN, vll(MN, 0));
    rep(i, MN)P[i][i]--;
    bool EXIT = 0;
    rep(i, N) {
        rep(j, N) {
            if (E[i][j] == 1 && US[i] && US[j]) {
                P[MP[i]][MP[j]] += inv(EN[i]);
                P[MP[i]][MP[j]] %= mod;
            }
            if (E[i][j] == 1 && US[i] && !US[j])EXIT = 1;
        }
    }
    if (EXIT == 0) {
        cout << -1 << endl;
        return 0;
    }
    rep(i, MN)rep(j, MN) {
        P[i][j] %= mod;
        if (P[i][j] < 0)P[i][j] += mod;
    }
    P = invmat(P);

    ll an = 0;
    rep(i, MN)an -= P[MP[S]][i];
    an %= mod;
    if (an < 0)an += mod;
    cout << an << endl;

}
accuracy: 1
time_ms: 20
memory_kb: 4960
final_rank: 8

code_snippet: #include <cmath>
#include <vector>
#include <iostream>
#include <iomanip>
#include <fstream>
#include <algorithm>
#include <set>
#include <queue>
#include <string>
#include <map>
#include <stack>
#include <climits>
#include <array>
#include <unordered_set>
#include <unordered_map>
#include <memory>
#include <functional>
#include <cfloat>
#include <numeric>
#include <random>
#include <sstream>
#include <bitset>
#include <complex>
#include <chrono>
#include <cassert>
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>

constexpr int MOD = 1000000007;
long long int gcd(long long int a, long long int b) {
	while (b > 0) {
		std::swap(a, b);
		b %= a;
	}
	return a;
}
long long int power(long long int base, long long int exp) {
	long long int result = 1L;
	while (exp > 0) {
		if (exp & 1) {
			result = result * base % MOD;
		}
		base = base * base % MOD;
		exp >>= 1;
	}
	return result;
}
struct Rational {
	long long int numerator, denominator;
	Rational operator+(const Rational other) const {
		return Rational{ (numerator * other.denominator + other.numerator * denominator) % MOD, denominator * other.denominator % MOD };
	}
	Rational operator-(const Rational other) const {
		return Rational{ (numerator * other.denominator - other.numerator * denominator) % MOD , denominator * other.denominator % MOD };
	}
	Rational operator*(const Rational other) const {
		return Rational{ numerator * other.numerator % MOD, denominator * other.denominator % MOD };
	}
	Rational operator/(const Rational other) const {
		return Rational{ numerator * other.denominator % MOD, denominator * other.numerator % MOD };
	}
	Rational& operator+=(const Rational other) {
		const auto result = *this + other;
		return *this = result;
	}
	Rational& operator-=(const Rational other) {
		const auto result = *this - other;
		return *this = result;
	}
	Rational operator-() const {
		return Rational{ - numerator, denominator };
	}
	int as_result() const {
		return (numerator + MOD) % MOD * power((denominator + MOD) % MOD, MOD - 2) % MOD;
	}
};

int main() {
	int n, m, s; std::cin >> n >> m >> s; --s;
	std::vector<std::vector<int>> nodes(n), reverse(n);
	for (auto i = 0; i < m; ++i) {
		int u, v; std::cin >> u >> v; --u; --v;
		nodes[u].push_back(v);
		reverse[v].push_back(u);
	}
	if (nodes[s].empty()) {
		std::cout << "0\n";
		return 0;
	}
	std::vector<bool> is_end(n, true);
	std::stack<int> stack;
	is_end[s] = false;
	stack.push(s);
	while (!stack.empty()) {
		const auto top = stack.top(); stack.pop();
		for (const auto prev : reverse[top]) {
			if (!is_end[prev]) continue;
			is_end[prev] = false;
			stack.push(prev);
		}
	}
	std::vector<std::vector<Rational>> expression;
	for (auto i = 0; i < n; ++i) {
		std::vector<Rational> columns(n + 1, Rational{ 0, 1 });
		if (!is_end[i]) {
			columns[n] += Rational{ 1, 1 };
			for (const auto next : nodes[i]) {
				columns[next] += Rational{ 1, (int)nodes[i].size() };
			}
		}
		columns[i] -= Rational{ 1, 1 };
		expression.emplace_back(std::move(columns));
	}
	for (auto i = 0; i < n; ++i) {
		int not_zero = -1;
		for (auto j = i; j < n; ++j) {
			if (expression[j][i].numerator != 0) {
				not_zero = j;
				break;
			}
		}
		if (not_zero < 0) continue;
		std::swap(expression[i], expression[not_zero]);
		for (auto j = 0; j < n; ++j) {
			if (i == j) continue;
			const auto ratio = expression[j][i] / expression[i][i];
			for (auto k = 0; k < expression[j].size(); ++k) {
				expression[j][k] -= ratio * expression[i][k];
			}
		}
	}
	if (expression[s][s].numerator == 0 || std::count_if(expression[s].begin(), std::next(expression[s].begin(), n), [](const Rational value) {return value.numerator != 0; }) > 1) {
		std::cout << "-1\n";
		return 0;
	}
	const auto result = -expression[s][n] / expression[s][s];
	std::cout << result.as_result() << '\n';
}
accuracy: 1
time_ms: 30
memory_kb: 4040
final_rank: 7

code_snippet: #include <cassert>
#include <numeric>
#include <type_traits>

#ifdef _MSC_VER
#include <intrin.h>
#endif


#include <utility>

#ifdef _MSC_VER
#include <intrin.h>
#endif

namespace atcoder {

namespace internal {

constexpr long long safe_mod(long long x, long long m) {
    x %= m;
    if (x < 0) x += m;
    return x;
}

struct barrett {
    unsigned int _m;
    unsigned long long im;

    barrett(unsigned int m) : _m(m), im((unsigned long long)(-1) / m + 1) {}

    unsigned int umod() const { return _m; }

    unsigned int mul(unsigned int a, unsigned int b) const {

        unsigned long long z = a;
        z *= b;
#ifdef _MSC_VER
        unsigned long long x;
        _umul128(z, im, &x);
#else
        unsigned long long x =
            (unsigned long long)(((unsigned __int128)(z)*im) >> 64);
#endif
        unsigned int v = (unsigned int)(z - x * _m);
        if (_m <= v) v += _m;
        return v;
    }
};

constexpr long long pow_mod_constexpr(long long x, long long n, int m) {
    if (m == 1) return 0;
    unsigned int _m = (unsigned int)(m);
    unsigned long long r = 1;
    unsigned long long y = safe_mod(x, m);
    while (n) {
        if (n & 1) r = (r * y) % _m;
        y = (y * y) % _m;
        n >>= 1;
    }
    return r;
}

constexpr bool is_prime_constexpr(int n) {
    if (n <= 1) return false;
    if (n == 2 || n == 7 || n == 61) return true;
    if (n % 2 == 0) return false;
    long long d = n - 1;
    while (d % 2 == 0) d /= 2;
    constexpr long long bases[3] = {2, 7, 61};
    for (long long a : bases) {
        long long t = d;
        long long y = pow_mod_constexpr(a, t, n);
        while (t != n - 1 && y != 1 && y != n - 1) {
            y = y * y % n;
            t <<= 1;
        }
        if (y != n - 1 && t % 2 == 0) {
            return false;
        }
    }
    return true;
}
template <int n> constexpr bool is_prime = is_prime_constexpr(n);

constexpr std::pair<long long, long long> inv_gcd(long long a, long long b) {
    a = safe_mod(a, b);
    if (a == 0) return {b, 0};

    long long s = b, t = a;
    long long m0 = 0, m1 = 1;

    while (t) {
        long long u = s / t;
        s -= t * u;
        m0 -= m1 * u;  // |m1 * u| <= |m1| * s <= b


        auto tmp = s;
        s = t;
        t = tmp;
        tmp = m0;
        m0 = m1;
        m1 = tmp;
    }
    if (m0 < 0) m0 += b / s;
    return {s, m0};
}

constexpr int primitive_root_constexpr(int m) {
    if (m == 2) return 1;
    if (m == 167772161) return 3;
    if (m == 469762049) return 3;
    if (m == 754974721) return 11;
    if (m == 998244353) return 3;
    int divs[20] = {};
    divs[0] = 2;
    int cnt = 1;
    int x = (m - 1) / 2;
    while (x % 2 == 0) x /= 2;
    for (int i = 3; (long long)(i)*i <= x; i += 2) {
        if (x % i == 0) {
            divs[cnt++] = i;
            while (x % i == 0) {
                x /= i;
            }
        }
    }
    if (x > 1) {
        divs[cnt++] = x;
    }
    for (int g = 2;; g++) {
        bool ok = true;
        for (int i = 0; i < cnt; i++) {
            if (pow_mod_constexpr(g, (m - 1) / divs[i], m) == 1) {
                ok = false;
                break;
            }
        }
        if (ok) return g;
    }
}
template <int m> constexpr int primitive_root = primitive_root_constexpr(m);

}  // namespace internal

}  // namespace atcoder


#include <cassert>
#include <numeric>
#include <type_traits>

namespace atcoder {

namespace internal {

#ifndef _MSC_VER
template <class T>
using is_signed_int128 =
    typename std::conditional<std::is_same<T, __int128_t>::value ||
                                  std::is_same<T, __int128>::value,
                              std::true_type,
                              std::false_type>::type;

template <class T>
using is_unsigned_int128 =
    typename std::conditional<std::is_same<T, __uint128_t>::value ||
                                  std::is_same<T, unsigned __int128>::value,
                              std::true_type,
                              std::false_type>::type;

template <class T>
using make_unsigned_int128 =
    typename std::conditional<std::is_same<T, __int128_t>::value,
                              __uint128_t,
                              unsigned __int128>;

template <class T>
using is_integral = typename std::conditional<std::is_integral<T>::value ||
                                                  is_signed_int128<T>::value ||
                                                  is_unsigned_int128<T>::value,
                                              std::true_type,
                                              std::false_type>::type;

template <class T>
using is_signed_int = typename std::conditional<(is_integral<T>::value &&
                                                 std::is_signed<T>::value) ||
                                                    is_signed_int128<T>::value,
                                                std::true_type,
                                                std::false_type>::type;

template <class T>
using is_unsigned_int =
    typename std::conditional<(is_integral<T>::value &&
                               std::is_unsigned<T>::value) ||
                                  is_unsigned_int128<T>::value,
                              std::true_type,
                              std::false_type>::type;

template <class T>
using to_unsigned = typename std::conditional<
    is_signed_int128<T>::value,
    make_unsigned_int128<T>,
    typename std::conditional<std::is_signed<T>::value,
                              std::make_unsigned<T>,
                              std::common_type<T>>::type>::type;

#else

template <class T> using is_integral = typename std::is_integral<T>;

template <class T>
using is_signed_int =
    typename std::conditional<is_integral<T>::value && std::is_signed<T>::value,
                              std::true_type,
                              std::false_type>::type;

template <class T>
using is_unsigned_int =
    typename std::conditional<is_integral<T>::value &&
                                  std::is_unsigned<T>::value,
                              std::true_type,
                              std::false_type>::type;

template <class T>
using to_unsigned = typename std::conditional<is_signed_int<T>::value,
                                              std::make_unsigned<T>,
                                              std::common_type<T>>::type;

#endif

template <class T>
using is_signed_int_t = std::enable_if_t<is_signed_int<T>::value>;

template <class T>
using is_unsigned_int_t = std::enable_if_t<is_unsigned_int<T>::value>;

template <class T> using to_unsigned_t = typename to_unsigned<T>::type;

}  // namespace internal

}  // namespace atcoder


namespace atcoder {

namespace internal {

struct modint_base {};
struct static_modint_base : modint_base {};

template <class T> using is_modint = std::is_base_of<modint_base, T>;
template <class T> using is_modint_t = std::enable_if_t<is_modint<T>::value>;

}  // namespace internal

template <int m, std::enable_if_t<(1 <= m)>* = nullptr>
struct static_modint : internal::static_modint_base {
    using mint = static_modint;

  public:
    static constexpr int mod() { return m; }
    static mint raw(int v) {
        mint x;
        x._v = v;
        return x;
    }

    static_modint() : _v(0) {}
    template <class T, internal::is_signed_int_t<T>* = nullptr>
    static_modint(T v) {
        long long x = (long long)(v % (long long)(umod()));
        if (x < 0) x += umod();
        _v = (unsigned int)(x);
    }
    template <class T, internal::is_unsigned_int_t<T>* = nullptr>
    static_modint(T v) {
        _v = (unsigned int)(v % umod());
    }
    static_modint(bool v) { _v = ((unsigned int)(v) % umod()); }

    unsigned int val() const { return _v; }

    mint& operator++() {
        _v++;
        if (_v == umod()) _v = 0;
        return *this;
    }
    mint& operator--() {
        if (_v == 0) _v = umod();
        _v--;
        return *this;
    }
    mint operator++(int) {
        mint result = *this;
        ++*this;
        return result;
    }
    mint operator--(int) {
        mint result = *this;
        --*this;
        return result;
    }

    mint& operator+=(const mint& rhs) {
        _v += rhs._v;
        if (_v >= umod()) _v -= umod();
        return *this;
    }
    mint& operator-=(const mint& rhs) {
        _v -= rhs._v;
        if (_v >= umod()) _v += umod();
        return *this;
    }
    mint& operator*=(const mint& rhs) {
        unsigned long long z = _v;
        z *= rhs._v;
        _v = (unsigned int)(z % umod());
        return *this;
    }
    mint& operator/=(const mint& rhs) { return *this = *this * rhs.inv(); }

    mint operator+() const { return *this; }
    mint operator-() const { return mint() - *this; }

    mint pow(long long n) const {
        assert(0 <= n);
        mint x = *this, r = 1;
        while (n) {
            if (n & 1) r *= x;
            x *= x;
            n >>= 1;
        }
        return r;
    }
    mint inv() const {
        if (prime) {
            assert(_v);
            return pow(umod() - 2);
        } else {
            auto eg = internal::inv_gcd(_v, m);
            assert(eg.first == 1);
            return eg.second;
        }
    }

    friend mint operator+(const mint& lhs, const mint& rhs) {
        return mint(lhs) += rhs;
    }
    friend mint operator-(const mint& lhs, const mint& rhs) {
        return mint(lhs) -= rhs;
    }
    friend mint operator*(const mint& lhs, const mint& rhs) {
        return mint(lhs) *= rhs;
    }
    friend mint operator/(const mint& lhs, const mint& rhs) {
        return mint(lhs) /= rhs;
    }
    friend bool operator==(const mint& lhs, const mint& rhs) {
        return lhs._v == rhs._v;
    }
    friend bool operator!=(const mint& lhs, const mint& rhs) {
        return lhs._v != rhs._v;
    }

  private:
    unsigned int _v;
    static constexpr unsigned int umod() { return m; }
    static constexpr bool prime = internal::is_prime<m>;
};

template <int id> struct dynamic_modint : internal::modint_base {
    using mint = dynamic_modint;

  public:
    static int mod() { return (int)(bt.umod()); }
    static void set_mod(int m) {
        assert(1 <= m);
        bt = internal::barrett(m);
    }
    static mint raw(int v) {
        mint x;
        x._v = v;
        return x;
    }

    dynamic_modint() : _v(0) {}
    template <class T, internal::is_signed_int_t<T>* = nullptr>
    dynamic_modint(T v) {
        long long x = (long long)(v % (long long)(mod()));
        if (x < 0) x += mod();
        _v = (unsigned int)(x);
    }
    template <class T, internal::is_unsigned_int_t<T>* = nullptr>
    dynamic_modint(T v) {
        _v = (unsigned int)(v % mod());
    }
    dynamic_modint(bool v) { _v = ((unsigned int)(v) % mod()); }

    unsigned int val() const { return _v; }

    mint& operator++() {
        _v++;
        if (_v == umod()) _v = 0;
        return *this;
    }
    mint& operator--() {
        if (_v == 0) _v = umod();
        _v--;
        return *this;
    }
    mint operator++(int) {
        mint result = *this;
        ++*this;
        return result;
    }
    mint operator--(int) {
        mint result = *this;
        --*this;
        return result;
    }

    mint& operator+=(const mint& rhs) {
        _v += rhs._v;
        if (_v >= umod()) _v -= umod();
        return *this;
    }
    mint& operator-=(const mint& rhs) {
        _v += mod() - rhs._v;
        if (_v >= umod()) _v -= umod();
        return *this;
    }
    mint& operator*=(const mint& rhs) {
        _v = bt.mul(_v, rhs._v);
        return *this;
    }
    mint& operator/=(const mint& rhs) { return *this = *this * rhs.inv(); }

    mint operator+() const { return *this; }
    mint operator-() const { return mint() - *this; }

    mint pow(long long n) const {
        assert(0 <= n);
        mint x = *this, r = 1;
        while (n) {
            if (n & 1) r *= x;
            x *= x;
            n >>= 1;
        }
        return r;
    }
    mint inv() const {
        auto eg = internal::inv_gcd(_v, mod());
        assert(eg.first == 1);
        return eg.second;
    }

    friend mint operator+(const mint& lhs, const mint& rhs) {
        return mint(lhs) += rhs;
    }
    friend mint operator-(const mint& lhs, const mint& rhs) {
        return mint(lhs) -= rhs;
    }
    friend mint operator*(const mint& lhs, const mint& rhs) {
        return mint(lhs) *= rhs;
    }
    friend mint operator/(const mint& lhs, const mint& rhs) {
        return mint(lhs) /= rhs;
    }
    friend bool operator==(const mint& lhs, const mint& rhs) {
        return lhs._v == rhs._v;
    }
    friend bool operator!=(const mint& lhs, const mint& rhs) {
        return lhs._v != rhs._v;
    }

  private:
    unsigned int _v;
    static internal::barrett bt;
    static unsigned int umod() { return bt.umod(); }
};
template <int id> internal::barrett dynamic_modint<id>::bt = 998244353;

using modint998244353 = static_modint<998244353>;
using modint1000000007 = static_modint<1000000007>;
using modint = dynamic_modint<-1>;

namespace internal {

template <class T>
using is_static_modint = std::is_base_of<internal::static_modint_base, T>;

template <class T>
using is_static_modint_t = std::enable_if_t<is_static_modint<T>::value>;

template <class> struct is_dynamic_modint : public std::false_type {};
template <int id>
struct is_dynamic_modint<dynamic_modint<id>> : public std::true_type {};

template <class T>
using is_dynamic_modint_t = std::enable_if_t<is_dynamic_modint<T>::value>;

}  // namespace internal

}  // namespace atcoder

#include <iostream>
#include <algorithm>
#include <vector>

using namespace std;

using mint = atcoder::modint1000000007;

// 強連結成分分解
vector<vector<int>> scc_decomp(const vector<vector<int>>& graph) {
    const int n = graph.size();

    vector<int> ords(n, -1), lows(n, -1);
    vector<bool> added(n, false);
    vector<int> stack;
    vector<vector<int>> sccs;

    int time = 0;
    auto dfs = [&](auto&& f, int v) -> void {
        ords[v] = lows[v] = time++;
        stack.push_back(v);

        for (auto u : graph[v]) {
            if (ords[u] == -1) {
                f(f, u);
                lows[v] = min(lows[v], lows[u]);
            } else {
                if (added[u]) continue;
                // uはvの親
                lows[v] = min(lows[v], ords[u]);
            }
        }

        if (lows[v] == ords[v]) {
            // vは強連結成分の根
            vector<int> scc;

            while (true) {
                auto u = stack.back();
                stack.pop_back();

                scc.push_back(u);
                added[u] = true;
                if (u == v) break;
            }

            sccs.push_back(scc);
        }
    };

    for (int v = 0; v < n; ++v) {
        if (ords[v] == -1) dfs(dfs, v);
    }

    // トポロジカル順序になるよう反転
    reverse(sccs.begin(), sccs.end());

    return sccs;
}

void solve() {
    int n, m, s;
    cin >> n >> m >> s;
    --s;

    vector<vector<int>> graph(n);
    while (m--) {
        int u, v;
        cin >> u >> v;
        graph[--u].push_back(--v);
    }

    auto sccs = scc_decomp(graph);
    vector<bool> reachable(n, false);  // sと同じ強連結成分に属するか
    for (const auto& scc : sccs) {
        if (!count(scc.begin(), scc.end(), s)) continue;
        for (auto v : scc) reachable[v] = true;
    }

    auto mat = vector(n + 1, vector(n + 1, mint(0)));
    for (int u = 0; u < n; ++u) {
        mat[u][u] = -1;
        if (!reachable[u] || graph[u].empty()) continue;

        mint kinv = mint(graph[u].size()).inv();
        for (auto v : graph[u]) mat[u][v] = kinv;
        mat[u][n] = 1;
    }
    mat[n][n] = 1;

    vector<mint> vec(n + 1, 0);
    vec[n] = 1;
    // mat * (t_1,...,t_n,1) = vec

    // 掃き出し法
    vector<int> cols(n + 1, -1);
    for (int j = 0; j <= n; ++j) {
        int i = 0;
        while (i <= n && !(cols[i] == -1 && mat[i][j] != 0)) ++i;
        if (i > n) continue;

        cols[i] = j;

        {
            auto c = mat[i][j];
            for (int k = 0; k <= n; ++k) mat[i][k] /= c;
            vec[i] /= c;
        }
        for (int ni = 0; ni <= n; ++ni) {
            if (ni == i) continue;

            auto c = mat[ni][j];
            if (c == 0) continue;

            for (int k = 0; k <= n; ++k) {
                mat[ni][k] -= mat[i][k] * c;
            }
            vec[ni] -= vec[i] * c;
        }
    }
    vector<mint> res(n + 1, 0);
    for (int i = 0; i <= n; ++i) {
        if (cols[i] != -1) res[cols[i]] = vec[i];
    }

    // check
    for (int i = 0; i <= n; ++i) {
        for (int j = 0; j <= n; ++j) vec[i] -= mat[i][j] * res[j];
        if (vec[i] != 0) {
            cout << "-1\n";
            return;
        }
    }

    cout << res[s].val() << "\n";
}

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

    solve();

    return 0;
}
accuracy: 1
time_ms: 10
memory_kb: 3676
final_rank: 1

code_snippet: #include <iostream>
#include <vector>

using namespace std;

const long long int MOD = 1e9+7;

long long int extgcd(long long int a, long long int b, long long int &x, long long int &y) {
  long long int d = a;
  if (b != 0) {
    d = extgcd(b, a % b, y, x);
    y -= (a / b) * x;
  } else {
    x = 1; y = 0;
  }
  return d;
}

long long int mod_inverse(long long int a) {
  long long int x, y;
  extgcd(a, MOD, x, y);
  return (MOD + x % MOD) % MOD;
}

vector< vector<bool> > createReachabilityTable(
					       const vector< vector<int> >& graph) {
  int N = graph.size();
  vector< vector<bool> > reachability_table(N, vector<bool>(N, false));
  for (int u = 0; u < N; ++u) {
    reachability_table[u][u] = true;
    for (int v : graph[u]) {
      reachability_table[u][v] = true;
    }
  }

  for (int k = 0; k < N; ++k) {
    for (int i = 0; i < N; ++i) {
      for (int j = 0; j < N; ++j) {
	if (reachability_table[i][k] & reachability_table[k][j]) {
	  reachability_table[i][j] = true;
	}
      }
    }
  }

  return reachability_table;
}

bool willStop(const vector< vector<bool> >& reachability_table, int S) {
  int N = reachability_table.size();
  for (int u = 0; u < N; ++u) {
    if (reachability_table[S][u] && !reachability_table[u][S]) {
      return true;
    }
  }
  return false;
}

vector< vector<long long int> > createTransitionMatrix(const vector< vector<int> >& graph) {
  int N = graph.size();
  vector< vector<long long int> > matrix(N, vector<long long int>(N, 0));
  for (int u = 0; u < N; ++u) {
    if (graph[u].size()) {
      long long int p = mod_inverse(graph[u].size());
      for (int v : graph[u]) {
	matrix[u][v] = p;
      }
    }
  }
  return matrix;
}

vector<long long int> gaussJordan(vector< vector<long long int> > matrix) {
  int N = matrix.size();
  vector<long long int> res(N, 0);
  res[N-1] = 1;

  for (int k = 0; k < N; ++k) {
    long long int d = mod_inverse(matrix[k][k]);
    for (int j = 0; j < (int)matrix[k].size(); ++j) {
      matrix[k][j] *= d;
      matrix[k][j] %= MOD;
    }
    res[k] *= d;
    res[k] %= MOD;

    for (int i = 0; i < N; ++i) {
      if (i == k) {
	continue;
      }
      long long int d = matrix[i][k];
      for (int j = 0; j < N; ++j) {
	matrix[i][j] -= (matrix[k][j] * d) % MOD;
	matrix[i][j] += MOD;
	matrix[i][j] %= MOD;
      }
      res[i] -= (res[k] * d) % MOD;
      res[i] += MOD;
      res[i] %= MOD;
    }
  }
  return res;
}

long long int solve(const vector< vector<int> >& graph, int S) {
  vector< vector<bool> > reachability_table = createReachabilityTable(graph);
  if (graph[S].empty()) {
    return 0;
  }
  if (!willStop(reachability_table, S)) {
    return -1;
  }

  int N = graph.size();
  vector< vector<long long int> > transitionMatrix = createTransitionMatrix(graph);

  for (int u = 0; u < N; ++u) {
    transitionMatrix[u].push_back(1);
  }
  transitionMatrix.push_back(vector<long long int>(N + 1, 0));
  transitionMatrix[N][N] = 1;

  for (int u = 0; u < N; ++u) {
    if (reachability_table[S][u] && reachability_table[u][S]) {
      transitionMatrix[u][u] += MOD - 1;
      transitionMatrix[u][u] %= MOD;
    } else {
      for (int v = 0; v < N + 1; ++v) {
	transitionMatrix[u][v] = 0;
      }
      transitionMatrix[u][u] = 1;
    }
  }

  vector<long long int> expectedValues = gaussJordan(transitionMatrix);
  return expectedValues[S];
}

int main() {
  cin.tie(0);
  ios::sync_with_stdio(false);
  
  int N, M, S;
  cin >> N >> M >> S;
  S--;
  vector< vector<int> > graph(N);
  for (int i = 0; i < M; ++i) {
    int u, v;
    cin >> u >> v;
    u--; v--;
    graph[u].push_back(v);
  }

  cout << solve(graph, S) << endl;
}
accuracy: 1
time_ms: 30
memory_kb: 3868
final_rank: 6