For a given polygon g, print "1" if g is a convex polygon, "0" otherwise. Here, in a convex polygon, all interior angles are less than or equal to 180 degrees.

g is represented by a sequence of points p1, p2,..., pn where line segments connecting pi and pi+1 (1 ≤ i ≤ n-1) are sides of the polygon. The line segment connecting pn and p1 is also a side of the polygon.

Constraints

* 3 ≤ n ≤ 100
* -10000 ≤ xi, yi ≤ 10000
* No point of the polygon will occur more than once.
* Two sides of the polygon can intersect only at a common endpoint.

Input

g is given by coordinates of the points p1,..., pn in the following format:


n
x1 y1
x2 y2
:
xn yn


The first integer n is the number of points. The coordinate of a point pi is given by two integers xi and yi. The coordinates of points are given in the order of counter-clockwise visit of them.

Output

Print "1" or "0" in a line.

Examples

Input

4
0 0
3 1
2 3
0 3


Output

1


Input

5
0 0
2 0
1 1
2 2
0 2


Output

0

#include<bits/stdc++.h>

typedef long double     lf;

using namespace std;

const lf EPS = 1e-9;
const lf oo = 1e15;

struct pt {
  lf x, y;
  pt( ) { }
  pt( lf x, lf y ) : x( x ), y ( y ) { }
};

inline lf x( pt P ) { return P.x; }
inline lf y( pt P ) { return P.y; }

istream& operator >> ( istream& in, pt& p ) {
  lf x,y; in >> x >> y;
  p = pt(x,y); return in;
}

ostream& operator << ( ostream& out, const pt& p ) {
  out << double(p.x) << " " << double(p.y);
  return out;
}

pt operator + ( const pt& A, const pt& B ) {
  return pt( x(A)+x(B), y(A)+y(B) );
}

pt operator - ( const pt& A, const pt& B ) {
  return pt( x(A)-x(B), y(A)-y(B) );
}


pt operator * ( const lf& B, const pt& A ) {
  return pt( x(A)*B, y(A)*B );
}

pt operator * ( const pt& A, const lf& B ) {
  return pt( x(A)*B, y(A)*B  );
}

inline lf dot( pt A, pt B ) {
  return x(A)*x(B) + y(A)*y(B);
}

inline lf norm( pt A ) {
  return x(A)*x(A) + y(A)*y(A);
}

inline lf abs( pt A ) {
  return sqrt( norm(A) );
}

inline lf dist ( pt A, pt B ) { return abs( B - A ); }

lf distToLine (pt p, pt A, pt B, pt &c) {
  lf u = dot( p-A , B-A ) / norm( B-A );
  c = A + u*( B-A );
  return dist( p , c );
}

pt refPoint(pt X, pt A, pt B) {
  pt aux; distToLine(X, A, B, aux);
  return X + lf(2.0)*(aux-X);
}

inline bool same ( lf a, lf b ) {
  return a+EPS > b && b+EPS > a;
}

inline lf cross( pt A, pt B ) {
  return x(A)*y(B) - y(A)*x(B);
}

///CHANGE
// 0  for collineal points ( angle = 0 )
// 1  for angle BAX counter clockwise
// -1 for angle BAX clockwise
inline int ccw (pt X, pt A, pt B) {
  lf c = cross( B-A, X-A );
  if( same( c, 0.0 ) ) { return 0; }
  if( c > EPS ) { return 1; }
  return -1;
}

///CHANGE
inline bool segContains ( pt X, pt A, pt B) {
  if ( !same ( 0, cross ( A-X, B-X ) ) ) return 0;
  return ( dot ( A-X, B-X ) < EPS );
}

inline bool parallel( pt A, pt B, pt C, pt D ) {
  return same ( 0, cross( B-A, D-C ) );
}

///NEW
inline bool ortho( pt A, pt B, pt C, pt D ) {
  return same ( 0, dot( B-A, D-C ) );
}

inline bool samePt ( pt A, pt B ) {
  return same ( x(A), x(B) ) && same ( y(A), y(B) );
}

pt linesIntersection ( pt A, pt B, pt C, pt D ) {
  lf x = cross ( C, D-C ) - cross ( A, D-C );
  x /= cross ( B-A, D-C );
  return A + x*(B-A);
}

inline bool collinearSegsIntersects ( pt A, pt B, pt C, pt D ) {
  return segContains(A,C,D) || segContains(B,C,D)
      || segContains(C,A,B) || segContains(D,A,B);
}

bool segmentsIntersect(pt A, pt B, pt C, pt D) {
  if( samePt(A,B) )
    return segContains( A, C, D );
  if( samePt(C,D) )
    return segContains( C, A, B );
  if( parallel(A,B,C,D) )
    return collinearSegsIntersects( A,B,C,D );
  pt aux = linesIntersection(A,B,C,D);
  return segContains(aux,A,B) && segContains(aux,C,D);
}

///CHANGE
lf distToSegment(pt p, pt A, pt B, pt &c) {
  lf u = dot( p-A , B-A ) / norm( B-A );
  if( u < -EPS ) { c = A; return dist( p , A ); }
  if( (u-1.0) > EPS ) { c = B; return dist( p, B ); }
  return distToLine(p,A,B,c);
}

// P[0] must be equal to P[n]
// Area is positive if the polygon is ccw
double signedArea(const vector<pt> &P) {
  double result = 0.0;
  for(int i = 0; i < (int)P.size()-1; i++) result += cross( P[i],P[i+1] );
  return result / 2.0;
}

double area(const vector<pt> &P) { return fabs(signedArea(P)); }

/// --------------------------------------------


///CHANGE
// P[0] must be equal to P[n]
bool isConvex( const vector<pt> &P) {
  int sz = (int) P.size(); if(sz <= 3) return false;
  bool isL = ccw(P[0], P[1], P[2]) >= 0;
  for (int i = 1; i < sz-1; i++) {
    if( ( ccw(P[i], P[i+1], P[(i+2) == sz ? 1 : i+2]) >= 0 ) != isL) return false;
  }
  return true;
}

int n;

int main() {
  ios_base::sync_with_stdio(0);
  cin.tie(0);
  cout << fixed << setprecision(1);

  cin >> n;
  vector<pt> P( n+1 );
  for( int i = 0; i < n; ++i ) {
    cin >> P[i];
  }
  P[n] = P[0];
  if( isConvex(P) )
    cout << "1\n";
  else
    cout << "0\n";
}