This time our child has a simple polygon. He has to find the number of ways to split the polygon into non-degenerate triangles, each way must satisfy the following requirements:

  * each vertex of each triangle is one of the polygon vertex; 
  * each side of the polygon must be the side of exactly one triangle; 
  * the area of intersection of every two triangles equals to zero, and the sum of all areas of triangles equals to the area of the polygon; 
  * each triangle must be completely inside the polygon; 
  * each side of each triangle must contain exactly two vertices of the polygon. 



The picture below depicts an example of a correct splitting.

<image>

Please, help the child. Calculate the described number of ways modulo 1000000007 (109 + 7) for him.

Input

The first line contains one integer n (3 ≤ n ≤ 200) — the number of vertices of the polygon. Then follow n lines, each line containing two integers. The i-th line contains xi, yi (|xi|, |yi| ≤ 107) — the i-th vertex of the polygon in clockwise or counterclockwise order.

It's guaranteed that the polygon is simple.

Output

Output the number of ways modulo 1000000007 (109 + 7).

Examples

Input

4
0 0
0 1
1 1
1 0


Output

2


Input

4
0 0
1 0
0 1
-1 0


Output

1


Input

5
0 0
1 0
1 1
0 1
-2 -1


Output

3

Note

In the first sample, there are two possible splittings:

<image>

In the second sample, there are only one possible splitting:

<image>
#include <bits/stdc++.h>
using namespace std;
vector<string> split(const string &s, char c) {
  vector<string> v;
  stringstream ss(s);
  string first;
  while (getline(ss, first, c)) v.emplace_back(first);
  return move(v);
}
void err(vector<string>::iterator it) {}
template <typename T, typename... Args>
void err(vector<string>::iterator it, T a, Args... args) {
  cerr << a << " ";
  err(++it, args...);
}
const double PI = acos(-1.0);
class PT {
 public:
  double first, second;
  PT() {}
  PT(double first, double second) : first(first), second(second) {}
  PT(const PT &p) : first(p.first), second(p.second) {}
  double Magnitude() { return sqrt(first * first + second * second); }
  PT operator+(const PT &p) const {
    return PT(first + p.first, second + p.second);
  }
  PT operator-(const PT &p) const {
    return PT(first - p.first, second - p.second);
  }
  PT operator*(double c) const { return PT(first * c, second * c); }
  PT operator/(double c) const { return PT(first / c, second / c); }
};
double dot(PT p, PT q) { return p.first * q.first + p.second * q.second; }
double dist2(PT p, PT q) { return dot(p - q, p - q); }
double dist(PT p, PT q) { return sqrt(dist2(p, q)); }
double cross(PT p, PT q) { return p.first * q.second - p.second * q.first; }
bool LinesParallel(PT a, PT b, PT c, PT d) {
  return fabs(cross(b - a, c - d)) < 1e-10;
}
bool LinesCollinear(PT a, PT b, PT c, PT d) {
  return LinesParallel(a, b, c, d) && fabs(cross(a - b, a - c)) < 1e-10 &&
         fabs(cross(c - d, c - a)) < 1e-10;
}
bool SegmentsIntersect(PT a, PT b, PT c, PT d) {
  if (LinesCollinear(a, b, c, d)) {
    if (dist2(a, c) < 1e-10 || dist2(a, d) < 1e-10 || dist2(b, c) < 1e-10 ||
        dist2(b, d) < 1e-10)
      return true;
    if (dot(c - a, c - b) > 0 && dot(d - a, d - b) > 0 && dot(c - b, d - b) > 0)
      return false;
    return true;
  }
  if (cross(d - a, b - a) * cross(c - a, b - a) > 0) return false;
  if (cross(a - c, d - c) * cross(b - c, d - c) > 0) return false;
  return true;
}
PT ProjectPointSegment(PT a, PT b, PT c) {
  double r = dot(b - a, b - a);
  if (fabs(r) < 1e-10) return a;
  r = dot(c - a, b - a) / r;
  if (r < 0) return a;
  if (r > 1) return b;
  return a + (b - a) * r;
}
bool PointInPolygon(const vector<PT> &p, PT q) {
  bool c = 0;
  for (long long i = 0; i < p.size(); i++) {
    long long j = (i + 1) % p.size();
    if ((p[i].second <= q.second && q.second < p[j].second ||
         p[j].second <= q.second && q.second < p[i].second) &&
        q.first < p[i].first + (p[j].first - p[i].first) *
                                   (q.second - p[i].second) /
                                   (p[j].second - p[i].second))
      c = !c;
  }
  return c;
}
bool PointOnPolygon(const vector<PT> &p, PT q) {
  for (long long i = 0; i < p.size(); i++)
    if (dist2(ProjectPointSegment(p[i], p[(i + 1) % p.size()], q), q) < 1e-10)
      return true;
  return false;
}
const long long M = 220, mod = 1000000007;
vector<PT> p;
bool isinside[M][M];
long long dp[M][M];
long long call(long long i, long long j) {
  if (j == i + 1) return 1;
  if (isinside[i][j] == 0) return 0;
  if (dp[i][j] != -1) return dp[i][j];
  long long sum = 0;
  for (long long k = i + 1; k < j; k++) {
    long long a = call(i, k), b = call(k, j);
    sum = (sum + a * b) % mod;
  }
  return dp[i][j] = sum;
}
int main() {
  ios_base::sync_with_stdio(false);
  long long n, i, j, k;
  scanf("%I64d", &n);
  for (i = 0; i < n; i++) {
    scanf("%I64d%I64d", &j, &k);
    p.push_back(PT(j, k));
  }
  memset((isinside), (false), sizeof(isinside));
  for (i = 0; i < n; i++) {
    for (j = i + 2; j < n; j++) {
      bool f = false;
      PT tt =
          PT((p[i].first + p[j].first) / 2, (p[i].second + p[j].second) / 2);
      if (PointInPolygon(p, tt) && !PointOnPolygon(p, tt))
        f = false;
      else
        f = true;
      for (long long l = 0; l < p.size(); l++) {
        long long r = (l + 1) % p.size();
        if (i == l || i == r || j == l || j == r) continue;
        f |= SegmentsIntersect(p[i], p[j], p[l], p[r]);
      }
      isinside[i][j] = !f;
    }
  }
  isinside[0][n - 1] = 1;
  memset((dp), (-1), sizeof(dp));
  printf("%I64d\n", call(0, n - 1));
  return 0;
}
