Problem:
Tournament Record
We had a tournament in which $N$ people participated. In the tournament, the participants play against each other one-on-one to decide who wins and who loses. The winner moves on to the next match, and the one who remains in the end is the winner. Since there is only one venue for the tournament, only one match can be played at a time.
As the recorder, you recorded the winners and losers of each match until the tournament was over and the winner was determined. You recorded correctly, using a sheet of paper for each match, but some of the papers you recorded may be rearranged by ascident.
Write a program to find out how many possible orders of the games are possible from the records of the games where the order may have been switched. Assume that the participants in the tournament are assigned numbers from 1 to $N$.
Input
The input is given in the following order.
$N$
$a_1$ $b_1$
$a_2$ $b_2$
:
$a_{N-1}$ $b_{N-1}$
The first line gives the number of contestants $N$ ($2 \leq N \leq 1000$). In the following $N-1$ lines, the records of the winners and losers of the match $a_i$, $b_i$ ($1 \leq a_i,b_i \leq N$) are given. $a_i$ represents the winner and $b_i$ represents the loser.
Output
Output the remainder of the number of possible orders of the matches divided by $10^6$ in a line.
Sample Input and Output
Sample Input 1
3
1 2
1 3
Sample Output 1
2
Sample Input 2
3
2 1
1 3
Sample Output 2
1

Submitted solutions:

code_snippet: #include <bits/stdc++.h>
using ll = long long;
using namespace std;
typedef long double ld;
using pii = pair<int,int>;
using dat = pair<ld,pair<int,int>>;
using pq = priority_queue<dat, vector<dat>, greater<dat>>;
vector<pii> dir = {{0,1},{1,0},{-1,0},{0,-1}};

template<typename T> bool chmin(T &a, T b) { if (a > b){ a = b; return true; } else return false; }

ld dist(int a,int b,int c,int d){
    return sqrt(ld(c - a) * ld(c - a) + ld(d - b) * ld(d - b));
}

int main(){
    int n;
    cin >> n;
    vector<vector<int>> g(n);
    int winner = -1;
    vector<bool> cnt(n,true);
    for (int i = 0;i < n - 1;i++){
        int a,b;
        cin >> a >> b;
        a--,b--;
        g[a].push_back(b);
        g[b].push_back(a);
        cnt[b] = false;
    }
    for (int i = 0;i < n;i++){
        if (cnt[i])winner = i;
    }
    ll mod = 1000000;
    vector<vector<ll>> binomial(2001,vector<ll> (2001));
    for (int i = 0;i <= 2000;i++){
        binomial[i][0] = binomial[i][i] = 1;
        for (int j = 1;j < i;j++){
            binomial[i][j] = (binomial[i - 1][j - 1] + binomial[i - 1][j]) % mod;
        }
    }
    // for (int i = 1;i <= 10;i++){
    //     for (int j = 1;j <= 10;j++){
    //         cout << binomial[i][j] << ' ';
    //     }cout << endl;
    // }

    auto dfs = [&](auto self,int now,int pre)->pair<ll,ll>{//部分木のサイズ、組合せの総数
        ll subtree_size = 0;
        ll kumi = 1;
        for (int i : g[now]){
            if (i == pre) continue;
            auto [x,y] = self(self,i,now);
            kumi *= binomial[x + subtree_size][x] * y % mod;
            kumi %= mod;
            subtree_size += x;
        }
        subtree_size += 1;
        return {subtree_size,kumi};
    };
    cout << dfs(dfs,winner,-1).second << endl;
    
}
accuracy: 1
time_ms: 10
memory_kb: 34504
final_rank: 5

code_snippet: #include <bits/stdc++.h>
using ll = long long;
using namespace std;
typedef long double ld;
using pii = pair<int,int>;
using dat = pair<ld,pair<int,int>>;
using pq = priority_queue<dat, vector<dat>, greater<dat>>;
vector<pii> dir = {{0,1},{1,0},{-1,0},{0,-1}};

template<typename T> bool chmin(T &a, T b) { if (a > b){ a = b; return true; } else return false; }

ld dist(int a,int b,int c,int d){
    return sqrt(ld(c - a) * ld(c - a) + ld(d - b) * ld(d - b));
}

int main(){
    int n;
    cin >> n;
    vector<vector<int>> g(n);
    int winner = -1;
    vector<bool> cnt(n,true);
    for (int i = 0;i < n - 1;i++){
        int a,b;
        cin >> a >> b;
        a--,b--;
        g[a].push_back(b);
        cnt[b] = false;
    }
    for (int i = 0;i < n;i++){
        if (cnt[i])winner = i;
    }
    ll mod = 1000000;
    vector<vector<ll>> binomial(2001,vector<ll> (2001));
    for (int i = 0;i <= 2000;i++){
        binomial[i][0] = binomial[i][i] = 1;
        for (int j = 1;j < i;j++){
            binomial[i][j] = (binomial[i - 1][j - 1] + binomial[i - 1][j]) % mod;
        }
    }
    // for (int i = 1;i <= 10;i++){
    //     for (int j = 1;j <= 10;j++){
    //         cout << binomial[i][j] << ' ';
    //     }cout << endl;
    // }

    auto dfs = [&](auto self,int now,int pre)->pair<ll,ll>{//部分木のサイズ、組合せの総数
        ll subtree_size = 0;
        ll kumi = 1;
        for (int i : g[now]){
            auto [x,y] = self(self,i,now);
            kumi *= binomial[x + subtree_size][x] * y % mod;
            kumi %= mod;
            subtree_size += x;
        }
        subtree_size += 1;
        return {subtree_size,kumi};
    };
    cout << dfs(dfs,winner,-1).second << endl;
    
}
accuracy: 1
time_ms: 10
memory_kb: 34484
final_rank: 4

code_snippet: #include <bits/stdc++.h>
using ll = long long;
using namespace std;
typedef long double ld;
using pii = pair<int,int>;
using dat = pair<ld,pair<int,int>>;
using pq = priority_queue<dat, vector<dat>, greater<dat>>;
vector<pii> dir = {{0,1},{1,0},{-1,0},{0,-1}};

template<typename T> bool chmin(T &a, T b) { if (a > b){ a = b; return true; } else return false; }

ld dist(int a,int b,int c,int d){
    return sqrt(ld(c - a) * ld(c - a) + ld(d - b) * ld(d - b));
}

int main(){
    int n;
    cin >> n;
    vector<vector<int>> g(n);
    int winner = -1;
    vector<bool> cnt(n,true);
    for (int i = 0;i < n - 1;i++){
        int a,b;
        cin >> a >> b;
        a--,b--;
        g[a].push_back(b);
        cnt[b] = false;
    }
    for (int i = 0;i < n;i++){
        if (cnt[i])winner = i;
    }
    ll mod = 1000000;
    vector<vector<ll>> binomial(2001,vector<ll> (2001));
    for (int i = 0;i <= 2000;i++){
        binomial[i][0] = binomial[i][i] = 1;
        for (int j = 1;j < i;j++){
            binomial[i][j] = (binomial[i - 1][j - 1] + binomial[i - 1][j]) % mod;
        }
    }
    // for (int i = 1;i <= 10;i++){
    //     for (int j = 1;j <= 10;j++){
    //         cout << binomial[i][j] << ' ';
    //     }cout << endl;
    // }

    auto dfs = [&](auto self,int now,int pre)->pair<ll,ll>{//部分木のサイズ、組合せの総数
        if (g[now].size() == 1){
            return {1,1};
        }
        ll subtree_size = 0;
        ll kumi = 1;
        for (int i : g[now]){
            auto [x,y] = self(self,i,now);
            kumi *= binomial[x + subtree_size][x] * y % mod;
            kumi %= mod;
            subtree_size += x;
        }
        subtree_size += 1;
        return {subtree_size,kumi};
    };
    cout << dfs(dfs,winner,-1).second << endl;
    
}
accuracy: 0.12
time_ms: 10
memory_kb: 34512
final_rank: 18

code_snippet: #include <bits/stdc++.h>
using ll = long long;
using namespace std;
typedef long double ld;
using pii = pair<int,int>;
using dat = pair<ld,pair<int,int>>;
using pq = priority_queue<dat, vector<dat>, greater<dat>>;
vector<pii> dir = {{0,1},{1,0},{-1,0},{0,-1}};

template<typename T> bool chmin(T &a, T b) { if (a > b){ a = b; return true; } else return false; }

ld dist(int a,int b,int c,int d){
    return sqrt(ld(c - a) * ld(c - a) + ld(d - b) * ld(d - b));
}

