Problem p02728 (C++) — buggy submission, verdict: Time Limit Exceeded

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

//////////////////////////////   Begin Macros

#define all(x) (x).begin(), (x).end()
#define rep(i, N) for (int i = 0; i < (int)(N); i++)
#define rep2(i, s, N) for (int i = (s); i < (int)(N); i++)
#define reprev(i, N) for (int i = N - 1; i >= 0; i--)
#define rep1(i, N) for (int i = 1; i <= N; i++)

using ll = long long int;
using pii = pair<int, int>;
using pll = pair<ll, ll>;

template <typename T> bool chmax(T &m, const T q) {
  if (m < q) {
    m = q;
    return true;
  } else
    return false;
}
template <typename T> bool chmin(T &m, const T q) {
  if (m > q) {
    m = q;
    return true;
  } else
    return false;
}
template <typename T1, typename T2>
pair<T1, T2> operator+(const pair<T1, T2> &l, const pair<T1, T2> &r) {
  return {l.first + r.first, l.second + r.second};
}
template <typename T1, typename T2>
pair<T1, T2> operator-(const pair<T1, T2> &l, const pair<T1, T2> &r) {
  return {l.first - r.first, l.second - r.second};
}
template <typename T> pair<T, T> operator*(const pair<T, T> &l, const T &r) {
  return {l.first * r, l.second * r};
}
template <typename T> pair<T, T> operator/(const pair<T, T> &l, const T &r) {
  return {l.first / r, l.second / r};
}
template <typename T> istream &operator>>(istream &is, vector<T> &vec) {
  for (auto &v : vec)
    is >> v;
  return is;
}
template <typename T> ostream &operator<<(ostream &os, const vector<T> &vec) {
  os << "[";
  for (auto v : vec)
    os << v << ",";
  os << "]";
  return os;
}
template <typename T> ostream &operator<<(ostream &os, const deque<T> &vec) {
  os << "deq[";
  for (auto v : vec)
    os << v << ",";
  os << "]";
  return os;
}
template <typename T> ostream &operator<<(ostream &os, const set<T> &vec) {
  os << "{";
  for (auto v : vec)
    os << v << ",";
  os << "}";
  return os;
}
template <typename T>
ostream &operator<<(ostream &os, const unordered_set<T> &vec) {
  os << "{";
  for (auto v : vec)
    os << v << ",";
  os << "}";
  return os;
}
template <typename T> ostream &operator<<(ostream &os, const multiset<T> &vec) {
  os << "{";
  for (auto v : vec)
    os << v << ",";
  os << "}";
  return os;
}
template <typename T>
ostream &operator<<(ostream &os, const unordered_multiset<T> &vec) {
  os << "{";
  for (auto v : vec)
    os << v << ",";
  os << "}";
  return os;
}
template <typename T1, typename T2>
ostream &operator<<(ostream &os, const pair<T1, T2> &pa) {
  os << "(" << pa.first << "," << pa.second << ")";
  return os;
}
template <typename TK, typename TV>
ostream &operator<<(ostream &os, const map<TK, TV> &mp) {
  os << "{";
  for (auto v : mp)
    os << v.first << "=>" << v.second << ",";
  os << "}";
  return os;
}
template <typename TK, typename TV>
ostream &operator<<(ostream &os, const unordered_map<TK, TV> &mp) {
  os << "{";
  for (auto v : mp)
    os << v.first << "=>" << v.second << ",";
  os << "}";
  return os;
}

template <typename T> void reset(vector<T> &v, const T reset_to) {
  for (auto &x : v)
    x = reset_to;
}
inline int popcount(const unsigned int x) { return __builtin_popcount(x); }
#define dbg(x)                                                                 \\
  cerr << #x << " = " << (x) << " (L" << __LINE__ << ") " << __FILE__ << endl;

const int intinf = numeric_limits<int>::max();
const pii udlr[4] = {{1, 0}, {0, 1}, {-1, 0}, {0, -1}};

//////////////////////////////   End Macros

// Modulo.h start----------------------------------------

#pragma once

#include <iostream>
#include <vector>

struct Modint;
std::vector<Modint> fact_mod;
std::vector<Modint> rev_fact_mod;

using namespace std;

