#include <bits/stdc++.h>
//#include <chrono>
#pragma GCC optimize("Ofast")
using namespace std;
#define reps(i,s,n) for(int i = s; i < n; i++)
#define rep(i,n) reps(i,0,n)
#define Rreps(i,n,e) for(int i = n - 1; i >= e; --i)
#define Rrep(i,n) Rreps(i,n,0)
#define ALL(a) a.begin(), a.end()

using ll = long long;
using vec = vector<ll>;
using mat = vector<vec>;

ll N,M,H,W,Q,K,A,B;
string S;
using P = pair<ll, ll>;
const ll INF = (1LL<<60);

template<class T> bool chmin(T &a, const T b){
    if(a > b) {a = b; return true;}
    else return false;
}
template<class T> bool chmax(T &a, const T b){
    if(a < b) {a = b; return true;}
    else return false;
}
template<class T> void my_printv(std::vector<T> v,bool endline = true){
    if(!v.empty()){
        for(std::size_t i{}; i<v.size()-1; ++i) std::cout<<v[i]<<" ";
        std::cout<<v.back();
    }
    if(endline) std::cout<<std::endl;
}

struct edge{
        int to, rev;
        bool used;
        edge(){}
        edge(int a, int b) : to(a), rev(b), used(false){}
    };
using ve = vector<edge>;

vec fibo, sz;
edge make_sz(edge to_v, vector<ve> &G, int k){
    int v = to_v.to;
    sz[v] = 1;
    edge res(-1, -1);
    for(const edge &e : G[v]){
        if((to_v.rev == -1 || e.to != G[v][to_v.rev].to) && !e.used){
            if((res = make_sz(e, G, k)).to != -1) return res;
            sz[v] += sz[e.to];
        }
    }
    if(sz[v] == fibo[k-1] || sz[v] == fibo[k-2]) return to_v;
    return res;
}

bool dfs(int k, int p, vector<ve> &G){
    if(k <= 1) return true;
    edge tmp(p, -1);
    edge res = make_sz(tmp, G, k);
    if(res.to == -1) return false;
    int nxtk = (sz[res.to] == fibo[k - 1] ? k - 1 : k - 2);
    edge &resrev = G[res.to][res.rev];
    resrev.used = true;
    G[resrev.to][resrev.rev].used = true;
    return dfs(nxtk, res.to, G) && dfs(k * 2 - 3 - nxtk, G[res.to][res.rev].to, G);
}

int main(){
    cin.tie(nullptr);
    ios::sync_with_stdio(false);
    int a = 1, b = 1;
    while(a < 200010){
        fibo.push_back(a);
        a += b;
        swap(a, b);
    }
    //my_printv(fibo);

    cin>>N;
    vector<ve> G(N);
    rep(i, N - 1){
        cin>>a>>b;
        --a; --b;
        G[a].emplace_back(b, (int)G[b].size());
        G[b].emplace_back(a, (int)G[a].size() - 1);
    }
    sz.resize(N);

    int k = -1;
    rep(i, (int)fibo.size()) if(fibo[i] == N) k = i;
    if(k == -1){
        cout<<"NO"<<endl;
    }else{
        cout<<(dfs(k, 0, G) ? "YES" : "NO")<<endl;
    }
}