// 演算法 / Algorithm:
// 1) 用 vector 建鄰接表，從 k 做迭代式 DFS，標記所有可疑（可達）節點。
//    Build adjacency list with vectors, iterative DFS from k, mark suspicious (reachable) nodes.
// 2) 掃每條邊，若非可疑 a 呼叫可疑 b -> 無法移除，回傳全部。
//    Scan edges; if non-suspicious a calls suspicious b -> cannot remove, return all.
// 3) 否則回傳所有非可疑節點。 Otherwise return every non-suspicious node.

#include <vector>
using namespace std;

class Solution {
public:
    vector<int> remainingMethods(int n, int k, vector<vector<int>>& invocations) {
        // adj[a] 是一個 vector，存 a 直接呼叫的所有節點 / adj[a] = list of nodes a calls directly
        vector<vector<int>> adj(n);                     // n 個空 vector / n empty adjacency lists
        for (auto& e : invocations)                     // range-for：逐條邊 / iterate each edge
            adj[e[0]].push_back(e[1]);                  // 在 a 的清單尾端加上 b / append b to a's list

        // suspicious[v]：v 是否從 k 可達 / whether v is reachable from k
        vector<char> suspicious(n, 0);                  // 用 char 當布林，初始全 0 / bool-like, all 0

        // 迭代式 DFS，用 vector 當堆疊，避免遞迴太深 / iterative DFS with a vector as an explicit stack
        vector<int> stk;                                // stk 就是我們的堆疊 / stk is our stack
        stk.push_back(k);                               // 推入起點 / push start node
        suspicious[k] = 1;                              // k 本身可疑 / k is suspicious
        while (!stk.empty()) {                          // 堆疊非空就繼續 / while stack not empty
            int u = stk.back(); stk.pop_back();         // 取出並移除頂端節點 / pop top node
            for (int v : adj[u]) {                      // 走過 u 呼叫的每個節點 / for each callee v
                if (!suspicious[v]) {                    // 只處理沒標記過的 / only unvisited
                    suspicious[v] = 1;                   // 標記可疑 / mark suspicious
                    stk.push_back(v);                    // 推入稍後展開 / push to expand later
                }
            }
        }

        // 檢查有沒有「外部呼叫內部」/ check for any outside->inside call
        bool canRemove = true;                          // 先假設可以移除 / assume removable
        for (auto& e : invocations) {
            if (!suspicious[e[0]] && suspicious[e[1]]) { // a 外部、b 內部 / a outside, b inside
                canRemove = false;                       // 違規，不能移除 / violation, keep all
                break;                                   // 一個就夠 / one is enough
            }
        }

        vector<int> ans;                                // 結果陣列 / answer
        ans.reserve(n);                                 // 預留空間避免多次擴容 / reserve to avoid regrow
        if (canRemove) {                                // 可以移除 -> 留下非可疑 / keep non-suspicious
            for (int i = 0; i < n; i++)
                if (!suspicious[i]) ans.push_back(i);
        } else {                                        // 不能移除 -> 全部保留 / keep everything
            for (int i = 0; i < n; i++)
                ans.push_back(i);
        }
        return ans;                                     // 回傳結果 / return the answer
    }
};