template <typename Tint> Tint gcd(Tint a, Tint b) {
  assert(!(a == 0 and b == 0));
  // O(log max(a,b))
  a = abs(a);
  b = abs(b);
  return b != 0 ? gcd(b, a % b) : a;
}

template <typename Tint> Tint lcm(Tint a, Tint b) { return a / gcd(a, b) * b; }

// a x + b y = gcd(a, b)
int extgcd(const int a, const int b, int &x, int &y) {
  // O(log max(a,b))
  int g = a;
  x = 1;
  y = 0;
  if (b != 0)
    g = extgcd(b, a % b, y, x), y -= (a / b) * x;
  return g;
}

int inv_mod(const int a, const int mod) {
  int x, y;
  if (extgcd(a, mod, x, y) == 1)
    return (x + mod) % mod;
  else // unsolvable
    return 0;
}

struct Modint {
  static int mod;
  long long value;
  Modint(long long value = 0) : value((value % mod + mod) % mod) {}
  inline bool operator==(const Modint &rhs) const { return value == rhs.value; }
  inline bool operator!=(const Modint &rhs) const { return !(*this == rhs); }
  inline Modint operator+() const { return *this; }
  inline Modint operator-() const { return Modint(-value); }
  inline Modint &operator+=(const Modint &rhs) {
    if ((value += rhs.value) >= mod)
      value -= mod;
    return *this;
  }
  inline Modint &operator-=(const Modint &rhs) {
    if ((value += mod - rhs.value) >= mod)
      value -= mod;
    return *this;
  }
  inline Modint &operator*=(const Modint &rhs) {
    (value *= rhs.value) %= mod;
    return *this;
  }
  Modint pow(ll k) const {
    assert(k >= 0);
    if (k == 0)
      return 1;
    Modint res = pow(k / 2);
    res *= res;
    if (k % 2 == 1)
      res *= *this;
    return res;
  }

  // for prime mod
  Modint inv() const { return pow(mod - 2); }
  inline Modint &operator/=(const Modint &rhs) { return *this *= rhs.inv(); }
};
int Modint::mod = 1000000007;
Modint operator+(const Modint &lhs, const Modint &rhs) {
  return Modint(lhs) += rhs;
}
Modint operator-(const Modint &lhs, const Modint &rhs) {
  return Modint(lhs) -= rhs;
}
Modint operator*(const Modint &lhs, const Modint &rhs) {
  return Modint(lhs) *= rhs;
}
Modint operator/(const Modint &lhs, const Modint &rhs) {
  return Modint(lhs) /= rhs;
}
ostream &operator>>(std::ostream &lhs, const Modint &rhs) {
  return lhs >> rhs.value;
}
ostream &operator<<(std::ostream &lhs, const Modint &rhs) {
  return lhs << rhs.value;
}

struct Combination {
  std::vector<Modint> fact, ifact;
  Combination(int n = 0) : fact(n + 1), ifact(n + 1) {
    assert(n >= 0);
    fact[0] = 1;
    for (int i = 1; i <= n; i++)
      fact[i] = fact[i - 1] * i;
    ifact[n] = fact[n].inv();
    for (int i = n; i >= 1; i--)
      ifact[i - 1] = ifact[i] * i;
  }
  Modint operator()(int n, int k) {
    assert(0 <= n and n <= fact.size());
    if (!(0 <= k and k <= n))
      return 0;
    return fact[n] * ifact[k] * ifact[n - k];
  }
};

// Modulo.h end----------------------------------------------
// Graph.h start--------------------------------------------
#pragma once

#include <vector>

using Weight = double;

struct Vertex;
struct Edge;

struct Vertex {
  int id;
  std::vector<Edge> edges;
  std::vector<int> ids_dst;

  Vertex(const int id = 0) : id(id){};
  void add_edge(const Edge &e);
};

struct Edge {
  int id_src, id_dst;
  Weight weight;

  Edge(const int id_src, const int id_dst, const Weight weight)
      : id_src(id_src), id_dst(id_dst), weight(weight){};
};

struct Graph {
  std::vector<Vertex> vertices;
  std::vector<Edge> edges;

  Graph(const int nvertices = 0);
  void add_edge(const Edge &edge);
  void add_edge(const int id_src, const int id_dst, const Weight w = 1) {
    add_edge(Edge(id_src, id_dst, w));
  };
};

//----------------------------------------------------------

