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
#define _CRT_SECURE_NO_WARNINGS
#define _USE_MATH_DEFINES
#include <iostream>
#include <cstdio>
#include <math.h>
#include <algorithm>
#include <vector>
#include <set>
const double EPS = 1e-9;
using namespace std;
class point {
public:
	double x, y;
	point(double a, double b) {
		x = a; y = b;
	}
	point operator - (point v) {
		return point(x - v.x, y - v.y);
	}
	point operator + (point v) {
		return point(x + v.x, y + v.y);
	}
};
class segment {
public:
	point p1, p2;
	segment(point p1, point p2) :p1(p1), p2(p2) {};
};
class Vector {
public:

	double x, y;
	Vector(double a, double  b) {
		x = a;
		y = b;
	};
	Vector operator * (const Vector &v)const {
		return Vector(x*v.x, y* v.y);
	}
	Vector operator * (double a) {
		return Vector(x * a, y * a);
	}
	Vector operator - (Vector v) {
		return Vector(x - v.x, y - v.y);
	}
	Vector operator + (Vector v) {
		return Vector(x + v.x, y + v.y);
	}
};
typedef vector<Vector> polygon;
class circle {
public:
	point p;
	double r;
	circle(point a, double b) : p(a), r(b) {};

};
inline double dot(Vector v1, Vector v2) {
	return v1.x*v2.x + v1.y*v2.y;
}
inline double squ(Vector v) {
	return v.x*v.x + v.y*v.y;
}
inline double norm(Vector v) {
	return sqrt(squ(v));
}
inline void printv(Vector v) {
	printf("%.10f %.10f\n", v.x, v.y);
}
inline void printpp(pair<point, point> p) {
	printf("%.7f %.7f %.7f %.7f", p.first.x, p.first.y, p.second.x, p.second.y);
}
inline void printc(Vector v1, Vector v2) {
	printf("%.10f %.10f %.10f %.10f\n", v1.x, v1.y, v2.x, v2.y);
}
inline void printpg(polygon pg, int min) {
	cout << pg.size() << endl;
	for (int i = min; i < pg.size(); i++)
		//printf("%d %d\n", pg[i].x, pg[i].y);
		cout << pg[i].x << " " << pg[i].y << endl;
	for(int i = 0; i < min; i++) cout << pg[i].x << " " << pg[i].y << endl;
}
inline Vector pro(Vector base, Vector v, Vector be) {
	double a = dot(base, v) / squ(base);
	Vector v1 = base * a;
	return v1 + be;
}
inline Vector ref(Vector v, Vector be) {
	return (v - be)*2 + be;
}
inline double cross(Vector v1, Vector v2) {
	return v1.x*v2.y - v1.y*v2.x;
}
inline int ccw(Vector v1, Vector v2, Vector v3) {
	Vector a = v2 - v1;
	Vector b = v3 - v1;
	if (cross(a, b) < 0.0) return -1;
	else if (cross(a, b) > 0.0) return 1;
	else if (dot(a, b) < 0.0) return -2;
	else if (dot(a, b) > squ(a)) return 2;
	else return 0;
}
inline int inter(Vector v1, Vector v2, Vector v3, Vector v4) {
	return (ccw(v1, v2, v3) * ccw(v1, v2, v4) <= 0) && (ccw(v3, v4, v1) * ccw(v3, v4, v2) <= 0);
}
inline double disPP(Vector v1, Vector v2) {
	return norm(v2 - v1);
}
inline double disLP(Vector v1, Vector v2, Vector v3) {
	Vector a = v2 - v1;
	Vector b = v3 - v1;
	return fabs(cross(a, b) / norm(a));
}
inline double disSP(Vector v1, Vector v2, Vector v3) {
	Vector a = v2 - v1;
	Vector b = v3 - v1;
	Vector c = v1 - v2;
	Vector d = v3 - v2;
	if (dot(a, b) < 0.0) return disPP(v1, v3);
	else if (dot(c, d) < 0.0) return disPP(v2, v3);
	else return disLP(v1, v2, v3);
}
inline double disSS(Vector v1, Vector v2, Vector v3, Vector v4) {
	if (inter(v1, v2, v3, v4)) return 0;
	double a = disSP(v1, v2, v3);
	double b = disSP(v1, v2, v4);
	double c = disSP(v3, v4, v1);
	double d = disSP(v3, v4, v2);
	return min(min(a, b), min(c, d));
}
inline Vector getcross(Vector v1, Vector v2, Vector v3, Vector v4) {
	Vector v5 = pro(v2 - v1, v3 - v1, v1);
	Vector v6 = pro(v2 - v1, v4 - v1, v1);
	double a = disPP(v3, v5);
	double b = disPP(v4, v6);
	Vector vans = (v6 - v5)*a*(1 / (a + b)) + v5;
	return vans;

}
inline pair<Vector, Vector> getccl(double r, Vector o, Vector v1, Vector v2) {
	Vector ev = (v2 - v1)*(1 / norm(v2 - v1));
	Vector pr = pro(v2 - v1, o - v1, v1);
	double l = sqrt(r *r - squ(o - pr));
	Vector ans1 = ev * l + pr;
	Vector ans2 = pr - ev * l;
	if (ans1.x > ans2.x) swap(ans1, ans2);
	else if (ans1.x == ans2.x)
		if (ans1.y > ans2.y) swap(ans1, ans2);
	return make_pair(ans1, ans2);
}
inline pair<point, point> getccc(circle c1, circle c2) {
	Vector v1(c2.p.x - c1.p.x, c2.p.y - c1.p.y);
	double dis = norm(v1);
	double a = acos((dis*dis + c1.r*c1.r - c2.r*c2.r) / (2 * c1.r*dis));
	double b = atan2(c2.p.y - c1.p.y, c2.p.x - c1.p.x);
	point pa(c1.r*cos(a + b), c1.r*sin(a + b));
	point pb(c1.r*cos(b - a), c1.r*sin(b -a));
	point ans1(c1.p + pa);
	point ans2(c1.p + pb);
	if (ans1.x > ans2.x || ((ans1.x == ans2.x) && (ans1.y > ans2.y))) swap(ans1, ans2);
	return make_pair(ans1, ans2);
}
const int num = 100000;
inline bool lessX(const Vector &p1, const Vector &p2) {
	return (p1.x < p2.x) || ((p1.x == p2.x) && (p1.y < p2.y));
}
inline polygon getpg(polygon o) {
	sort(o.begin(), o.end(), lessX);
	polygon t, u;
	t.push_back(o[0]);
	t.push_back(o[1]);
	u.push_back(o[0]);
	u.push_back(o[1]);
	for (int i = 2; i < o.size(); i++) {
		for (int j = t.size(); (t.size() > 1) && (ccw(t[t.size() - 2], t[t.size() - 1], o[i]) == 1); j--)
			t.pop_back();
		t.push_back(o[i]);
	}
	for (int i = 2; i < o.size(); i++) {
		for (int j = u.size(); (u.size() > 1) && (ccw(u[u.size() - 2], u[u.size() - 1], o[i]) == -1); j--) {
			u.pop_back();
		}
		u.push_back(o[i]);
	}
	reverse(t.begin(), t.end());
	for (int i = 1; i < t.size() - 1; i++)
		u.push_back(t[i]);
	return u;
}
inline int cont(polygon pg, Vector p) {
	int x = 0;
	Vector v3(1, 1), v4(1, 1);
	for (int i = 0; i < pg.size(); i++) {
		Vector v1 = pg[i] - p;
		Vector v2 = pg[(i + 1)%pg.size()] - p;
		if (((cross(v1, v2) == 0) && (dot(v1, v2) < 0.0)) || norm(v1) == 0 || norm(v2) == 0) return 1;
		if (v1.y > v2.y) swap(v1, v2);
		if ((cross(v1, v2) > 0.0) && v1.y < EPS && v2.y > EPS) x++;
		if (v3.y = 0 && v4.y == 0 && (v1.y == 0 || v2.y == 0)) x--;
		v3 = v1;
		v4 = v2;
	}
	return (x % 2 == 0) ? 0 : 2;
}
const int B = 0, L = 1, R = 2, T = 3;
class endpoint {
public:
	int so, id;
	point p;
	endpoint(point p, int a, int b) :p(p), so(a), id(b) {};
	bool operator < (const endpoint &ep) const {
		if (p.y == ep.p.y) return so < ep.so;
		else return p.y < ep.p.y;
	}
};
vector<endpoint> ep;
inline int solve(vector<segment> s) {
	for (int i = 0; i < s.size(); i++) {
		if (s[i].p1.y > s[i].p2.y) swap(s[i].p1, s[i].p2);
		else if (s[i].p1.y == s[i].p2.y && s[i].p1.x > s[i].p2.x) swap(s[i].p1, s[i].p2);
	}
	for (int i = 0; i < s.size(); i++) {
		if (s[i].p1.y == s[i].p2.y) {
			ep.push_back(endpoint(s[i].p1, L, i));
			ep.push_back(endpoint(s[i].p2, R, i));
		}
		else {
			ep.push_back(endpoint(s[i].p1, B, i));
			ep.push_back(endpoint(s[i].p2, T, i));
		}
	}
	sort(ep.begin(),ep.end());
	set<double> st;
	int cnt = 0;
	st.insert(1000000001);
	for (int i = 0; i < ep.size(); i++) {
		if (ep[i].so == B) st.insert(ep[i].p.x);
		else if (ep[i].so == T) st.erase(ep[i].p.x);
		else if (ep[i].so == L) {
			set<double>::iterator b = lower_bound(st.begin(), st.end(), s[ep[i].id].p1.x);
			set<double>::iterator e = upper_bound(st.begin(), st.end(), s[ep[i].id].p2.x);
			cnt += distance(b, e);
		}
	}
	return cnt;
}
int main() {
	int n;
	vector<segment> s;
	double x0, y0, x1, y1;
	cin >> n;
	for (int i = 0; i < n; i++) {
		scanf("%lf%lf%lf%lf", &x0, &y0, &x1, &y1);
		s.push_back(segment(point(x0, y0), point(x1, y1)));
	}
	cout << solve(s) << endl;
	return 0;
}