int main(){
    int n;
    cin >> n;
    vector<vector<int>> g(n);
    int winner = -1;
    vector<bool> cnt(n,true);
    for (int i = 0;i < n - 1;i++){
        int a,b;
        cin >> a >> b;
        a--,b--;
        g[a].push_back(b);
        g[b].push_back(a);
        cnt[b] = false;
    }
    for (int i = 0;i < n;i++){
        if (cnt[i])winner = i;
    }
    ll mod = 1000000;
    vector<vector<ll>> binomial(2001,vector<ll> (2001));
    for (int i = 0;i <= 2000;i++){
        binomial[i][0] = binomial[i][i] = 1;
        for (int j = 1;j < i;j++){
            binomial[i][j] = (binomial[i - 1][j - 1] + binomial[i - 1][j]) % mod;
        }
    }
    // for (int i = 1;i <= 10;i++){
    //     for (int j = 1;j <= 10;j++){
    //         cout << binomial[i][j] << ' ';
    //     }cout << endl;
    // }
    vector<int> dp(n,1),sub(n,1);
    auto dfs = [&](auto self,int now,int pre)->pair<ll,ll>{//部分木のサイズ、組合せの総数
        if (g[now].size() == 1){
            return {1,1};
        }
        int sum = 0;
        for (int i : g[now]){
            if (i == pre) continue;
            auto [x,y] = self(self,i,now);
            sum += x;
            dp[now] *= binomial[sum][x] * y % mod;
            dp[now] %= mod;
        }
        return {sum + 1,dp[now]};
    };
    cout << dfs(dfs,winner,-1).second << endl;
    
}
accuracy: 0.44
time_ms: 10
memory_kb: 34484
final_rank: 11

code_snippet: #include <bits/stdc++.h>
using ll = long long;
using namespace std;
typedef long double ld;
using pii = pair<int,int>;
using dat = pair<ld,pair<int,int>>;
using pq = priority_queue<dat, vector<dat>, greater<dat>>;
vector<pii> dir = {{0,1},{1,0},{-1,0},{0,-1}};

template<typename T> bool chmin(T &a, T b) { if (a > b){ a = b; return true; } else return false; }

ld dist(int a,int b,int c,int d){
    return sqrt(ld(c - a) * ld(c - a) + ld(d - b) * ld(d - b));
}

int main(){
    int n;
    cin >> n;
    vector<vector<int>> g(n);
    int winner = -1;
    vector<bool> cnt(n,true);
    for (int i = 0;i < n - 1;i++){
        int a,b;
        cin >> a >> b;
        a--,b--;
        g[a].push_back(b);
        g[b].push_back(a);
        cnt[b] = false;
    }
    for (int i = 0;i < n;i++){
        if (cnt[i])winner = i;
    }
    ll mod = 1000000;
    vector<vector<ll>> binomial(2001,vector<ll> (2001));
    for (int i = 0;i <= 2000;i++){
        binomial[i][0] = binomial[i][i] = 1;
        for (int j = 1;j < i;j++){
            binomial[i][j] = (binomial[i - 1][j - 1] + binomial[i - 1][j]) % mod;
        }
    }
    // for (int i = 1;i <= 10;i++){
    //     for (int j = 1;j <= 10;j++){
    //         cout << binomial[i][j] << ' ';
    //     }cout << endl;
    // }

    auto dfs = [&](auto self,int now,int pre)->pair<ll,ll>{//部分木のサイズ、組合せの総数
        if (g[now].size() == 1){
            return {1,1};
        }
        ll subtree_size = 0;
        ll kumi = 1;
        for (int i : g[now]){
            if (i == pre) continue;
            auto [x,y] = self(self,i,now);
            kumi *= binomial[x + subtree_size][x] * y % mod;
            kumi %= mod;
            subtree_size += x;
        }
        subtree_size += 1;
        return {subtree_size,kumi};
    };
    cout << dfs(dfs,winner,-1).second << endl;
    
}
accuracy: 0.44
time_ms: 10
memory_kb: 34508
final_rank: 12

code_snippet: #include <bits/stdc++.h>
using ll = long long;
using namespace std;
typedef long double ld;
using pii = pair<int,int>;
using dat = pair<ld,pair<int,int>>;
using pq = priority_queue<dat, vector<dat>, greater<dat>>;
vector<pii> dir = {{0,1},{1,0},{-1,0},{0,-1}};

template<typename T> bool chmin(T &a, T b) { if (a > b){ a = b; return true; } else return false; }

ld dist(int a,int b,int c,int d){
    return sqrt(ld(c - a) * ld(c - a) + ld(d - b) * ld(d - b));
}

int main(){
    int n;
    cin >> n;
    vector<vector<int>> g(n);
    int winner = -1;
    vector<bool> cnt(n,true);
    for (int i = 0;i < n - 1;i++){
        int a,b;
        cin >> a >> b;
        a--,b--;
        g[a].push_back(b);
        cnt[b] = false;
    }
    for (int i = 0;i < n;i++){
        if (cnt[i])winner = i;
    }
    ll mod = 1000000;
    vector<vector<ll>> binomial(2001,vector<ll> (2001));
    for (int i = 1;i <= 2000;i++){
        binomial[i][0] = binomial[i][i] = 1;
        for (int j = 1;j < i;j++){
            binomial[i][j] = (binomial[i - 1][j - 1] + binomial[i - 1][j]) % mod;
        }
    }
    // for (int i = 1;i <= 10;i++){
    //     for (int j = 1;j <= 10;j++){
    //         cout << binomial[i][j] << ' ';
    //     }cout << endl;
    // }

    auto dfs = [&](auto self,int now,int pre)->pair<ll,ll>{//部分木のサイズ、組合せの総数
        if (g[now].size() == 1){
            return {1,1};
        }
        ll subtree_size = 0;
        ll kumi = 1;
        for (int i : g[now]){
            auto [x,y] = self(self,i,now);
            kumi *= binomial[x + subtree_size][x] * y % mod;
            kumi %= mod;
            subtree_size += x;
        }
        subtree_size += 1;
        return {subtree_size,kumi};
    };
    cout << dfs(dfs,winner,-1).second << endl;
    
}
accuracy: 0.12
time_ms: 20
memory_kb: 34484
final_rank: 19

code_snippet: #include <bits/stdc++.h>
using ll = long long;
using namespace std;
typedef long double ld;
using pii = pair<int,int>;
using dat = pair<ld,pair<int,int>>;
using pq = priority_queue<dat, vector<dat>, greater<dat>>;
vector<pii> dir = {{0,1},{1,0},{-1,0},{0,-1}};

template<typename T> bool chmin(T &a, T b) { if (a > b){ a = b; return true; } else return false; }

ld dist(int a,int b,int c,int d){
    return sqrt(ld(c - a) * ld(c - a) + ld(d - b) * ld(d - b));
}

int main(){
    int n;
    cin >> n;
    vector<vector<int>> g(n);
    int winner = -1;
    vector<bool> cnt(n,true);
    for (int i = 0;i < n - 1;i++){
        int a,b;
        cin >> a >> b;
        a--,b--;
        g[a].push_back(b);
        g[b].push_back(a);
        cnt[b] = false;
    }
    for (int i = 0;i < n;i++){
        if (cnt[i])winner = i;
    }
    ll mod = 1000000;
    vector<vector<ll>> binomial(2001,vector<ll> (2001));
    for (int i = 1;i <= 2000;i++){
        binomial[i][0] = binomial[i][i] = 1;
        for (int j = 1;j < i;j++){
            binomial[i][j] = (binomial[i - 1][j - 1] + binomial[i - 1][j]) % mod;
        }
    }
    // for (int i = 1;i <= 10;i++){
    //     for (int j = 1;j <= 10;j++){
    //         cout << binomial[i][j] << ' ';
    //     }cout << endl;
    // }

    auto dfs = [&](auto self,int now,int pre)->pair<ll,ll>{//部分木のサイズ、組合せの総数
        if (g[now].size() == 1){
            return {1,1};
        }
        ll subtree_size = 0;
        ll kumi = 1;
        for (int i : g[now]){
            if (i == pre) continue;
            auto [x,y] = self(self,i,now);
            kumi *= binomial[x + subtree_size][x] * y % mod;
            kumi %= mod;
            subtree_size += x;
        }
        subtree_size += 1;
        return {subtree_size,kumi};
    };
    cout << dfs(dfs,winner,-1).second << endl;
    
}
accuracy: 0.44
time_ms: 20
memory_kb: 34480
final_rank: 14

code_snippet: #include <bits/stdc++.h>
using ll = long long;
using namespace std;
typedef long double ld;
using pii = pair<int,int>;
using dat = pair<ld,pair<int,int>>;
using pq = priority_queue<dat, vector<dat>, greater<dat>>;
vector<pii> dir = {{0,1},{1,0},{-1,0},{0,-1}};

template<typename T> bool chmin(T &a, T b) { if (a > b){ a = b; return true; } else return false; }

