#include #define rep(i, n) for(ll i=0; i<(n); ++i) #define rep1(i,n) for(ll i=1; i<=(n); ++i) #define repi(i,a,b) for(ll i=a; i<=(b); ++i) #define rrep(i,n) for(ll i=(n-1); i>=0; --i) #define ITR(itr,mp) for(auto itr = (mp).begin(); itr != (mp).end(); ++itr) #define ALL(obj) (obj).begin(), (obj).end() #define RALL(obj) (obj).rbegin(), (obj).rend() #define pb push_back #define mp make_pair #define to_s to_string #define sz(v) (int)v.size() #define UNIQUE(v) v.erase( unique(v.begin(), v.end()), v.end() ) #define print(x) cout<<(x)<<'\n' #define debug(x) cout << #x << ": " << (x) << '\n' using namespace std; using ll = long long; using Edge = pair; using Graph = vector>; typedef pair P; struct aaa{aaa(){ cin.tie(0); ios::sync_with_stdio(0); cout< par; vector rank; vector num; UnionFind(int N) : par(N),rank(N),num(N) { for(int i = 0; i < N; i++){ par[i] = i; rank[i] = 0; num[i] = 1; } } void init(int N){ for(int i = 0; i < N; i++){ par[i] = i; rank[i] = 0; num[i] = 1; } } int root(int x) { if (par[x] == x) return x; return par[x] = root(par[x]); } int ranker(int x){ x = root(x); return rank[x]; } int number(int x){ x = root(x); return num[x]; } void unite(int x, int y){ int rx = root(x); int ry = root(y); if ( rx == ry ) return; if ( rank[rx] < rank[ry] ){ par[rx] = ry; num[ry] += num[rx]; num[rx] = 0; } else { par[ry] = rx; num[rx] += num[ry]; num[ry] = 0; if ( rank[rx] == rank[ry] ) rank[rx]++; } } bool same(int x, int y){ return root(x) == root(y); } }; int main(){ ll N; cin >> N; Graph G(N); UnionFind UF(N); rep(_, N-1){ ll u, v; cin >> u >> v; G[u].pb({v,1}); G[v].pb({u,1}); UF.unite(u,v); } bool flag = true; rep(i,N) if(sz(G[i]) < 2) flag = false; if(flag) print("Bob"); else if(UF.number(0) == N) print("Bob"); else print("Alice"); return 0; }