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;
const double eps = 1e-10;
const double pi = acos(-1.0);
int cmp(double x) {
  if (fabs(x) < eps) return 0;
  if (x > 0) return 1;
  return -1;
}
inline double sqr(double x) { return x * x; }
struct point {
  double x, y;
  point() {}
  point(double a, double b) : x(a), y(b) {}
  void input() { scanf("%lf%lf", &x, &y); }
  friend point operator+(const point &a, const point &b) {
    return point(a.x + b.x, a.y + b.y);
  }
  friend point operator-(const point &a, const point &b) {
    return point(a.x - b.x, a.y - b.y);
  }
  friend bool operator==(const point &a, const point &b) {
    return cmp(a.x - b.x) == 0 && cmp(a.y - b.y) == 0;
  }
  friend bool operator<(const point &a, const point &b) {
    return cmp(a.x - b.x) < 0 || cmp(a.x - b.x) == 0 && cmp(a.y - b.y) < 0;
  }
  friend point operator*(const point &a, const double &b) {
    return point(a.x * b, a.y * b);
  }
  friend point operator*(const double &a, const point &b) {
    return point(a * b.x, a * b.y);
  }
  friend point operator/(const point &a, const double &b) {
    return point(a.x / b, a.y / b);
  }
  double norm() { return sqrt(sqr(x) + sqr(y)); }
};
double det(const point &a, const point &b) { return a.x * b.y - a.y * b.x; }
double dot(const point &a, const point &b) { return a.x * b.x + a.y * b.y; }
double dist(const point &a, const point &b) { return (a - b).norm(); }
double Angle(point a, point b) {
  if (cmp(dot(a, b) - a.norm() * b.norm()) == 0) return 0;
  if (cmp(dot(a, b) + a.norm() * b.norm()) == 0) return pi;
  return acos(dot(a, b) / a.norm() / b.norm());
}
double angle(point p) { return atan2(p.y, p.x); }
point point_rotate(const point &p, double A) {
  double tx = p.x, ty = p.y;
  return point(tx * cos(A) - ty * sin(A), tx * sin(A) + ty * cos(A));
}
point point_rotate(const point &p, double sint, double cost) {
  double tx = p.x, ty = p.y;
  return point(tx * cost - ty * sint, tx * sint + ty * cost);
}
struct line {
  point a, b;
  line() {}
  line(point x, point y) : a(x), b(y) {}
  void input() {
    a.input();
    b.input();
  }
};
void point_pro_line(const point p, const point s, const point t, point &cp) {
  double r = dot(t - s, p - s) / dot(t - s, t - s);
  cp = s + r * (t - s);
}
bool point_pro_segment(const point p, const point s, const point t, point &cp) {
  if (cmp(dot(p - s, t - s)) < 0) {
    cp = s;
    return 0;
  }
  if (cmp(dot(p - t, s - t)) < 0) {
    cp = t;
    return 0;
  }
  double r = dot(t - s, p - s) / dot(t - s, t - s);
  cp = s + r * (t - s);
  return 1;
}
bool point_on_segment(point p, point s, point t) {
  return cmp(det(p - s, t - s)) == 0 && cmp(dot(p - s, p - t)) < 0;
}
bool parallel(line a, line b) { return !cmp(det(a.a - a.b, b.a - b.b)); }
bool line_cross_line(line a, line b, point &res) {
  if (parallel(a, b)) return false;
  double s1 = det(a.a - b.a, b.b - b.a);
  double s2 = det(a.b - b.a, b.b - b.a);
  res = (s1 * a.b - s2 * a.a) / (s1 - s2);
  return true;
}
int segment_cross_segment(const point &a1, const point &a2, const point &b1,
                          const point &b2, point &res) {
  double c1 = det(a2 - a1, b1 - a1);
  double c2 = det(a2 - a1, b2 - a1);
  double c3 = det(b2 - b1, a1 - b1);
  double c4 = det(b2 - b1, a2 - b1);
  if (cmp(c1) * cmp(c2) < 0 && cmp(c3) * cmp(c4) < 0) {
    res.x = (b1.x * c2 - b2.x * c1) / (c2 - c1);
    res.y = (b1.y * c2 - b2.y * c1) / (c2 - c1);
    return 1;
  }
  if (point_on_segment(a1, b1, b2)) {
    res = a1;
    return 2;
  }
  if (point_on_segment(a2, b1, b2)) {
    res = a2;
    return 2;
  }
  if (point_on_segment(b1, a1, a2)) {
    res = b1;
    return 2;
  }
  if (point_on_segment(b2, a1, a2)) {
    res = b2;
    return 2;
  }
  return 0;
}
int segment_cross_segment(const line &l1, const line &l2, point &res) {
  point a1 = l1.a, a2 = l1.b, b1 = l2.a, b2 = l2.b;
  double c1 = det(a2 - a1, b1 - a1);
  double c2 = det(a2 - a1, b2 - a1);
  double c3 = det(b2 - b1, a1 - b1);
  double c4 = det(b2 - b1, a2 - b1);
  if (cmp(c1) * cmp(c2) < 0 && cmp(c3) * cmp(c4) < 0) {
    res.x = (b1.x * c2 - b2.x * c1) / (c2 - c1);
    res.y = (b1.y * c2 - b2.y * c1) / (c2 - c1);
    return 1;
  }
  if (point_on_segment(a1, b1, b2)) {
    res = a1;
    return 2;
  }
  if (point_on_segment(a2, b1, b2)) {
    res = a2;
    return 2;
  }
  if (point_on_segment(b1, a1, a2)) {
    res = b1;
    return 2;
  }
  if (point_on_segment(b2, a1, a2)) {
    res = b2;
    return 2;
  }
  return 0;
}
struct circle {
  point c;
  double r;
  circle() {}
  circle(point _c, double _r) : c(_c), r(_r) {}
  void input() {
    c.input();
    scanf("%lf", &r);
  }
  double perimeter() { return 2 * pi * r; }
  double area() { return sqr(r) * pi; }
};
bool point_on_circle(const point &p, const circle &c) {
  return cmp((p - c.c).norm() - c.r) == 0;
}
bool point_in_circle(const point &p, const circle &c) {
  return cmp((p - c.c).norm() - c.r) < 0;
}
int circle_cross_line(circle C, line l, double &t1, double &t2, point res[]) {
  double a = l.b.x - l.a.x;
  double b = l.a.x - C.c.x;
  double c = l.b.y - l.a.y;
  double d = l.a.y - C.c.y;
  double e = sqr(a) + sqr(c);
  double f = 2 * (a * b + c * d);
  double g = sqr(b) + sqr(d) - sqr(C.r);
  double delta = f * f - 4 * e * g;
  if (cmp(delta) < 0) return 0;
  if (cmp(delta) == 0) {
    t1 = t2 = -f / (2 * e);
    res[0] = point(l.a.x + t1 * a, l.a.y + t1 * c);
    return 1;
  }
  t1 = (-f - sqrt(delta)) / (2 * e);
  t2 = (-f + sqrt(delta)) / (2 * e);
  res[0] = point(l.a.x + t1 * a, l.a.y + t1 * c);
  res[1] = point(l.a.x + t2 * a, l.a.y + t2 * c);
  return 2;
}
int circle_cross_circle(circle C1, circle C2, point res[]) {
  double d = (C1.c - C2.c).norm();
  if (cmp(C1.r + C2.r - d) < 0 || cmp(fabs(C1.r - C2.r) - d) > 0) return 0;
  if (cmp(C1.r + C2.r - d) == 0 || cmp(fabs(C1.r - C2.r) - d) == 0) {
    if (cmp(C2.r - C1.r) > 0) swap(C1, C2);
    res[0] = (C2.c - C1.c) / d * C1.r + C1.c;
    return 1;
  }
  double cost = (sqr(C1.r) + sqr(d) - sqr(C2.r)) / (2 * C1.r * d);
  double sint = sqrt(1.0 - sqr(cost));
  point p = (C2.c - C1.c) / d * C1.r;
  res[0] = C1.c + point_rotate(p, -sint, cost);
  res[1] = C1.c + point_rotate(p, sint, cost);
  return 2;
}
struct polygon {
  vector<point> P;
  polygon(int size = 0) { P.resize(size); }
  point &operator[](int index) { return P[index]; }
  int size() { return P.size(); }
  double area() {
    int n = size();
    double sum = 0;
    for (int i = 0; i < n; i++) sum += det(P[i], P[(i + 1) % n]);
    return sum * 0.5;
  }
};
struct polygon_convex {
  vector<point> P;
  polygon_convex(int size = 0) { P.resize(size); }
  point &operator[](int index) { return P[index]; }
  int size() { return P.size(); }
};
bool comp_less(const point &a, const point &b) {
  return cmp(a.x - b.x) < 0 || cmp(a.x - b.x) == 0 && cmp(a.y - b.y) < 0;
}
polygon_convex convex_hull(vector<point> &a) {
  polygon_convex res(2 * a.size() + 5);
  sort(a.begin(), a.end(), comp_less);
  a.erase(unique(a.begin(), a.end()), a.end());
  int m = 0;
  for (int i = 0; i < a.size(); i++) {
    while (m > 1 && cmp(det(res[m - 1] - res[m - 2], a[i] - res[m - 2])) <= 0)
      m--;
    res[m++] = a[i];
  }
  int k = m;
  for (int i = int(a.size()) - 2; i >= 0; i--) {
    while (m > k && cmp(det(res[m - 1] - res[m - 2], a[i] - res[m - 2])) <= 0)
      m--;
    res[m++] = a[i];
  }
  res.P.resize(m);
  if (a.size() > 1) res.P.resize(m - 1);
  return res;
}
bool map[233][233];
long long dp[233][233];
bool vis[233][233];
int n;
polygon pol;
const long long mod = 1e9 + 7;
long long Search(int l, int r) {
  if (vis[l][r]) return dp[l][r];
  vis[l][r] = 1;
  if (r - l == 1) return dp[l][r] = 1;
  dp[l][r] = 0;
  for (int i = l + 1; i < r; i++) {
    if (cmp(det(pol[l] - pol[r], pol[i] - pol[r])) > 0) {
      dp[l][r] += Search(l, i) * Search(i, r);
      dp[l][r] %= mod;
    }
  }
  return dp[l][r];
}
int main() {
  scanf("%d", &n);
  pol = polygon(n);
  for (int i = 0; i < n; i++) pol[i].input();
  if (pol.area() < 0) {
    for (int i = 0; i < n / 2; i++) swap(pol[i], pol[n - i - 1]);
  }
  memset(vis, 0, sizeof(vis));
  cout << Search(0, n - 1) << endl;
  return 0;
}
