Problem: Let F_k denote the k-th term of Fibonacci sequence, defined as below:

  * F_0 = F_1 = 1
  * for any integer n ≥ 0, F_{n+2} = F_{n+1} + F_n



You are given a tree with n vertices. Recall that a tree is a connected undirected graph without cycles.

We call a tree a Fib-tree, if its number of vertices equals F_k for some k, and at least one of the following conditions holds:

  * The tree consists of only 1 vertex;
  * You can divide it into two Fib-trees by removing some edge of the tree. 



Determine whether the given tree is a Fib-tree or not.

Input

The first line of the input contains a single integer n (1 ≤ n ≤ 2 ⋅ 10^5) — the number of vertices in the tree.

Then n-1 lines follow, each of which contains two integers u and v (1≤ u,v ≤ n, u ≠ v), representing an edge between vertices u and v. It's guaranteed that given edges form a tree.

Output

Print "YES" if the given tree is a Fib-tree, or "NO" otherwise.

You can print your answer in any case. For example, if the answer is "YES", then the output "Yes" or "yeS" will also be considered as correct answer.

Examples

Input


3
1 2
2 3


Output


YES


Input


5
1 2
1 3
1 4
1 5


Output


NO


Input


5
1 3
1 2
4 5
3 4


Output


YES

Note

In the first sample, we can cut the edge (1, 2), and the tree will be split into 2 trees of sizes 1 and 2 correspondently. Any tree of size 2 is a Fib-tree, as it can be split into 2 trees of size 1.

In the second sample, no matter what edge we cut, the tree will be split into 2 trees of sizes 1 and 4. As 4 isn't F_k for any k, it's not Fib-tree.

In the third sample, here is one possible order of cutting the edges so that all the trees in the process are Fib-trees: (1, 3), (1, 2), (4, 5), (3, 4). 

Solution (in CPP):

Solution:
#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;
    }
}