using namespace std;

void Vertex::add_edge(const Edge &e) {
  edges.push_back(e);
  ids_dst.push_back(e.id_dst);
}

bool operator<(const Edge &e1, const Edge &e2) {
  return e1.weight != e2.weight ? e1.weight > e2.weight : // !!INVERSE!!
             e1.id_src != e2.id_src ? e1.id_src < e2.id_src
                                    : e1.id_dst < e2.id_dst;
}

Graph::Graph(const int nvertices) {
  for (int id = 0; id < nvertices; id++)
    vertices.push_back(Vertex(id));
}
void Graph::add_edge(const Edge &edge) {
  edges.push_back(edge);
  vertices[edge.id_src].add_edge(edge);
}

// Graph.h end----------------------------------------------

Graph g;
Combination comb;

struct DP {
  Modint nways;
  int size;
  DP(Modint nways = 1, int size = 0) : nways(nways), size(size){};
  DP &operator+=(const DP &rhs) {
    nways *= rhs.nways;
    nways *= comb(size + rhs.size, rhs.size);
    size += rhs.size;
    return *this;
  }
  DP &operator-=(const DP &rhs) {
    size -= rhs.size;
    nways /= comb(size + rhs.size, rhs.size);
    nways /= rhs.nways;
    return *this;
  }

  DP add_root() const {
    DP res(*this);
    res.size++;
    return res;
  }
};
DP operator-(const DP &lhs, const DP &rhs) { return DP(lhs) -= rhs; }

vector<DP> dp;

void dfs(int v, int parent = -1) {
  for (int nextv : g.vertices[v].ids_dst) {
    if (nextv == parent)
      continue;
    dfs(nextv, v);
    dp[v] += dp[nextv].add_root();
  }
}

void bfs(int v, int parent = -1) {
  for (int nextv : g.vertices[v].ids_dst) {
    if (nextv == parent)
      continue;
    dp[nextv] += (dp[v] - dp[nextv].add_root()).add_root();
    bfs(nextv, v);
  }
}

void solve() {
  int N;
  cin >> N;
  g = Graph(N);
  comb = Combination(N);
  dp = vector<DP>(N);
  rep(i, N - 1) {
    int a, b;
    cin >> a >> b;
    a--;
    b--;
    g.add_edge(a, b);
    g.add_edge(b, a);
  }

  dfs(0);
  bfs(0);
  rep(k, N) cout << dp[k].add_root().nways << endl;
}

int main() {
  solve();
  return 0;
}


Error: TLE

Fixed submission:

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

//////////////////////////////   Begin Macros

#define all(x) (x).begin(), (x).end()
#define rep(i, N) for (int i = 0; i < (int)(N); i++)
#define rep2(i, s, N) for (int i = (s); i < (int)(N); i++)
#define reprev(i, N) for (int i = N - 1; i >= 0; i--)
#define rep1(i, N) for (int i = 1; i <= N; i++)

using ll = long long int;
using pii = pair<int, int>;
using pll = pair<ll, ll>;