ld dist(int a,int b,int c,int d){
    return sqrt(ld(c - a) * ld(c - a) + ld(d - b) * ld(d - b));
}

int main(){
    int n;
    cin >> n;
    vector<vector<int>> g(n);
    int winner = -1;
    vector<bool> cnt(n,true);
    for (int i = 0;i < n - 1;i++){
        int a,b;
        cin >> a >> b;
        a--,b--;
        g[a].push_back(b);
        g[b].push_back(a);
        cnt[b] = false;
    }
    for (int i = 0;i < n;i++){
        if (cnt[i])winner = i;
    }
    ll mod = 1000000;
    vector<vector<ll>> binomial(2001,vector<ll> (2001));
    for (int i = 1;i <= 2000;i++){
        binomial[i][0] = binomial[i][i] = 1;
        for (int j = 1;j < i;j++){
            binomial[i][j] = (binomial[i - 1][j - 1] + binomial[i - 1][j]) % mod;
        }
    }
    // for (int i = 1;i <= 10;i++){
    //     for (int j = 1;j <= 10;j++){
    //         cout << binomial[i][j] << ' ';
    //     }cout << endl;
    // }

    auto dfs = [&](auto self,int now,int pre)->pair<ll,ll>{//部分木のサイズ、組合せの総数
        if (g[now].size() == 1){
            return {1,1};
        }
        ll subtree_size = 0;
        ll kumi = 1;
        for (int i : g[now]){
            if (i == pre) continue;
            auto [x,y] = self(self,i,now);
            kumi = kumi * binomial[x + subtree_size][x] % mod * y % mod;
            subtree_size += x;
        }
        subtree_size += 1;
        return {subtree_size,kumi};
    };
    cout << dfs(dfs,winner,-1).second << endl;
    
}
accuracy: 0.44
time_ms: 10
memory_kb: 34512
final_rank: 13

code_snippet: #include <bits/stdc++.h>
using namespace std;

const long long MOD = 1000000;
map<pair<int, int>, long long> memo;
long long binom(int n, int r) {
  if(r < 0 || r > n) return 0;
  if(r == 0 || r == n) return 1;
  if(!memo.count(make_pair(n, r))) {
    memo[make_pair(n, r)] = (binom(n-1, r-1)+binom(n-1, r))%MOD;
  }
  return memo[make_pair(n, r)];
}

int main() {
  int N;
  cin >> N;
  vector<int> parent(N, -1);
  vector<vector<int>> child(N);
  for(int i = 0; i < N-1; i++) {
    int a, b;
    cin >> a >> b;
    a--, b--;
    parent[b] = a;
    child[a].push_back(b);
  }
  vector<long long> sz(N, 1), dp(N, 1);
  auto dfs = [&](auto dfs, int cur) -> void {
    for(const int &nxt : child[cur]) {
      dfs(dfs, nxt);
      dp[cur] *= dp[nxt]*binom(sz[cur]+sz[nxt]-1, sz[nxt])%MOD;
      dp[cur] %= MOD;
      sz[cur] += sz[nxt];
    }
  };
  for(int i = 0; i < N; i++) {
    if(parent[i] == -1) {
      dfs(dfs, i);
      cout << dp[i] << endl;
      break;
    }
  }
}
accuracy: 1
time_ms: 100
memory_kb: 17788
final_rank: 7

code_snippet: #include <bits/stdc++.h>
using namespace std;
#if __has_include(<atcoder/all>)
#include <atcoder/all>
using namespace atcoder;
#endif
using ll = long long;
using ld = long double;
using ull = unsigned long long;
#define endl "\n"
typedef pair<int, int> Pii;
#define REP(i, n) for (int i = 0; i < (n); ++i)
#define REP3(i, m, n) for (int i = (m); (i) < int(n); ++ (i))
#define FOR(i,a,b) for(ll i=a;i<=(ll)(b);i++)
#define rep(i,a,b) for(int i=(int)(a);i<(int)(b);i++)
#define ALL(x) begin(x), end(x)
#define rrep(i,a,b) for(int i=a;i>=b;i--)
#define fore(i,a) for(auto &i:a)
#define all(s) (s).begin(),(s).end()
#define drep2(i, m, n) for (int i = (m)-1; i >= (n); --i)
#define drep(i, n) drep2(i, n, 0)
#define rever(vec) reverse(vec.begin(), vec.end())
#define sor(vec) sort(vec.begin(), vec.end())
#define fi first
#define se second
#define pb push_back
#define P pair<ll,ll>
#define PQminll priority_queue<ll, vector<ll>, greater<ll>>
#define PQmaxll priority_queue<ll,vector<ll>,less<ll>>
#define PQminP priority_queue<P, vector<P>, greater<P>>
#define PQmaxP priority_queue<P,vector<P>,less<P>>
#define NP next_permutation
//const ll mod = 1000000009;
const ll mod = 998244353;
//const ll mod = 1000000007;
const ll inf = 4100000000000000000ll;
const ld eps = ld(0.00000000001);
static const long double pi = 3.141592653589793;
template<class T>void vcin(vector<T> &n){for(int i=0;i<int(n.size());i++) cin>>n[i];}
template<class T,class K>void vcin(vector<T> &n,vector<K> &m){for(int i=0;i<int(n.size());i++) cin>>n[i]>>m[i];}
template<class T>void vcout(vector<T> &n){for(int i=0;i<int(n.size());i++){cout<<n[i]<<" ";}cout<<endl;}
template<class T>void vcin(vector<vector<T>> &n){for(int i=0;i<int(n.size());i++){for(int j=0;j<int(n[i].size());j++){cin>>n[i][j];}}}
template<class T>void vcout(vector<vector<T>> &n){for(int i=0;i<int(n.size());i++){for(int j=0;j<int(n[i].size());j++){cout<<n[i][j]<<" ";}cout<<endl;}cout<<endl;}
void yes(bool a){cout<<(a?"yes":"no")<<endl;}
void YES(bool a){cout<<(a?"YES":"NO")<<endl;}
void Yes(bool a){cout<<(a?"Yes":"No")<<endl;}
void possible(bool a){ cout<<(a?"possible":"impossible")<<endl; }
void Possible(bool a){ cout<<(a?"Possible":"Impossible")<<endl; }
void POSSIBLE(bool a){ cout<<(a?"POSSIBLE":"IMPOSSIBLE")<<endl; }
template<class T>auto min(const T& a){ return *min_element(all(a)); }
template<class T>auto max(const T& a){ return *max_element(all(a)); }
template<class T,class F>void print(pair<T,F> a){cout<<a.fi<<" "<<a.se<<endl;}
template<class T>bool chmax(T &a, const T &b) { if (a<b) { a=b; return 1; } return 0;}
template<class T>bool chmin(T &a, const T &b) { if (b<a) { a=b; return 1; } return 0;}
template<class T> void ifmin(T t,T u){if(t>u){cout<<-1<<endl;}else{cout<<t<<endl;}}
template<class T> void ifmax(T t,T u){if(t>u){cout<<-1<<endl;}else{cout<<t<<endl;}}
ll fastgcd(ll u,ll v){ll shl=0;while(u&&v&&u!=v){bool eu=!(u&1);bool ev=!(v&1);if(eu&&ev){++shl;u>>=1;v>>=1;}else if(eu&&!ev){u>>=1;}else if(!eu&&ev){v>>=1;}else if(u>=v){u=(u-v)>>1;}else{ll tmp=u;u=(v-u)>>1;v=tmp;}}return !u?v<<shl:u<<shl;}
ll modPow(ll a, ll n, ll mod) { if(mod==1) return 0;ll ret = 1; ll p = a % mod; while (n) { if (n & 1) ret = ret * p % mod; p = p * p % mod; n >>= 1; } return ret; }
vector<ll> divisor(ll x){ vector<ll> ans; for(ll i = 1; i * i <= x; i++){ if(x % i == 0) {ans.push_back(i); if(i*i!=x){ ans.push_back(x / ans[i]);}}}sor(ans); return ans; }
ll pop(ll x){return __builtin_popcountll(x);}
ll poplong(ll x){ll y=-1;while(x){x/=2;y++;}return y;}
P hyou(P a){ll x=fastgcd(abs(a.fi),abs(a.se));a.fi/=x;a.se/=x;if(a.se<0){a.fi*=-1;a.se*=-1;}return a;}
P Pplus(P a,P b){ return hyou({a.fi*b.se+b.fi*a.se,a.se*b.se});}
P Ptimes(P a,ll b){ return hyou({a.fi*b,a.se});}
P Ptimes(P a,P b){ return hyou({a.fi*b.fi,a.se*b.se});}
P Pminus(P a,P b){ return hyou({a.fi*b.se-b.fi*a.se,a.se*b.se});}
P Pgyaku(P a){ return hyou({a.se,a.fi});}
template<class T>
struct Sum{
  vector<T> data;
  Sum(const vector<T>& v):data(v.size()+1){
    for(ll i=0;i<v.size();i++) data[i+1]=data[i]+v[i];
  }
  T get(ll l,ll r) const {
    return data[r]-data[l];
  }
};
template<class T>
struct Sum2{
  vector<vector<T>> data;
  Sum2(const vector<vector<T>> &v):data(v.size()+1,vector<T>(v[0].size()+1)){
    for(int i=0;i<v.size();i++) for(int j=0;j<v[i].size();j++) data[i+1][j+1]=data[i][j+1]+v[i][j];
    for(int i=0;i<v.size();i++) for(int j=0;j<v[i].size();j++) data[i+1][j+1]+=data[i+1][j];
  }
  T get(ll x1,ll y1,ll x2,ll y2) const {
    return data[x2][y2]+data[x1][y1]-data[x1][y2]-data[x2][y1];
  }
};

