This documentation is automatically generated by online-judge-tools/verification-helper
#define PROBLEM "https://onlinejudge.u-aizu.ac.jp/problems/2891"
#include "./../Graph/CycleDetection.cpp"
#include <iostream>
#include <vector>
#include <cassert>
using namespace std;
int main() {
cin.tie(nullptr);
ios_base::sync_with_stdio(false);
int n;
cin >> n;
vector<pair<int, int>> edges(n);
for (int i = 0; i < n; ++i) {
int u, v;
cin >> u >> v;
u--;
v--;
edges[i] = {u, v};
}
auto cycle = CycleDetectionVertex(n, edges, false);
assert(cycle);
vector<bool> flag(n);
for (int i : *cycle) {
flag[i] = true;
}
int q;
cin >> q;
while (q--) {
int a, b;
cin >> a >> b;
a--;
b--;
if (flag[a] && flag[b]) {
cout << 2 << '\n';
} else {
cout << 1 << '\n';
}
}
}
#line 1 "test/CycleDetectionVertex_Undirected.test.cpp"
#define PROBLEM "https://onlinejudge.u-aizu.ac.jp/problems/2891"
#line 2 "Graph/CycleDetection.cpp"
#include <vector>
#include <stack>
#include <algorithm>
#include <optional>
std::optional<std::vector<int>> CycleDetectionEdge(
int n, const std::vector<std::pair<int, int>>& edges, bool directed = true) {
std::vector<std::vector<std::pair<int, int>>> graph(n);
for (std::size_t i = 0; i < edges.size(); ++i) {
auto [u, v] = edges[i];
graph[u].emplace_back(v, i);
if (!directed) graph[v].emplace_back(u, i);
}
std::vector<bool> visited(n), finished(n);
std::stack<std::pair<int, int>> st;
std::optional<int> pos;
auto dfs = [&](auto&& f, int v, int prev_edge) -> void {
visited[v] = true;
for (auto [u, i] : graph[v]) {
if (!finished[u] && (directed || i != prev_edge)) {
st.emplace(i, v);
if (visited[u]) {
pos = u;
return;
}
f(f, u, i);
if (pos) return;
st.pop();
}
}
finished[v] = true;
};
for (int i = 0; i < n && !pos; ++i) {
if (!visited[i]) dfs(dfs, i, -1);
}
if (pos) {
std::vector<int> cycle;
while (!st.empty()) {
auto [top, from] = st.top();
st.pop();
cycle.push_back(top);
if (from == *pos) {
break;
}
}
std::reverse(cycle.begin(), cycle.end());
return cycle;
} else {
return std::nullopt;
}
}
std::optional<std::vector<int>> CycleDetectionVertex(
const std::vector<std::vector<int>>& graph, bool directed = true) {
int n = graph.size();
std::vector<bool> visited(n), finished(n);
std::stack<int> st;
std::optional<int> pos;
auto dfs = [&](auto&& f, int v, int prev) -> void {
visited[v] = true;
st.push(v);
for (int u : graph[v]) {
if (!finished[u] && (directed || u != prev)) {
if (visited[u]) {
pos = u;
return;
}
f(f, u, v);
if (pos) return;
}
}
finished[v] = true;
st.pop();
};
for (int i = 0; i < n && !pos; ++i) {
if (!visited[i]) dfs(dfs, i, -1);
}
if (pos) {
std::vector<int> cycle;
while (!st.empty()) {
int top = st.top();
st.pop();
cycle.push_back(top);
if (top == *pos) {
break;
}
}
std::reverse(cycle.begin(), cycle.end());
return cycle;
} else {
return std::nullopt;
}
}
auto CycleDetectionVertex(int n, const std::vector<std::pair<int, int>>& edges,
bool directed = true) {
std::vector<std::vector<int>> graph(n);
for (auto [u, v] : edges) {
graph[u].push_back(v);
if (!directed) graph[v].push_back(u);
}
return CycleDetectionVertex(graph, directed);
}
#line 3 "test/CycleDetectionVertex_Undirected.test.cpp"
#include <iostream>
#line 5 "test/CycleDetectionVertex_Undirected.test.cpp"
#include <cassert>
using namespace std;
int main() {
cin.tie(nullptr);
ios_base::sync_with_stdio(false);
int n;
cin >> n;
vector<pair<int, int>> edges(n);
for (int i = 0; i < n; ++i) {
int u, v;
cin >> u >> v;
u--;
v--;
edges[i] = {u, v};
}
auto cycle = CycleDetectionVertex(n, edges, false);
assert(cycle);
vector<bool> flag(n);
for (int i : *cycle) {
flag[i] = true;
}
int q;
cin >> q;
while (q--) {
int a, b;
cin >> a >> b;
a--;
b--;
if (flag[a] && flag[b]) {
cout << 2 << '\n';
} else {
cout << 1 << '\n';
}
}
}