template <typename T> bool chmax(T &m, const T q) {
  if (m < q) {
    m = q;
    return true;
  } else
    return false;
}
template <typename T> bool chmin(T &m, const T q) {
  if (m > q) {
    m = q;
    return true;
  } else
    return false;
}
template <typename T1, typename T2>
pair<T1, T2> operator+(const pair<T1, T2> &l, const pair<T1, T2> &r) {
  return {l.first + r.first, l.second + r.second};
}
template <typename T1, typename T2>
pair<T1, T2> operator-(const pair<T1, T2> &l, const pair<T1, T2> &r) {
  return {l.first - r.first, l.second - r.second};
}
template <typename T> pair<T, T> operator*(const pair<T, T> &l, const T &r) {
  return {l.first * r, l.second * r};
}
template <typename T> pair<T, T> operator/(const pair<T, T> &l, const T &r) {
  return {l.first / r, l.second / r};
}
template <typename T> istream &operator>>(istream &is, vector<T> &vec) {
  for (auto &v : vec)
    is >> v;
  return is;
}
template <typename T> ostream &operator<<(ostream &os, const vector<T> &vec) {
  os << "[";
  for (auto v : vec)
    os << v << ",";
  os << "]";
  return os;
}
template <typename T> ostream &operator<<(ostream &os, const deque<T> &vec) {
  os << "deq[";
  for (auto v : vec)
    os << v << ",";
  os << "]";
  return os;
}
template <typename T> ostream &operator<<(ostream &os, const set<T> &vec) {
  os << "{";
  for (auto v : vec)
    os << v << ",";
  os << "}";
  return os;
}
template <typename T>
ostream &operator<<(ostream &os, const unordered_set<T> &vec) {
  os << "{";
  for (auto v : vec)
    os << v << ",";
  os << "}";
  return os;
}
template <typename T> ostream &operator<<(ostream &os, const multiset<T> &vec) {
  os << "{";
  for (auto v : vec)
    os << v << ",";
  os << "}";
  return os;
}
template <typename T>
ostream &operator<<(ostream &os, const unordered_multiset<T> &vec) {
  os << "{";
  for (auto v : vec)
    os << v << ",";
  os << "}";
  return os;
}
template <typename T1, typename T2>
ostream &operator<<(ostream &os, const pair<T1, T2> &pa) {
  os << "(" << pa.first << "," << pa.second << ")";
  return os;
}
template <typename TK, typename TV>
ostream &operator<<(ostream &os, const map<TK, TV> &mp) {
  os << "{";
  for (auto v : mp)
    os << v.first << "=>" << v.second << ",";
  os << "}";
  return os;
}
template <typename TK, typename TV>
ostream &operator<<(ostream &os, const unordered_map<TK, TV> &mp) {
  os << "{";
  for (auto v : mp)
    os << v.first << "=>" << v.second << ",";
  os << "}";
  return os;
}

template <typename T> void reset(vector<T> &v, const T reset_to) {
  for (auto &x : v)
    x = reset_to;
}
inline int popcount(const unsigned int x) { return __builtin_popcount(x); }
#define dbg(x)                                                                 \\
  cerr << #x << " = " << (x) << " (L" << __LINE__ << ") " << __FILE__ << endl;

const int intinf = numeric_limits<int>::max();
const pii udlr[4] = {{1, 0}, {0, 1}, {-1, 0}, {0, -1}};

//////////////////////////////   End Macros

// Modulo.h start----------------------------------------

#pragma once

#include <iostream>
#include <vector>

unsigned int mod = 1000000007;
struct Modint;
std::vector<Modint> fact_mod;
std::vector<Modint> rev_fact_mod;

using namespace std;

template <typename Tint> Tint gcd(Tint a, Tint b) {
  // O(log max(a,b))
  a = abs(a);
  b = abs(b);
  return b != 0 ? gcd(b, a % b) : a;
}

template <typename Tint> Tint lcm(Tint a, Tint b) { return a / gcd(a, b) * b; }

// a x + b y = gcd(a, b)
int extgcd(const unsigned int a, const unsigned int b, int &x, int &y) {
  // O(log max(a,b))
  int g = a;
  x = 1;
  y = 0;
  if (b != 0)
    g = extgcd(b, a % b, y, x), y -= (a / b) * x;
  return g;
}

void set_mod(const unsigned int m) { mod = m; }
void set_mod(const int m) {
  if (m > 0)
    set_mod((unsigned int)m);
  else
    std::cout << "Error in set_mod" << std::endl;
}

unsigned int inv_mod(const unsigned int a) {
  int x, y;
  if (extgcd(a, mod, x, y) == 1)
    return (unsigned int)(((long long)x + mod) % mod);
  else // unsolvable
    return 0;
}

