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<cstdio>
#include<algorithm>
#include<cmath>
#include<set>
#include<vector>
using namespace std;
#define INF 0x7fffffff
#define EPS (1e-10)
#define equals(a, b) (fabs(a-b)<EPS)
static const int CCW=1;//?????¶???
static const int CW=-1;//?????¶???
static const int BACK=-2;//?????¢
static const int FRONT=2;//?????¢
static const int ON=0;//?????????

struct Point//???
{
    double x, y;
    Point(double x=0, double y=0):x(x), y(y) {}
};
typedef Point Vector;//??????

struct Segment
{
    Point p1, p2;
    Segment(Point p1=Point(), Point p2=Point()):p1(p1), p2(p2) {}
};//??????
typedef Segment Line;//??´???

class Circle//???
{
public:
    Point c;
    double r;
    Circle(Point c=Point(), double r=0.0):c(c), r(r) {}
};

typedef vector<Point> Polygon;//????????¢

Point operator + (Point a, Point b)
{
    return Point(a.x+b.x, a.y+b.y);
}
Point operator - (Point a, Point b)
{
    return Point(a.x-b.x, a.y-b.y);
}
Point operator * (Point a, double p)
{
    return  Point(a.x*p, a.y*p);
}
Point operator / (Point a, double p)
{
    return Point(a.x/p, a.y/p);
}
bool operator < (const Point &a,const Point &b)
{
    return a.x<b.x||(a.x==b.x&&a.y<b.y);
}
double norm(Vector a)
{
    return a.x*a.x+a.y*a.y;   //?????°????¨?????????????
}
double abs(Vector a)
{
    return sqrt(norm(a));   //?¨?
}
double dot(Vector a, Vector b)
{
    return a.x*b.x+a.y*b.y;   //??????
}
double cross(Vector a, Vector b)
{
    return a.x*b.y-a.y*b.x;   //??????
}
bool isOrthgonal(Vector a, Vector b)
{
    return equals(dot(a, b), 0.0);   //???????????´????????????
}
bool isOrthgonal(Point a1, Point a2, Point b1, Point b2)
{
    return isOrthgonal(a1-a2, b1-b2);   //???????????´???4?????????
}
bool isOrthgonal(Segment s1, Segment s2)
{
    return equals(dot(s1.p2-s1.p1, s2.p2-s2.p1), 0.0);   //???????????´????????????
}
bool isParallel(Vector a, Vector b)
{
    return equals(cross(a, b), 0.0);   //????????????????????????
}
bool isParallel(Point a1, Point a2, Point b1, Point b2)
{
    return isParallel(a1-a2, b1-b2);   //???????????????4?????????
}
bool isParallel(Segment s1, Segment s2)
{
    return equals(cross(s1.p2-s1.p1, s2.p2-s2.p1), 0.0);   //????????????????????????
}

Point project(Segment s, Point p)//?±?????¶?
{
    Vector base=s.p2-s.p1;
    double r=dot(p-s.p1, base)/norm(base);
    return s.p1+base*r;
}

Point reflect(Segment s, Point p)//?±??????°??´??????????§°???
{
    return p+(project(s, p)-p)*2.0;
}

int ccw(Point p0, Point p1, Point p2)//??????P0,P1,P2??????????????????
{
    Vector a=p1-p0;
    Vector b=p2-p0;
    if( cross(a, b)>EPS ) return CCW;
    if( cross(a, b)<-EPS ) return CW;
    if( dot(a, b)<-EPS ) return BACK;
    if( norm(a)<norm(b) ) return FRONT;
    return ON;
}

bool intersect(Point p1, Point p2, Point p3, Point p4)
{
    return (ccw(p1, p2, p3)*ccw(p1, p2, p4)<=0 &&ccw(p3, p4, p1)*ccw(p3, p4, p2)<=0);    //???????????????4?????????
}
bool intersect(Segment s1, Segment s2)
{
    return intersect(s1.p1, s1.p2, s2.p1, s2.p2);    //???????????????????????????
}

double getDistance(Point a, Point b)
{
    return abs(a-b);    //????????´?????????
}
double getDistanceLP(Line l, Point p)
{
    return abs(cross(l.p2-l.p1, p-l.p1)/abs(l.p2-l.p1));    //?????°??´????????????
}
double getDistanceSP(Segment s, Point p)//?????°???????????????
{
    if(dot(s.p2-s.p1, p-s.p1)<0.0) return abs(p-s.p1);
    if(dot(s.p1-s.p2, p-s.p2)<0.0) return abs(p-s.p2);
    return getDistanceLP(s, p);
}
double getDistanceSS(Segment s1, Segment s2)//???????????´?????????
{
    if(intersect(s1, s2)) return 0.0;
    return min( min(getDistanceSP(s1,s2.p1), getDistanceSP(s1,s2.p2)),
                min(getDistanceSP(s2,s1.p1), getDistanceSP(s2,s1.p2)) );
}