void cincout(){
  ios::sync_with_stdio(false);
    std::cin.tie(nullptr);
  cout<< fixed << setprecision(15);
}
vector<pair<int,int>> g[1000];
int ng[1000];
vector<int> now,edge;
void dfs(ll v){
  for(auto e:g[v]){
    if(ng[e.fi]) continue;
    edge.pb(e.se);
    now.pb(e.fi);
    dfs(e.fi);
  }
}
vector<P> prime[1001];
ll solve(ll n,vector<int> a,vector<int> b){
  if(n<=2) return 1;
  vector<int> f;
  for(auto e:a) f.pb(e);
  for(auto e:b) f.pb(e);
  map<int,int> m;
  for(auto e:f) m[e]++;
  int N=0;
  for(auto &e:m){
    e.se=N;
    N++;
  }
  for(int i=0;i<n-1;i++) a[i]=m[a[i]];
  for(int i=0;i<n-1;i++) b[i]=m[b[i]];
  for(int i=0;i<n;i++) g[i].clear();
  for(int i=0;i<n;i++) ng[i]=0;
  for(int i=0;i<n-1;i++) g[a[i]].pb({b[i],i});
  vector<ll> d(n);
  for(auto e:b) d[e]++;
  ll win=0;
  for(int i=0;i<n;i++) if(d[i]==0) win=i;
  ll ans=1;
  ll cnt=0;
  for(int i=0;i<n-1;i++) if(a[i]==win) cnt++;
  vector<int> A(n+1);
  for(int i=1;i<=n-1;i++){
    for(auto e:prime[i]){
      A[e.fi]+=e.se;
    }
  }
  vector<int> p;
  for(int i=0;i<n-1;i++) if(a[i]==win) p.pb(b[i]);
  for(auto e:p) ng[e]=1;
  vector<pair<vector<int>,vector<int>>> CD;
  for(int i=0;i<p.size();i++){
    now={};
    edge={};
    now.pb(p[i]);
    dfs(p[i]);
    vector<int> c,d;
    for(auto e:edge){
      c.pb(a[e]);
      d.pb(b[e]);
    }
    CD.pb({c,d});
    for(int j=1;j<=c.size()+1;j++){
      for(auto e:prime[j]){
        A[e.fi]-=e.se;
      }
    }
  }
  for(auto e:CD) (ans*=solve(e.fi.size()+1,e.fi,e.se))%=1000000;
  for(int i=1;i<=n;i++) (ans*=modPow(i,A[i],1000000))%=1000000;
  return ans;
}
int main() {
  cincout();
  ll n;
  cin>>n;
  vector<int> a(n-1),b(n-1);
  for(int i=0;i<n-1;i++){
    cin>>a[i]>>b[i];
    a[i]--;
    b[i]--;
  }
  vector<int> p(1001,1000000);
  for(int i=2;i<=1000;i++){
    for(int j=i;j<=1000;j+=i) p[j]=min(p[j],i);
  }
  for(int i=1;i<=1000;i++){
    int x=i;
    map<int,int> m;
    while(x>1){
      m[p[x]]++;
      x/=p[x];
    }
    for(auto e:m) prime[i].pb(e);
  }
  cout<<solve(n,a,b)<<endl;
}
accuracy: 1
time_ms: 90
memory_kb: 50296
final_rank: 9

code_snippet: #include <iostream>
#include <string>
#include <vector>
#include <algorithm>
#include <utility>
#include <tuple>
#include <cstdint>
#include <cstdio>
#include <map>
#include <cstdint>
#include <queue>
#include <set>
#include <stack>
#include <deque>
#include <unordered_map>
#include <unordered_set>
#include <bitset>
#include <cctype>
#include <functional>
#include <ctime>
#include <fstream>
#include <cmath>
#include <limits>
#include <chrono>
#include <numeric>
#include <type_traits>
#include <iomanip>
#include <float.h>
#include <math.h>
#include <cassert>
#include <random>
using namespace std;
using ll = long long;

ll ll_gcd(ll a, ll b) {
	if (a < b) return ll_gcd(b, a);
	ll r;
	while ((r = a % b)) {
		a = b;
		b = r;
	}
	return b;
}

int dfs(vector<vector<int>>& z, vector<ll>& ans, int n,int now) {
	int a = 1;
	for (int i = 0; i < z[now].size(); i++) {
		a += dfs(z, ans, n, z[now][i]);
	}
	int b = a;
	for (int i = 0; i < n; i++) {
		int h = ll_gcd(ans[i], b);
		ans[i] /= h;
		b /= h;
	}
	return a;
}

int main(){
	ll n;
	cin >> n;
	vector<vector<int>> z(n);
	set<int> s;
	for (int i = 0; i < n; i++) {
		s.insert(i);
	}
	for (int i = 0; i < n-1; i++) {
		int a, b;
		cin >> a >> b;
		a--;
		b--;
		z[a].push_back(b);
		s.erase(b);
	}
	int a = 0;
	for (int i = 0; i < n; i++) {
		if (s.count(i))a = i;
	}
	vector<ll> ans(n);
	for (int i = 0; i < n; i++) {
		ans[i] = i + 1;
	}
	dfs(z, ans, n, a);
	ll ansa = 1;
	for (int i = 0; i < n; i++) {
		ansa *= ans[i];
		ansa %= 1000000;
	}
	cout << ansa << endl;
}
accuracy: 1
time_ms: 10
memory_kb: 3464
final_rank: 1

code_snippet: #include <bits/stdc++.h>
using namespace std;
#define rep(i, n)  for(long long i=0;i<(long long)(n);i++)
#define REP(i,k,n) for(long long i=k;i<(long long)(n);i++)
#define pb emplace_back
#define lb(v,k) (lower_bound(all(v),(k))-v.begin())
#define ub(v,k) (upper_bound(all(v),(k))-v.begin())
#define fi first
#define se second
#define pi M_PI
#define PQ(T) priority_queue<T>
#define SPQ(T) priority_queue<T,vector<T>,greater<T>>
#define dame(a) {out(a);return 0;}
#define decimal cout<<fixed<<setprecision(15);
#define all(a) a.begin(),a.end()
#define rsort(a) {sort(all(a));reverse(all(a));}
#define dupli(a) {sort(all(a));a.erase(unique(all(a)),a.end());}
#define popcnt __builtin_popcountll
typedef long long ll;
typedef pair<ll,ll> P;
typedef tuple<ll,ll,ll> PP;
typedef tuple<ll,ll,ll,ll> PPP;
using vi=vector<ll>;
using vvi=vector<vi>;
using vvvi=vector<vvi>;
using vvvvi=vector<vvvi>;
using vp=vector<P>;
using vvp=vector<vp>;
using vb=vector<bool>;
using vvb=vector<vb>;
const ll inf=1001001001001001001;
const ll INF=1001001001;
const ll mod=998244353;
const double eps=1e-10;
template<class T> bool chmin(T&a,T b){if(a>b){a=b;return true;}return false;}
template<class T> bool chmax(T&a,T b){if(a<b){a=b;return true;}return false;}
template<class T> void out(T a){cout<<a<<'\n';}
template<class T> void outp(T a){cout<<'('<<a.fi<<','<<a.se<<')'<<'\n';}
template<class T> void outvp(T v){rep(i,v.size())cout<<'('<<v[i].fi<<','<<v[i].se<<')';cout<<'\n';}
template<class T> void outvvp(T v){rep(i,v.size())outvp(v[i]);}
template<class T> void outv(T v){rep(i,v.size()){if(i)cout<<' ';cout<<v[i];}cout<<'\n';}
template<class T> void outvv(T v){rep(i,v.size())outv(v[i]);}
template<class T> bool isin(T x,T l,T r){return (l)<=(x)&&(x)<=(r);}
template<class T> void yesno(T b){if(b)out("yes");else out("no");}
template<class T> void YesNo(T b){if(b)out("Yes");else out("No");}
template<class T> void YESNO(T b){if(b)out("YES");else out("NO");}
template<class T> void outset(T s){auto itr=s.begin();while(itr!=s.end()){if(itr!=s.begin())cout<<' ';cout<<*itr;itr++;}cout<<'\n';}
void outs(ll a,ll b){if(a>=inf-100)out(b);else out(a);}
ll gcd(ll a,ll b){if(b==0)return a;return gcd(b,a%b);}
ll modpow(ll a,ll b){ll res=1;a%=mod;while(b){if(b&1)res=res*a%mod;a=a*a%mod;b>>=1;}return res;}

