#include using namespace std; struct BiconnectedComponents { int n; int time; vector is_art_point; vector idx, low; set> bridges; vector> g; BiconnectedComponents(int _n) : n(_n), time(0), is_art_point(_n, false), idx(_n, -1), low(_n, -1), g(_n) {} void add_edge(int u, int v) { g[u].push_back(v); g[v].push_back(u); } void build() { for (int i = 0; i < n; ++i) { if (idx[i] == -1) dfs(i, -1); } } void dfs(int u, int p) { idx[u] = low[u] = time++; for (auto&& v : g[u]) { if (idx[v] == -1) { dfs(v, u); low[u] = min(low[u], low[v]); if (idx[u] <= low[v]) is_art_point[u] = (idx[u] > 0) || (idx[v] > 1); if (idx[u] < low[v]) bridges.insert({min(u, v), max(u, v)}); } else if (v != p) { low[u] = min(low[u], idx[v]); } } } }; struct UnionFind { vector data; UnionFind(int n) : data(n, -1) {} inline int root(int x) { return (data[x] < 0) ? x : data[x] = root(data[x]); } inline int size(int x) { return -data[root(x)]; } inline bool same(int x, int y) { return root(x) == root(y); } bool unite(int x, int y) { x = root(x); y = root(y); if (x == y) return false; if (data[x] > data[y]) swap(x, y); data[x] += data[y]; data[y] = x; return true; } }; int main() { int n; cin >> n; BiconnectedComponents g(n); UnionFind uf(n); for (int i = 0; i < n - 1; i++) { int u, v; cin >> u >> v; g.add_edge(u, v); uf.unite(u, v); } g.build(); int cnt = 0; vector used(n, false); for (int i = 0; i < n; i++) { if (used[uf.root(i)]) continue; used[uf.root(i)] = true; cnt++; } if (cnt <= 1) { cout << "Bob" << endl; return 0; } if (cnt >= 3) { cout << "Alice" << endl; return 0; } if (g.bridges.size() > 1) { cout << "Alice" << endl; } else { cout << "Bob" << endl; } }