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
/*
  ????????????????????????????????????????????????
  ??????????????????????????????????????????????????????????????????????????????????????¨??????????????°????±???????
  ??¢?????´?????????????????¢??°?????? O(n log n)
 */
#include <bits/stdc++.h>

using namespace std;

struct Point {
    int x, y;
    Point(int x, int y) : x(x), y(y) {}
    Point() {}
};
/**
 * Line in two dimensional
 */
class Line : public std::array<Point, 2> {
public:
    Line() {}
    Line(const Point &p1, const Point &p2) {
        (*this)[0] = p1;
        (*this)[1] = p2;
    }
};
// Input of a line
std::istream& operator>>(std::istream &is, Line &l) {
    return is >> l[0].x >> l[0].y >> l[1].x >> l[1].y;
}
/**
 * Segment in two dimensional
 */
class Segment : public Line {
public:
    Segment() {}
    Segment(const Point &p1, const Point &p2) : Line(p1, p2) {}
};

enum SegmentType {
    BOTTOM, LEFT, RIGHT, TOP,
};
struct EndPoint {
    Point p;
    int id;
    SegmentType type;
    EndPoint(Point p, int id, SegmentType type) : p(p), id(id), type(type) {}
    EndPoint() {}

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


int SegmentIntersectionManhattan(vector<Segment> &segs) {
    const int n = segs.size();
    int MAX_X = 0;
    vector<EndPoint> event(2 * n);

    for (int i = 0, k = 0; i < n; ++i) {
        if (segs[i][0].y > segs[i][1].y ||
            (segs[i][0].y == segs[i][1].y && segs[i][0].x > segs[i][1].x))
            swap(segs[i][0], segs[i][1]);


        if (segs[i][0].y == segs[i][1].y) { // horizontal segment
            event[k++] = EndPoint(segs[i][0], i, LEFT);
            event[k++] = EndPoint(segs[i][1], i, RIGHT);
        }
        else { // vertical setment
            event[k++] = EndPoint(segs[i][0], i, BOTTOM);
            event[k++] = EndPoint(segs[i][1], i, TOP);
        }

        MAX_X = max({MAX_X, segs[i][0].x, segs[i][1].x});
    }

    sort(event.begin(), event.end());

    set<int> bt; // binary search tree
    bt.insert(MAX_X + 1); // sentinel
    int cnt = 0;

    for (int i = 0; i < 2 * n; ++i) {
        if (event[i].type == TOP)
            bt.erase(event[i].p.x);
        else if (event[i].type == BOTTOM)
            bt.insert(event[i].p.x);
        else if (event[i].type == LEFT) {
            auto lb = lower_bound(bt.begin(), bt.end(), segs[event[i].id][0].x);
            auto ub = upper_bound(bt.begin(), bt.end(), segs[event[i].id][1].x);

            cnt += distance(lb, ub);
        }
    }

    return cnt;
}

int main()
{
    cin.tie(0);
    ios::sync_with_stdio(false);

    int n;

    cin >> n;
    vector<Segment> segs(n);
    for (int i = 0; i < n; ++i)
        cin >> segs[i];

    cout << SegmentIntersectionManhattan(segs) << endl;

    return 0;
}