int main(){
    ll m=1000000;
    ll n;cin>>n;
    vvi g(n);
    vb ok(n,true);
    rep(i,n-1){
        ll a,b;cin>>a>>b;a--;b--;
        g[a].pb(b);ok[b]=false;
    }
    ll ne=0;while(!ok[ne])ne++;
    vi dp(n,1),sub(n,1);
    vvi table(n+1,vi(n+1));table[0][0]=1;
    rep(i,n+1)rep(j,n+1){
        table[i][j]%=m;
        if(i!=n&&j!=n)table[i+1][j+1]+=table[i][j];
        if(i!=n)table[i+1][j]+=table[i][j];
    }
    function<void(ll,ll)> dfs=[&](ll i,ll p){
        vi al;
        for(ll x:g[i])if(x!=p){
            dfs(x,i);
            sub[i]+=sub[x];
            dp[i]=dp[i]*dp[x]%m;
            al.pb(sub[x]);
        }
        ll cur=sub[i]-1;
        for(ll x:al){
            dp[i]=dp[i]*table[cur][x]%m;
            cur-=x;
        }
    };dfs(ne,-1);
    out(dp[ne]);
}
accuracy: 1
time_ms: 10
memory_kb: 11112
final_rank: 2

code_snippet: #include <iostream>
#include <vector>

using namespace std;
typedef long long ll;

const ll MOD = 1e6;
vector<vector<int>> graph;

vector<vector<ll>> nCr(2010, vector<ll>(2010));
void init() {
    for (int i = 0; i < 2010; i++) {
        for (int j = 0; j < 2010; j++) {
            if (i < j)nCr[i][j] = 0;
            else if (j == 0) nCr[i][j] = 1;
            else nCr[i][j] = (nCr[i - 1][j - 1] + nCr[i - 1][j]) % MOD;
        }
    }
}

pair<ll, int> dfs(int prev, int here) {
    ll ret = 1, size = 0;
    for (auto &next:graph[here]) {
        if (next == prev)continue;
        auto result = dfs(here, next);
        ret *= result.first, ret %= MOD;
        ret *= nCr[size + result.second][size], ret %= MOD;
        size += result.second;
    }
    return {ret % MOD, size + 1};
}

int main() {
    init();

    int n;
    cin >> n;

    graph.resize(n);
    vector<bool> winner(n, true);
    for (int i = 0; i < n - 1; i++) {
        int a, b;
        cin >> a >> b, a--, b--;
        graph[a].push_back(b);
        winner[b] = false;
    }

    int top = -1;
    for (int i = 0; i < n; i++) {
        if (winner[i])top = i;
    }

    auto ret = dfs(-1, top);
    cout << ret.first << endl;
    return 0;
}
accuracy: 1
time_ms: 10
memory_kb: 34416
final_rank: 3

code_snippet: #include <iostream>
#include <vector>

using namespace std;
typedef long long ll;

const ll MOD = 1e6;
vector<vector<int>> graph;

vector<vector<ll>> nCr(2010, vector<ll>(2010));
void init() {
    for (int i = 0; i < 2010; i++) {
        for (int j = 0; j < 2010; j++) {
            if (i < j)nCr[i][j] = 0;
            else if (j == 0) nCr[i][j] = 1;
            else nCr[i][j] = (nCr[i - 1][j - 1] + nCr[i - 1][j]) % MOD;
        }
    }
}

pair<ll, int> dfs(int prev, int here) {
    int ret = 1, size = 0;
    for (auto &next:graph[here]) {
        if (next == prev)continue;
        auto result = dfs(here, next);
        ret *= result.first, ret %= MOD;
        ret *= nCr[size + result.second][size], ret %= MOD;
        size += result.second;
    }
    return {ret % MOD, size + 1};
}

int main() {
    init();

    int n;
    cin >> n;

    graph.resize(n);
    vector<bool> winner(n, true);
    for (int i = 0; i < n - 1; i++) {
        int a, b;
        cin >> a >> b, a--, b--;
        graph[a].push_back(b);
        winner[b] = false;
    }

    int top = -1;
    for (int i = 0; i < n; i++) {
        if (winner[i])top = i;
    }

    auto ret = dfs(-1, top);
    cout << ret.first << endl;
    return 0;
}
accuracy: 0.76
time_ms: 10
memory_kb: 34396
final_rank: 10

code_snippet: #include <bits/stdc++.h>
using namespace std;
 
#define REP(i, n) for (ll i = 0; i < n; i++)
#define REPR(i, n) for (ll i = n; i >= 0; i--)
#define FOR(i, m, n) for (ll i = m; i < n; i++)
#define FORR(i, m, n) for (ll i = m; i >= n; i--)
#define REPO(i, n) for (ll i = 1; i <= n; i++)
#define ll long long
#define INF (ll)1 << 60
#define MINF (-1 * INF)
#define ALL(n) n.begin(), n.end()
#define MOD 1000000007
#define P pair<ll, ll>



ll n, dp[110000], sz[110000], mod = 1e6;
vector<ll> in(110000);
vector<ll> g[110000];
ll com[2100][2100];

void cominit(){
    
    REP(i, 2010){
        com[i][0] = 1;
        REPO(j, i){
            com[i][j] = com[i - 1][j - 1] + com[i - 1][j];
            com[i][j] %= mod;
        }
    }
}
void dfs(ll v, ll p){
    ll now = 1;
    vector<ll> l;
    REP(i, g[v].size()){
        ll w = g[v][i];
        if(w == p)continue;
        dfs(w, v);
        now *= dp[w];
        now %= mod;
        sz[v] += sz[w];
        l.push_back(sz[w]);
    }
    ll t = sz[v];
    REP(i, l.size()){
        now *= com[t][l[i]];
        now %= mod;
        t -= l[i];
    }
    sz[v] += 1;
    dp[v] = now;
}

int main() {
    cominit();
    cin >> n;
    REP(i, n - 1){
        ll a, b;
        cin >>a >> b;
        a--;
        b--;
        g[a].push_back(b);
        in[b]++;
    }
    REP(i, n){
        if(in[i] == 0){
            dfs(i, -1);
            cout << dp[i] << endl;
            return 0;
        }
    }
}
accuracy: 1
time_ms: 20
memory_kb: 29340
final_rank: 6

code_snippet: #include "bits/stdc++.h"
#define int long long
#define FOR(i, a, b) for (int i = (int)(a); i < (int)(b); i++)
#define rep(i, n) for (int i = 0; i < (int)(n); i++)
#define ALL(obj) begin(obj), end(obj)
#define MAX(x) *max_element(ALL(x))
#define MIN(x) *min_element(ALL(x))
#define LOWER_BOUND(A, key) distance(A.begin(), lower_bound(ALL(A), key))
#define UPPER_BOUND(A, key) distance(A.begin(), upper_bound(ALL(A), key))

using namespace std;
using ll      = long long;
const int MOD = (int)(1e9 + 7);
const int INF = (int)(1e13 + 7);

int ceil_(int a, int b) { return (a >= 0 ? (a + (b - 1)) / b : (a - (b - 1)) / b); }
int mod(int a, int b) { return a >= 0 ? a % b : a - (b * ceil_(a, b)); }
int bpm(int x, unsigned int y) {
  if (x == 0) return 0;
  if (y == 0) return 1;
  int ans   = 1;
  int digit = (int)((log((double)y) / log((double)2) / 1 + 1));
  x %= MOD;
  for (unsigned int i = 0; i < digit; i++) {
    if (((y >> i) & 1u) == 1) ans = ans * x % MOD;
    x = x * x % MOD;
  }
  return ans;
}
template <class T>
void cumulative_sum(T &container) {
  for (int i = 0; i < container.size() - 1; i++) container[i + 1] += container[i];
}
int ans = 1;
#define MAX_ 500000
int inv_list[MAX_]; //inv_list[i-1] = inverse of i
int fac[MAX_];
int finv[MAX_];
void nCk_init() {
  inv_list[0] = fac[0] = finv[0] = 1;
  for (int i = 0; i < MAX_ - 1; i++) {
    inv_list[i + 1] = MOD - ((inv_list[(MOD % (i + 2)) - 1] * (MOD / (i + 2))) % MOD);
    fac[i + 1]      = (fac[i] * (i + 2)) % MOD;
    finv[i + 1]     = (finv[i] * inv_list[i + 1]) % MOD;
  }
}
int nCk(int n, int k) {
  return (fac[n - 1] * ((finv[k - 1] * finv[n - k - 1]) % MOD)) % MOD;
}
int edge_num(vector<vector<int>> &edge, int now) {
  int ret = 0;
  if (edge[now].empty()) {
    return 1;
  } else {
    rep(i, edge[now].size()) {
      ret += edge_num(edge, edge[now][i]);
    }
    return ret + 1;
  }
}

