#line 1 "/workspaces/algorithm/verify/yukicoder/no_2290.cpp" #define PROBLEM "https://yukicoder.me/problems/no/2290" #include #include #line 1 "/workspaces/algorithm/algorithm/DataStructure/UnionFind/union_find.hpp" #include #include #include #include namespace algorithm { class UnionFind { int m_vn; // m_vn:=(要素数). int m_gn; // m_gn:=(集合の数). std::vector m_par; // m_par[x]:=(要素xの親). 0未満の場合,要素xは代表元であり,値の絶対値は属する集合のサイズを表す. int root_internal(int x) { if(m_par[x] < 0) return x; return m_par[x] = root_internal(m_par[x]); // 経路圧縮. } public: UnionFind() {} explicit UnionFind(int n) : m_vn(n), m_gn(n), m_par(n, -1) { assert(n >= 0); } // 要素数を取得する. int vn() const { return m_vn; } // 集合の数を取得する. int gn() const { return m_gn; } // 要素xが属する集合の代表元を取得する. int root(int x) { assert(0 <= x && x < vn()); return root_internal(x); } // 要素xが属する集合のサイズを取得する. int size(int x) { assert(0 <= x and x < vn()); return -m_par[root_internal(x)]; } // 要素x, yが同じ集合に属するか判定する. bool is_same(int x, int y) { assert(0 <= x and x < vn()); assert(0 <= y and y < vn()); return root_internal(x) == root_internal(y); } // 要素x, yが属するそれぞれの集合を合併する. bool unite(int x, int y) { assert(0 <= x and x < vn()); assert(0 <= y and y < vn()); x = root_internal(x), y = root_internal(y); if(x == y) return false; // Do nothing. if(-m_par[x] < -m_par[y]) std::swap(x, y); // Merge technique (union by size). m_par[x] += m_par[y]; m_par[y] = x; --m_gn; return true; } void reset() { m_gn = m_vn; std::fill(m_par.begin(), m_par.end(), -1); } }; } // namespace algorithm #line 7 "/workspaces/algorithm/verify/yukicoder/no_2290.cpp" int main() { int n; int q; std::cin >> n >> q; algorithm::UnionFind uf(n); std::set st; for(int i = 0; i < n; ++i) st.insert(st.end(), i); while(q--) { int t; std::cin >> t; if(t == 1) { int u, v; std::cin >> u >> v; u = uf.root(u); v = uf.root(v); st.erase(u); st.erase(v); uf.unite(u, v); st.insert(uf.root(u)); } else { int u; std::cin >> u; if(uf.gn() == 1) { std::cout << -1 << "\n"; continue; } u = uf.root(u); for(auto v : st) { if(v != u) { std::cout << v << "\n"; break; } } } } }