For given $n$ segments which are parallel to X-axis or Y-axis, find the number of intersections of them.

Constraints

* $1 \leq n \leq 100,000$
* $ -1,000,000,000 \leq x_1, y_1, x_2, y_2 \leq 1,000,000,000$
* Two parallel segments never overlap or touch.
* The number of intersections $\leq 1,000,000$

Input

In the first line, the number of segments $n$ is given. In the following $n$ lines, the $i$-th segment is given by coordinates of its end points in the following format:

$x_1 \; y_1 \; x_2 \; y_2$

The coordinates are given in integers.

Output

Print the number of intersections in a line.

Example

Input

6
2 2 2 5
1 3 5 3
4 1 4 4
5 2 7 2
6 1 6 3
6 5 6 7


Output

3
#include <algorithm>
#include <cstdio>
#include <cmath>
#include <vector>
#include <set>
using namespace std;

#define EPS (1e-10)
#define equals( A, B ) (fabs((A) - (B)) < EPS)

class Point {
public:
    double x, y;
    Point( double x = 0, double y = 0 ): x(x), y(y) {}
    
    Point operator + ( Point p ) { return Point( x + p.x, y + p.y ); }
    Point operator - ( Point p ) { return Point( x - p.x, y - p.y ); }
    Point operator * ( double a ) { return Point( a * x, a * y ); }
    Point operator / ( double a ) { return Point( x / a, y / a ); }

    double abs() { return sqrt( norm() ); }
    double norm() { return x * x + y * y; }

    bool operator < ( const Point &p ) const {
	return ( x != p.x ) ? x < p.x : y < p.y;
    }

    bool operator == ( const Point &p ) const {
	return equals( x, p.x ) && equals( y, p.y ); 
    }

    double dot( Point a ) { return x * a.x + y * a.y; }
    double cross( Point a ) { return x * a.y - y * a.x; }
    double distance( Point a ) {
	return (*this - a).abs();
    }
    double arg() {
	return atan2( y, x );
    }
};

typedef Point Vector;

typedef vector<Point> Polygon;

int contains( Polygon poly, Point p ) {
    int n = poly.size();
    int count = 0;
    for ( int i = 0; i < n; i++ ) {
	Vector a = poly[i] - p;
	Vector b = poly[ ( i + 1 ) % n ] - p;

	// ???????????????
	if ( abs( a.cross( b ) ) < EPS && a.dot( b ) < EPS ) {
	    return 1;
	}
	// a.y???b.y??\?????????????????????
	if ( a.y > b.y ) {
	    Vector tmp = a; a = b; b = tmp;
	}
	// ??£?????????????????´????????????????????´???
	if ( a.y < EPS && b.y > EPS && a.cross( b ) > EPS ) {
	    count++;
	}
    }

    return ( count % 2 ) ? 2 : 0;
}

static const int COUNTER_CLOCKWISE = 1;
static const int CLOCKWISE = -1;
static const int ONLINE_BACK = 2;
static const int ONLINE_FRONT = -2;
static const int ON_SEGMENT = 0;

class Line {
public:
    Point p1, p2;
    Line( Point p1 = Point(), Point p2 = Point() ): p1(p1), p2(p2){}
    // ?????´????????????( cos = 0 )
    bool isOrthogonal( Line a ) {
	return equals( 0.0, (p1 - p2).dot( a.p1 - a.p2 ) );
    }
    // ??????????????????( sin = 0 )
    bool isParallel( Line a ) {
	return equals( 0.0, (p1 - p2).cross( a.p1 - a.p2 ) );
    }

    Point projection( Point p ) {
	Vector v12 = p2 - p1;
	double r = v12.dot( p - p1 ) / v12.norm();
	return p1 + v12 * r;
    }

    Point reflection( Point p ) {
	return p + ( projection( p ) - p ) * 2.0;
    }

    double distance( Point p ) {
	Vector v12 = this->p2 -this->p1;
	Vector v10 = p - this->p1;
	
	return abs( v12.cross( v10 ) / v12.abs() );
    }