void calc(vector<vector<int>> &edge, int now) {
  if (edge[now].size() == 2) {
    ans *= nCk(edge_num(edge, edge[now][0]) + edge_num(edge, edge[now][1]), edge_num(edge, edge[now][0]));
  }
  rep(i, edge[now].size()) {
    calc(edge, edge[now][i]);
  }
}

signed main() {
  int N;
  cin >> N;
  nCk_init();
  vector<vector<int>> edge(N);
  vector<bool> check(N, false);
  rep(i, N - 1) {
    int a, b;
    cin >> a >> b;
    edge[a - 1].emplace_back(b - 1);
    check[b - 1] = true;
  }
  rep(i, N) {
    if (check[i] == false) {
      calc(edge, i);
      break;
    }
  }
  cout << ans << endl;
}
accuracy: 0.12
time_ms: 10
memory_kb: 14852
final_rank: 17

code_snippet: #include <iostream>
//#include <iomanip>
//#include <string>
#include <vector>
#include <algorithm>
//#include <utility>
//#include <set>
//#include <map>
//#include <stack>
//#include <deque>
//#include <bitset>
//#include <math.h>
using namespace std ;
using ll = long long ;
//using ld = long double ;
using vll = vector<ll> ;
using vvll = vector<vll> ;
//using vc = vector<char> ;
//using vvc = vector<vc> ;
using vb = vector<bool> ;
//using vvb = vector<vb> ;
//using pll = pair<ll,ll> ;

ll mod = 1000000 ;
//long double pie = acos(-1) ;

//void yorn(bool a){if(a) cout << "Yes" << endl ; else cout << "No" << endl ;}
//void YorN(bool a){if(a) cout << "YES" << endl ; else cout << "NO" << endl ;}
//ll gcd(long long a,long long b){if(b==0) return a ; return gcd(b,a%b) ;}
//ll lcm(long long a,long long b){return a/gcd(a,b)*b ;}
//ll sa(long long a,long long b){if(a>b) return a-b ; return b-a ;}
//void mysort(vector<pll> &a){sort(a.begin(),a.end()) ;}
//void myrev(vector<long long> &a){reverse(a.begin(),a.end()) ;}

vvll nCr(2010,vll(2011,1)) ;

void tree_size(vvll &g,vll &cnt,int n){
	if(g.at(n).size()==0){
		cnt.at(n) = 1 ;
	}else{
		cnt.at(n) = 1 ;
		for(int i=0;i<g.at(n).size();i++){
			tree_size(g,cnt,g.at(n).at(i)) ;
			cnt.at(n) += cnt.at(g.at(n).at(i)) ;
		}
	}
}

ll solve(vvll &g,vll &cnt,int n){
	if(g.at(n).size()==1) return 1 ;
	ll sum = 0 ;
	ll res = 1 ;
	sum = cnt.at(n)-1 ;
	ll sub = 0 ;
	for(int i=0;i<g.at(n).size();i++){
		res = res*nCr.at(sum-sub+cnt.at(g.at(n).at(i))-1).at(cnt.at(g.at(n).at(i)))%mod*solve(g,cnt,g.at(n).at(i))%mod ;
		sub += cnt.at(g.at(n).at(i)) ;
	}
	return res ;
}

int main(){
	for(int i=1;i<2010;i++){
		for(int j=1;j<i;j++){
			nCr.at(i).at(j) = nCr.at(i-1).at(j-1)+nCr.at(i-1).at(j) ;
			nCr.at(i).at(j) %= mod ;
		}
	}
	ll n ; cin >> n ;
	vvll g(n,vll(0)) ;
	vb root(n,true) ;
	for(int i=0;i<n-1;i++){
		ll a,b ;
		cin >> a >> b ;
		a-- ; b-- ;
		g.at(a).push_back(b) ;
		root.at(b) = false ;
	}
	ll s = -1 ;
	for(int i=0;i<n;i++){
		if(root.at(i)){
			s = i ;
			break ;
		}
	}
	vll cnt(n,0) ;
	tree_size(g,cnt,s) ;
	cout << solve(g,cnt,s) << endl ;
}
accuracy: 0.08
time_ms: 10
memory_kb: 34324
final_rank: 20

code_snippet: #include <iostream>
#include <cstdio>
#include <string>
#include <cstring>
#include <deque>
#include <list>
#include <queue>
#include <stack>
#include <vector>
#include <utility>
#include <algorithm>
#include <map>
#include <set>
#include <complex>
#include <cmath>
#include <limits>
#include <climits>
#include <ctime>
#include <cassert>
#include <numeric>
#include <functional>
#include <bitset>

using namespace std;
using lint = long long int;
long long int INF = 1001001001001001LL;
int inf = 1000000007;
long long int MOD = 1000000LL;
double PI = 3.1415926535897932;

template<typename T1,typename T2>inline void chmin(T1 &a,const T2 &b){if(a>b) a=b;}
template<typename T1,typename T2>inline void chmax(T1 &a,const T2 &b){if(a<b) a=b;}

#define ALL(a) a.begin(),a.end()
#define RALL(a) a.rbegin(),a.rend()

/* do your best */

const long long MAXN = 1001024;

// a, b の最大公約数を返す O( log max(a, b) )
long long gcd(long long a, long long b) {
  if(b == 0) return a;
  return gcd(b, a % b);
}

// ax + by = 1 となるような (x, y) と gcd(a, b) を返す. gcd(a, b) = 1 の時、解が存在する.
long long extgcd(long long a, long long b, long long &x, long long &y){
  long long d = a;
  if(b != 0){
    d = extgcd(b, a, y, x);
    y -= (a / b) * x;
  }else{
    x = 1;
    y = 0;
  }
  return d;
}


// 区間 [a, b) に存在する素数の個数を返す関数

long long prime[MAXN];        // [a,b) の素数のうち i 番目の素数
bool is_prime[MAXN];    // 整数 i が素数であるかどうか
bool is_prime_ab[MAXN]; // 整数 i+a が素数であるかどうか

long long sieve(long long n) {
  long long res = 0; fill(is_prime, is_prime + MAXN, true);
  is_prime[0] = is_prime[1] = false; // 0 と 1 は素数ではない。
  for(long long i = 2; i <= n; ++i) {
    if(!is_prime[i]) continue;
    prime[res++] = i;
    for(long long j = 2 * i; j <= n; j += i) is_prime[j] = false; // 素数 i の倍数は素数ではない (ふるい(篩)にかける)
  }
  return res;
}

/*
long long segment_sieve(long long a, long long b){
  fill(is_prime, is_prime + MAXN, true);
  fill(is_prime_ab, is_prime_ab + MAXN, true);
  for(long long i = 2; i * i <= b - 1; i++) {
    if(!is_prime[i]) continue;
    for(long long j = 2 * i; j * j <= b - 1; j += i) is_prime[j] = false; // 素数 i で篩にかける
    for(long long j = a - a % i; j < b; j += i) {
      if(j < a) continue;
      if(is_prime_ab[j-a]) is_prime_ab[j-a] = false; // 素数 i で篩にかける
    }
  }

  long long res = 0;
  for(long long i = a; i < b; i++) if(is_prime_ab[i - a]) prime[res++] = i;
  return res;
}
*/

// ある整数の約数列挙
vector<long long> divisors(long long n) {
  vector<long long> res;
  for(long long i = 1; i*i <= n; ++i) {
    if(n % i != 0) continue;
    res.push_back(i);
    if(n/i == i) continue; // 上の行で追加済み。
    res.push_back(n/i);
  }
  sort(res.begin(), res.end());
  return res;
}


// 素因数分解
map<long long, long long> prime_factors(long long n) {
  map<long long, long long> res;
  if(n == 1) { // n=1 の素因数分解は n^1
    res[n] = 1;
    return res;
  }
  for(long long i = 2, _n = n; i*i <= _n; ++i) {
    while(n % i == 0) {
      ++res[i]; // 素数i^{res[i]}
      n /= i;
    }
  }
  if(n != 1) res[n] = 1;
  return res;
}