struct Modint {
  unsigned int value;
  Modint() {}
  Modint(unsigned int value) : value(value % mod) {}
  Modint(int value) : Modint((unsigned int)(value % mod + mod)) {}
  Modint(unsigned long long value) : Modint((unsigned int)(value % mod)) {}
  Modint(long long value) : Modint((unsigned int)(value % mod + mod)) {}
  Modint(const Modint &rhs) : Modint(rhs.value) {}
  bool operator==(const Modint &rhs) const;
  inline bool operator!=(const Modint &rhs) const { return !(*this == rhs); }
  Modint &operator+=(const Modint &rhs);
  Modint &operator+=(const unsigned int rhs);
  Modint &operator+=(const int rhs);
  Modint &operator+=(const unsigned long long rhs);
  Modint &operator+=(const long long rhs);
  Modint &operator-=(const Modint &rhs);
  Modint &operator-=(const unsigned int rhs);
  Modint &operator-=(const int rhs);
  Modint &operator-=(const unsigned long long rhs);
  Modint &operator-=(const long long rhs);
  Modint &operator*=(const Modint &rhs);
  Modint &operator*=(const unsigned int rhs);
  Modint &operator*=(const int rhs);
  Modint &operator*=(const unsigned long long rhs);
  Modint &operator*=(const long long rhs);
  Modint &operator/=(const Modint &rhs);
  Modint &operator/=(const unsigned int rhs);
  Modint &operator/=(const int rhs);
  Modint &operator/=(const unsigned long long rhs);
  Modint &operator/=(const long long rhs);
};
bool Modint::operator==(const Modint &rhs) const { return value == rhs.value; }
Modint &Modint::operator+=(const unsigned int rhs) {
  unsigned long long tmp = this->value;
  tmp += rhs;
  tmp %= mod;
  this->value = (unsigned int)tmp;
  return *this;
}
Modint &Modint::operator+=(const Modint &rhs) {
  (*this) += rhs.value;
  return *this;
}
Modint &Modint::operator+=(const int rhs) {
  (*this) += (unsigned int)(rhs % mod + mod);
  return *this;
}
Modint &Modint::operator+=(const unsigned long long rhs) {
  (*this) += (unsigned int)(rhs % mod);
  return *this;
}
Modint &Modint::operator+=(const long long rhs) {
  (*this) += (unsigned int)(rhs % mod + mod);
  return *this;
}
Modint &Modint::operator-=(const Modint &rhs) {
  (*this) -= rhs.value;
  return *this;
}
Modint &Modint::operator-=(const unsigned int rhs) {
  *this += mod - rhs % mod;
  return *this;
}
Modint &Modint::operator-=(const int rhs) {
  *this -= (unsigned int)(rhs % mod + mod);
  return *this;
}
Modint &Modint::operator-=(const unsigned long long rhs) {
  (*this) -= (unsigned int)(rhs % mod);
  return *this;
}
Modint &Modint::operator-=(const long long rhs) {
  (*this) -= (unsigned int)(rhs % mod + mod);
  return *this;
}
Modint &Modint::operator*=(const Modint &rhs) {
  (*this) *= rhs.value;
  return *this;
}
Modint &Modint::operator*=(const unsigned int rhs) {
  unsigned long long tmp = this->value;
  tmp *= rhs;
  tmp %= mod;
  this->value = (unsigned int)tmp;
  return *this;
}
Modint &Modint::operator*=(const int rhs) {
  (*this) *= (unsigned int)(rhs % mod + mod);
  return *this;
}
Modint &Modint::operator*=(const unsigned long long rhs) {
  (*this) *= (unsigned int)(rhs % mod);
  return *this;
}
Modint &Modint::operator*=(const long long rhs) {
  (*this) *= (unsigned int)(rhs % mod + mod);
  return *this;
}
Modint &Modint::operator/=(const Modint &rhs) {
  (*this) /= rhs.value;
  return *this;
}
Modint &Modint::operator/=(const unsigned int rhs) {
  *this *= inv_mod(rhs);
  return *this;
}
Modint &Modint::operator/=(const int rhs) {
  *this /= (unsigned int)(rhs % mod + mod);
  return *this;
}
Modint &Modint::operator/=(const unsigned long long rhs) {
  *this /= (unsigned int)(rhs % mod);
  return *this;
}
Modint &Modint::operator/=(const long long rhs) {
  *this /= (unsigned int)(rhs % mod + mod);
  return *this;
}
const Modint operator+(const Modint &lhs, const Modint &rhs) {
  return Modint(lhs) += rhs;
}
const Modint operator+(const Modint &lhs, unsigned int rhs) {
  return Modint(lhs) += rhs;
}
const Modint operator+(unsigned int lhs, const Modint &rhs) {
  return Modint(lhs) += rhs;
}
const Modint operator-(const Modint &lhs, const Modint &rhs) {
  return Modint(lhs) -= rhs;
}
const Modint operator-(const Modint &lhs, unsigned int rhs) {
  return Modint(lhs) -= rhs;
}
const Modint operator-(unsigned int lhs, const Modint &rhs) {
  return Modint(lhs) -= rhs;
}
const Modint operator*(const Modint &lhs, const Modint &rhs) {
  return Modint(lhs) *= rhs;
}
const Modint operator*(const Modint &lhs, unsigned int rhs) {
  return Modint(lhs) *= rhs;
}
const Modint operator*(unsigned int lhs, const Modint &rhs) {
  return Modint(lhs) *= rhs;
}
const Modint operator/(const Modint &lhs, const Modint &rhs) {
  return Modint(lhs) /= rhs;
}
const Modint operator/(const Modint &lhs, unsigned int rhs) {
  return Modint(lhs) /= rhs;
}
const Modint operator/(unsigned int lhs, const Modint &rhs) {
  return Modint(lhs) /= rhs;
}
ostream &operator<<(std::ostream &lhs, const Modint &rhs) {
  lhs << rhs.value;
  return lhs;
}