Point getCrossPoint(Segment s1, Segment s2)//??????????????????
{
    Vector base=s2.p2-s2.p1;
    double d1=abs(cross(base, s1.p1-s2.p1));
    double d2=abs(cross(base, s1.p2-s2.p1));
    double t=d1/(d1+d2);
    return s1.p1+(s1.p2-s1.p1)*t;
}
/*
???????????¨????????¢?????¨
IN 2
ON 1
OUT 0
*/
int contains(Polygon g, Point p)
{
    int n=g.size();
    bool x=false;
    for(int i=0; i<n; i++)
    {
        Point a=g[i]-p;
        Point b=g[(i+1)%n]-p;
        if(abs(cross(a, b))<EPS && dot(a, b)<EPS) return 1;
        if(a.y>b.y) swap(a,b);
        if(a.y<EPS && EPS<b.y && cross(a,b)>EPS) x=!x;
    }
    return (x? 2 : 0);
}

Polygon andrewScan(Polygon s)//??????(CCW/CW)
{
    Polygon u, l;
    if(s.size()<3) return s;
    sort(s.begin(), s.end());
    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 n=u.size(); n>=2 && ccw(u[n-2], u[n-1], s[i])!=CW; n--)
            u.pop_back();
        u.push_back(s[i]);
    }
    for(int i=s.size()-3; i>=0; i--)
    {
        for(int n=l.size(); n>=2 && ccw(l[n-2], l[n-1], s[i])!=CW; n--)
            l.pop_back();
        l.push_back(s[i]);
    }
    reverse(l.begin(), l.end());
    for(int i=u.size()-2; i>=1; i--) l.push_back(u[i]);
    return l;
}

double TriArea(Vector a, Vector b)
{
    return 0.5*abs(cross(a,b));    //?±?????§???¢??¢?§?
}

double RotatingCalipers(const Polygon& s)//?±??????¢???????????????????????§??????
{
    Polygon l;
    double dis, maxn=0.0;
    int len, i, k;
    l=andrewScan(s);
    len=l.size();
    if(len>=3)
    {
        for(i=0, k=2; i<len; i++)
        {
            while(cross(l[(k+1)%len]-l[i], l[(k+1)%len]-l[(i+1)%len])>=cross(l[k%len]-l[i], l[k%len]-l[(i+1)%len]))
                k++;
            dis=max(norm(l[k%len]-l[i]), norm(l[k%len]-l[(i+1)%len]));
            if(dis>maxn) maxn=dis;
        }
    }
    else maxn=norm(l[1]-l[0]);
    return maxn;
}

Point intersectL(Segment a, Segment b)//??´?????????
{
    double x1=a.p1.x,y1=a.p1.y,x2=a.p2.x,y2=a.p2.y;
    double x3=b.p1.x,y3=b.p1.y,x4=b.p2.x,y4=b.p2.y;
    double k1=(x4-x3)*(y2-y1),k2=(x2-x1)*(y4-y3);
    double ans_x=(k1*x1-k2*x3+(y3-y1)*(x2-x1)*(x4-x3))/(k1-k2);
    double ans_y=(k2*y1-k1*y3+(x3-x1)*(y2-y1)*(y4-y3))/(k2-k1);
    return Point(ans_x,ans_y);
}

Circle CircumscribedCircle(Point a, Point b, Point c)//?????\???
{
    double x=0.5*(norm(b)*c.y+norm(c)*a.y+norm(a)*b.y-norm(b)*a.y-norm(c)*b.y-norm(a)*c.y)
             /(b.x*c.y+c.x*a.y+a.x*b.y-b.x*a.y-c.x*b.y-a.x*c.y);
    double y=0.5*(norm(b)*a.x+norm(c)*b.x+norm(a)*c.x-norm(b)*c.x-norm(c)*a.x-norm(a)*b.x)
             /(b.x*c.y+c.x*a.y+a.x*b.y-b.x*a.y-c.x*b.y-a.x*c.y);
    Point O(x, y);
    double r=abs(O-a);
    Circle m(O, r);
    return m;
}

Circle InscribedCircle(Point a, Point b, Point c)//?????????
{
    double A=abs(b-c), B=abs(a-c), C=abs(a-b);
    double x=(A*a.x+B*b.x+C*c.x)/(A+B+C);
    double y=(A*a.y+B*b.y+C*c.y)/(A+B+C);
    Point O(x, y);
    Line l(a, b);
    double r=getDistanceLP(l, O);
    Circle m(O, r);
    return m;
}

Segment TangentLineThroughPoint(Circle m, Point p)
{
    Point c=m.c;
    double l=abs(c-p);
    double r=m.r;
    double k=(2*r*r-l*l+norm(p)-norm(c)-2*p.y*c.y+2*c.y*c.y)/(2*(p.y-c.y));
    double A=1+(p.x-c.x)*(p.x-c.x)/((p.y-c.y)*(p.y-c.y));
    double B=-(2*k*(p.x-c.x)/(p.y-c.y)+2*c.x);
    double C=c.x*c.x+k*k-r*r;
    double x1, x2, y1, y2;

    x1=(-B-sqrt(B*B-4*A*C))/(2*A);
    x2=(-B+sqrt(B*B-4*A*C))/(2*A);
    y1=(2*r*r-l*l+norm(p)-norm(c)-2*(p.x-c.x)*x1)/(2*(p.y-c.y));
    y2=(2*r*r-l*l+norm(p)-norm(c)-2*(p.x-c.x)*x2)/(2*(p.y-c.y));
    Point p1(x1, y1), p2(x2, y2);
    Segment L(p1, p2);
    return L;
}

