#include<cstdio>
#include<vector>
#include<algorithm>
#include<utility>
#include<numeric>
#include<iostream>
#include<array>
#include<string>
#include<sstream>
#include<stack>
#include<queue>
#include<list>
#include<functional>
#include<set>
#include<complex>
#include<complex>
#define _USE_MATH_DEFINES

#include<math.h>
#include<map>

#define INF 200000000

using namespace std;

typedef long long ll;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
typedef pair<ll, int> pli;
typedef pair<double, double> pdd;

enum
{
	BOTTOM,
	LEFT,
	RIGHT,
	TOP
};

struct P
{
	double x, y;
	P(double x,double y) :x(x), y(y) {}
	P() :P(0, 0) {}
	P operator+(const P& v)const
	{
		return P(x + v.x, y + v.y);
	}
	P operator-(const P& v)const
	{
		return P(x - v.x, y - v.y);
	}
	P operator*(const double v)const
	{
		return P(x*v, y*v);
	}
	bool operator==(const P& v)const
	{
		return abs(x - v.x) <= 0.0000000000001&&abs(y - v.y) <= 0.00000000000001;
	}
	bool operator!=(const P& v)const
	{
		return abs(x - v.x) > 0.0000000000001 || abs(y - v.y) > 0.00000000000001;
	}

	double dot(const P& v)const
	{
		return x*v.x + y*v.y;
	}
	double cross(const P& v)const
	{
		return x*v.y - y*v.x;
	}
	double length()const
	{
		return sqrt(x*x + y*y);
	}
	double length2()const
	{
		return (x*x + y*y);
	}
	
	bool operator<(const P& v)const
	{
		return x<v.x || (x == v.x) && y < v.y;
	}
	bool operator>(const P& v)const
	{
		return x>v.x || (x == v.x) && y > v.y;
	}
};

struct Segment
{
	P p1, p2;
	Segment(P p1,P p2):p1(p1),p2(p2){}
	Segment():Segment(P(0,0),P(0,0)){}
};

struct EndPoint
{
	P p;
	int idx, type;
	EndPoint(P p,int idx,int type):p(p),idx(idx),type(type){}
	EndPoint() :EndPoint(P(0, 0), -1, -1){}

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

Segment segments[100000];
EndPoint eps[200000];

int CalcIntersection(int n)
{
	for (int i = 0, k = 0; i < n; i++)
	{
		if (segments[i].p1.x == segments[i].p2.x)
		{
			if (segments[i].p1.y>segments[i].p2.y)
			{
				swap(segments[i].p1, segments[i].p2);
			}
		}
		else
		{
			if (segments[i].p1.x>segments[i].p2.x)
			{
				swap(segments[i].p1, segments[i].p2);
			}
		}

		if (segments[i].p1.x == segments[i].p2.x)
		{
			eps[k++] = EndPoint(segments[i].p1, i, BOTTOM);
			eps[k++] = EndPoint(segments[i].p2, i, TOP);
		}
		else
		{
			eps[k++] = EndPoint(segments[i].p1, i, LEFT);
			eps[k++] = EndPoint(segments[i].p2, i, RIGHT);
		}
	}

	sort(eps, eps + (2 * n));

	set<int> BT;
	BT.insert(1000000001);
	int count = 0;

	for (int i = 0; i < (2 * n); i++)
	{
		if (eps[i].type == TOP)
		{
			BT.erase(eps[i].p.x);
		}
		else if (eps[i].type == BOTTOM)
		{
			BT.insert(eps[i].p.x);
		}
		else if (eps[i].type == LEFT)
		{
			auto l = lower_bound(BT.begin(), BT.end(), segments[eps[i].idx].p1.x);
			auto u = upper_bound(BT.begin(), BT.end(), segments[eps[i].idx].p2.x);
			count += distance(l, u);
		}
	}

	return count;
}

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

	int n;
	cin >> n;

	for (int i = 0; i < n; i++)
	{
		double x1, y1, x2, y2;
		cin >> x1 >> y1 >> x2 >> y2;
		segments[i] = Segment(P(x1, y1), P(x2, y2));
	}

	printf("%d\n", CalcIntersection(n));

	return 0;
}


Measured memory_bytes: 14152