Modint pow_mod(const Modint &x, const unsigned int k) { // x^k (mod)
  if (k == 0)
    return Modint(1);
  if (k % 2 == 0)
    return pow_mod(x * x, k / 2);
  else
    return x * pow_mod(x, k - 1);
}
Modint pow_mod(const unsigned int x, const unsigned int k) {
  return pow_mod(Modint(x), k);
}

std::vector<Modint> set_fact_mod(unsigned int n) {
  // O(n)
  fact_mod = vector<Modint>(n + 1);
  fact_mod[0] = 1;
  for (unsigned int i = 1; i <= n; i++) {
    fact_mod[i] = fact_mod[i - 1] * i;
  }
  return fact_mod;
}

std::vector<Modint> set_rev_fact_mod(unsigned int n) {
  // O(n)
  rev_fact_mod = vector<Modint>(n + 1);
  rev_fact_mod[n] = 1 / fact_mod[n];
  for (int i = n - 1; i >= 0; i--) {
    rev_fact_mod[i] = rev_fact_mod[i + 1] * (unsigned int)(i + 1);
  }
  return rev_fact_mod;
}

Modint combination_mod_precalculation(unsigned int n, unsigned int r) {
  // set_mod, fact_mod, rev_fact_mod
  return fact_mod[n] * rev_fact_mod[r] * rev_fact_mod[n - r];
}

Modint combination_mod_straightforward(
    unsigned long long n, unsigned long long r) { // mod is prime, O(sqrt(n))
  if (r * 2 > n)
    r = n - r;
  Modint numerator = 1;
  Modint denominator = 1;
  for (unsigned long long i = 1; i <= r; ++i) {
    numerator *= n - i + 1;
    denominator *= i;
  }
  return numerator / denominator;
}

// Modulo.h end----------------------------------------------
vector<vector<int>> edges;

vector<unordered_map<int, pair<int, Modint>>> from_to_ways;
pair<int, Modint> dfs(int from, int to) {
  if (from >= 0 and from_to_ways[from].find(to) != from_to_ways[from].end())
    return from_to_ways[from][to];

  int nvertice = 1;
  Modint ways = 1;
  queue<int> nvs;
  for (auto nextto : edges[to]) {
    if (nextto == from)
      continue;

    auto pd = dfs(to, nextto);
    nvertice += pd.first;
    nvs.push(pd.first);
    ways *= pd.second;
  }

  ways *= fact_mod[nvertice - 1];
  while (!nvs.empty()) {
    int nv = nvs.front();
    nvs.pop();
    ways *= rev_fact_mod[nv];
  }

  pair<int, Modint> res = {nvertice, ways};

  if (from >= 0)
    from_to_ways[from][to] = res;
  return res;
}

void solve() {
  int N;
  cin >> N;
  vector<int> a(N - 1), b(N - 1);
  edges = vector<vector<int>>(N);
  rep(i, N - 1) {
    cin >> a[i] >> b[i];
    a[i]--;
    b[i]--;
    edges[a[i]].push_back(b[i]);
    edges[b[i]].push_back(a[i]);
  }
  set_mod(1000000007);
  set_fact_mod(N);
  set_rev_fact_mod(N);

  from_to_ways = vector<unordered_map<int, pair<int, Modint>>>(N);

  rep(k, N) { cout << dfs(-1, k).second << endl; }
}

int main() {
  solve();
  return 0;
}