#ifndef ONLINE_JUDGE #define _GLIBCXX_DEBUG #endif #include using namespace std; // #include // using namespace atcoder; using ll = long long; // 2^63-1まで 負の値は可 using ull = unsigned long long; // 0<= ull <=2^64-1の範囲 負の値は不可 using vl = vector; using vvl = vector; using P = pair; template using MNPQ = priority_queue, greater>; template using MXPQ = priority_queue, less>; #define rep(i, n) for (int i = 0; i < n; i++) #define srep(i, s, n) for (int i = s; i < n; i++) #define rrep(i, s, n) for (int i = s; i > n; i--) #define chmax(x, y) x = max(x, y) #define chmin(x, y) x = min(x, y) #define nall(a) a.begin(), a.end() #define rall(a) a.rbegin(), a.rend() #define vunique(v) v.erase(unique(nall(v)), v.end()) #define IN(a, x) find(nall(a), x) != a.end() #define YN(flg) cout << (flg ? "Yes" : "No") << "\n" #define out_grid(x, y, h, w) !(0 <= x && x < h && 0 <= y && y < w) #define lmd(...) [&](__VA_ARGS__) #define debug(x) cerr << #x << " = " << x << endl; const ll INF = 2e18; template istream& operator>>(istream& is, vector& a) { for (auto& x : a) is >> x; return is; } template ostream& operator<<(ostream& os, vector& a) { for (int i = 0; i < (int)a.size(); i++) os << a[i] << " "; return os; } template ostream& operator<<(ostream& os, pair& p) { os << "{" << p.first << "," << p.second << "}"; return os; } template ostream& operator<<(ostream& os, map& a) { for (auto& [k, v] : a) os << "{key:" << k << ", item:" << v << "} "; return os; } int main() { ios_base::sync_with_stdio(false); cin.tie(nullptr); ll n, m; cin >> n >> m; vvl graph(n + 1); rep(i, m) { ll u, v; cin >> u >> v; graph[u].push_back(v); graph[v].push_back(u); } vector ng(n + 1); ll l; cin >> l; vector d(n + 1, -1); MXPQ> pq; rep(i, l) { ll j, k; cin >> j >> k; pq.emplace(k, j); d[j] = k; } while (!pq.empty()) { auto [w, v] = pq.top(); pq.pop(); ng[v] = 1; if (!w) continue; if (d[v] > w) continue; for (auto i : graph[v]) { if (d[i] >= w - 1) continue; d[i] = w - 1; pq.emplace(d[i], i); } } vector dist(n + 1, INF); queue que; dist[1] = 0; que.emplace(1); while (!que.empty()) { auto v = que.front(); que.pop(); if (ng[v]) continue; for (auto i : graph[v]) { if (dist[i] != INF) continue; if (ng[i]) continue; dist[i] = dist[v] + 1; que.emplace(i); } } if (dist[n] != INF) { cout << "Yes" << endl; cout << dist[n] << endl; } else { cout << "No" << endl; } return 0; }