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;
#pragma GCC target("avx2")
#pragma GCC optimization("O3")
#pragma GCC optimization("unroll-loops")
#pragma comment(linker, "/stack:200000000")
#pragma GCC optimize("Ofast")
#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
struct Point {
  double x, y;
  Point(double _x = 0, double _y = 0) : x(_x), y(_y){};
  Point(Point A, Point B) {
    x = B.x - A.x;
    y = B.y - A.y;
  }
  Point operator+(Point a) { return {x + a.x, y + a.y}; }
  Point operator-(Point a) { return {x - a.x, y - a.y}; }
  Point operator*(double d) { return {x * d, y * d}; }
  Point operator/(double d) { return {x / d, y / d}; }
  bool operator==(Point a) {
    return (fabs(x - a.x) < 1e-9 && fabs(y - a.y) < 1e-9);
  }
  bool operator!=(Point a) { return !(*this == a); }
  bool operator<(const Point& a) const {
    return (fabs(x - a.x) > 1e-9) ? (x < a.x) : (y < a.y);
  }
};
ostream& operator<<(ostream& os, Point P) {
  return os << "(" << P.x << ", " << P.y << ")";
}
double dot(Point v, Point w) { return v.x * w.x + v.y * w.y; }
double cross(Point v, Point w) { return v.x * w.y - v.y * w.x; }
double sq(Point p) { return p.x * p.x + p.y * p.y; }
double abs(Point p) { return sqrt(sq(p)); }
double det(Point p, Point q) { return p.x * q.y - p.y * q.x; }
Point getUnitVec(Point p) { return p / abs(p); }
Point translate(Point v, Point p) { return v + p; }
Point scale(Point v, double factor, Point C = Point(0, 0)) {
  return C + (v - C) * factor;
}
Point perp(Point p) { return {-p.y, p.x}; }
double isPerp(Point v, Point w) { return dot(v, w) < 1e-9; }
double orient(Point A, Point B, Point C) { return cross(B - A, C - A); }
int orientation(Point A, Point B, Point C) {
  double val = orient(A, B, C);
  if (abs(val) < 1e-9) return 0;
  return (val < 0) ? -1 : 1;
}
double distToLine(Point a, Point b, Point p, Point& c) {
  Point ap = p - a, ab = b - a;
  double u = dot(ap, ab) / sq(ab);
  c = translate(a, scale(ab, u));
  return abs(c - p);
}
double distToLineSegment(Point a, Point b, Point p, Point& c) {
  Point ap = p - a, ab = b - a;
  double u = dot(ap, ab) / sq(ab);
  if (u < 0.0) {
    c = a;
    return abs(a - p);
  } else if (u > 1.0) {
    c = b;
    return abs(b - p);
  }
  c = translate(a, scale(ab, u));
  return abs(c - p);
}
Point rotate(Point p, double rad, Point C = Point(0, 0)) {
  p = p - C;
  return C + Point(p.x * cos(rad) - p.y * sin(rad),
                   p.x * sin(rad) + p.y * cos(rad));
}
double angle(Point v, Point w) {
  double cosTheta = dot(v, w) / abs(v) / abs(w);
  return acos(max(-1.0, min(1.0, cosTheta)));
}
double signedAngle(Point A, Point B, Point P) {
  double ampli = angle(B - A, P - A);
  if (orient(A, B, P) >= 0) return ampli;
  return -ampli;
}
int windingNumber(vector<Point> p, Point a) {
  double ampli = 0;
  for (int i = 0, n = p.size(); i < n; i++)
    ampli += signedAngle(a, p[i], p[(i + 1) % n]);
  return round(ampli / (2.0 * acos(-1.0)));
}
double polarAngle(Point v) { return atan2(v.y, v.x); }
double orientedAngle(Point A, Point B, Point C) {
  if (orient(A, B, C) >= 0)
    return angle(B - A, C - A);
  else
    return 2 * acos(-1.0) - angle(B - A, C - A);
}
bool inAngle(Point a, Point b, Point c, Point p) {
  assert(orient(a, b, c) != 0);
  if (orient(a, b, c) < 0) swap(b, c);
  return orient(a, b, p) >= 0 && orient(a, c, p) <= 0;
}
double sqrDistance(Point A, Point B) {
  return (A.x - B.x) * (A.x - B.x) + (A.y - B.y) * (A.y - B.y);
}
struct line {
  Point v;
  double c;
  line(Point _v, double _c) : v(_v), c(_c){};
  line(double a, double b, double c) : v({b, -a}), c(c){};
  line(Point p, Point q) : v(q - p), c(cross(v, p)){};
  double side(Point P) { return cross(v, P) - c; }
  double dist(Point P) { return abs(side(P)) / abs(v); }
  double sqDist(Point P) { return ((side(P)) * (side(P))) / (double)sq(v); }
  line perpThrough(Point p) { return {p, p + perp(v)}; }
  bool cmpProj(Point p, Point q) { return dot(v, p) < dot(v, q); }
  line translate(Point t) { return {v, c + cross(v, t)}; }
  line shiftLeft(double dist) { return {v, c + dist * abs(v)}; }
  Point proj(Point p) { return {p - perp(v) * side(p) / sq(v)}; }
  Point refl(Point p) { return {p - perp(v) * 2 * side(p) / sq(v)}; }
};
Point projOnLine(Point A, Point B, Point P) {
  Point C;
  Point AP = P - A, AB = B - A;
  double u = dot(AP, AB) / sq(AB);
  return C = A + AB * u;
}
bool lineLineIntersect(line l1, line l2, Point& out) {
  double d = cross(l1.v, l2.v);
  if (d == 0) return false;
  out = (l2.v * l1.c - l1.v * l2.c) / d;
  return true;
}
line bisector(line l1, line l2, bool interior) {
  assert(cross(l1.v, l2.v) != 0);
  double sign = interior ? 1 : -1;
  return {l2.v / abs(l2.v) + l1.v / abs(l1.v) * sign,
          l2.c / abs(l2.v) + l1.c / abs(l1.v) * sign};
}
bool inDisk2(Point A, Point B, Point C) {
  double max_x = max(A.x, B.x), min_x = min(A.x, B.x);
  double max_y = max(A.y, B.y), min_y = min(A.y, B.y);
  return (C.x + 1e-9 >= min_x && C.x - 1e-9 <= max_x && C.y + 1e-9 >= min_y &&
          C.y - 1e-9 <= max_y);
}
bool pointOnSegment2(Point A, Point B, Point C) {
  return (orientation(A, B, C) == 0 && inDisk2(A, B, C));
}
bool inDisk(Point a, Point b, Point p) { return dot(a - p, b - p) <= 0; }
bool pointOnSegment(Point a, Point b, Point p) {
  return abs(orient(a, b, p)) < 1e-9 && inDisk(a, b, p);
}
bool properIntersect(Point a, Point b, Point c, Point d, Point& out) {
  double oa = orient(c, d, a), ob = orient(c, d, b), oc = orient(a, b, c),
         od = orient(a, b, d);
  if (oa * ob < 0 && oc * od < 0) {
    out = (a * ob - b * oa) / (ob - oa);
    return true;
  }
  return false;
}
double triangleArea(Point& a, Point& b, Point& c) {
  return ((a.x * (b.y - c.y) + b.x * (c.y - a.y) + c.x * (a.y - b.y))) / 2.0;
}
const long long MOD = 1e9 + 7;
int n;
const int N = 205;
long long dp[N][N];
int flag[N][N];
Point ara[N];
double totalArea;
int go(int x, int y) {
  if (x + 1 == y or (y + 1) % n == x) return 1;
  for (int i = x; i < y; i++) {
    if (i == x or i == y) continue;
    if (pointOnSegment(ara[x], ara[y], ara[i])) return 0;
  }
  for (int i = 0; i < n; i++) {
    int v1 = i;
    int v2 = (i + 1) % n;
    if (x == v1 or x == v2 or y == v1 or y == v2) continue;
    Point out;
    if (properIntersect(ara[v1], ara[v2], ara[x], ara[y], out) ||
        pointOnSegment(ara[v1], ara[v2], ara[x]) ||
        pointOnSegment(ara[v1], ara[v2], ara[y]) ||
        pointOnSegment(ara[x], ara[y], ara[v1]) ||
        pointOnSegment(ara[x], ara[y], ara[v2]))
      return 0;
  }
  double a1 = 0, a2 = 0;
  for (int i = x + 1; i < y; i++) {
    a1 += triangleArea(ara[x], ara[i], ara[i + 1]);
  }
  for (int i = y + 1; i < x + n; i++) {
    a2 += triangleArea(ara[y], ara[i % n], ara[(i + 1) % n]);
  }
  a1 = abs(a1);
  a2 = abs(a2);
  if (a1 < 1e-9 or a2 < 1e-9) return 0;
  if (abs((a1 + a2 - totalArea)) < 1e-9)
    return 1;
  else
    return 0;
}
long long call(int x, int y) {
  if (x + 1 == y) return 1;
  if (dp[x][y] != -1) return dp[x][y];
  long long ret = 0;
  for (int i = x + 1; i < y; i++) {
    if (flag[x][i] and flag[i][y]) ret += (call(x, i) * call(i, y)) % MOD;
    ret %= MOD;
  }
  return dp[x][y] = ret % MOD;
}
int main() {
  cin >> n;
  for (int i = 0; i < n; i++) {
    cin >> ara[i].x >> ara[i].y;
  }
  for (int i = 1; i < n - 1; i++) {
    totalArea += triangleArea(ara[0], ara[i], ara[i + 1]);
  }
  totalArea = abs(totalArea);
  for (int i = 0; i < n; i++) {
    for (int j = i + 1; j < n; j++) {
      flag[i][j] = go(i, j);
    }
  }
  memset(dp, -1, sizeof(dp));
  cout << call(0, n - 1) << "\n";
}
