#include"bits/stdc++.h" using namespace std; #define ALL(x) begin(x),end(x) #define rep(i,n) for(int i=0;i<(n);i++) #define debug(v) cout<<#v<<":";for(auto x:v){cout<bool chmax(T &a,const T &b){if(abool chmin(T &a,const T &b){if(b ostream &operator<<(ostream &os,const vector&v){ for(int i=0;i<(int)v.size();i++) os< istream &operator>>(istream &is,vector&v){ for(T &x:v)is>>x; return is; } // graph template // ref : https://ei1333.github.io/library/graph/graph-template.cpp template struct Edge{ int from,to; T w; int idx; Edge()=default; Edge(int from,int to,T w=1,int idx=-1):from(from),to(to),w(w),idx(idx){} operator int() const{return to;} }; template struct Graph{ vector>> g; int V,E; Graph()=default; Graph(int n):g(n),V(n),E(0){} int size(){ return (int)g.size(); } void resize(int k){ g.resize(k); V=k; } inline const vector> &operator[](int k)const{ return (g.at(k)); } inline vector> &operator[](int k){ return (g.at(k)); } void add_directed_edge(int from,int to,T cost=1){ g[from].emplace_back(from,to,cost,E++); } void add_edge(int from,int to,T cost=1){ g[from].emplace_back(from,to,cost,E); g[to].emplace_back(to,from,cost,E++); } void read(int m,int pad=-1,bool weighted=false,bool directed=false){ for(int i=0;i>u>>v; u+=pad,v+=pad; T w=T(1); if(weighted) cin>>w; if(directed) add_directed_edge(u,v,w); else add_edge(u,v,w); } } }; template vector TreeCenter(Graph G){ auto BFS=[&](Graph &g,int st,vector &dis,bool memo_parent=false){ vector par; if(memo_parent) par.assign(g.size(),-1); dis.assign(g.size(),-1); dis[st]=0; queue que; que.push(st); while(!que.empty()){ int cur=que.front();que.pop(); for(auto &to:g[cur]){ if(dis[to]>=0) continue; dis[to]=dis[cur]+1; if(memo_parent) par[to]=cur; que.push(to); } } return par; }; vector d; BFS(G,0,d); int u=max_element(begin(d),end(d))-begin(d); auto par=BFS(G,u,d,true); int v=max_element(begin(d),end(d))-begin(d); int diameter=d[v]; for(int i=0;i ret; ret.push_back(v); if(diameter%2) ret.push_back(par[v]); return ret; } template struct Dijkstra{ const T inf; Graph g; vector d; vector prev,eid; Dijkstra(Graph g):inf(numeric_limits::max()/4),g(g){} vector build(int st){ d.assign(g.V,inf); prev.assign(g.V,-1); eid.assign(g.V,-1); d[st]=0; priority_queue,vector>,greater>> que; que.emplace(d[st],st); while(!que.empty()){ auto p=que.top();que.pop(); int cur=p.second; if(d[cur]d[cur]+e.w){ d[e]=d[cur]+e.w; prev[e]=cur; que.emplace(d[e],e); } } } return d; } // vertex = false :-> edge idx vector get_path(int gl,bool vertex=true){ vector ret; if(d[gl]==inf) return ret; for(;gl!=-1;gl=prev[gl]){ ret.push_back(vertex?gl:eid[gl]); } reverse(ret.begin(),ret.end()); return ret; } }; signed main(){ int N;cin>>N; Graph G(N); G.read(N-1); int cnt=0; rep(i,N)if(G[i].size()==1) cnt++; if(cnt<=2){ cout<<"Yes"< dij(G); auto d=dij.build(c); set st; rep(i,N){ if(G[i].size()==1) st.insert(d[i]); } if(st.size()==1){ cout<<"Yes"<