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 <utility>
#include <vector>
#include <complex>
#include <cmath>
#include <algorithm>
#include <set>

using namespace std;

static const double EPS=1e-12;
static const double INF=1e24;

using Point=complex<double>;
using Plane=vector<Point>;
using Polygon=vector<Point>;

bool operator<(const Point &a, const Point &b) {
    return real(a)!=real(b)? real(a)<real(b) : imag(a)<imag(b);
}

double cross_prod(const Point &a, const Point &b) {
    return imag(conj(a)*b);
}

double dot_prod(const Point &a, const Point &b) {
    return real(conj(a)*b);
}

struct LineSeg: public pair<Point, Point> {
    LineSeg() {}
    LineSeg(const Point &a, const Point &b) {
        first = a;
        second = b;
    }
};

enum PointType {
    BOTTOM,
    LEFT,
    RIGHT,
    TOP,
};

struct EndPoint {
    Point p;
    size_t seg;
    PointType type;
    EndPoint() {}
    EndPoint(Point p, size_t s, PointType t): p(p), seg(s), type(t) {}
    bool operator<(const EndPoint &rhs) const {
        return imag(p)!=imag(rhs.p)? imag(p)<imag(rhs.p) : type<rhs.type;
    }
};

size_t num_mintersect(vector<LineSeg> g) {
    size_t V=g.size();

    vector<EndPoint> h;
    for (size_t i=0; i<V; ++i) {
        if (imag(g[i].first) == imag(g[i].second)) {
            if (real(g[i].first) > real(g[i].second))
                swap(g[i].first, g[i].second);
        } else if (imag(g[i].first) > imag(g[i].second)) {
            swap(g[i].first, g[i].second);
        }

        if (imag(g[i].first) == imag(g[i].second)) {
            h.push_back(EndPoint(g[i].first, i, LEFT));
            h.push_back(EndPoint(g[i].second, i, RIGHT));
        } else {
            h.push_back(EndPoint(g[i].first, i, BOTTOM));
            h.push_back(EndPoint(g[i].second, i, TOP));
        }
    }
    sort(h.begin(), h.end());

    set<double> vlines;
    vlines.insert(INF);

    size_t count=0;
    for (size_t i=0; i<(V<<1); ++i) {
        if (h[i].type == TOP) {
            vlines.erase(real(h[i].p));
        } else if (h[i].type == BOTTOM) {
            vlines.insert(real(h[i].p));
        } else if (h[i].type == LEFT) {
            set<double>::iterator lb=lower_bound(
                vlines.begin(), vlines.end(), real(g[h[i].seg].first)
            );
            set<double>::iterator ub=upper_bound(
                vlines.begin(), vlines.end(), real(g[h[i].seg].second)
            );
            count += distance(lb, ub);
        }
    }

    return count;
}

int main() {
    size_t n;
    scanf("%zu", &n);

    vector<LineSeg> g(n);
    for (size_t i=0; i<n; ++i) {
        double x, y;
        scanf("%lf %lf", &x, &y);
        Point p1(x, y);

        scanf("%lf %lf", &x, &y);
        Point p2(x, y);

        g[i] = LineSeg(p1, p2);
    }

    printf("%zu\n", num_mintersect(g));
    return 0;
}