// Nikita Golikov, 2023 #include using namespace std; using uint = unsigned int; using ll = long long; using ull = unsigned long long; #ifdef GOLIKOV #include "/Users/golikovnik/contests/debug.h" #else #define debug(...) ; #endif template bool smin(A& x, B&& y) { if (y < x) { x = y; return true; } return false; } template bool smax(A& x, B&& y) { if (x < y) { x = y; return true; } return false; } int main() { #ifdef GOLIKOV assert(freopen("in", "rt", stdin)); auto _clock_start = chrono::high_resolution_clock::now(); #endif ios::sync_with_stdio(false); cin.tie(nullptr); int n; cin >> n; auto getId = [&](string s) { auto posD = s.find('d'); assert(posD != string::npos); auto posC = s.find(':'); assert(posC != string::npos && posC > posD); int day = atoi(s.substr(0, posD).c_str()); int hour = atoi(s.substr(posD + 1, posC - (posD + 1)).c_str()); int minute = atoi(s.substr(posC + 1).c_str()); debug(s, day, hour, minute); return 24 * 60 * day + 60 * hour + minute; }; map vertex; auto getIdV = [&](string s) { if (!vertex.count(s)) vertex[s] = int(vertex.size()); return vertex[s]; }; struct edge { int from; int to; int f; int t; }; vector edges(n); for (int i = 0; i < n; ++i) { string from; string fromT; string to; string toT; cin >> from >> fromT >> to >> toT; int f = getId(fromT); int t = getId(toT); assert(f < t); int idF = getIdV(from); int idT = getIdV(to); edges[i] = {idF, idT, f, t}; } int s; cin >> s; vector ord(s); vector used(n); for (auto& x : ord) { cin >> x; --x; used[x] = 1; } int dst = edges[ord[s - 1]].to; vector> events; for (int i = 0; i < n; ++i) { events.emplace_back(edges[i].f, edges[i].from, i); events.emplace_back(edges[i].t, ~edges[i].to, i); } sort(events.rbegin(), events.rend()); int const INF = int(1e9); vector ansForEdge(n, INF); int const nv = int(vertex.size()); vector ansForVertex(nv, INF); int worstTime = 0; for (int it = 0; it < int(events.size()); ++it) { auto[t, v, i] = events[it]; if (v < 0) { v = ~v; debug(t, v, i, "end"); if (v == dst) { smin(ansForVertex[v], t); } smin(ansForEdge[i], ansForVertex[v]); continue; } int mn = INF; int mnPos = -1; int mn2 = INF; int jt = it; while (jt < int(events.size()) && get<0>(events[jt]) == get<0>(events[it]) && get<1>(events[jt]) == get<1>(events[it])) { int ind = get<2>(events[jt++]); int val = ansForEdge[ind]; if (val < mn) { mn2 = mn; mn = val; mnPos = ind; } else { smin(mn2, val); } } for (int p = it; p < jt; ++p) { int ind = get<2>(events[p]); if (used[ind]) { smax(worstTime, min(ansForVertex[v], ind == mnPos ? mn2 : mn)); } } smin(ansForVertex[v], mn); it = jt - 1; // debug(t, v, i, "start"); // if (used[i]) { // debug(i, ansForEdge[i]); // smax(worstTime, ansForVertex[v]); // } // smin(ansForVertex[v], ansForEdge[i]); } if (worstTime == INF) { cout << "stranded\n"; } else { cout << max(0, worstTime - edges[ord[s - 1]].t) << '\n'; } #ifdef GOLIKOV cerr << "Executed in " << chrono::duration_cast( chrono::high_resolution_clock::now() - _clock_start).count() << "ms." << endl; #endif return 0; }