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 int long long
#define endl '\n'
#define FOR(i, a, n) for (int i = (a); i < (n); ++i)
#define REP(i, n) FOR(i, 0, n)
using namespace std;

using T = long double;
const T EPS = 1e-10;
const T PI = acos(-1.0);
T torad(int deg) {return (T)(deg) * PI / 180;}
T todeg(T ang) {return ang * 180 / PI;}

/* Point */
using P = complex<T>;
#define x real()
#define y imag()
template <typename T> inline bool eq(T p, T q) { return abs(p - q) < EPS; }
inline int sgn(T x) { return (0.0 < x) - (x < 0.0); }
inline T dot(P v, P w) { return (conj(v) * w).x; }
inline T cross(P v, P w) { return (conj(v) * w).y; }
inline bool isOrth(P v, P w) { return dot(v, w) == 0; }
inline bool isPara(P v, P w) { return cross(v, w) == 0; }
inline P unit(P v) { return v / abs(v); }
inline P translate(P p, P v) { return p + v; }
inline P scale(P p, P c, T k) { return c + (p - c) * k; }
inline P rot(P p, T a) { return p * polar(T(1), a); }
inline P rot90(P p) { return {-p.y, p.x}; }
inline T orient(P a, P b, P c) { return cross(b - a, c - a); }
istream& operator>>(istream& is, P& p) { T xx, yy; is >> xx >> yy; p = P(xx, yy); return is; }
bool cmpX(const P& a, const P& b) { return a.x != b.x ? a.x < b.x : a.y < b.y; }
bool cmpY(const P& a, const P& b) { return a.y != b.y ? a.y < b.y : a.x < b.x; }
namespace std {
    bool operator < (const P& a, const P& b) { return cmpX(a, b); }
}

P linearTransform(P p, P q, P fp, P fq, P r) {
    return fp + (r - p) * (fq - fp) / (q - p);
}

int ccw(P a, P b, P c) {
    b -= a; c -= a;
    if (cross(b, c) > EPS) return +1;      // counter clockwise
    if (cross(b, c) < -EPS) return -1;      // clockwise
    if (dot(b, c) < -EPS) return +2;        // c--a--b on line
    if (norm(b) < norm(c) - EPS) return -2;    // a--b--c on line or a==b
    return 0;                            // a--c--b on line or a==c or b==c
}

T angle(P v, P w) {
    T cosTheta = dot(v, w) / abs(v) / abs(w);
    return acos(max(T(-1.0), min(T(1.0), cosTheta)));
}
T orientedAngle(P a, P b, P c) {
    if (orient(a, b, c) >= 0) return angle(b - a, c - a);
    return 2 * PI - angle(b - a, c - a);
}
bool inAngle(P a, P b, P c, P p) {
    assert(abs(orient(a, b, c)) != 0);
    if (orient(a, b, c) < 0) swap(b, c);
    return orient(a, b, p) >= 0 && orient(a, c, p) <= 0;
}

// polar sort
bool half(P p) {
    assert(p.x != 0 || p.y != 0);
    return p.y > 0 || (p.y == 0 && p.x < 0);
}
void polarSort(vector<P>& v, P o = P(0.0, 0.0)) {
    sort(v.begin(), v.end(), [&](P v, P w) {
        return make_tuple(half(v - o), 0, norm(v - o)) <
            make_tuple(half(w - o), cross(v - o, w - o), norm(w - o));
    });
}

/* Line */
struct L : array<P, 2> {
    P v; T c;
    L(P a = P(0.0, 0.0), P b = P(0.0, 0.0)) : array<P, 2>({a, b}), v(b - a), c(cross(v, a)) {}
    T side(P p) { return cross(v, p) - c; }
    P proj(P p) { return p - rot90(v) * side(p) / norm(v); }
    P refl(P p) { return p - rot90(v) * T(2) * side(p) / norm(v); }
    friend istream& operator>>(istream& is, L& l) { P p, q; is >> p >> q; l = L(p, q); return is; }
    friend ostream& operator<<(ostream& os, const L& l) { return os << '{' << l[0] << ", " << l[1] << '}'; }
};

struct EndPoint {
    P p;
    int seg, st;
    EndPoint() {}
    EndPoint(P p, int seg, int st) : 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);
    }
};
int manhattanIntersection(vector<L> s, const T INF = numeric_limits<T>::max()) {
    const int BTM = 0;
    const int LFT = 1;
    const int RGH = 2;
    const int TOP = 3;

    int n = s.size();
    vector<EndPoint> ep;
    for (int i = 0; i < n; ++i) {
        if (s[i][0].y == s[i][1].y) {
            if (s[i][0].x > s[i][1].x) {
                swap(s[i][0], s[i][1]);
            }
        } else if (s[i][0].y > s[i][1].y) {
            swap(s[i][0], s[i][1]);
        }

        if (s[i][0].y == s[i][1].y) {
            ep.emplace_back(s[i][0], i, LFT);
            ep.emplace_back(s[i][1], i, RGH);
        } else {
            ep.emplace_back(s[i][0], i, BTM);
            ep.emplace_back(s[i][1], i, TOP);
        }
    }
    sort(ep.begin(), ep.end());
    set<T> bt;
    bt.insert(INF);
    int res = 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 == BTM) {
            bt.insert(ep[i].p.x);
        } else if (ep[i].st == LFT) {
            auto b = bt.lower_bound(s[ep[i].seg][0].x);
            auto e = bt.upper_bound(s[ep[i].seg][1].x);
            res += distance(b, e);
        }
    }
    return res;
}

signed main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    cout << fixed << setprecision(10);

    int n;
    cin >> n;
    vector<L> ls(n);
    REP (i, n) cin >> ls[i];
    cout << manhattanIntersection(ls) << endl;
}
