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<cstdlib>
#include<cstring>
#include<stack>
#include<algorithm>
#include<iostream>
#include<cmath>
#include<cassert>

#include<vector>
#include<queue>
#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.0, double y = 0.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);
        }

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

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

        bool operator == ( const Point &p) const
        {
            return fabs(x - p.x) < EPS && fabs(y -p.y) < EPS;
        }

        // -----▲▲▲ 演算子のオーバーロード ▲▲▲-----

        // 2点間の距離の算出
        double distance()
        {
            return sqrt( norm() );
        }

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

// 線分を表すクラス
class Segment
{
    public:
        Point p1, p2;
        // コンストラクタ
        Segment(Point p1, Point p2) : p1(p1), p2(p2){ }
};

// 端点の種類
#define BOTTOM 0
#define LEFT 1
#define RIGHT 2
#define TOP 3

class EndPoint
{
    public :
        Point p;
        // 入力線分のID, 端点の種類
        int seg, st;

        EndPoint() {}
        EndPoint(Point p, int seg, int st) : p(p), seg(seg), st(st) {}

        bool operator < (const EndPoint &ep) const
        {
            // y座標が小さい順に整列
            if( p.y == ep.p.y )
            {
                // yが同一の場合は, 下端点(BOTTOM), 左端点(LEFT), 右端点(RIGHT), 上端点(TOP)の順に並べる
                return st < ep.st;
            }
            else
            {
                return p.y < ep.p.y;
            }
        }
};

// 端点のリスト
EndPoint EP[2 * 100000];
//EndPoint EP[2 * 100];

// 線分交差問題　：　マンハッタン幾何
int manhattanIntersection(vector<Segment> S)
{
    int n = S.size();

    for(int i = 0, k = 0; i < n; i++)
    {
        // ---▼▼▼ 端点 p1, p2 が左下を基準に並ぶように調整 ▼▼▼---

        if( S[i].p1.y == S[i].p2.y )
        {
            // X軸に平行な線分の時
            if( S[i].p1.x > S[i].p2.x )
            {
                swap(S[i].p1, S[i].p2);
            }
        }
        else if( S[i].p1.y > S[i].p2.y )
        {
            swap(S[i].p1, S[i].p2);
        }

        // ---▲▲▲ 端点 p1, p2 が左下を基準に並ぶように調整 ▲▲▲---

        if( S[i].p1.y == S[i].p2.y )
        {
            // 水平成分を端点リストに追加 (X軸に平行)
            EP[k++] = EndPoint(S[i].p1, i, LEFT);
            EP[k++] = EndPoint(S[i].p2, i, RIGHT);
        }
        else
        {
            // 垂直成分を端点リストに追加 (Y軸に平行)
            EP[k++] = EndPoint(S[i].p1, i, BOTTOM);
            EP[k++] = EndPoint(S[i].p2, i, TOP);
        }
    }

    // 端点の y 座標に関して昇順に整列
    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 )
        {
            // 走査線とX軸に平行な線分が重なった時

            // O(log n) - X軸の左端の範囲の検索
            set<int>::iterator b = BT.lower_bound(S[EP[i].seg].p1.x);
            // O(log n) - X軸の右端の範囲の検索
            set<int>::iterator e = BT.upper_bound(S[EP[i].seg].p2.x);
            // b と e の距離(点の数)を加算, O(k)
            cnt += distance(b, e);
        }
    }

    return cnt;
}

int main(void)
{

    int n, count;
    Point start, end;
    vector<Segment> v_segment;

    cin >> n;

    for(int i = 0; i < n; i++)
    {
        cin >> start.x >> start.y >> end.x >> end.y;

        // 線分の集合を作成
        Segment seg(start, end);

        v_segment.push_back(seg);
    }

    // 結果の表示
    count = manhattanIntersection(v_segment);
    printf("%d\n", count);

    return 0;
}

