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 <iostream>
#include <cmath>
#include <vector>
#include <cstdio>
#include <set>
#include <algorithm>
#define EPS (1e-10)
#define MAX 100000
using namespace std;
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;
static const int TOP=3;
static const int RIGHT=1;
static const int LEFT=2;
static const int BOTTOM=0;
class Point{
public:
    double x,y;
    Point(double x=0, double y=0):x(x),y(y){}
    Point operator +(const Point &p){
        return Point(x+p.x,y+p.y);
    }
    Point operator -(const Point &p){
        return Point(x-p.x,y-p.y);
    }
    Point operator *(double k){
        return Point(k*x,k*y);
    }
    Point operator /(double k){
        return Point(x/k,y/k);
    }

    double norm(){
        return x*x+y*y;
    }
    double abs(){
        return sqrt(norm());
    }
};
typedef Point Vector;
class EndPoint{
public:
    Point p;
    int seg,state;
    EndPoint(){}
    EndPoint(Point p,int seg,int state):p(p),seg(seg),state(state){}
    bool operator <(const EndPoint &ep) const{
        if(p.y==ep.p.y)return state<ep.state;
        return p.y<ep.p.y;
    }
};
vector<Point>g;
typedef vector<Point> Polygon;
Polygon s;
struct segment{
    Point p1,p2;
};
typedef segment Line;
class Circle{
public:
    Point c;
    double r;
    Circle (double x=0, double y=0,double r=0):c(x,y),r(r){}
};
double dot(const Vector &v1,const Vector &v2){
    return v1.x*v2.x+v1.y*v2.y;
}
double cross(const Vector &v1,const Vector &v2){
    return v1.x*v2.y-v1.y*v2.x;
}
bool isParallel(const Vector &v1,const Vector &v2){
    if(fabs(cross(v1,v2)-0.0)<EPS)return true;
    return false;
}
bool isOrthogonal(const Vector &v1,const Vector &v2){
    if(fabs(dot(v1,v2)-0.0)<EPS)return true;
    return false;
}
Point projection( Point &p, Point &p1, Point &p2){
    Vector a=p-p1;
    Vector b=p2-p1;
    double r=dot(a,b);
    double pro_abs=r/b.norm();
    Vector res=b*pro_abs;
    return Point(res.x+p1.x,res.y+p1.y);
}
Point reflection(Point &p, Point &p1, Point &p2){
    Point pro=projection(p,p1,p2);
    Vector v=pro-p;
    v=v*2;
    return Point(v.x+p.x,v.y+p.y);
}
int ccw(Point &p, Point &p1, Point &p2){
    Vector a=p1-p;
    Vector b=p2-p;
    if(cross(a,b)>0)return COUNTER_CLOCKWISE;
    if(cross(a,b)<0)return CLOCKWISE;
    if(dot(a,b)<0)return ONLINE_BACK;
    if(a.norm()>b.norm())return ONLINE_FRONT;
    return ON_SEGMENT;
}
bool intersect(segment &s1,segment &s2){
    if(ccw(s2.p1,s2.p2,s1.p1)*ccw(s2.p1,s2.p2,s1.p2)<=0 && ccw(s1.p1,s1.p2,s2.p1)*ccw(s1.p1,s1.p2,s2.p2)<=0)
        return true;
    return false;
}
double getDistanceSP(Point &p,segment &s){
    if(dot(p-s.p1,s.p2-s.p1)<0)return (p-s.p1).abs();
    if(dot(p-s.p2,s.p1-s.p2)<0)return (p-s.p2).abs();
    return fabs(cross(p-s.p1,s.p2-s.p1)/(s.p2-s.p1).abs());
}
double Distance(segment &s1,segment &s2){
    if(intersect(s1,s2))return 0;
    return min(min(getDistanceSP(s1.p1,s2),getDistanceSP(s1.p2,s2)),min(getDistanceSP(s2.p1,s1),getDistanceSP(s2.p2,s1)));
}
Point CrossPoint(segment &s1,segment &s2){
    Vector base =s2.p2-s2.p1;
    double d1=fabs(cross(base,s1.p1-s2.p1));
    double d2=fabs(cross(base,s1.p2-s2.p1));
    double t=d1/(d1+d2);
    return (s1.p2-s1.p1)*t+s1.p1;
}
pair<Point,Point> getCrossPoints(Circle &c,Line &l){
    Vector e = (l.p2-l.p1)/(l.p2-l.p1).abs();
    Point p=projection(c.c,l.p1,l.p2);
    double len=sqrt(c.r*c.r-(p-c.c).norm());
    return make_pair(p-e*len,p+e*len);
 }
