#pragma GCC target("avx2") #pragma GCC optimize("O3") #pragma GCC optimize("unroll-loops") #include #if __has_include() #include using namespace atcoder; #endif #include #include using namespace std; using namespace chrono; #define rep(i, n) for (ll i = 0; i < (n); ++i) #define rep1(i, n) for (ll i = 1; i <= (n); ++i) #define rrep(i, n) for (ll i = n; i > 0; --i) #define bitrep(i, n) for (ll i = 0; i < (1 << n); ++i) #define all(a) (a).begin(), (a).end() #define yesNo(b) ((b) ? "Yes" : "No") using ll = long long; using ull = unsigned long long; using ld = long double; using mint = modint998244353; using MINT = modint1000000007; string alphabet = "abcdefghijklmnopqrstuvwxyz"; string ALPHABET = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; constexpr double pi = 3.141592653589793; constexpr ll smallMOD = 998244353; constexpr ll bigMOD = 1000000007; constexpr ll dx[] = {1, 0, -1, 0, 1, -1, -1, 1}; constexpr ll dy[] = {0, 1, 0, -1, 1, 1, -1, -1}; struct Init { Init() { ios::sync_with_stdio(0); cin.tie(0); cout << fixed << setprecision(15); } } init; template ostream &operator<<(ostream &os, const vector &vec) { os << "["; rep(i, vec.size()) { os << vec[i]; if (i != vec.size() - 1) os << ", "; } os << "]"; return os; } template ostream &operator<<(ostream &os, const vector> &vec) { os << "["; rep(i, vec.size()) { os << vec[i]; if (i != vec.size() - 1) os << ", "; } os << "]"; return os; } template ostream &operator<<(ostream &os, const pair &pair_var) { os << "(" << pair_var.first << ", " << pair_var.second << ")"; return os; } template ostream &operator<<(ostream &os, const set &st) { os << "{"; for (auto itr = st.begin(); itr != st.end(); ++itr) { os << *itr; if (next(itr) != st.end()) os << ", "; } os << "}"; return os; } // graph_template struct Edge { ll to; ll cost; Edge(ll to, ll cost) : to(to), cost(cost) {} bool operator>(const Edge &e) const { return cost > e.cost; } }; struct Graph { vector> g; Graph(ll n) { g.resize(n); } ll size() { return g.size(); } void add_edge(ll from, ll to, ll cost = 1) { g[from].push_back(Edge(to, cost)); g[to].push_back(Edge(from, cost)); } void add_directed_edge(ll from, ll to, ll cost = 1) { g[from].push_back(Edge(to, cost)); } pair> tree_diameter() { function(ll, ll)> dfs = [&](ll v, ll p) -> pair { pair res = {0, v}; for (auto e : g[v]) { if (e.to == p) continue; auto [d, u] = dfs(e.to, v); d += e.cost; if (res.first < d) { res.first = d; res.second = u; } } return res; }; auto [d, u] = dfs(0, -1); auto [d2, v] = dfs(u, -1); vector path; function get_path = [&](ll v, ll p, ll u) { if (v == u) { path.push_back(v); return; } for (auto e : g[v]) { if (e.to == p) continue; get_path(e.to, v, u); if (!path.empty()) { path.push_back(v); return; } } }; get_path(u, -1, v); return {d2, path}; } vector> get_all_closed_circuit() { // グラフ上のすべての閉路のパスを返す vector> res; vector path; vector used(g.size(), 0); function dfs = [&](ll v, ll p) -> void { used[v] = 1; path.push_back(v); for (auto e : g[v]) { if (e.to == p) continue; if (used[e.to] == 1) { // 閉路を検出 vector cycle; for (ll i = path.size() - 1; i >= 0; --i) { cycle.push_back(path[i]); if (path[i] == e.to) break; } res.push_back(cycle); } else if (used[e.to] == 0) { dfs(e.to, v); } } path.pop_back(); used[v] = 2; }; dfs(0, -1); return res; } vector &operator[](ll v) { return g[v]; } }; int main() { ll n, m; cin >> n >> m; Graph g(n); rep(i, m) { ll u, v; cin >> u >> v; g.add_edge(u, v); } auto all_path = g.get_all_closed_circuit(); set t; rep(i, 3) { ll x; cin >> x; t.insert(x); } for (auto path : all_path) { bool ok = true; for (auto v : path) { if (t.find(v) == t.end()) { ok = false; break; } } if (ok) { cout << "No" << endl; return 0; } } cout << "Yes" << endl; return 0; }