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 <bits/stdc++.h>

#define EPS (1e-10)
#define rep(i, a, b) for (int i = a; i < (int)(b); ++i)
#define rrep(i, a, b) for (int i = b - 1; i >= (int)(a); --i)

using namespace std;
using ll = long long;
using vi = vector<int>;
using vll = vector<ll>;
using vd = vector<double>;
using vvi = vector<vi>;

constexpr int MOD = 1000000007;

struct Point {
    double x, y;
    Point(double x = 0, double y = 0) : x(x), y(y) {}
    Point(const Point& p) : x(p.x), y(p.y) {}

    Point operator+(const Point& p) const { return Point(x + p.x, y + p.y); }
    Point operator-(const Point& p) const { return Point(x - p.x, y - p.y); }
    Point operator*(double k) const { return Point(k * x, k * y); }
    Point operator/(double k) const { return Point(x / k, y / k); }

    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; }

    static double norm(const Point& p) { return sqrt(p.x * p.x + p.y * p.y); }
    static double dot(const Point& p1, const Point& p2) { return p1.x * p2.x + p1.y * p2.y; }
    static double cross(const Point& p1, const Point& p2) { return p1.x * p2.y - p1.y * p2.x; }
};

struct Segment {
    Point s, t;
    Segment(const Point& s, const Point& t) : s(s), t(t) {}
    Segment(const Segment& seg) : s(seg.s), t(seg.t) {}
};

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

struct EndPoint {
    int id;
    Point p;
    int type;

    EndPoint(int id, const Point p, int type) : id(id), p(p), type(type) {}
    EndPoint(const EndPoint& ep) : id(ep.id), p(ep.p), type(ep.type) {}
};

bool less_y(const EndPoint& ep1, const EndPoint& ep2) {
    return ep1.p.y != ep2.p.y ? ep1.p.y < ep2.p.y : ep1.type < ep2.type;
}

int sweep(vector<EndPoint> EPs, const vector<Segment>& segs) {
    // Sort EPs.
    sort(EPs.begin(), EPs.end(), less_y);

    // Initialize binary tree.
    set<int> tree;
    tree.insert(INT_MAX);

    int sum = 0;
    for (EndPoint ep : EPs) {
        if (ep.type == TOP) {
            // Upper point of vertical line.
            tree.erase(ep.p.x);
        } else if (ep.type == BOTTOM) {
            // Lower point of vertical line.
            tree.insert(ep.p.x);
        } else if (ep.type == LEFT) {
            // Left point of horizontal line.
            int s = segs[ep.id].s.x;
            int t = segs[ep.id].t.x;
            auto s_itr = tree.lower_bound(s);
            auto t_itr = tree.upper_bound(t);
            sum += distance(s_itr, t_itr);
        }
    }
    return sum;
}

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

    int n;
    cin >> n;

    vector<EndPoint> EPs;
    vector<Segment> segs;

    rep(i, 0, n) {
        int x1, y1, x2, y2;
        cin >> x1 >> y1 >> x2 >> y2;

        if (x1 == x2) {
            Point s(x1, min(y1, y2));
            Point t(x2, max(y1, y2));
            EPs.emplace_back(i, s, BOTTOM);
            EPs.emplace_back(i, t, TOP);
            segs.emplace_back(s, t);
        } else {
            Point s(min(x1, x2), y1);
            Point t(max(x1, x2), y2);
            EPs.emplace_back(i, s, LEFT);
            EPs.emplace_back(i, t, RIGHT);
            segs.emplace_back(s, t);
        }
    }

    cout << sweep(EPs, segs) << endl;

    return 0;
}