pair<Point,Point> getCrossPoints(Circle &c1,Circle &c2){
    double d=(c1.c-c2.c).abs();
    double a=acos((c1.r*c1.r+d*d-c2.r*c2.r)/(2*c1.r*d));
    double t=atan2((c2.c-c1.c).y,(c2.c-c1.c).x);
    Point p1(c1.r*cos(t+a),c1.r*sin(t+a));
    Point p2(c1.r*cos(t-a),c1.r*sin(t-a));
    return make_pair(c1.c+p1,c1.c+p2);
}
//点的内包
int PPC(Point &p){
    int n=g.size();
    bool x=false;
    for(int i=0;i<n;i++)
    {
        Vector a=g[i]-p;
        Vector b=g[(i+1)%n]-p;
        if(fabs(cross(a,b)-0)<EPS && dot(a,b)<=0)return 1;
        if(a.y>b.y)swap(a,b);
        if(a.y<EPS && 0<b.y &&cross(a,b)>0)x!=x;
    }
    return x?2:0;
}
void merge(int l,int mid,int r)
{
    Polygon left,right;
    Point p(MAX,MAX);
    for(int i=0;i<mid-l;i++)
        left.push_back(s[l+i]);
    left.push_back(p);
    for(int i=0;i<r-mid;i++)
        right.push_back(s[mid+i]);
    right.push_back(p);
    int l_index=0,r_index=0;
    for(int i=l;i<r;i++)
    {
        if(left[l_index].x<right[r_index].x){
            s[i]=left[l_index++];
        } else if(fabs(left[l_index].x-right[r_index].x)<EPS){
            if(left[l_index].y<right[r_index].y)
                s[i]=left[l_index++];
            else
                s[i]=right[r_index++];
        } else
            s[i]=right[r_index++];
    }
}
void mergesort(int l,int r)
{
    if(l+1<r){
        int mid=(l+r)/2;
        mergesort(l,mid);
        mergesort(mid,r);
        merge(l,mid,r);
    }
}
Polygon andrewScan(){
    Polygon u,l;
    mergesort(0,s.size());
    for(int i=0;i<s.size();i++)
        cout<<s[i].x<<' '<<s[i].y<<endl;
    u.push_back(s[0]);
    u.push_back(s[1]);
    l.push_back(s[s.size()-1]);
    l.push_back(s[s.size()-2]);
    for(int i=2;i<s.size();i++)
    {
        for(int j=u.size();j>=2;j--)
            if(ccw(u[j-2],u[j-1],s[i])==COUNTER_CLOCKWISE)u.pop_back();
        u.push_back(s[i]);
    }
    for(int i=s.size()-3;i>=0;i--)
    {
        for(int j=l.size();j>=2;j--)
            if(ccw(l[j-2],l[j-1],s[i])==COUNTER_CLOCKWISE)l.pop_back();
        l.push_back(s[i]);
    }
    //cout<<u.size()<<endl<<l.size()<<endl;
    reverse(l.begin(),l.end());
    for(int i=u.size()-2;i>0;i--)
        l.push_back(u[i]);
    return l;
}
int manhattanIntersection(vector<segment> &s)
{
    int n=s.size(),count=0;
    EndPoint ep[n*2];
    int k=0;
    for(int i=0;i<n;i++){
        if(s[i].p1.y==s[i].p2.y){
            if(s[i].p1.x>s[i].p2.x)
                swap(s[i].p1,s[i].p2);
            ep[k++]=EndPoint(s[i].p1,i,LEFT);
            ep[k++]=EndPoint(s[i].p2,i,RIGHT);
        }
        else{
            if(s[i].p1.y>s[i].p2.y)
                swap(s[i].p1, s[i].p2);
            ep[k++]=EndPoint(s[i].p1,i,BOTTOM);
            ep[k++]=EndPoint(s[i].p2,i,TOP);
        }
    }
    sort(ep,ep+n*2);
    set<double>BT;
    for(int i=0;i<n*2;i++)
    {
        if(ep[i].state==BOTTOM)BT.insert(ep[i].p.x);
        else if(ep[i].state==TOP)BT.erase(ep[i].p.x);
        else if(ep[i].state==LEFT){
            set<double>::iterator a=BT.lower_bound(s[ep[i].seg].p1.x);
            set<double>::iterator b=BT.upper_bound(s[ep[i].seg].p2.x);
            count+=distance(a,b);
        }
    }
    return count;
}
int main()
{
    int n;
    vector<segment>S;
    segment s;
    double x1,y1,x2,y2;
    cin>>n;
    for(int i=0;i<n;i++)
    {
        cin>>x1>>y1>>x2>>y2;
        s.p1=Point(x1,y1);
        s.p2=Point(x2,y2);
        S.push_back(s);
    }
    cout<<manhattanIntersection(S)<<endl;
    return 0;
}
