#include <bits/stdc++.h>

#define ALL(a) (a).begin(), (a).end()

using namespace std;

template<long long mod>
class modint{
private:
  long long a;
public:
  constexpr modint(const long long x = 0) noexcept : a(x%mod) {}
  constexpr long long& value() noexcept { return a; }
  constexpr const long long& value() const noexcept { return a; }
  constexpr modint operator+(const modint rhs) const noexcept {
    return modint(*this) += rhs;
  }
  constexpr modint operator-(const modint rhs) const noexcept {
    return modint(*this) -= rhs;
  }
  constexpr modint operator*(const modint rhs) const noexcept {
    return modint(*this) *= rhs;
  }
  constexpr modint operator/(const modint rhs) const noexcept {
    return modint(*this) /= rhs;
  }
  constexpr modint& operator+=(const modint rhs) noexcept {
    a += rhs.a;
    if(a >= mod) a -= mod;
    return *this;
  }
  constexpr modint &operator-=(const modint rhs) noexcept {
    if(a < rhs.a) a += mod;
    a -= rhs.a;
    return *this;
  }
  constexpr modint& operator*=(const modint rhs) noexcept {
    a = a*rhs.a%mod;
    return *this;
  }
  constexpr modint& operator/=(modint rhs) noexcept {
    long long k = mod-2;
    while(k > 0){
      if(k&1){
        *this *= rhs;
      }
      rhs *= rhs;
      k /= 2;
    }
    return *this;
  }
  friend ostream& operator<<(ostream &os, const modint &X){
    return os << X.a;
  }
  friend istream& operator>>(istream &is, modint &X){
    is >> X.a;
    X.a %= mod;
    if(X.a < 0) X.a += mod;
    return is;
  }
};
using Modint = modint<1000000>;

template<typename T>
struct Combination {
private:
  int sz;
  vector<vector<Modint>> F;
  vector<vector<bool>> calc;
public:
  Combination(int sz) : sz(sz), F(sz+1,vector<Modint>(sz+1, -1)), calc(sz+1, vector<bool>(sz+1, false)) {
  }

  T C(int i, int j){
	  if(calc[i][j]) return F[i][j];
	  calc[i][j] = true;
	  if(i < j) F[i][j] = 0;
	  //else if(i == 0) F[i][j] = 0;
	  else if(j == 0) F[i][j] = 1;
	  else {	
		  F[i][j] = C(i-1, j-1) + C(i-1, j);
	  }
	  return F[i][j];
    //assert(n <= sz);
    //if(n < 0 or k > n) return (T)0;
	//if(n < k) return (T)0;
    //return F[n][k];
  }
};

Combination<Modint> com(1020);

//first := 子孫の頂点数, second := 子孫の通り数
pair<Modint, Modint> dfs(const vector<vector<pair<int, int>>>& edge, size_t v){
	if(edge[v].size() == 0) { return make_pair(0, Modint(1)); }
//	cerr << "v = " << v << endl;
	Modint n = 0;
	Modint m = 1;
	vector<pair<Modint, Modint>> children;
	
	for(auto &e : edge[v]) {
		children.push_back(dfs(edge, e.second));
		children.back().first += 1;
		n += children.back().first;
	}
	pair<Modint, Modint> ret(n,m);
//	cerr << "i(" << n << "," << m << ")" << endl;

	for(auto &e : children) {
//		cerr << "(" << e.first << "," << e.second << ")" << endl;
//		cerr << "n = " << n.value() << ", m = " << e.first.value() << ", ";
//		cerr << "com = " << com.C(n.value(), e.first.value()) << endl;
		m *= e.second * com.C(n.value(), e.first.value());
//		cerr << "m= "<<m << endl;
		n -= e.first;
	}
	assert(n.value() == 0);
	ret.second = m;
	return ret;
}

Modint solve() {
	int n; cin >> n;
	vector<pair<int, int>> game(n-1);
	for(auto& e : game){
		cin >> e.first >> e.second;
		e.first--;
		e.second--;
	}
	vector<vector<pair<int, int>>> edge(n);
	vector<int> lose(n,0);
	for(auto & e : game) {
		lose[e.second] += 1;
		edge[e.first].emplace_back(e);
	}
	for(auto e : edge){
		for(auto a : e){
//			cerr << a.first << " -> " << a.second << " , ";
		}
//		cerr << endl;
	}
	size_t root =-1;
	for(int i = 0; i < n; i++){
		if(lose[i] == 0) root = i;
	}
	return dfs(edge,root).second;
}

signed main(){
	cout << solve() << endl;

	return 0;
}




Measured memory_bytes: 11700