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;
inline void pisz(int n) { printf("%d\n", n); }
template <typename T, typename TT>
ostream &operator<<(ostream &s, pair<T, TT> t) {
  return s << "(" << t.first << "," << t.second << ")";
}
template <typename T>
ostream &operator<<(ostream &s, vector<T> t) {
  for (int(i) = 0; (i) < (((int)((t).size()))); ++(i)) s << t[i] << " ";
  return s;
}
const long double eps = 1e-9;
inline bool iszero(long double x) { return x <= eps && x >= -eps; }
struct pt {
  long double x, y;
  pt(long double xx = 0, long double yy = 0) : x(xx), y(yy) {}
  bool operator==(pt &a) { return iszero(a.x - x) && iszero(a.y - y); }
};
bool operator<(const pt &a, const pt &b) {
  if (a.x != b.x) return a.x < b.x;
  return a.y < b.y;
}
ostream &operator<<(ostream &s, pt p) {
  return s << "(" << p.x << "," << p.y << ")";
}
pt operator+(pt a, pt b) { return pt(a.x + b.x, a.y + b.y); }
pt operator-(pt a, pt b) { return pt(a.x - b.x, a.y - b.y); }
pt operator*(pt a, long double r) { return pt(a.x * r, a.y * r); }
long double vec(pt a, pt b) { return a.x * b.y - a.y * b.x; }
long double det(pt a, pt b, pt c) { return vec(b - a, c - a); }
pt operator*(pt a, pt b) {
  return pt(a.x * b.x - a.y * b.y, b.x * a.y + b.y * a.x);
}
long double sqabs(pt a) { return a.x * a.x + a.y * a.y; }
pt operator/(pt a, pt b) { return (a * pt(b.x, -b.y)) / sqabs(b); }
long double abs(pt a) { return sqrt(a.x * a.x + a.y * a.y); }
long double dist(pt a, pt b) {
  return sqrt((a.x - b.x) * (a.x - b.x) + (a.y - b.y) * (a.y - b.y));
}
long double sqdist(pt a, pt b) {
  return (a.x - b.x) * (a.x - b.x) + (a.y - b.y) * (a.y - b.y);
}
bool przecinanie(pt a, pt b, pt c, pt d) {
  long double d1 = vec(b - a, c - a), d2 = vec(b - a, d - a);
  if ((d1 > eps && d2 > eps) || (d1 < -eps && d2 < -eps)) return 0;
  if (iszero(d1) && iszero(d2)) {
    if (iszero(a.x - b.x) && iszero(c.x - d.x)) a = a * pt(0, 1);
    b = b * pt(0, 1);
    c = c * pt(0, 1);
    d = d * pt(0, 1);
    if (a.x > b.x) swap(a, b);
    if (c.x > d.x) swap(c, d);
    if (a.x < c.x + eps && c.x < b.x + eps) return 1;
    if (a.x < d.x + eps && d.x < b.x + eps) return 1;
    if (c.x < a.x + eps && a.x < d.x + eps) return 1;
    return 0;
  }
  d1 = vec(d - c, a - c), d2 = vec(d - c, b - c);
  if ((d1 > eps && d2 > eps) || (d1 < -eps && d2 < -eps)) return 0;
  return 1;
}
bool insegment(pt a, pt b, pt c) {
  if (iszero(det(a, b, c)))
    if (min(b.x, c.x) - eps <= a.x && a.x - eps <= max(b.x, c.x))
      if (min(b.y, c.y) - eps <= a.y && a.y - eps <= max(b.y, c.y)) return 1;
  return 0;
}
bool przecinanie_wl(pt a, pt b, pt c, pt d) {
  long double d1 = vec(b - a, c - a), d2 = vec(b - a, d - a);
  if (!(d1 > eps && d2 < -eps) && !(d1 < -eps && d2 > eps)) return 0;
  d1 = vec(d - c, a - c), d2 = vec(d - c, b - c);
  if (!(d1 > eps && d2 < -eps) && !(d1 < -eps && d2 > eps)) return 0;
  return 1;
}
bool inpoly(pt a, vector<pt> &pol) {
  pt b(3e8 + 500.0, 4e6 + 77777.0);
  int pr = 0;
  for (int(i) = 0; (i) < (((int)((pol).size()))); ++(i))
    pr += przecinanie_wl(a, b, pol[i], pol[(i + 1) % ((int)((pol).size()))]);
  return pr % 2;
}
bool onborder(pt a, vector<pt> &pol) {
  for (int(i) = 0; (i) < (((int)((pol).size()))); ++(i))
    if (insegment(a, pol[i], pol[(i + 1) % ((int)((pol).size()))])) return 1;
  return 0;
}
vector<pt> poly;
long long dp[505][505];
bool ok[505][505];
const int mod = 1000000007;
int main() {
  int(n);
  scanf("%d", &(n));
  for (int(i) = 0; (i) < (n); ++(i)) {
    int(xi);
    scanf("%d", &(xi));
    int(yi);
    scanf("%d", &(yi));
    poly.push_back(pt(xi, yi));
  }
  for (int(p) = 0; (p) < (n); ++(p)) dp[p][(p + 1) % n] = 1;
  for (int(d) = (2); (d) <= (n - 1); ++d) {
    for (int(p) = 0; (p) < (n); ++(p)) {
      int q = (p + d) % n;
      dp[p][q] = 0;
      pt srodek = poly[p] + (poly[q] - poly[p]) * 0.46579841564;
      if (p == 1 && q == 4) {
      }
      if ((!inpoly(srodek, poly)) && (!onborder(srodek, poly))) {
        continue;
      }
      bool bad = 0;
      for (int(k) = 0; (k) < (n); ++(k))
        if (!(k == p && (k + 1) % n == q) && !(k == q && (k + 1) % n == p)) {
          if (przecinanie_wl(poly[p], poly[q], poly[k], poly[(k + 1) % n]))
            bad = 1;
        }
      for (int(k) = 0; (k) < (n); ++(k))
        if (k != p && k != q) {
          if (insegment(poly[k], poly[p], poly[q])) bad = 1;
        }
      if (bad) {
        continue;
      }
      for (int r = (p + 1) % n; r != q; r = (r + 1) % n) {
        dp[p][q] += dp[p][r] * dp[r][q] % mod;
      }
      dp[p][q] %= mod;
    }
  }
  int res = dp[0][n - 1];
  res %= mod;
  if (res < 0) res += mod;
  pisz(res);
}
