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;
int getint() {
  unsigned int c;
  int x = 0;
  while (((c = getchar()) - '0') >= 10) {
    if (c == '-') return -getint();
    if (!~c) exit(0);
  }
  do {
    x = (x << 3) + (x << 1) + (c - '0');
  } while (((c = getchar()) - '0') < 10);
  return x;
}
const int MOD = 1000000007;
struct modint {
  int v;
  modint() : v(0) {}
  modint(int a) : v(a) {
    if (v < 0) v += MOD;
    if (v >= MOD) v -= MOD;
  }
  modint(long long a) {
    if (a < 0) a = a % MOD + MOD;
    if (a >= MOD) a = a % MOD;
    v = a;
  }
  void clear() { v = ~0; }
  bool is() { return ~v; }
  int to_int() { return v; }
  modint& operator+=(modint x) { return *this = v + x.v; }
  modint& operator-=(modint x) { return *this = MOD + v - x.v; }
  modint& operator*=(modint x) { return *this = (long long)v * x.v; }
  modint operator+(modint x) const { return modint(v) += x; }
  modint operator-(modint x) const { return modint(v) -= x; }
  modint operator*(modint x) const { return modint(v) *= x; }
  modint operator-() { return modint(0) - *this; }
};
ostream& operator<<(ostream& os, modint x) {
  os << x.v;
  return os;
}
modint mod_pow(modint x, long long n) {
  modint y = 1;
  for (; n; x *= x, n >>= 1)
    if (n & 1) y *= x;
  return y;
}
modint mod_inv(modint x) {
  modint y = 1;
  for (int n = MOD - 2; n; x *= x, n >>= 1)
    if (n & 1) y *= x;
  return y;
}
modint& operator/=(modint& x, modint y) { return x *= mod_inv(y); }
modint operator/(modint x, modint y) { return x /= y; }
const double eps = 1e-10;
const double real_inf = 1e30;
int isign(double r) {
  return (r < -eps) ? -1 : (r > eps) ? 1 : 0;
  return 0;
}
inline double ab(double x) { return x > 0 ? x : -x; }
struct Point {
  double x, y;
  Point(){};
  Point(double x, double y) : x(x), y(y){};
  Point& operator+=(const Point& a) {
    x += a.x, y += a.y;
    return *this;
  }
  Point& operator-=(const Point& a) {
    x -= a.x, y -= a.y;
    return *this;
  }
  Point operator-() const { return Point(-x, -y); }
  Point operator+(const Point& a) const { return Point(*this) += a; }
  Point operator-(const Point& a) const { return Point(*this) -= a; }
  Point operator*(double k) const { return Point(x * k, y * k); }
  Point operator/(double k) const { return Point(x / k, y / k); }
  bool operator<(const Point& a) const {
    return (x != a.x) ? (x < a.x) : (y < a.y);
  }
  bool operator==(const Point& a) const {
    return isign(x - a.x) == 0 and isign(y - a.y) == 0;
  }
};
Point operator*(const double& k, const Point& p) {
  return Point(k * p.x, k * p.y);
}
inline double abs(const Point& a) { return sqrt(a.x * a.x + a.y * a.y); }
inline double nrm(const Point& a) { return a.x * a.x + a.y * a.y; }
inline double arg(const Point& a) {
  double t = atan2(a.y, a.x);
  return t > 0 ? t : t + 2 * M_PI;
}
inline double crs(const Point& a, const Point& b) {
  return a.x * b.y - b.x * a.y;
}
inline double dot(const Point& a, const Point& b) {
  return a.x * b.x + a.y * b.y;
}
inline double arg(const Point& a, const Point& b) {
  double t = abs(arg(a) - arg(b));
  if (t > M_PI) t = 2 * M_PI - t;
  return t;
}
inline Point rotate(const Point& p, double rad) {
  double a = abs(p), t = arg(p);
  return Point(a * cos(t + rad), a * sin(t + rad));
}
inline Point rotate(const Point& p, const Point& o, double rad) {
  return rotate(p - o, rad) + o;
}
inline int ccw(Point a, Point b, Point c) {
  b -= a, c -= a, a.x = crs(b, c);
  if (a.x > 0) return 1;
  if (a.x < 0) return -1;
  if (dot(b, c) < 0) return 2;
  a.x = nrm(b), a.y = nrm(c);
  if (a.x < a.y) return -2;
  return 0;
}
inline double pt_pt_dist(Point p, const Point& q) {
  p -= q;
  return abs(p);
}
ostream& operator<<(ostream& os, const Point& a) {
  os << "(" << a.x << ", " << a.y << ")";
  return os;
}
struct Line {
  Point p1, p2, dr;
  Line(){};
  Line(const Point& pt1, const Point& pt2) { set_2pt(pt1, pt2); }
  void set_2pt(const Point& pt1, const Point& pt2) {
    p1 = pt1, p2 = pt2, dr = pt2 - pt1;
  }
  void set_dir(const Point& pt1, const Point& dir) {
    p1 = pt1, dr = dir, p2 = p1 + dr;
  }
};
inline bool pt_sg_isct(const Point& p, const Line& s) {
  return abs(s.p1 - p) + abs(s.p2 - p) - abs(s.dr) < eps;
}
inline bool sg_sg_isct(const Line& s, const Line& t) {
  return ccw(s.p1, s.p2, t.p1) * ccw(s.p1, s.p2, t.p2) <= 0 and
         ccw(t.p1, t.p2, s.p1) * ccw(t.p1, t.p2, s.p2) <= 0;
}
int point_inside_polygon(const vector<Point>& poly, const Point& p) {
  bool ins = false;
  for (int i = 0; i < (int)poly.size(); i++) {
    Point a = poly[i] - p;
    Point b = poly[(i + 1) % poly.size()] - p;
    if (a.y > b.y) swap(a, b);
    if (a.y <= 0 and 0 < b.y and crs(a, b) < 0) ins = !ins;
    if (crs(a, b) == 0 and dot(a, b) <= 0) return 2;
  }
  return ins ? 1 : 0;
}
int n;
vector<Point> ps;
bool canConnect[222][222];
modint cache[222][222];
modint solve(int srt, int end) {
  modint& res = cache[srt][end];
  if (res.is()) return res;
  if (canConnect[srt][end] == 0) return res = 0;
  if (srt == end) return res = 0;
  if (srt + 1 == end) return res = 1;
  if (srt + 2 == end) return res = 1;
  res = 0;
  for (int k = srt + 1; k < end; k++) {
    if (canConnect[srt][k] and canConnect[k][end]) {
      res += solve(srt, k) * solve(k, end);
    }
  }
  return res;
}
int main() {
  int i, j, k, tcc, tc = 1 << 28;
  for (tcc = 0; tcc < tc; tcc++) {
    n = getint();
    ps.resize(n);
    for (i = 0; i < n; i++) ps[i].x = 2 * getint(), ps[i].y = 2 * getint();
    for (i = 0; i < n; i++)
      for (j = i + 1; j < n; j++) {
        Line sg(ps[i], ps[j]);
        bool ok = 1;
        for (k = 0; k < n; k++)
          if (k != i and k != j) {
            if (pt_sg_isct(ps[k], sg)) {
              ok = 0;
              break;
            }
          }
        if (!ok) continue;
        Point mid = (ps[i] + ps[j]) / 2;
        if (point_inside_polygon(ps, mid) == 0) ok = 0;
        if (!ok) continue;
        for (k = 0; k < n; k++) {
          int l = (k + 1) % n;
          if (k == i or k == j) continue;
          if (l == i or l == j) continue;
          Line sg1(ps[i], ps[j]);
          Line sg2(ps[k], ps[l]);
          if (sg_sg_isct(sg1, sg2)) {
            ok = 0;
            break;
          }
        }
        if (!ok) continue;
        canConnect[i][j] = canConnect[j][i] = 1;
      }
    memset(cache, ~0, sizeof(cache));
    modint res = solve(0, n - 1);
    cout << res << endl;
  }
  return 0;
}