double Angle(Vector a)
{
    Point p0(0.0, 0.0);
    Point p1(1.0, 0.0);
    Point p2(a.x, a.y);
    Vector b=p1;
    double ans=0;
    if(ccw(p0, p1, p2)==CW) ans=180-acos(dot(a, b)/(abs(a)*abs(b)))*180/acos(-1);
    else if(ccw(p0, p1, p2)==CCW) ans=acos(dot(a, b)/(abs(a)*abs(b)))*180/acos(-1);
    else ans=0;
    if(ans>=180) ans-=180;
    if(ans<0) ans+=180;
    return ans;
}

int CircleContain(Circle m, Point p)
{
    double r=m.r;
    double l=abs(p-m.c);
    if(r>l) return 2;
    if(r==l) return 1;
    if(r<l) return 0;
}

void CircleThroughAPointAndTangentToALineWithRadius(Point p, Line l, double r)
{
    Point m=project(l, p);
    if(abs(p-m)>2*r)
    {
        printf("[]\n");
    }
    else if(abs(p-m)==2*r)
    {
        Circle c((p+m)/2, r);
        printf("[(%.6lf,%.6lf)]\n", c.c.x, c.c.y);
    }
    else if(abs(p-m)<EPS)
    {
        Point m0(m.x+1, m.y);
        if(abs(m0-project(l, m0))<EPS) m0.y+=2;
        Point m1=project(l, m0);
        Circle c1(m-(m0-m1)/abs(m0-m1)*r, r);
        Circle c2(m+(m0-m1)/abs(m0-m1)*r, r);
        printf("[(%.6lf,%.6lf),(%.6lf,%.6lf)]\n", c1.c.x, c1.c.y, c2.c.x, c2.c.y);
    }
    else if(abs(p-m)<2*r)
    {
        double s=abs(p-m);
        double d=sqrt(r*r-(r-s)*(r-s));
        Point m1, m2;
        m1=(m+(l.p1-l.p2)/abs(l.p1-l.p2)*d);
        m2=(m-(l.p1-l.p2)/abs(l.p1-l.p2)*d);
        Circle c1(m1+(p-m)/abs(p-m)*r, r);
        Circle c2(m2+(p-m)/abs(p-m)*r, r);
        printf("[(%.6lf,%.6lf),(%.6lf,%.6lf)]\n", c1.c.x, c1.c.y, c2.c.x, c2.c.y);
    }
    return ;
}

#define BOTTOM 0
#define LEFT 1
#define RIGHT 2
#define TOP 3

struct EndPoint
{
    Point p;
    int seg, st;
    EndPoint(Point p = Point(0.0, 0.0), int seg = 0, int st = 0):
        p{p}, seg(seg), st(st) {}
    bool operator < (const EndPoint &ep) const
    {
        return (p.y == ep.p.y) ? (st < ep.st) : (p.y < ep.p.y);
    }
};
EndPoint EP[2 * 100000];
int manhattanIntersection(vector<Segment> S)
{
    int n = S.size();
    int k = -1;
    for(int i=0; i<n; i++)
    {
        if((S[i].p1.y == S[i].p2.y && S[i].p1.x > S[i].p2.x) || (S[i].p1.y > S[i].p2.y))
            swap(S[i].p1, S[i].p2);
        if(S[i].p1.y == S[i].p2.y)
        {
            EP[++k] = EndPoint(S[i].p1, i, LEFT);
            EP[++k] = EndPoint(S[i].p2, i, RIGHT);
        }
        else
        {
            EP[++k] = EndPoint(S[i].p1, i, BOTTOM);
            EP[++k] = EndPoint(S[i].p2, i, TOP);
        }
    }
    sort(EP, EP + (2 * n));
    set<int> BT;
    BT.insert(1000000001);
    int cnt = 0;
    for(int i=0; i<2*n; i++)
    {
        if (EP[i].st == TOP) BT.erase(EP[i].p.x);
        else if (EP[i].st == BOTTOM) BT.insert(EP[i].p.x);
        else if (EP[i].st == LEFT)
        {
            set<int>::iterator b = BT.lower_bound(S[EP[i].seg].p1.x);
            set<int>::iterator e = BT.upper_bound(S[EP[i].seg].p2.x);
            cnt += distance(b, e);
        }
    }
    return cnt;
}

int main()
{
    int T;
    scanf("%d", &T);
    vector<Segment> S;
    while(T--)
    {
        Segment L;
        scanf("%lf%lf%lf%lf", &L.p1.x, &L.p1.y, &L.p2.x, &L.p2.y);
        S.push_back(L);
    }
    printf("%d\n", manhattanIntersection(S));
    return 0;
}