// 繰り返し 2 乗法
long long modpow(long long a, long long n) {
  long long res = 1;
  while (n > 0) {
    if (n & 1) res = res * a % MOD;
    a = a * a % MOD;
    n >>= 1;
  }
  return res;
}


// 逆元を求める. a と m は互いに素であることが要請される.
long long modinv(long long a, long long m) {
  long long b = m, u = 1, v = 0;
  while(b){
    long long t = a / b;
    a -= t * b; swap(a, b);
    u -= t * v; swap(u, v);
  }
  u %= m; 
  if (u < 0) u += m;
  return u;
}

long long fac[MAXN], finv[MAXN], inv[MAXN];

lint comb[2000][2000];

// 前処理 O(n)
void math_init(){
  for(int n = 0; n < 2000; n++) comb[n][0] = 1;
  
  for(int n = 1; n < 2000; n++) {
    for(int r = 1; r < 2000; r++) {
      comb[n][r] = comb[n - 1][r - 1] + comb[n - 1][r];
      comb[n][r] %= MOD;
    }
  }

  fac[0] = fac[1] = 1;
  finv[0] = finv[1] = 1;
  inv[1] = 1;
  for(long long i = 2; i < MAXN; i++){
    fac[i] = fac[i - 1] * i % MOD;
    inv[i] = MOD - inv[MOD%i] * (MOD / i) % MOD;
    finv[i] = finv[i - 1] * inv[i] % MOD;
  }
}

// 二項係数計算 O(1)
long long COM(long long n, long long k){
  if (n < k) return 0;
  if (n < 0 || k < 0) return 0;
  return fac[n] * (finv[k] * finv[n - k] % MOD) % MOD;
}


// before your coding, you have to write a line "math_init()"
void dfs(int cur, vector<vector<int>> &g, vector<lint> &dp, vector<lint> &sz) {
  if(g[cur].size() == 0) {
    dp[cur] = 1;
    sz[cur] = 1;
  // cerr << "dp[" << cur << "] = " << dp[cur] << endl;
    return;
  }
  
  for(auto nxt : g[cur]) {
    dfs(nxt, g, dp, sz);
  }
  // sz を計算
  for(auto nxt : g[cur]) {
    sz[cur] += sz[nxt];
    sz[cur] %= MOD;
  }
  sz[cur] %= MOD;
  // dp を計算
  dp[cur] = 1LL;
  for(auto nxt : g[cur]) {
    dp[cur] *= dp[nxt];
    dp[cur] %= MOD;
    // dp[cur] /= fac[sz[nxt]];
  }

  lint mul = 1LL;
  lint n = sz[cur];
  for(auto nxt : g[cur]) {
    mul *= comb[n][sz[nxt]];
    mul %= MOD;
    n -= sz[nxt];
  }
  dp[cur] *= mul;
  dp[cur] %= MOD;
  // cerr << "dp[" << cur << "] = " << dp[cur] << endl;
  sz[cur]++;
  return;
}

int main() {
  
  math_init();
  int n; cin >> n;
  vector<vector<int>> g(n);
  set<lint> loser;
  for(int i = 0; i < n - 1; i++) {
    int a, b; cin >> a >> b;
    a--;
    b--;
    loser.insert(b);
    g[a].push_back(b);
  }

  lint winner = -1;
  for(int i = 0; i < n; i++) {
    if(loser.count(i) == 0) {
      winner = i;
    }
  }

  assert(winner != -1);
  vector<lint> dp(n, 0);
  vector<lint> sz(n, 0);
  dfs(winner, g, dp, sz);
  cout << dp[winner] << endl;
  return 0;
}
accuracy: 1
time_ms: 70
memory_kb: 57984
final_rank: 8

code_snippet: #include <iostream>
#include <cstdio>
#include <string>
#include <cstring>
#include <deque>
#include <list>
#include <queue>
#include <stack>
#include <vector>
#include <utility>
#include <algorithm>
#include <map>
#include <set>
#include <complex>
#include <cmath>
#include <limits>
#include <climits>
#include <ctime>
#include <cassert>
#include <numeric>
#include <functional>
#include <bitset>

using namespace std;
using lint = long long int;
long long int INF = 1001001001001001LL;
int inf = 1000000007;
long long int MOD = 1000000LL;
double PI = 3.1415926535897932;

template<typename T1,typename T2>inline void chmin(T1 &a,const T2 &b){if(a>b) a=b;}
template<typename T1,typename T2>inline void chmax(T1 &a,const T2 &b){if(a<b) a=b;}

#define ALL(a) a.begin(),a.end()
#define RALL(a) a.rbegin(),a.rend()

/* do your best */

const long long MAXN = 1001024;

// a, b の最大公約数を返す O( log max(a, b) )
long long gcd(long long a, long long b) {
  if(b == 0) return a;
  return gcd(b, a % b);
}

// ax + by = 1 となるような (x, y) と gcd(a, b) を返す. gcd(a, b) = 1 の時、解が存在する.
long long extgcd(long long a, long long b, long long &x, long long &y){
  long long d = a;
  if(b != 0){
    d = extgcd(b, a, y, x);
    y -= (a / b) * x;
  }else{
    x = 1;
    y = 0;
  }
  return d;
}


// 区間 [a, b) に存在する素数の個数を返す関数

long long prime[MAXN];        // [a,b) の素数のうち i 番目の素数
bool is_prime[MAXN];    // 整数 i が素数であるかどうか
bool is_prime_ab[MAXN]; // 整数 i+a が素数であるかどうか

long long sieve(long long n) {
  long long res = 0; fill(is_prime, is_prime + MAXN, true);
  is_prime[0] = is_prime[1] = false; // 0 と 1 は素数ではない。
  for(long long i = 2; i <= n; ++i) {
    if(!is_prime[i]) continue;
    prime[res++] = i;
    for(long long j = 2 * i; j <= n; j += i) is_prime[j] = false; // 素数 i の倍数は素数ではない (ふるい(篩)にかける)
  }
  return res;
}

/*
long long segment_sieve(long long a, long long b){
  fill(is_prime, is_prime + MAXN, true);
  fill(is_prime_ab, is_prime_ab + MAXN, true);
  for(long long i = 2; i * i <= b - 1; i++) {
    if(!is_prime[i]) continue;
    for(long long j = 2 * i; j * j <= b - 1; j += i) is_prime[j] = false; // 素数 i で篩にかける
    for(long long j = a - a % i; j < b; j += i) {
      if(j < a) continue;
      if(is_prime_ab[j-a]) is_prime_ab[j-a] = false; // 素数 i で篩にかける
    }
  }

  long long res = 0;
  for(long long i = a; i < b; i++) if(is_prime_ab[i - a]) prime[res++] = i;
  return res;
}
*/

// ある整数の約数列挙
vector<long long> divisors(long long n) {
  vector<long long> res;
  for(long long i = 1; i*i <= n; ++i) {
    if(n % i != 0) continue;
    res.push_back(i);
    if(n/i == i) continue; // 上の行で追加済み。
    res.push_back(n/i);
  }
  sort(res.begin(), res.end());
  return res;
}


// 素因数分解
map<long long, long long> prime_factors(long long n) {
  map<long long, long long> res;
  if(n == 1) { // n=1 の素因数分解は n^1
    res[n] = 1;
    return res;
  }
  for(long long i = 2, _n = n; i*i <= _n; ++i) {
    while(n % i == 0) {
      ++res[i]; // 素数i^{res[i]}
      n /= i;
    }
  }
  if(n != 1) res[n] = 1;
  return res;
}


// 繰り返し 2 乗法
long long modpow(long long a, long long n) {
  long long res = 1;
  while (n > 0) {
    if (n & 1) res = res * a % MOD;
    a = a * a % MOD;
    n >>= 1;
  }
  return res;
}


// 逆元を求める. a と m は互いに素であることが要請される.
long long modinv(long long a, long long m) {
  long long b = m, u = 1, v = 0;
  while(b){
    long long t = a / b;
    a -= t * b; swap(a, b);
    u -= t * v; swap(u, v);
  }
  u %= m; 
  if (u < 0) u += m;
  return u;
}

long long fac[MAXN], finv[MAXN], inv[MAXN];

// 前処理 O(n)
void math_init(){
  fac[0] = fac[1] = 1;
  finv[0] = finv[1] = 1;
  inv[1] = 1;
  for(long long i = 2; i < MAXN; i++){
    fac[i] = fac[i - 1] * i % MOD;
    inv[i] = MOD - inv[MOD%i] * (MOD / i) % MOD;
    finv[i] = finv[i - 1] * inv[i] % MOD;
  }
}

// 二項係数計算 O(1)
long long COM(long long n, long long k){
  if (n < k) return 0;
  if (n < 0 || k < 0) return 0;
  return fac[n] * (finv[k] * finv[n - k] % MOD) % MOD;
}