    double distanceSP( Point p ) {
	if ( (p - this->p1).dot( this->p2 - this->p1 ) < 0.0 ) {
	    return this->p1.distance( p );
	} else if ( (p - this->p2).dot( this->p1 - this->p2 ) < 0.0 ) {
	    return this->p2.distance( p );
	}
	else {
	    return distance( p );
	}
    }

    int ccw( Point p ) {
	Vector a = p2 - p1;
	Vector b = p - p1;
	if ( a.cross( b ) > EPS ) return COUNTER_CLOCKWISE;
	else if ( a.cross( b ) < -EPS ) return CLOCKWISE;
	else if ( a.dot( b ) < -EPS ) return ONLINE_BACK;
	else if ( a.norm() < b.norm() ) return ONLINE_FRONT;
	else return ON_SEGMENT;
    }

    bool intersect( Line l ) {
	return ( ( ccw( l.p1 ) * ccw( l.p2 ) <= 0 && l.ccw( p1 ) * l.ccw( p2 ) <= 0 ) );
    }

    Point crossPoint( Line l ) {
	Vector base = p2 - p1;
	Vector v1 = l.p1 - p1;
	Vector v2 = l.p2 - p1;
	double d1 = base.cross( v1 );
	double d2 = base.cross( v2 );	
	double t = d1 / ( d1 + d2 );

	return l.p1 + ( l.p2 - l.p1 ) * t;
    }
};

typedef Line Segment;

typedef enum {
    EP_BOTTOM,
    EP_LEFT,
    EP_RIGHT,
    EP_TOP,
} PointType;

class EndPoint {
public:
    Point p;
    int id;
    PointType type;
    EndPoint() {}
    EndPoint( Point p, int id, PointType type ): p(p), id(id), type(type) {}

    bool operator < ( const EndPoint &ep ) const {
	if ( p.y != ep.p.y ) return ( p.y < ep.p.y );
	else return ( type < ep.type );
    }
};

#define MAX_N (100010)

Segment S[MAX_N];

EndPoint EP[MAX_N << 1];

int main()
{
    int n;

    scanf("%d", &n);
    
    for ( int i = 0; i < n; i++ ) {
	Point p1, p2;
	scanf("%lf %lf %lf %lf", &p1.x, &p1.y, &p2.x, &p2.y);
	S[i] = ( p1 < p2 ) ? Segment( p1, p2 ) : Segment( p2, p1 );
	if ( p1.y == p2.y ) {	// ?°´???
	    EndPoint ep0 = EndPoint( S[i].p1, i, EP_LEFT );
	    EndPoint ep1 = EndPoint( S[i].p2, i, EP_RIGHT );
	    EP[i<<1] = ep0;
	    EP[(i<<1) + 1] = ep1;
	}
	else {			// ?????´
	    EndPoint ep0 = EndPoint( S[i].p1, i, EP_BOTTOM );
	    EndPoint ep1 = EndPoint( S[i].p2, i, EP_TOP );
	    EP[i<<1] = ep0;
	    EP[(i<<1) + 1] = ep1;
	}
    }
    
    sort(EP, EP + (n << 1));

    set<int> T;		// ????????¢?´¢??¨
    //T.insert( 1000000001 );
    int ans = 0;
    for ( int i = 0; i < (n<<1); i++ ) {
	EndPoint ep = EP[i];
	if ( ep.type == EP_BOTTOM ) {
	    T.insert( (int)ep.p.x );
	}
	else if ( ep.type == EP_TOP ) {
	    T.erase( (int)ep.p.x );
	}
	else if ( ep.type == EP_LEFT ) {
	    Segment s = S[ep.id];
	    set<int>::iterator l = lower_bound( T.begin(), T.end(), (int)s.p1.x );
	    set<int>::iterator u = upper_bound( T.begin(), T.end(), (int)s.p2.x );
	    ans += distance( l, u );
	}
    }

    printf("%d\n", ans);

    return 0;
}