// before your coding, you have to write a line "math_init()"
void dfs(int cur, vector<vector<int>> &g, vector<lint> &dp, vector<lint> &sz) {
  if(g[cur].size() == 0) {
    dp[cur] = 1;
    sz[cur] = 1;
  // cerr << "dp[" << cur << "] = " << dp[cur] << endl;
    return;
  }
  
  for(auto nxt : g[cur]) {
    dfs(nxt, g, dp, sz);
  }
  // sz を計算
  for(auto nxt : g[cur]) {
    sz[cur] += sz[nxt];
    sz[cur] %= MOD;
  }
  sz[cur] %= MOD;
  // dp を計算
  dp[cur] = fac[sz[cur]];
  for(auto nxt : g[cur]) {
    dp[cur] *= dp[nxt];
    dp[cur] /= fac[sz[nxt]];
    // dp[cur] /= fac[sz[nxt]];
  }
  dp[cur] %= MOD;
  // cerr << "dp[" << cur << "] = " << dp[cur] << endl;
  sz[cur]++;
  return;
}

int main() {
  
  math_init();
  int n; cin >> n;
  vector<vector<int>> g(n);
  set<lint> loser;
  for(int i = 0; i < n - 1; i++) {
    int a, b; cin >> a >> b;
    a--;
    b--;
    loser.insert(b);
    g[a].push_back(b);
  }

  lint winner = -1;
  for(int i = 0; i < n; i++) {
    if(loser.count(i) == 0) {
      winner = i;
    }
  }

  assert(winner != -1);
  vector<lint> dp(n, 0);
  vector<lint> sz(n, 0);
  dfs(winner, g, dp, sz);
  cout << dp[winner] << endl;
  return 0;
}
accuracy: 0.16
time_ms: 30
memory_kb: 26612
final_rank: 15

code_snippet: #include <iostream>
#include <cstdio>
#include <string>
#include <cstring>
#include <deque>
#include <list>
#include <queue>
#include <stack>
#include <vector>
#include <utility>
#include <algorithm>
#include <map>
#include <set>
#include <complex>
#include <cmath>
#include <limits>
#include <climits>
#include <ctime>
#include <cassert>
#include <numeric>
#include <functional>
#include <bitset>

using namespace std;
using lint = long long int;
long long int INF = 1001001001001001LL;
int inf = 1000000007;
long long int MOD = 1000000LL;
double PI = 3.1415926535897932;

template<typename T1,typename T2>inline void chmin(T1 &a,const T2 &b){if(a>b) a=b;}
template<typename T1,typename T2>inline void chmax(T1 &a,const T2 &b){if(a<b) a=b;}

#define ALL(a) a.begin(),a.end()
#define RALL(a) a.rbegin(),a.rend()

/* do your best */

const long long MAXN = 1001024;

// a, b の最大公約数を返す O( log max(a, b) )
long long gcd(long long a, long long b) {
  if(b == 0) return a;
  return gcd(b, a % b);
}

// ax + by = 1 となるような (x, y) と gcd(a, b) を返す. gcd(a, b) = 1 の時、解が存在する.
long long extgcd(long long a, long long b, long long &x, long long &y){
  long long d = a;
  if(b != 0){
    d = extgcd(b, a, y, x);
    y -= (a / b) * x;
  }else{
    x = 1;
    y = 0;
  }
  return d;
}


// 区間 [a, b) に存在する素数の個数を返す関数

long long prime[MAXN];        // [a,b) の素数のうち i 番目の素数
bool is_prime[MAXN];    // 整数 i が素数であるかどうか
bool is_prime_ab[MAXN]; // 整数 i+a が素数であるかどうか

long long sieve(long long n) {
  long long res = 0; fill(is_prime, is_prime + MAXN, true);
  is_prime[0] = is_prime[1] = false; // 0 と 1 は素数ではない。
  for(long long i = 2; i <= n; ++i) {
    if(!is_prime[i]) continue;
    prime[res++] = i;
    for(long long j = 2 * i; j <= n; j += i) is_prime[j] = false; // 素数 i の倍数は素数ではない (ふるい(篩)にかける)
  }
  return res;
}

/*
long long segment_sieve(long long a, long long b){
  fill(is_prime, is_prime + MAXN, true);
  fill(is_prime_ab, is_prime_ab + MAXN, true);
  for(long long i = 2; i * i <= b - 1; i++) {
    if(!is_prime[i]) continue;
    for(long long j = 2 * i; j * j <= b - 1; j += i) is_prime[j] = false; // 素数 i で篩にかける
    for(long long j = a - a % i; j < b; j += i) {
      if(j < a) continue;
      if(is_prime_ab[j-a]) is_prime_ab[j-a] = false; // 素数 i で篩にかける
    }
  }

  long long res = 0;
  for(long long i = a; i < b; i++) if(is_prime_ab[i - a]) prime[res++] = i;
  return res;
}
*/

// ある整数の約数列挙
vector<long long> divisors(long long n) {
  vector<long long> res;
  for(long long i = 1; i*i <= n; ++i) {
    if(n % i != 0) continue;
    res.push_back(i);
    if(n/i == i) continue; // 上の行で追加済み。
    res.push_back(n/i);
  }
  sort(res.begin(), res.end());
  return res;
}


// 素因数分解
map<long long, long long> prime_factors(long long n) {
  map<long long, long long> res;
  if(n == 1) { // n=1 の素因数分解は n^1
    res[n] = 1;
    return res;
  }
  for(long long i = 2, _n = n; i*i <= _n; ++i) {
    while(n % i == 0) {
      ++res[i]; // 素数i^{res[i]}
      n /= i;
    }
  }
  if(n != 1) res[n] = 1;
  return res;
}


// 繰り返し 2 乗法
long long modpow(long long a, long long n) {
  long long res = 1;
  while (n > 0) {
    if (n & 1) res = res * a % MOD;
    a = a * a % MOD;
    n >>= 1;
  }
  return res;
}


// 逆元を求める. a と m は互いに素であることが要請される.
long long modinv(long long a, long long m) {
  long long b = m, u = 1, v = 0;
  while(b){
    long long t = a / b;
    a -= t * b; swap(a, b);
    u -= t * v; swap(u, v);
  }
  u %= m; 
  if (u < 0) u += m;
  return u;
}

long long fac[MAXN], finv[MAXN], inv[MAXN];

// 前処理 O(n)
void math_init(){
  fac[0] = fac[1] = 1;
  finv[0] = finv[1] = 1;
  inv[1] = 1;
  for(long long i = 2; i < MAXN; i++){
    fac[i] = fac[i - 1] * i % MOD;
    inv[i] = MOD - inv[MOD%i] * (MOD / i) % MOD;
    finv[i] = finv[i - 1] * inv[i] % MOD;
  }
}

// 二項係数計算 O(1)
long long COM(long long n, long long k){
  if (n < k) return 0;
  if (n < 0 || k < 0) return 0;
  return fac[n] * (finv[k] * finv[n - k] % MOD) % MOD;
}


// before your coding, you have to write a line "math_init()"
void dfs(int cur, vector<vector<int>> &g, vector<lint> &dp, vector<lint> &sz) {
  if(g[cur].size() == 0) {
    dp[cur] = 1;
    sz[cur] = 1;
  // cerr << "dp[" << cur << "] = " << dp[cur] << endl;
    return;
  }
  
  for(auto nxt : g[cur]) {
    dfs(nxt, g, dp, sz);
  }
  // sz を計算
  for(auto nxt : g[cur]) {
    sz[cur] += sz[nxt];
    sz[cur] %= MOD;
  }
  sz[cur] %= MOD;
  // dp を計算
  dp[cur] = fac[sz[cur]];
  for(auto nxt : g[cur]) {
    dp[cur] *= dp[nxt];
    dp[cur] %= MOD;
    dp[cur] /= fac[sz[nxt]];
    // dp[cur] /= fac[sz[nxt]];
  }
  dp[cur] %= MOD;
  // cerr << "dp[" << cur << "] = " << dp[cur] << endl;
  sz[cur]++;
  return;
}

int main() {
  
  math_init();
  int n; cin >> n;
  vector<vector<int>> g(n);
  set<lint> loser;
  for(int i = 0; i < n - 1; i++) {
    int a, b; cin >> a >> b;
    a--;
    b--;
    loser.insert(b);
    g[a].push_back(b);
  }

  lint winner = -1;
  for(int i = 0; i < n; i++) {
    if(loser.count(i) == 0) {
      winner = i;
    }
  }

  assert(winner != -1);
  vector<lint> dp(n, 0);
  vector<lint> sz(n, 0);
  dfs(winner, g, dp, sz);
  cout << dp[winner] << endl;
  return 0;
}
accuracy: 0.16
time_ms: 30
memory_kb: 26620
final_rank: 16