#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
#include <queue>
#include <map>
#include <cmath>
#include <stack>
#include <unordered_map>

#define LL long long
#define ll long long
#define ull unsigned long long
#define ls l, mid, rt << 1
#define rs mid + 1, r, rt << 1 | 1
using namespace std;
const int maxn=5005;
struct Edge
{
	int x1, y1, x2, y2;
	Edge(int _x1, int _y1, int _x2, int _y2)
	{
		x1 = _x1; y1 = _y1; x2 = _x2; y2 = _y2;
	}
};
vector<Edge>e1, e2, tmp;
bool cmp1(Edge a, Edge b)
{
	return a.x1 < b.x1;
}
bool cmp2(Edge a, Edge b)
{
	return a.y1 < b.y1;
}
bool cmp3(Edge a, Edge b)
{
	return a.y2 < b.y2;
}
int tr[40010];
int lowbit(int x)
{
	return x & (-x);
}
void update(int x)
{
	for(; x <= 10005; x += lowbit(x))
		tr[x] += 1;
}
int query(int x)
{
	int ans = 0;
	for(; x; x -= lowbit(x))
		ans += tr[x];
	return ans;
}
int main()
{
	int n;
	scanf("%d", &n);
	while(n --)
	{
		int x1, x2, y1, y2;
		scanf("%d %d %d %d", &x1, &y1, &x2, &y2);
		x1 += 5002, y1 += 5002, x2 += 5002, y2 += 5002;
		if(x1 == x2)
		{
			if(y1 < y2)
				swap(y1, y2);
			e2.push_back(Edge(x1, y1, x2, y2));
		}
		else
		{
			if(x1 > x2)
				swap(x1, x2);
			e1.push_back(Edge(x1, y1, x2, y2));
		}
	}
	sort(e1.begin(), e1.end(), cmp2);
	LL ans = 0;
	sort(e2.begin(), e2.end(), cmp1);
	int siz1 = e1.size(), siz2 = e2.size();
	for(int i = 1; i < siz1; i ++)
	{
		for(int j = 0; j < siz2; j ++)
		{
			if(e2[j].x1 >= e1[i].x1 && e2[j].x2 <= e1[i].x2 && e2[j].y1 >= e1[i].y1 && e2[j].y2 <= e1[i].y2)
			{
				tmp.push_back(e2[j]);
			}
		}
		sort(tmp.begin(), tmp.end(), cmp3);

		int sizz = tmp.size();
		int st = 0;
		for(int j = 0; j < i; j ++)
		{
			//cout << e1[j].x1 << " " << e1[j].y1 << " " << e1[j].x2 << " " << e1[j].y2 << endl;
			while(tmp[st].y2 <= e1[j].y1 && st < sizz)
			{
				//cout << tmp[st].x1 << endl;
				update(tmp[st].x1);
				st ++;
			}
			//cout << e1[j].y1 << " " << e1[j].y2 << endl;
			//cout << query(e1[j].y2) << " " << query(e1[j].y1 - 1) << endl;
			int temp = query(e1[j].x2) - query(e1[j].x1 - 1);
			ans += 1LL * temp * (temp - 1) / 2;
		}
		tmp.clear();
		memset(tr, 0, sizeof(tr));
		//cout << ans << endl;
	}
	cout << ans << endl;
	return 0;
}


#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
#include <queue>
#include <map>
#include <cmath>
#include <stack>
#include <unordered_map>

#define LL long long
#define ll long long
#define ull unsigned long long
#define ls l, mid, rt << 1
#define rs mid + 1, r, rt << 1 | 1
using namespace std;
const int maxn=5005;
struct Edge
{
	int x1, y1, x2, y2;
	Edge(int _x1, int _y1, int _x2, int _y2)
	{
		x1 = _x1; y1 = _y1; x2 = _x2; y2 = _y2;
	}
};
vector<Edge>e1, e2, tmp;
bool cmp1(Edge a, Edge b)
{
	return a.x1 < b.x1;
}
bool cmp2(Edge a, Edge b)
{
	return a.y1 < b.y1;
}
bool cmp3(Edge a, Edge b)
{
	return a.y2 < b.y2;
}
int tr[40010];
int lowbit(int x)
{
	return x & (-x);
}
void update(int x)
{
	for(; x <= 10005; x += lowbit(x))
		tr[x] += 1;
}
int query(int x)
{
	int ans = 0;
	for(; x; x -= lowbit(x))
		ans += tr[x];
	return ans;
}
int main()
{
	int n;
	scanf("%d", &n);
	while(n --)
	{
		int x1, x2, y1, y2;
		scanf("%d %d %d %d", &x1, &y1, &x2, &y2);
		x1 += 5002, y1 += 5002, x2 += 5002, y2 += 5002;
		if(x1 == x2)
		{
			if(y1 < y2)
				swap(y1, y2);
			e2.push_back(Edge(x1, y1, x2, y2));
		}
		else
		{
			if(x1 > x2)
				swap(x1, x2);
			e1.push_back(Edge(x1, y1, x2, y2));
		}
	}
	sort(e1.begin(), e1.end(), cmp2);
	LL ans = 0;
	sort(e2.begin(), e2.end(), cmp1);
	int siz1 = e1.size(), siz2 = e2.size();
	for(int i = 1; i < siz1; i ++)
	{
		for(int j = 0; j < siz2; j ++)
		{
			if(e2[j].x1 >= e1[i].x1 && e2[j].x2 <= e1[i].x2 && e2[j].y1 >= e1[i].y1 && e2[j].y2 <= e1[i].y2)
			{
				tmp.push_back(e2[j]);
			}
		}
		sort(tmp.begin(), tmp.end(), cmp3);

		int sizz = tmp.size();
		int st = 0;
		for(int j = 0; j < i; j ++)
		{
			while(st < sizz && tmp[st].y2 <= e1[j].y1)
			{
				update(tmp[st].x1);
				st ++;
			}
			int temp = query(e1[j].x2) - query(e1[j].x1 - 1);
			ans += 1LL * temp * (temp - 1) / 2;
		}
		tmp.clear();
		memset(tr, 0, sizeof(tr));
	}
	cout << ans << endl;
	return 0;
}


#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
#include <queue>
#include <map>
#include <cmath>
#include <stack>
#include <unordered_map>

#define LL long long
#define ll long long
#define ull unsigned long long
#define ls l, mid, rt << 1
#define rs mid + 1, r, rt << 1 | 1
using namespace std;
const int maxn=5005;
struct Edge
{
	int x1, y1, x2, y2;
	Edge(int _x1, int _y1, int _x2, int _y2)
	{
		x1 = _x1; y1 = _y1; x2 = _x2; y2 = _y2;
	}
};
vector<Edge>e1, e2, tmp;
bool cmp1(Edge a, Edge b)
{
	return a.x1 < b.x1;
}
bool cmp2(Edge a, Edge b)
{
	return a.y1 < b.y1;
}
bool cmp3(Edge a, Edge b)
{
	return a.y2 < b.y2;
}
int tr[20010];
int lowbit(int x)
{
	return x & (-x);
}
void update(int x)
{
	for(; x <= 10005; x += lowbit(x))
		tr[x] += 1;
}
int query(int x)
{
	int ans = 0;
	for(; x; x -= lowbit(x))
		ans += tr[x];
	return ans;
}
int main()
{
	int n;
	scanf("%d", &n);
	while(n --)
	{
		int x1, x2, y1, y2;
		scanf("%d %d %d %d", &x1, &y1, &x2, &y2);
		x1 += 5002, y1 += 5002, x2 += 5002, y2 += 5002;
		if(x1 == x2)
		{
			if(y1 < y2)
				swap(y1, y2);
			e2.push_back(Edge(x1, y1, x2, y2));
		}
		else
		{
			if(x1 > x2)
				swap(x1, x2);
			e1.push_back(Edge(x1, y1, x2, y2));
		}
	}
	sort(e1.begin(), e1.end(), cmp2);
	LL ans = 0;
	sort(e2.begin(), e2.end(), cmp1);
	int siz1 = e1.size(), siz2 = e2.size();
	for(int i = 1; i < siz1; i ++)
	{
		for(int j = 0; j < siz2; j ++)
		{
			if(e2[j].x1 >= e1[i].x1 && e2[j].x2 <= e1[i].x2 && e2[j].y1 >= e1[i].y1 && e2[j].y2 <= e1[i].y2)
			{
				tmp.push_back(e2[j]);
			}
		}
		sort(tmp.begin(), tmp.end(), cmp3);

		int sizz = tmp.size();
		int st = 0;
		for(int j = 0; j < i; j ++)
		{
			//cout << e1[j].x1 << " " << e1[j].y1 << " " << e1[j].x2 << " " << e1[j].y2 << endl;
			while(tmp[st].y2 <= e1[j].y1 && st < sizz)
			{
				//cout << tmp[st].x1 << endl;
				update(tmp[st].x1);
				st ++;
			}
			//cout << e1[j].y1 << " " << e1[j].y2 << endl;
			//cout << query(e1[j].y2) << " " << query(e1[j].y1 - 1) << endl;
			int temp = query(e1[j].x2) - query(e1[j].x1 - 1);
			ans += 1LL * temp * (temp - 1) / 2;
		}
		tmp.clear();
		memset(tr, 0, sizeof(tr));
		//cout << ans << endl;
	}
	cout << ans << endl;
	return 0;
}


#include<bits/stdc++.h>
#define endl '\n'
#define ll long long
using namespace std;

ll ft_a [10000+30];

ll getSum(ll BITree[], int index)
{
    ll sum = 0; // Iniialize result

    // index in BITree[] is 1 more than the index in arr[]
    index = index + 1;

    // Traverse ancestors of BITree[index]
    while (index>0)
    {
        // Add current element of BITree to sum
        sum += BITree[index];

        // Move index to parent node in getSum View
        index -= index & (-index);
    }
    return sum;
}

// Updates a node in Binary Index Tree (BITree) at given index
// in BITree. The given value 'val' is added to BITree[i] and
// all of its ancestors in tree.
void updateBIT(ll BITree[], int n, int index, ll val)
{
    // index in BITree[] is 1 more than the index in arr[]
    index = index + 1;

    // Traverse all ancestors and add 'val'
    while (index <= n)
    {
    // Add 'val' to current node of BI Tree
    BITree[index] += val;

    // Update index to that of parent in update View
    index += index & (-index);
    }
}

// Constructs and returns a Binary Indexed Tree for given
// array of size n.
ll *constructBITree(ll arr[], int n)
{
    // Create and initialize BITree[] as 0
    ll *BITree = new ll[n+1];
    for (int i=1; i<=n; i++)
        BITree[i] = 0;

    // Store the actual values in BITree[] using update()
    for (int i=0; i<n; i++)
        updateBIT(BITree, n, i, arr[i]);

    // Uncomment below lines to see contents of BITree[]
    //for (int i=1; i<=n; i++)
    //     cout << BITree[i] << " ";

    return BITree;
}

class event{

    public:
        int type;
        ll x1, x2, y;
        event(int type_c, ll y_c, ll x1_c, ll x2_c){
            type= type_c;
            x1 = x1_c;
            x2 = x2_c;
            y = y_c;
        }
        event(){}
    bool operator<(const event &e) const {
        if (y != e.y) return y < e.y;
        return type < e.type;

    }
}
;

int main()
{
    ll n;
    cin>>n;
    vector<pair<ll,pair<ll,ll>>> horizontal;
    vector<pair<ll,pair<ll,ll>>> vertical;
    for(int i = 0; i < n; ++i){
        ll x1, y1, x2, y2;
        cin>>x1>>y1>>x2>>y2;
        x1+=5003;
        x2+= 5003;
        if(x1>x2 || y1 > y2){
            swap(x1,x2);
            swap(y1,y2);
        }
        if(x1 == x2){
            vertical.push_back(make_pair(x1,make_pair(y1,y2)));
        }
        else{
            horizontal.push_back(make_pair(y1,make_pair(x1,x2)));
        }
    }
    if(vertical.size() <=1){
        cout<<0<<endl;
        return 0
    }
    sort(horizontal.begin(),horizontal.end());
    ll tot = 0;

    ll *BITree = new ll[10030+1];
    for (int i=1; i<=10030; i++)
        BITree[i] = 0;
    for( int i =0; i < horizontal.size(); ++i){

        ll y = horizontal[i].first;
        ll x1 = horizontal[i].second.first;
        ll x2 = horizontal[i].second.second;
        vector<event> evs(horizontal.size() - i);
        for(int j =0; j < vertical.size();++j)
            if(vertical[j].first >= x1 && vertical[j].first <= x2 && vertical[j].second.first <= y){
                updateBIT(BITree, 10030, vertical[j].first, 1);
                event e(1, vertical[j].second.second, vertical[j].first, vertical[j].first);
                evs.push_back(e);
            }
        for(int j = i+1; j < horizontal.size(); ++j){
            event e(0,horizontal[j].first, horizontal[j].second.first, horizontal[j].second.second);
            evs[j-i-1] = e;
        }
        sort(evs.begin(), evs.end());
        for(int j =0; j < evs.size(); ++j){
            event e = evs[j];
            if(e.type == 0){
                ll q = getSum(BITree, e.x2) - getSum(BITree, e.x1-1);
                tot+= q*(q-1ll)/2ll;
            }
            else if(e.type == 1){
                updateBIT(BITree, 10030, e.x1, -1);
            }
        }
    }

    cout<<tot<<endl;
    return 0;
}


#include<bits/stdc++.h>
#define endl '\n'
#define ll long long
using namespace std;

const int lim = 5000+10;
struct st {
    struct node {
        node *l, *r;
        int mx, lz;

        node() : l(0), r(0), mx(0), lz(0){}

        node* le(){
            if (l == nullptr){
                l = new node();
            }
            return l;
        }

        node* ri(){
            if (r == nullptr){
                r = new node();
            }
            return r;
        }

        void push(){
            le(); ri();

            if (lz){
                l->mx += lz;
                l->lz += lz;
                r->mx += lz;
                r->lz += lz;
                lz = 0;
            }
        }

        void fix(){
            mx = le()->mx + ri()->mx;
        }
    };

    node *root;

    st(){
        root = new node();
    }

    int update(int x, int y, int v){
        // cout << "[ " << x << " " << y << " " << v << endl;
        update(root, -lim, lim, x, y+1, v);
    }

    int update(node *u, int b, int e, int x, int y, int v){
        if (x <= b && e <= y){
            u->lz += v;
            u->mx += v;
        } else {
            int m = (b + e) >> 1;

            u->push();

            if (x < m) update(u->l, b, m, x, y, v);
            if (m < y) update(u->r, m, e, x, y, v);

            u->fix();
        }

        // cout << "UPDATE:" << b << " " << e << " " << x << " " << y << " " << v << " : " << u->mx << " " << u->lz << endl;
    }

    int query (int x, int y){
        return query(root, -lim, +lim, x, y+1);
    }
    int query( node *u, int b, int e, int x, int y){
        if (x <= b && e <= y){
            return u->mx;
        } else {
            int m = (b + e) >> 1;

            u->push();
            int a = 0; b = 0;
            if (x < m)
                a = query(u->l, b, m, x, y);
            if (m < y)
                b = query(u->r, m, e, x, y);
            return a + b;
        }
    }
};

class event{

    public:
        ll type;
        pair<ll,ll> id;
        ll x1, x2, y;
        ll pos = 0;
        event(ll type_c, ll y_c, ll x1_c, ll x2_c){
            type= type_c;
            x1 = x1_c;
            x2 = x2_c;
            y = y_c;
        }
    bool operator<(const event &e) const {
        if (y != e.y) return y < e.y;
        return type < e.type;

    }
}
;

int main()
{
    ll n;
    cin>>n;
    vector<pair<ll,pair<ll,ll>>> horizontal;
    vector<pair<ll,pair<ll,ll>>> vertical;
    for(int i = 0; i < n; ++i){
        ll x1, y1, x2, y2;
        cin>>x1>>y1>>x2>>y2;
        if(x1>x2 || y1 > y2){
            swap(x1,x2);
            swap(y1,y2);
        }
        if(x1 == x2){
            vertical.push_back(make_pair(x1,make_pair(y1,y2)));
        }
        else{
            horizontal.push_back(make_pair(y1,make_pair(x1,x2)));
        }
    }
    sort(horizontal.begin(),horizontal.end());
    ll tot = 0;
    for( int i =0; i < horizontal.size(); ++i){
        st pepe;
        ll y = horizontal[i].first;
        ll x1 = horizontal[i].second.first;
        ll x2 = horizontal[i].second.second;
        vector<event> evs;
        vector<pair<ll,pair<ll,ll>>> good;
        for(int j =0; j < vertical.size();++j)
            if(vertical[j].first >= x1 && vertical[j].first <= x2 && vertical[j].second.first <= y){
                pepe.update(vertical[j].first,vertical[j].first,1);
                good.push_back(vertical[j]);
            }
        for(int j = i+1; j < horizontal.size(); ++j){
            event e(0,horizontal[j].first, horizontal[j].second.first, horizontal[j].second.second);
            evs.push_back(e);
        }
        for(int j = 0; j < good.size();++j){
            event e(1, good[j].second.second, good[j].first, good[j].first);
            evs.push_back(e);
        }

        sort(evs.begin(), evs.end());
        for(int j =0; j < evs.size(); ++j){
            event e = evs[j];
            if(e.type == 0){
                ll q = pepe.query(e.x1, e.x2);
                tot+= q*(q-1)/2;
            }
            else if(e.type == 1){
                pepe.update(e.x1,e.x1,-1);
            }
        }
    }
    cout<<tot<<endl;
    return 0;
}


#include<bits/stdc++.h>
#define endl '\n'
#define ll long long
using namespace std;

ll ft_a [10000+30];

ll getSum(ll BITree[], int index)
{
    ll sum = 0; // Iniialize result

    // index in BITree[] is 1 more than the index in arr[]
    index = index + 1;

    // Traverse ancestors of BITree[index]
    while (index>0)
    {
        // Add current element of BITree to sum
        sum += BITree[index];

        // Move index to parent node in getSum View
        index -= index & (-index);
    }
    return sum;
}

// Updates a node in Binary Index Tree (BITree) at given index
// in BITree. The given value 'val' is added to BITree[i] and
// all of its ancestors in tree.
void updateBIT(ll BITree[], int n, int index, ll val)
{
    // index in BITree[] is 1 more than the index in arr[]
    index = index + 1;

    // Traverse all ancestors and add 'val'
    while (index <= n)
    {
    // Add 'val' to current node of BI Tree
    BITree[index] += val;

    // Update index to that of parent in update View
    index += index & (-index);
    }
}

// Constructs and returns a Binary Indexed Tree for given
// array of size n.
ll *constructBITree(ll arr[], int n)
{
    // Create and initialize BITree[] as 0
    ll *BITree = new ll[n+1];
    for (int i=1; i<=n; i++)
        BITree[i] = 0;

    // Store the actual values in BITree[] using update()
    for (int i=0; i<n; i++)
        updateBIT(BITree, n, i, arr[i]);

    // Uncomment below lines to see contents of BITree[]
    //for (int i=1; i<=n; i++)
    //     cout << BITree[i] << " ";

    return BITree;
}

class event{

    public:
        int type;
        ll x1, x2, y;
        event(int type_c, ll y_c, ll x1_c, ll x2_c){
            type= type_c;
            x1 = x1_c;
            x2 = x2_c;
            y = y_c;
        }
        event(){}
    bool operator<(const event &e) const {
        if (y != e.y) return y < e.y;
        return type < e.type;

    }
}
;

int main()
{
    ll n;
    cin>>n;
    vector<pair<ll,pair<ll,ll>>> horizontal;
    vector<pair<ll,pair<ll,ll>>> vertical;
    for(int i = 0; i < n; ++i){
        ll x1, y1, x2, y2;
        cin>>x1>>y1>>x2>>y2;
        x1+=5003;
        x2+= 5003;
        if(x1>x2 || y1 > y2){
            swap(x1,x2);
            swap(y1,y2);
        }
        if(x1 == x2){
            vertical.push_back(make_pair(x1,make_pair(y1,y2)));
        }
        else{
            horizontal.push_back(make_pair(y1,make_pair(x1,x2)));
        }
    }
    sort(horizontal.begin(),horizontal.end());
    ll tot = 0;

    ll *BITree = new ll[10030+1];
    for (int i=1; i<=10030; i++)
        BITree[i] = 0;
    for( int i =0; i < horizontal.size(); ++i){

        ll y = horizontal[i].first;
        ll x1 = horizontal[i].second.first;
        ll x2 = horizontal[i].second.second;
        vector<event> evs(n);
        for(int j =0; j < vertical.size();++j)
            if(vertical[j].first >= x1 && vertical[j].first <= x2 && vertical[j].second.first <= y){
                updateBIT(BITree, 10030, vertical[j].first, 1);
                event e(1, vertical[j].second.second, vertical[j].first, vertical[j].first);
                evs.push_back(e);
            }
        for(int j = i+1; j < horizontal.size(); ++j){
            event e(0,horizontal[j].first, horizontal[j].second.first, horizontal[j].second.second);
            evs[j-i-1] = e;
        }
        sort(evs.begin(), evs.end());
        for(int j =0; j < evs.size(); ++j){
            event e = evs[j];
            if(e.type == 0){
                ll q = getSum(BITree, e.x2) - getSum(BITree, e.x1-1);
                tot+= q*(q-1ll)/2ll;
            }
            else if(e.type == 1){
                updateBIT(BITree, 10030, e.x1, -1);
            }
        }
    }

    cout<<tot<<endl;
    return 0;
}


#include<bits/stdc++.h>
#define endl '\n'
#define ll long long
using namespace std;

const int lim = 5000 + 10;
struct st {
    struct node {
        node *l, *r;
        int mx, lz;

        node() : l(0), r(0), mx(0), lz(0){}

        node* le(){
            if (l == nullptr){
                l = new node();
            }
            return l;
        }

        node* ri(){
            if (r == nullptr){
                r = new node();
            }
            return r;
        }

        void push(){
            le(); ri();

            if (lz){
                l->mx += lz;
                l->lz += lz;
                r->mx += lz;
                r->lz += lz;
                lz = 0;
            }
        }

        void fix(){
            mx = le()->mx + ri()->mx;
        }
    };

    node *root;

    st(){
        root = new node();
    }

    int update(int x, int y, int v){
        // cout << "[ " << x << " " << y << " " << v << endl;
        update(root, -lim, lim, x, y+1, v);
    }

    int update(node *u, int b, int e, int x, int y, int v){
        if (x <= b && e <= y){
            u->lz += v;
            u->mx += v;
        } else {
            int m = (b + e) >> 1;

            u->push();

            if (x < m) update(u->l, b, m, x, y, v);
            if (m < y) update(u->r, m, e, x, y, v);

            u->fix();
        }

        // cout << "UPDATE:" << b << " " << e << " " << x << " " << y << " " << v << " : " << u->mx << " " << u->lz << endl;
    }

    int query (int x, int y){
        return query(root, -lim, +lim, x, y+1);
    }
    int query( node *u, int b, int e, int x, int y){
        if (x <= b && e <= y){
            return u->mx;
        } else {
            int m = (b + e) >> 1;

            u->push();
            int a = 0; b = 0;
            if (x < m)
                a = query(u->l, b, m, x, y);
            if (m < y)
                b = query(u->r, m, e, x, y);
            return a + b;
        }
    }
};

class event{

    public:
        int type;
        pair<int,int> id;
        int x1, x2, y;
        int pos = 0;
        event(int type_c, int y_c, int x1_c, int x2_c){
            type= type_c;
            x1 = x1_c;
            x2 = x2_c;
            y = y_c;
        }
    bool operator<(const event &e) const {
        if (y != e.y) return y < e.y;
        return type < e.type;

    }
}
;

int main()
{
    int n;
    cin>>n;
    vector<pair<int,pair<int,int>>> horizontal;
    vector<pair<int,pair<int,int>>> vertical;
    for(int i = 0; i < n; ++i){
        int x1, y1, x2, y2;
        cin>>x1>>y1>>x2>>y2;
        if(x1>x2 || y1 > y2){
            swap(x1,x2);
            swap(y1,y2);
        }
        if(x1 == x2){
            vertical.push_back(make_pair(x1,make_pair(y1,y2)));
        }
        else{
            horizontal.push_back(make_pair(y1,make_pair(x1,x2)));
        }
    }
    sort(horizontal.begin(),horizontal.end());
    int tot = 0;
    st pepe;
    for( int i =0; i < horizontal.size(); ++i){
        int y = horizontal[i].first;
        int x1 = horizontal[i].second.first;
        int x2 = horizontal[i].second.second;
        vector<event> evs;
        for(int j =0; j < vertical.size();++j)
            if(vertical[j].first >= x1 && vertical[j].first <= x2 && vertical[j].second.first <= y){
                pepe.update(vertical[j].first,vertical[j].first,1);
                event e(1, vertical[j].second.second, vertical[j].first, vertical[j].first);
                evs.push_back(e);
            }
        for(int j = i+1; j < horizontal.size(); ++j){
            event e(0,horizontal[j].first, horizontal[j].second.first, horizontal[j].second.second);
            evs.push_back(e);
        }
        sort(evs.begin(), evs.end());
        for(int j =0; j < evs.size(); ++j){
            event e = evs[j];
            if(e.type == 0){
                ll q = pepe.query(e.x1, e.x2);
                tot+= q*(q-1)/2;
            }
            else if(e.type == 1){
                pepe.update(e.x1,e.x1,-1);
            }
        }
    }
    cout<<tot<<endl;
    return 0;
}


#include<bits/stdc++.h>
#define endl '\n'
#define ll long long
using namespace std;

const int lim = 5000 + 10;
struct st {
    struct node {
        node *l, *r;
        int mx, lz;

        node() : l(0), r(0), mx(0), lz(0){}

        node* le(){
            if (l == nullptr){
                l = new node();
            }
            return l;
        }

        node* ri(){
            if (r == nullptr){
                r = new node();
            }
            return r;
        }

        void push(){
            le(); ri();

            if (lz){
                l->mx += lz;
                l->lz += lz;
                r->mx += lz;
                r->lz += lz;
                lz = 0;
            }
        }

        void fix(){
            mx = le()->mx + ri()->mx;
        }

    };

    node *root;

    st(){
        root = new node();
    }
    int best(){
        return root->mx;
    }
    int update(int x, int y, int v){
        // cout << "[ " << x << " " << y << " " << v << endl;
        update(root, -lim, lim, x, y+1, v);
    }

    int update(node *u, int b, int e, int x, int y, int v){
        if (x <= b && e <= y){
            u->lz += v;
            u->mx += v*(e-b);
        } else {
            int m = (b + e) >> 1;

            u->push();

            if (x < m) update(u->l, b, m, x, y, v);
            if (m < y) update(u->r, m, e, x, y, v);

            u->fix();
        }

        // cout << "UPDATE:" << b << " " << e << " " << x << " " << y << " " << v << " : " << u->mx << " " << u->lz << endl;
    }

    int query (int x, int y){
        return query(root, -lim, lim, x, y+1);
    }
    int query( node *u, int b, int e, int x, int y){
        if (x <= b && e <= y){
            return u->mx;
        } else {
            int m = (b + e) >> 1;

            u->push();
            int p = 0, q = 0;
            if (x < m)
                p = query(u->l, b, m, x, y);
            if (m < y)
                q = query(u->r, m, e, x, y);
            u->fix();
            return p + q;
        }
    }
};

class event{

    public:
        int type;
        pair<int,int> id;
        int x1, x2, y;
        int pos = 0;
        event(int type_c, int y_c, int x1_c, int x2_c){
            type= type_c;
            x1 = x1_c;
            x2 = x2_c;
            y = y_c;
        }
    bool operator<(const event &e) const {
        if (y != e.y) return y < e.y;
        return type < e.type;

    }
}
;

int main()
{
    int n;
    cin>>n;
    vector<pair<int,pair<int,int>>> horizontal;
    vector<pair<int,pair<int,int>>> vertical;
    for(int i = 0; i < n; ++i){
        int x1, y1, x2, y2;
        cin>>x1>>y1>>x2>>y2;
        if(x1>x2 || y1 > y2){
            swap(x1,x2);
            swap(y1,y2);
        }
        if(x1 == x2){
            vertical.push_back(make_pair(x1,make_pair(y1,y2)));
        }
        else{
            horizontal.push_back(make_pair(y1,make_pair(x1,x2)));
        }
    }
    sort(horizontal.begin(),horizontal.end());
    int tot = 0;
    st pepe;
    for( int i =0; i < horizontal.size(); ++i){

        int y = horizontal[i].first;
        int x1 = horizontal[i].second.first;
        int x2 = horizontal[i].second.second;
        vector<event> evs;
        for(int j =0; j < vertical.size();++j)
            if(vertical[j].first >= x1 && vertical[j].first <= x2 && vertical[j].second.first <= y){
                pepe.update(vertical[j].first,vertical[j].first,1);
                event e(1, vertical[j].second.second, vertical[j].first, vertical[j].first);
                evs.push_back(e);
            }
        for(int j = i+1; j < horizontal.size(); ++j){
            event e(0,horizontal[j].first, horizontal[j].second.first, horizontal[j].second.second);
            evs.push_back(e);
        }
        sort(evs.begin(), evs.end());
        for(int j =0; j < evs.size(); ++j){
            event e = evs[j];
            if(e.type == 0){
                ll q = pepe.query(e.x1, e.x2);
                tot+= q*(q-1)/2;
            }
            else if(e.type == 1){
                pepe.update(e.x1,e.x1,-1);
            }
        }
    }
    st juan;

    cout<<tot<<endl;
    return 0;
}


#include<bits/stdc++.h>
#define endl '\n'
#define ll long long
using namespace std;

ll inf = 1000000000;
ll minf = -1000000000;
ll amount_cut[5000+3][5000+3];
class event{

    public:
        ll compress = 0;
        ll type;
        pair<ll,ll> id;
        ll fixed;
        ll pos = 0;
        event(ll type_c, ll fixed_c ,pair<ll,ll> coords){
            type= type_c;
            compress = 0;
            if(type_c == 0){

                pos = coords.first;
                id = coords;
                fixed = fixed_c;
            }
            if(type_c == 1){
                 pos = coords.second;
                 id = coords;
                 fixed = fixed_c;
            }
            if(type_c == 2){
                pos = fixed_c;
                id = coords;
                fixed = fixed_c;
            }
        }
    bool operator<(const event &e) const {
        if (pos != e.pos) return pos < e.pos;
        return type > e.type;

    }
    void print(){
            if(type < 2)
                cout<<type<<" "<<fixed<<" ("<<id.first<<","<<id.second<<") "<<compress<<endl;
    }
}
;

int main()
{
    ll n;
    cin>>n;

    vector<event> evs;
    for(int i =0; i< n ; ++i){
        ll x1, x2, y1, y2;
        cin>>x1>>y1>>x2>>y2;
        if(x1 == x2){
            if(y2 < y1){
                swap(x1,x2);
                swap(y1,y2);
            }
            evs.push_back(event(2,x1, make_pair(y1,y2)));

        }
        else{
            if(x2 < x1){
                swap(x1,x2);
                swap(y1,y2);
            }
            evs.push_back(event(0,y1, make_pair(x1,x2)));
            evs.push_back(event(1,y1, make_pair(x1,x2)));
        }
    }
    sort(evs.begin(),evs.end());
    ll c = 0;
    map<pair<ll, pair<ll,ll>>,ll> comp_m;
    for(int i = 0; i < evs.size();++i){
        if(evs[i].type == 0){
            evs[i].compress = c;
            comp_m[make_pair(evs[i].fixed, evs[i].id)] = c;
            c++;
        }
        else if(evs[i].type == 1){
            evs[i].compress = comp_m[make_pair(evs[i].fixed, evs[i].id)];
        }
        //evs[i].print();
    }
    //cout<<"asdsad  "<<c<<endl;
    set<pair<ll,pair<pair<ll,ll>,ll>>> y_ordered;
    for(int i =0; i< n; ++i){
        //if(evs[i].compress == 6){
            //cout<<"Y ESA PINGA!!"<<endl;
        //}
        if(evs[i].type == 0){
            y_ordered.insert(make_pair(evs[i].fixed, make_pair (evs[i].id, evs[i].compress)));
        }
        else if(evs[i].type == 1){
            y_ordered.erase(make_pair(evs[i].fixed, make_pair(evs[i].id,evs[i].compress) )) ;
        }
        else if(evs[i].type ==2 ){
            ll y1 = evs[i].id.first;
            ll y2 = evs[i].id.second;
            ll x = evs[i].pos;

            auto it_first = y_ordered.lower_bound(make_pair(y1, make_pair(make_pair(minf, minf),minf)));
            auto it_last = y_ordered.upper_bound(make_pair(y2,make_pair(make_pair(inf,inf), inf)));

            vector<pair<ll,pair<pair<ll,ll>,ll>>> found;
            for(auto var = it_first; var != it_last; var++){
                //cout<<"pepe"<<endl;
                //ll am = 0;
                pair<ll,pair<pair<ll,ll>,ll>> element = *var;
                for(int j = 0; j< found.size();++j){
                    ll a = element.second.second;
                    ll b = found[j].second.second;
                    if(a > b){
                        swap(a,b);
                    }
                    //if(a == 0&& b == 1){
                      //  cout<<element.first<<" ("<<element.second.first.first<<","<<element.second.first.second<<") asdasd "<<element.second.second<<endl;
                    //}
                    //if (b == 6){
                      //  cout<<element.first<<" ("<<element.second.first.first<<","<<element.second.first.second<<") asdasd "<<element.second.second<<endl;
                        //cout<<"UWEQWE"<<endl;
                    //}
                    amount_cut[a][b]++;
                    //am ++;
                }
                //cout<<am<<endl;
                found.push_back(element);

            }

        }
    }
    ll tot = 0;
    for(int i =0; i < c; ++i){
        for(int j = 0; j < c; ++j){
            //cout<<amount_cut[i][j]<< " "<< i << " "<< j<<endl;
            tot+= amount_cut[i][j]*(amount_cut[i][j]-1)/2;
        }
    }
    cout<<tot<<endl;
    return 0;
}


#include<bits/stdc++.h>
#define endl '\n'
#define ll long long
using namespace std;

const int lim = 10000;
struct st {
    struct node {
        node *l, *r;
        int mx, lz;

        node() : l(0), r(0), mx(0), lz(0){}

        node* le(){
            if (l == nullptr){
                l = new node();
            }
            return l;
        }

        node* ri(){
            if (r == nullptr){
                r = new node();
            }
            return r;
        }

        void push(){
            le(); ri();

            if (lz){
                l->mx += lz;
                l->lz += lz;
                r->mx += lz;
                r->lz += lz;
                lz = 0;
            }
        }

        void fix(){
            mx = le()->mx + ri()->mx;
        }
    };

    node *root;

    st(){
        root = new node();
    }

    int update(int x, int y, int v){
        // cout << "[ " << x << " " << y << " " << v << endl;
        update(root, -lim, lim, x, y+1, v);
    }

    int update(node *u, int b, int e, int x, int y, int v){
        if (x <= b && e <= y){
            u->lz += v;
            u->mx += v;
        } else {
            int m = (b + e) >> 1;

            u->push();

            if (x < m) update(u->l, b, m, x, y, v);
            if (m < y) update(u->r, m, e, x, y, v);

            u->fix();
        }

        // cout << "UPDATE:" << b << " " << e << " " << x << " " << y << " " << v << " : " << u->mx << " " << u->lz << endl;
    }

    int query (int x, int y){
        return query(root, -lim, +lim, x, y+1);
    }
    int query( node *u, int b, int e, int x, int y){
        if (x <= b && e <= y){
            return u->mx;
        } else {
            int m = (b + e) >> 1;

            u->push();
            int a = 0; b = 0;
            if (x < m)
                a = query(u->l, b, m, x, y);
            if (m < y)
                b = query(u->r, m, e, x, y);
            return a + b;
        }
    }
};

class event{

    public:
        ll type;
        pair<ll,ll> id;
        ll x1, x2, y;
        ll pos = 0;
        event(ll type_c, ll y_c, ll x1_c, ll x2_c){
            type= type_c;
            x1 = x1_c;
            x2 = x2_c;
            y = y_c;
        }
    bool operator<(const event &e) const {
        if (y != e.y) return y < e.y;
        return type < e.type;

    }
}
;

int main()
{
    ll n;
    cin>>n;
    vector<pair<ll,pair<ll,ll>>> horizontal;
    vector<pair<ll,pair<ll,ll>>> vertical;
    for(int i = 0; i < n; ++i){
        ll x1, y1, x2, y2;
        cin>>x1>>y1>>x2>>y2;
        if(x1>x2 || y1 > y2){
            swap(x1,x2);
            swap(y1,y2);
        }
        if(x1 == x2){
            vertical.push_back(make_pair(x1,make_pair(y1,y2)));
        }
        else{
            horizontal.push_back(make_pair(y1,make_pair(x1,x2)));
        }
    }
    sort(horizontal.begin(),horizontal.end());
    ll tot = 0;
    for( int i =0; i < horizontal.size(); ++i){
        st pepe;
        ll y = horizontal[i].first;
        ll x1 = horizontal[i].second.first;
        ll x2 = horizontal[i].second.second;
        vector<event> evs;
        vector<pair<ll,pair<ll,ll>>> good;
        for(int j =0; j < vertical.size();++j)
            if(vertical[j].first >= x1 && vertical[j].first <= x2 && vertical[j].second.first <= y){
                pepe.update(vertical[j].first,vertical[j].first,1);
                good.push_back(vertical[j]);
            }
        for(int j = i+1; j < horizontal.size(); ++j){
            event e(0,horizontal[j].first, horizontal[j].second.first, horizontal[j].second.second);
            evs.push_back(e);
        }
        for(int j = 0; j < good.size();++j){
            event e(1, good[j].second.second, good[j].first, good[j].first);
            evs.push_back(e);
        }

        sort(evs.begin(), evs.end());
        for(int j =0; j < evs.size(); ++j){
            event e = evs[j];
            if(e.type == 0){
                ll q = pepe.query(e.x1, e.x2);
                tot+= q*(q-1)/2;
            }
            else if(e.type == 1){
                pepe.update(e.x1,e.x1,-1);
            }
        }
    }
    cout<<tot<<endl;
    return 0;
}


#include<bits/stdc++.h>
#define endl '\n'
#define ll long long
using namespace std;

ll ft_a [10000+30];

ll getSum(ll BITree[], int index)
{
    ll sum = 0; // Iniialize result

    // index in BITree[] is 1 more than the index in arr[]
    index = index + 1;

    // Traverse ancestors of BITree[index]
    while (index>0)
    {
        // Add current element of BITree to sum
        sum += BITree[index];

        // Move index to parent node in getSum View
        index -= index & (-index);
    }
    return sum;
}

// Updates a node in Binary Index Tree (BITree) at given index
// in BITree. The given value 'val' is added to BITree[i] and
// all of its ancestors in tree.
void updateBIT(ll BITree[], int n, int index, ll val)
{
    // index in BITree[] is 1 more than the index in arr[]
    index = index + 1;

    // Traverse all ancestors and add 'val'
    while (index <= n)
    {
    // Add 'val' to current node of BI Tree
    BITree[index] += val;

    // Update index to that of parent in update View
    index += index & (-index);
    }
}

// Constructs and returns a Binary Indexed Tree for given
// array of size n.
ll *constructBITree(ll arr[], int n)
{
    // Create and initialize BITree[] as 0
    ll *BITree = new ll[n+1];
    for (int i=1; i<=n; i++)
        BITree[i] = 0;

    // Store the actual values in BITree[] using update()
    for (int i=0; i<n; i++)
        updateBIT(BITree, n, i, arr[i]);

    // Uncomment below lines to see contents of BITree[]
    //for (int i=1; i<=n; i++)
    //     cout << BITree[i] << " ";

    return BITree;
}

class event{

    public:
        int type;
        ll x1, x2, y;
        event(int type_c, ll y_c, ll x1_c, ll x2_c){
            type= type_c;
            x1 = x1_c;
            x2 = x2_c;
            y = y_c;
        }
    bool operator<(const event &e) const {
        if (y != e.y) return y < e.y;
        return type < e.type;

    }
}
;

int main()
{
    ll n;
    cin>>n;
    vector<pair<ll,pair<ll,ll>>> horizontal;
    vector<pair<ll,pair<ll,ll>>> vertical;
    for(int i = 0; i < n; ++i){
        ll x1, y1, x2, y2;
        cin>>x1>>y1>>x2>>y2;
        x1+=5003;
        x2+= 5003;
        if(x1>x2 || y1 > y2){
            swap(x1,x2);
            swap(y1,y2);
        }
        if(x1 == x2){
            vertical.push_back(make_pair(x1,make_pair(y1,y2)));
        }
        else{
            horizontal.push_back(make_pair(y1,make_pair(x1,x2)));
        }
    }
    sort(horizontal.begin(),horizontal.end());
    ll tot = 0;

    ll *BITree = new ll[10030+1];
    for (int i=1; i<=10030; i++)
        BITree[i] = 0;
    for( int i =0; i < horizontal.size(); ++i){

        ll y = horizontal[i].first;
        ll x1 = horizontal[i].second.first;
        ll x2 = horizontal[i].second.second;
        vector<event> evs;
        for(int j =0; j < vertical.size();++j)
            if(vertical[j].first >= x1 && vertical[j].first <= x2 && vertical[j].second.first <= y){
                updateBIT(BITree, 10030, vertical[j].first, 1);
                event e(1, vertical[j].second.second, vertical[j].first, vertical[j].first);
                evs.push_back(e);
            }
        for(int j = i+1; j < horizontal.size(); ++j){
            event e(0,horizontal[j].first, horizontal[j].second.first, horizontal[j].second.second);
            evs.push_back(e);
        }
        sort(evs.begin(), evs.end());
        for(int j =0; j < evs.size(); ++j){
            event e = evs[j];
            if(e.type == 0){
                ll q = getSum(BITree, e.x2) - getSum(BITree, e.x1-1);
                tot+= q*(q-1ll)/2ll;
            }
            else if(e.type == 1){
                updateBIT(BITree, 10030, e.x1, -1);
            }
        }
    }

    cout<<tot<<endl;
    return 0;
}


#include<bits/stdc++.h>
#define endl '\n'
#define ll long long
using namespace std;

ll ft_a [10000+30];
const int lim = 5000 + 10;
ll getSum(int BITree[], int index)
{
    ll sum = 0; // Iniialize result

    // index in BITree[] is 1 more than the index in arr[]
    index = index + 1;

    // Traverse ancestors of BITree[index]
    while (index>0)
    {
        // Add current element of BITree to sum
        sum += BITree[index];

        // Move index to parent node in getSum View
        index -= index & (-index);
    }
    return sum;
}

// Updates a node in Binary Index Tree (BITree) at given index
// in BITree. The given value 'val' is added to BITree[i] and
// all of its ancestors in tree.
void updateBIT(int BITree[], int n, int index, ll val)
{
    // index in BITree[] is 1 more than the index in arr[]
    index = index + 1;

    // Traverse all ancestors and add 'val'
    while (index <= n)
    {
    // Add 'val' to current node of BI Tree
    BITree[index] += val;

    // Update index to that of parent in update View
    index += index & (-index);
    }
}

// Constructs and returns a Binary Indexed Tree for given
// array of size n.
ll *constructBITree(int arr[], int n)
{
    // Create and initialize BITree[] as 0
    ll *BITree = new ll[n+1];
    for (int i=1; i<=n; i++)
        BITree[i] = 0;

    // Store the actual values in BITree[] using update()
    for (int i=0; i<n; i++)
        updateBIT(BITree, n, i, arr[i]);

    // Uncomment below lines to see contents of BITree[]
    //for (int i=1; i<=n; i++)
    //     cout << BITree[i] << " ";

    return BITree;
}

class event{

    public:
        int type;
        pair<int,int> id;
        int x1, x2, y;
        int pos = 0;
        event(int type_c, int y_c, int x1_c, int x2_c){
            type= type_c;
            x1 = x1_c;
            x2 = x2_c;
            y = y_c;
        }
    bool operator<(const event &e) const {
        if (y != e.y) return y < e.y;
        return type < e.type;

    }
}
;

int main()
{
    int n;
    cin>>n;
    vector<pair<int,pair<int,int>>> horizontal;
    vector<pair<int,pair<int,int>>> vertical;
    for(int i = 0; i < n; ++i){
        int x1, y1, x2, y2;
        cin>>x1>>y1>>x2>>y2;
        x1+=5003;
        x2+= 5003;
        if(x1>x2 || y1 > y2){
            swap(x1,x2);
            swap(y1,y2);
        }
        if(x1 == x2){
            vertical.push_back(make_pair(x1,make_pair(y1,y2)));
        }
        else{
            horizontal.push_back(make_pair(y1,make_pair(x1,x2)));
        }
    }
    sort(horizontal.begin(),horizontal.end());
    ll tot = 0;

    for( int i =0; i < horizontal.size(); ++i){
        ll *BITree = new ll[10030+1];
        for (int i=1; i<=10030; i++)
            BITree[i] = 0;
        int y = horizontal[i].first;
        int x1 = horizontal[i].second.first;
        int x2 = horizontal[i].second.second;
        vector<event> evs;
        for(int j =0; j < vertical.size();++j)
            if(vertical[j].first >= x1 && vertical[j].first <= x2 && vertical[j].second.first <= y){
                updateBIT(BITree, 10030, vertical[j].first, 1);
                event e(1, vertical[j].second.second, vertical[j].first, vertical[j].first);
                evs.push_back(e);
            }
        for(int j = i+1; j < horizontal.size(); ++j){
            event e(0,horizontal[j].first, horizontal[j].second.first, horizontal[j].second.second);
            evs.push_back(e);
        }
        sort(evs.begin(), evs.end());
        for(int j =0; j < evs.size(); ++j){
            event e = evs[j];
            if(e.type == 0){
                ll q = getSum(BITree, e.x2) - getSum(BITree, e.x1-1);
                tot+= q*(q-1ll)/2ll;
            }
            else if(e.type == 1){
                updateBIT(BITree, 10030, e.x1, -1);
            }
        }
    }

    cout<<tot<<endl;
    return 0;
}


#include<bits/stdc++.h>
#define endl '\n'
#define ll long long
using namespace std;

ll inf = 1000000000;
ll minf = -1000000000;
ll amount_cut[5000+3][5000+3];
class event{

    public:
        ll compress = 0;
        ll type;
        pair<ll,ll> id;
        ll fixed;
        ll pos = 0;
        event(ll type_c, ll fixed_c ,pair<ll,ll> coords){
            type= type_c;
            compress = 0;
            if(type_c == 0){

                pos = coords.first;
                id = coords;
                fixed = fixed_c;
            }
            if(type_c == 1){
                 pos = coords.second;
                 id = coords;
                 fixed = fixed_c;
            }
            if(type_c == 2){
                pos = fixed_c;
                id = coords;
                fixed = fixed_c;
            }
        }
    bool operator<(const event &e) const {
        if (pos != e.pos) return pos < e.pos;
        return type > e.type;

    }
    void print(){
            if(type < 2)
                cout<<type<<" "<<fixed<<" ("<<id.first<<","<<id.second<<") "<<compress<<endl;
    }
}
;

int main()
{
    ll n;
    cin>>n;

    vector<event> evs;
    for(int i =0; i< n ; ++i){
        ll x1, x2, y1, y2;
        cin>>x1>>y1>>x2>>y2;
        if(x1 == x2){
            if(y2 < y1){
                swap(x1,x2);
                swap(y1,y2);
            }
            evs.push_back(event(2,x1, make_pair(y1,y2)));

        }
        else{
            if(x2 < x1){
                swap(x1,x2);
                swap(y1,y2);
            }
            evs.push_back(event(0,y1, make_pair(x1,x2)));
            evs.push_back(event(1,y1, make_pair(x1,x2)));
        }
    }
    sort(evs.begin(),evs.end());
    ll c = 0;
    map<pair<ll, pair<ll,ll>>,ll> comp_m;
    for(int i = 0; i < evs.size();++i){
        if(evs[i].type == 0){
            evs[i].compress = c;
            comp_m[make_pair(evs[i].fixed, evs[i].id)] = c;
            c++;
        }
        else if(evs[i].type == 1){
            evs[i].compress = comp_m[make_pair(evs[i].fixed, evs[i].id)];
        }
        //evs[i].print();
    }
    //cout<<"asdsad  "<<c<<endl;
    set<pair<ll,pair<pair<ll,ll>,ll>>> y_ordered;
    for(int i =0; i< n; ++i){
        //if(evs[i].compress == 6){
            //cout<<"Y ESA PINGA!!"<<endl;
        //}
        if(evs[i].type == 0){
            y_ordered.insert(make_pair(evs[i].fixed, make_pair (evs[i].id, evs[i].compress)));
        }
        else if(evs[i].type == 1){
            y_ordered.erase(make_pair(evs[i].fixed, make_pair(evs[i].id,evs[i].compress) )) ;
        }
        else if(evs[i].type ==2 ){
            ll y1 = evs[i].id.first;
            ll y2 = evs[i].id.second;
            ll x = evs[i].pos;

            auto it_first = y_ordered.lower_bound(make_pair(y1, make_pair(make_pair(minf, minf),minf)));
            auto it_last = y_ordered.upper_bound(make_pair(y2,make_pair(make_pair(inf,inf), inf)));

            vector<pair<ll,pair<pair<ll,ll>,ll>>> found;
            for(auto var = it_first; var != it_last; var++){
                //cout<<"pepe"<<endl;
                //ll am = 0;
                pair<ll,pair<pair<ll,ll>,ll>> element = *var;
                for(int j = 0; j< found.size();++j){
                    ll a = element.second.second;
                    ll b = found[j].second.second;
                    if(a > b){
                        swap(a,b);
                    }
                    //if(a == 0&& b == 1){
                      //  cout<<element.first<<" ("<<element.second.first.first<<","<<element.second.first.second<<") asdasd "<<element.second.second<<endl;
                    //}
                    //if (b == 6){
                      //  cout<<element.first<<" ("<<element.second.first.first<<","<<element.second.first.second<<") asdasd "<<element.second.second<<endl;
                        //cout<<"UWEQWE"<<endl;
                    //}
                    amount_cut[a][b]++;
                    //am ++;
                }
                //cout<<am<<endl;
                found.push_back(element);

            }

        }
    }
    ll tot = 0;
    for(int i =0; i < n; ++i){
        for(int j = 0; j < n; ++j){
            //cout<<amount_cut[i][j]<< " "<< i << " "<< j<<endl;
            tot+= amount_cut[i][j]*(amount_cut[i][j]-1)/2;
        }
    }
    cout<<tot<<endl;
    return 0;
}


#include<bits/stdc++.h>
#define endl '\n'
#define ll long long
using namespace std;

ll ft_a [10000+30];

ll getSum(ll BITree[], int index)
{
    ll sum = 0; // Iniialize result

    // index in BITree[] is 1 more than the index in arr[]
    index = index + 1;

    // Traverse ancestors of BITree[index]
    while (index>0)
    {
        // Add current element of BITree to sum
        sum += BITree[index];

        // Move index to parent node in getSum View
        index -= index & (-index);
    }
    return sum;
}

// Updates a node in Binary Index Tree (BITree) at given index
// in BITree. The given value 'val' is added to BITree[i] and
// all of its ancestors in tree.
void updateBIT(ll BITree[], int n, int index, ll val)
{
    // index in BITree[] is 1 more than the index in arr[]
    index = index + 1;

    // Traverse all ancestors and add 'val'
    while (index <= n)
    {
    // Add 'val' to current node of BI Tree
    BITree[index] += val;

    // Update index to that of parent in update View
    index += index & (-index);
    }
}

// Constructs and returns a Binary Indexed Tree for given
// array of size n.
ll *constructBITree(ll arr[], int n)
{
    // Create and initialize BITree[] as 0
    ll *BITree = new ll[n+1];
    for (int i=1; i<=n; i++)
        BITree[i] = 0;

    // Store the actual values in BITree[] using update()
    for (int i=0; i<n; i++)
        updateBIT(BITree, n, i, arr[i]);

    // Uncomment below lines to see contents of BITree[]
    //for (int i=1; i<=n; i++)
    //     cout << BITree[i] << " ";

    return BITree;
}

class event{

    public:
        int type;
        ll x1, x2, y;
        event(int type_c, ll y_c, ll x1_c, ll x2_c){
            type= type_c;
            x1 = x1_c;
            x2 = x2_c;
            y = y_c;
        }
        event(){}
    bool operator<(const event &e) const {
        if (y != e.y) return y < e.y;
        return type < e.type;

    }
}
;

int main()
{
    ll n;
    cin>>n;
    vector<pair<ll,pair<ll,ll>>> horizontal;
    vector<pair<ll,pair<ll,ll>>> vertical;
    for(int i = 0; i < n; ++i){
        ll x1, y1, x2, y2;
        cin>>x1>>y1>>x2>>y2;
        x1+=5003;
        x2+= 5003;
        if(x1>x2 || y1 > y2){
            swap(x1,x2);
            swap(y1,y2);
        }
        if(x1 == x2){
            vertical.push_back(make_pair(x1,make_pair(y1,y2)));
        }
        else{
            horizontal.push_back(make_pair(y1,make_pair(x1,x2)));
        }
    }
    sort(horizontal.begin(),horizontal.end());
    ll tot = 0;

    ll *BITree = new ll[10030+1];
    for (int i=1; i<=10030; i++)
        BITree[i] = 0;
    for( int i =0; i < horizontal.size(); ++i){

        ll y = horizontal[i].first;
        ll x1 = horizontal[i].second.first;
        ll x2 = horizontal[i].second.second;
        vector<event> evs(horizontal.size() - i);
        for(int j =0; j < vertical.size();++j)
            if(vertical[j].first >= x1 && vertical[j].first <= x2 && vertical[j].second.first <= y){
                updateBIT(BITree, 10030, vertical[j].first, 1);
                event e(1, vertical[j].second.second, vertical[j].first, vertical[j].first);
                evs.push_back(e);
            }
        for(int j = i+1; j < horizontal.size(); ++j){
            event e(0,horizontal[j].first, horizontal[j].second.first, horizontal[j].second.second);
            evs[j-i-1] = e;
        }
        sort(evs.begin(), evs.end());
        for(int j =0; j < evs.size(); ++j){
            event e = evs[j];
            if(e.type == 0){
                ll q = getSum(BITree, e.x2) - getSum(BITree, e.x1-1);
                tot+= q*(q-1ll)/2ll;
            }
            else if(e.type == 1){
                updateBIT(BITree, 10030, e.x1, -1);
            }
        }
    }

    cout<<tot<<endl;
    return 0;
}


#include<bits/stdc++.h>
#define endl '\n'
#define ll long long
using namespace std;

ll inf = 1000000000;
ll minf = -1000000000;
class event{

    public:
        ll type;
        pair<ll,ll> id;
        ll fixed;
        ll pos = 0;
        event(ll type_c, ll fixed_c ,pair<ll,ll> coords){
            type= type_c;
            if(type_c == 0){

                pos = coords.first;
                id = coords;
                fixed = fixed_c;
            }
            if(type_c == 1){
                 pos = coords.second;
                 id = coords;
                 fixed = fixed_c;
            }
            if(type_c == 2){
                pos = fixed_c;
                id = coords;
                fixed = fixed_c;
            }
        }
        bool operator<(const event &e) const {
        if (pos != e.pos) return pos < e.pos;
        return type > e.type;
    }
}
;
int main()
{
    ll n;
    cin>>n;

    vector<event> evs;
    for(int i =0; i< n ; ++i){
        ll x1, x2, y1, y2;
        cin>>x1>>y1>>x2>>y2;
        if(x1 == x2){
            if(y2 < y1){
                swap(x1,x2);
                swap(y1,y2);
            }
            evs.push_back(event(2,x1, make_pair(y1,y2)));

        }
        else{
            if(x2 < x1){
                swap(x1,x2);
                swap(y1,y2);
            }
            evs.push_back(event(0,y1, make_pair(x1,x2)));
            evs.push_back(event(1,y1, make_pair(x1,x2)));
        }
    }
    sort(evs.begin(),evs.end());
    for(int i = 0; i < evs.size();++i){
        //cout<<evs[i].type<<" "<<evs[i].id.first<<" "<<evs[i].id.second<<" "<<evs[i].fixed<<endl;
    }
    set<pair<ll,pair<ll,ll>>> y_ordered;
    map<pair <pair<ll,pair<ll,ll>>,pair<ll,pair<ll,ll>>> , ll> amount_cut;
    for(int i =0; i< n; ++i){
        if(evs[i].type == 0){
            y_ordered.insert(make_pair(evs[i].fixed,evs[i].id));
        }
        else if(evs[i].type == 1){
            y_ordered.erase(make_pair(evs[i].fixed, evs[i].id));
        }
        else if(evs[i].type ==2 ){
            ll y1 = evs[i].id.first;
            ll y2 = evs[i].id.second;
            ll x = evs[i].pos;

            auto it_first = y_ordered.lower_bound(make_pair(y1, make_pair(minf, minf)));
            auto it_last = y_ordered.upper_bound(make_pair(y2,make_pair(inf,inf)));

            vector<pair<ll,pair<ll,ll>>> found;
            for(auto var = it_first; var != it_last; var++){
                //cout<<"pepe"<<endl;
                pair<ll,pair<ll,ll>> element = *var;
                for(int j = 0; j< found.size();++j){
                    amount_cut[make_pair(element, found[j])]++;
                }
                found.push_back(element);

            }

        }
    }
    ll tot = 0;
    for (auto x: amount_cut){
        tot+= x.second*(x.second-1)/2;
    }
    cout<<tot<<endl;
    return 0;
}


#include<bits/stdc++.h>
#define endl '\n'
#define ll long long
using namespace std;

ll ft_a [10000+30];

ll getSum(ll BITree[], int index)
{
    ll sum = 0; // Iniialize result

    // index in BITree[] is 1 more than the index in arr[]
    index = index + 1;

    // Traverse ancestors of BITree[index]
    while (index>0)
    {
        // Add current element of BITree to sum
        sum += BITree[index];

        // Move index to parent node in getSum View
        index -= index & (-index);
    }
    return sum;
}

// Updates a node in Binary Index Tree (BITree) at given index
// in BITree. The given value 'val' is added to BITree[i] and
// all of its ancestors in tree.
void updateBIT(ll BITree[], int n, int index, ll val)
{
    // index in BITree[] is 1 more than the index in arr[]
    index = index + 1;

    // Traverse all ancestors and add 'val'
    while (index <= n)
    {
    // Add 'val' to current node of BI Tree
    BITree[index] += val;

    // Update index to that of parent in update View
    index += index & (-index);
    }
}

// Constructs and returns a Binary Indexed Tree for given
// array of size n.
ll *constructBITree(ll arr[], int n)
{
    // Create and initialize BITree[] as 0
    ll *BITree = new ll[n+1];
    for (int i=1; i<=n; i++)
        BITree[i] = 0;

    // Store the actual values in BITree[] using update()
    for (int i=0; i<n; i++)
        updateBIT(BITree, n, i, arr[i]);

    // Uncomment below lines to see contents of BITree[]
    //for (int i=1; i<=n; i++)
    //     cout << BITree[i] << " ";

    return BITree;
}

class event{

    public:
        int type;
        ll x1, x2, y;
        event(int type_c, ll y_c, ll x1_c, ll x2_c){
            type= type_c;
            x1 = x1_c;
            x2 = x2_c;
            y = y_c;
        }
    bool operator<(const event &e) const {
        if (y != e.y) return y < e.y;
        return type < e.type;

    }
}
;

int main()
{
    ll n;
    cin>>n;
    vector<pair<ll,pair<ll,ll>>> horizontal;
    vector<pair<ll,pair<ll,ll>>> vertical;
    for(int i = 0; i < n; ++i){
        ll x1, y1, x2, y2;
        cin>>x1>>y1>>x2>>y2;
        x1+=5003;
        x2+= 5003;
        if(x1>x2 || y1 > y2){
            swap(x1,x2);
            swap(y1,y2);
        }
        if(x1 == x2){
            vertical.push_back(make_pair(x1,make_pair(y1,y2)));
        }
        else{
            horizontal.push_back(make_pair(y1,make_pair(x1,x2)));
        }
    }
    sort(horizontal.begin(),horizontal.end());
    ll tot = 0;

    for( int i =0; i < horizontal.size(); ++i){
        ll *BITree = new ll[10030+1];
        for (int i=1; i<=10030; i++)
            BITree[i] = 0;
        ll y = horizontal[i].first;
        ll x1 = horizontal[i].second.first;
        ll x2 = horizontal[i].second.second;
        vector<event> evs;
        for(int j =0; j < vertical.size();++j)
            if(vertical[j].first >= x1 && vertical[j].first <= x2 && vertical[j].second.first <= y){
                updateBIT(BITree, 10030, vertical[j].first, 1);
                event e(1, vertical[j].second.second, vertical[j].first, vertical[j].first);
                evs.push_back(e);
            }
        for(int j = i+1; j < horizontal.size(); ++j){
            event e(0,horizontal[j].first, horizontal[j].second.first, horizontal[j].second.second);
            evs.push_back(e);
        }
        sort(evs.begin(), evs.end());
        for(int j =0; j < evs.size(); ++j){
            event e = evs[j];
            if(e.type == 0){
                ll q = getSum(BITree, e.x2) - getSum(BITree, e.x1-1);
                tot+= q*(q-1ll)/2ll;
            }
            else if(e.type == 1){
                updateBIT(BITree, 10030, e.x1, -1);
            }
        }
    }

    cout<<tot<<endl;
    return 0;
}


#include<bits/stdc++.h>
#define endl '\n'
#define ll long long
using namespace std;

ll ft_a [10000+30];
const int lim = 5000 + 10;
ll getSum(int BITree[], int index)
{
    ll sum = 0; // Iniialize result

    // index in BITree[] is 1 more than the index in arr[]
    index = index + 1;

    // Traverse ancestors of BITree[index]
    while (index>0)
    {
        // Add current element of BITree to sum
        sum += BITree[index];

        // Move index to parent node in getSum View
        index -= index & (-index);
    }
    return sum;
}

// Updates a node in Binary Index Tree (BITree) at given index
// in BITree. The given value 'val' is added to BITree[i] and
// all of its ancestors in tree.
void updateBIT(int BITree[], int n, int index, ll val)
{
    // index in BITree[] is 1 more than the index in arr[]
    index = index + 1;

    // Traverse all ancestors and add 'val'
    while (index <= n)
    {
    // Add 'val' to current node of BI Tree
    BITree[index] += val;

    // Update index to that of parent in update View
    index += index & (-index);
    }
}

// Constructs and returns a Binary Indexed Tree for given
// array of size n.
ll *constructBITree(int arr[], int n)
{
    // Create and initialize BITree[] as 0
    ll *BITree = new int[n+1];
    for (int i=1; i<=n; i++)
        BITree[i] = 0;

    // Store the actual values in BITree[] using update()
    for (int i=0; i<n; i++)
        updateBIT(BITree, n, i, arr[i]);

    // Uncomment below lines to see contents of BITree[]
    //for (int i=1; i<=n; i++)
    //     cout << BITree[i] << " ";

    return BITree;
}

class event{

    public:
        int type;
        pair<int,int> id;
        int x1, x2, y;
        int pos = 0;
        event(int type_c, int y_c, int x1_c, int x2_c){
            type= type_c;
            x1 = x1_c;
            x2 = x2_c;
            y = y_c;
        }
    bool operator<(const event &e) const {
        if (y != e.y) return y < e.y;
        return type < e.type;

    }
}
;

int main()
{
    int n;
    cin>>n;
    vector<pair<int,pair<int,int>>> horizontal;
    vector<pair<int,pair<int,int>>> vertical;
    for(int i = 0; i < n; ++i){
        int x1, y1, x2, y2;
        cin>>x1>>y1>>x2>>y2;
        x1+=5003;
        x2+= 5003;
        if(x1>x2 || y1 > y2){
            swap(x1,x2);
            swap(y1,y2);
        }
        if(x1 == x2){
            vertical.push_back(make_pair(x1,make_pair(y1,y2)));
        }
        else{
            horizontal.push_back(make_pair(y1,make_pair(x1,x2)));
        }
    }
    sort(horizontal.begin(),horizontal.end());
    ll tot = 0;

    for( int i =0; i < horizontal.size(); ++i){
        ll *BITree = new ll[10030+1];
        for (int i=1; i<=10030; i++)
            BITree[i] = 0;
        int y = horizontal[i].first;
        int x1 = horizontal[i].second.first;
        int x2 = horizontal[i].second.second;
        vector<event> evs;
        for(int j =0; j < vertical.size();++j)
            if(vertical[j].first >= x1 && vertical[j].first <= x2 && vertical[j].second.first <= y){
                updateBIT(BITree, 10030, vertical[j].first, 1);
                event e(1, vertical[j].second.second, vertical[j].first, vertical[j].first);
                evs.push_back(e);
            }
        for(int j = i+1; j < horizontal.size(); ++j){
            event e(0,horizontal[j].first, horizontal[j].second.first, horizontal[j].second.second);
            evs.push_back(e);
        }
        sort(evs.begin(), evs.end());
        for(int j =0; j < evs.size(); ++j){
            event e = evs[j];
            if(e.type == 0){
                ll q = getSum(BITree, e.x2) - getSum(BITree, e.x1-1);
                tot+= q*(q-1ll)/2ll;
            }
            else if(e.type == 1){
                updateBIT(BITree, 10030, e.x1, -1);
            }
        }
    }

    cout<<tot<<endl;
    return 0;
}


#include<bits/stdc++.h>
#define endl '\n'
#define ll long long
using namespace std;

const int lim = 5000 + 10;
struct st {
    struct node {
        node *l, *r;
        int mx, lz;

        node() : l(0), r(0), mx(0), lz(0){}

        node* le(){
            if (l == nullptr){
                l = new node();
            }
            return l;
        }

        node* ri(){
            if (r == nullptr){
                r = new node();
            }
            return r;
        }

        void push(){
            le(); ri();

            if (lz){
                l->mx += lz;
                l->lz += lz;
                r->mx += lz;
                r->lz += lz;
                lz = 0;
            }
        }

        void fix(){
            mx = le()->mx + ri()->mx;
        }
    };

    node *root;

    st(){
        root = new node();
    }

    int update(int x, int y, int v){
        // cout << "[ " << x << " " << y << " " << v << endl;
        update(root, -lim, lim, x, y+1, v);
    }

    int update(node *u, int b, int e, int x, int y, int v){
        if (x <= b && e <= y){
            u->lz += v;
            u->mx += v;
        } else {
            int m = (b + e) >> 1;

            u->push();

            if (x < m) update(u->l, b, m, x, y, v);
            if (m < y) update(u->r, m, e, x, y, v);

            u->fix();
        }

        // cout << "UPDATE:" << b << " " << e << " " << x << " " << y << " " << v << " : " << u->mx << " " << u->lz << endl;
    }

    int query (int x, int y){
        return query(root, -lim, lim, x, y+1);
    }
    int query( node *u, int b, int e, int x, int y){
        if (x <= b && e <= y){
            return u->mx;
        } else {
            int m = (b + e) >> 1;

            u->push();
            int p = 0, q = 0;
            if (x < m)
                p = query(u->l, b, m, x, y);
            if (m < y)
                q = query(u->r, m, e, x, y);
            u->fix();
            return p + q;
        }
    }
};

class event{

    public:
        int type;
        pair<int,int> id;
        int x1, x2, y;
        int pos = 0;
        event(int type_c, int y_c, int x1_c, int x2_c){
            type= type_c;
            x1 = x1_c;
            x2 = x2_c;
            y = y_c;
        }
    bool operator<(const event &e) const {
        if (y != e.y) return y < e.y;
        return type < e.type;

    }
}
;

int main()
{
    int n;
    cin>>n;
    vector<pair<int,pair<int,int>>> horizontal;
    vector<pair<int,pair<int,int>>> vertical;
    for(int i = 0; i < n; ++i){
        int x1, y1, x2, y2;
        cin>>x1>>y1>>x2>>y2;
        if(x1>x2 || y1 > y2){
            swap(x1,x2);
            swap(y1,y2);
        }
        if(x1 == x2){
            vertical.push_back(make_pair(x1,make_pair(y1,y2)));
        }
        else{
            horizontal.push_back(make_pair(y1,make_pair(x1,x2)));
        }
    }
    sort(horizontal.begin(),horizontal.end());
    int tot = 0;
    st pepe;
    for( int i =0; i < horizontal.size(); ++i){

        int y = horizontal[i].first;
        int x1 = horizontal[i].second.first;
        int x2 = horizontal[i].second.second;
        vector<event> evs;
        for(int j =0; j < vertical.size();++j)
            if(vertical[j].first >= x1 && vertical[j].first <= x2 && vertical[j].second.first <= y){
                pepe.update(vertical[j].first,vertical[j].first,1);
                event e(1, vertical[j].second.second, vertical[j].first, vertical[j].first);
                evs.push_back(e);
            }
        for(int j = i+1; j < horizontal.size(); ++j){
            event e(0,horizontal[j].first, horizontal[j].second.first, horizontal[j].second.second);
            evs.push_back(e);
        }
        sort(evs.begin(), evs.end());
        for(int j =0; j < evs.size(); ++j){
            event e = evs[j];
            if(e.type == 0){
                ll q = pepe.query(e.x1, e.x2);
                tot+= q*(q-1)/2;
            }
            else if(e.type == 1){
                pepe.update(e.x1,e.x1,-1);
            }
        }
    }
    //st juan;
    //juan.update(-10, 5000, 5);
    //cout<<juan.query(1,3)<<endl;
    cout<<tot<<endl;
    return 0;
}


#include<bits/stdc++.h>
#define endl '\n'
#define ll long long
using namespace std;

ll ft_a [10000+30];

ll getSum(ll BITree[], int index)
{
    ll sum = 0; // Iniialize result

    // index in BITree[] is 1 more than the index in arr[]
    index = index + 1;

    // Traverse ancestors of BITree[index]
    while (index>0)
    {
        // Add current element of BITree to sum
        sum += BITree[index];

        // Move index to parent node in getSum View
        index -= index & (-index);
    }
    return sum;
}

// Updates a node in Binary Index Tree (BITree) at given index
// in BITree. The given value 'val' is added to BITree[i] and
// all of its ancestors in tree.
void updateBIT(ll BITree[], int n, int index, ll val)
{
    // index in BITree[] is 1 more than the index in arr[]
    index = index + 1;

    // Traverse all ancestors and add 'val'
    while (index <= n)
    {
    // Add 'val' to current node of BI Tree
    BITree[index] += val;

    // Update index to that of parent in update View
    index += index & (-index);
    }
}

// Constructs and returns a Binary Indexed Tree for given
// array of size n.
ll *constructBITree(ll arr[], int n)
{
    // Create and initialize BITree[] as 0
    ll *BITree = new ll[n+1];
    for (int i=1; i<=n; i++)
        BITree[i] = 0;

    // Store the actual values in BITree[] using update()
    for (int i=0; i<n; i++)
        updateBIT(BITree, n, i, arr[i]);

    // Uncomment below lines to see contents of BITree[]
    //for (int i=1; i<=n; i++)
    //     cout << BITree[i] << " ";

    return BITree;
}

class event{

    public:
        int type;
        ll x1, x2, y;
        event(int type_c, ll y_c, ll x1_c, ll x2_c){
            type= type_c;
            x1 = x1_c;
            x2 = x2_c;
            y = y_c;
        }
    bool operator<(const event &e) const {
        if (y != e.y) return y < e.y;
        return type < e.type;

    }
}
;

int main()
{
    ll n;
    cin>>n;
    vector<pair<ll,pair<ll,ll>>> horizontal;
    vector<pair<ll,pair<ll,ll>>> vertical;
    for(int i = 0; i < n; ++i){
        ll x1, y1, x2, y2;
        cin>>x1>>y1>>x2>>y2;
        x1+=5003;
        x2+= 5003;
        if(x1>x2 || y1 > y2){
            swap(x1,x2);
            swap(y1,y2);
        }
        if(x1 == x2){
            vertical.push_back(make_pair(x1,make_pair(y1,y2)));
        }
        else{
            horizontal.push_back(make_pair(y1,make_pair(x1,x2)));
        }
    }
    sort(horizontal.begin(),horizontal.end());
    if(vertical.size()<=1){
        cout<<0<<endl;
        return 0;
    }
    ll tot = 0;

    ll *BITree = new ll[10030+1];
    for (int i=1; i<=10030; i++)
        BITree[i] = 0;
    for( int i =0; i < horizontal.size(); ++i){

        ll y = horizontal[i].first;
        ll x1 = horizontal[i].second.first;
        ll x2 = horizontal[i].second.second;
        vector<event> evs;
        for(int j =0; j < vertical.size();++j)
            if(vertical[j].first >= x1 && vertical[j].first <= x2 && vertical[j].second.first <= y){
                updateBIT(BITree, 10030, vertical[j].first, 1);
                event e(1, vertical[j].second.second, vertical[j].first, vertical[j].first);
                evs.push_back(e);
            }
        for(int j = i+1; j < horizontal.size(); ++j){
            event e(0,horizontal[j].first, horizontal[j].second.first, horizontal[j].second.second);
            evs.push_back(e);
        }
        sort(evs.begin(), evs.end());
        for(int j =0; j < evs.size(); ++j){
            event e = evs[j];
            if(e.type == 0){
                ll q = getSum(BITree, e.x2) - getSum(BITree, e.x1-1);
                tot+= q*(q-1ll)/2ll;
            }
            else if(e.type == 1){
                updateBIT(BITree, 10030, e.x1, -1);
            }
        }
    }

    cout<<tot<<endl;
    return 0;
}


#include<bits/stdc++.h>
#define endl '\n'
#define ll long long
using namespace std;

int ft_a [10000+30];
const int lim = 5000 + 10;
int getSum(int BITree[], int index)
{
    int sum = 0; // Iniialize result

    // index in BITree[] is 1 more than the index in arr[]
    index = index + 1;

    // Traverse ancestors of BITree[index]
    while (index>0)
    {
        // Add current element of BITree to sum
        sum += BITree[index];

        // Move index to parent node in getSum View
        index -= index & (-index);
    }
    return sum;
}

// Updates a node in Binary Index Tree (BITree) at given index
// in BITree. The given value 'val' is added to BITree[i] and
// all of its ancestors in tree.
void updateBIT(int BITree[], int n, int index, int val)
{
    // index in BITree[] is 1 more than the index in arr[]
    index = index + 1;

    // Traverse all ancestors and add 'val'
    while (index <= n)
    {
    // Add 'val' to current node of BI Tree
    BITree[index] += val;

    // Update index to that of parent in update View
    index += index & (-index);
    }
}

// Constructs and returns a Binary Indexed Tree for given
// array of size n.
int *constructBITree(int arr[], int n)
{
    // Create and initialize BITree[] as 0
    int *BITree = new int[n+1];
    for (int i=1; i<=n; i++)
        BITree[i] = 0;

    // Store the actual values in BITree[] using update()
    for (int i=0; i<n; i++)
        updateBIT(BITree, n, i, arr[i]);

    // Uncomment below lines to see contents of BITree[]
    //for (int i=1; i<=n; i++)
    //     cout << BITree[i] << " ";

    return BITree;
}

class event{

    public:
        int type;
        pair<int,int> id;
        int x1, x2, y;
        int pos = 0;
        event(int type_c, int y_c, int x1_c, int x2_c){
            type= type_c;
            x1 = x1_c;
            x2 = x2_c;
            y = y_c;
        }
    bool operator<(const event &e) const {
        if (y != e.y) return y < e.y;
        return type < e.type;

    }
}
;

int main()
{
    int n;
    cin>>n;
    vector<pair<int,pair<int,int>>> horizontal;
    vector<pair<int,pair<int,int>>> vertical;
    for(int i = 0; i < n; ++i){
        int x1, y1, x2, y2;
        cin>>x1>>y1>>x2>>y2;
        x1+=5003;
        x2+= 5003;
        if(x1>x2 || y1 > y2){
            swap(x1,x2);
            swap(y1,y2);
        }
        if(x1 == x2){
            vertical.push_back(make_pair(x1,make_pair(y1,y2)));
        }
        else{
            horizontal.push_back(make_pair(y1,make_pair(x1,x2)));
        }
    }
    sort(horizontal.begin(),horizontal.end());
    int tot = 0;

    for( int i =0; i < horizontal.size(); ++i){
        int *BITree = new int[10030+1];
        for (int i=1; i<=10030; i++)
            BITree[i] = 0;
        int y = horizontal[i].first;
        int x1 = horizontal[i].second.first;
        int x2 = horizontal[i].second.second;
        vector<event> evs;
        for(int j =0; j < vertical.size();++j)
            if(vertical[j].first >= x1 && vertical[j].first <= x2 && vertical[j].second.first <= y){
                updateBIT(BITree, 10030, vertical[j].first, 1);
                event e(1, vertical[j].second.second, vertical[j].first, vertical[j].first);
                evs.push_back(e);
            }
        for(int j = i+1; j < horizontal.size(); ++j){
            event e(0,horizontal[j].first, horizontal[j].second.first, horizontal[j].second.second);
            evs.push_back(e);
        }
        sort(evs.begin(), evs.end());
        for(int j =0; j < evs.size(); ++j){
            event e = evs[j];
            if(e.type == 0){
                ll q = getSum(BITree, e.x2) - getSum(BITree, e.x1-1);
                tot+= q*(q-1)/2;
            }
            else if(e.type == 1){
                updateBIT(BITree, 10030, e.x1, -1);
            }
        }
    }

    cout<<tot<<endl;
    return 0;
}


#include<bits/stdc++.h>
#define endl '\n'
#define ll long long
using namespace std;

int ft_a [10000+30];

ll getSum(ll BITree[], int index)
{
    ll sum = 0; // Iniialize result

    // index in BITree[] is 1 more than the index in arr[]
    index = index + 1;

    // Traverse ancestors of BITree[index]
    while (index>0)
    {
        // Add current element of BITree to sum
        sum += BITree[index];

        // Move index to parent node in getSum View
        index -= index & (-index);
    }
    return sum;
}

// Updates a node in Binary Index Tree (BITree) at given index
// in BITree. The given value 'val' is added to BITree[i] and
// all of its ancestors in tree.
void updateBIT(ll BITree[], int n, int index, ll val)
{
    // index in BITree[] is 1 more than the index in arr[]
    index = index + 1;

    // Traverse all ancestors and add 'val'
    while (index <= n)
    {
    // Add 'val' to current node of BI Tree
    BITree[index] += val;

    // Update index to that of parent in update View
    index += index & (-index);
    }
}

// Constructs and returns a Binary Indexed Tree for given
// array of size n.
ll *constructBITree(int arr[], int n)
{
    // Create and initialize BITree[] as 0
    ll *BITree = new ll[n+1];
    for (int i=1; i<=n; i++)
        BITree[i] = 0;

    // Store the actual values in BITree[] using update()
    for (int i=0; i<n; i++)
        updateBIT(BITree, n, i, arr[i]);

    // Uncomment below lines to see contents of BITree[]
    //for (int i=1; i<=n; i++)
    //     cout << BITree[i] << " ";

    return BITree;
}

class event{

    public:
        int type;
        int x1, x2, y;
        event(int type_c, int y_c, int x1_c, int x2_c){
            type= type_c;
            x1 = x1_c;
            x2 = x2_c;
            y = y_c;
        }
    bool operator<(const event &e) const {
        if (y != e.y) return y < e.y;
        return type < e.type;

    }
}
;

int main()
{
    int n;
    cin>>n;
    vector<pair<int,pair<int,int>>> horizontal;
    vector<pair<int,pair<int,int>>> vertical;
    for(int i = 0; i < n; ++i){
        int x1, y1, x2, y2;
        cin>>x1>>y1>>x2>>y2;
        x1+=5001;
        x2+= 5001;
        if(x1>x2 || y1 > y2){
            swap(x1,x2);
            swap(y1,y2);
        }
        if(x1 == x2){
            vertical.push_back(make_pair(x1,make_pair(y1,y2)));
        }
        else{
            horizontal.push_back(make_pair(y1,make_pair(x1,x2)));
        }
    }
    sort(horizontal.begin(),horizontal.end());
    if(vertical.size()<=1){
        cout<<0<<endl;
        return 0;
    }
    ll tot = 0;

    ll *BITree = new ll[10030+1];
    for (int i=1; i<=10030; i++)
        BITree[i] = 0;
    for( int i =0; i < horizontal.size(); ++i){

        int y = horizontal[i].first;
        int x1 = horizontal[i].second.first;
        int x2 = horizontal[i].second.second;
        vector<event> evs;
        for(int j =0; j < vertical.size();++j)
            if(vertical[j].first >= x1 && vertical[j].first <= x2 && vertical[j].second.first <= y){
                updateBIT(BITree, 10030, vertical[j].first, 1);
                event e(1, vertical[j].second.second, vertical[j].first, vertical[j].first);
                evs.push_back(e);
            }
        for(int j = i+1; j < horizontal.size(); ++j){
            event e(0,horizontal[j].first, horizontal[j].second.first, horizontal[j].second.second);
            evs.push_back(e);
        }
        sort(evs.begin(), evs.end());
        for(int j =0; j < evs.size(); ++j){
            event e = evs[j];
            if(e.type == 0){
                ll q = getSum(BITree, e.x2) - getSum(BITree, e.x1-1);
                tot+= q*(q-1ll)/2ll;
            }
            else if(e.type == 1){
                updateBIT(BITree, 10030, e.x1, -1);
            }
        }
    }

    cout<<tot<<endl;
    return 0;
}


#include<bits/stdc++.h>
#define ms(a,v) memset(a,v,sizeof a)
#define ll long long
using namespace std;
map<int,bool> mat[10002];
short points[10002][4];
vector< pair<short,short> >inter;
vector< pair<short,short> >rec;

//Code By Stephan Ramirez dsramirezc@unal.edu.co
int main(){
    int n;
    scanf("%d",&n);
    for(int i=0;i<n;i++){
        scanf("%d %d %d %d",&points[i][0],&points[i][1],&points[i][2],&points[i][3]);
        points[i][0]+=5000;
        points[i][1]+=5000;
        points[i][2]+=5000;
        points[i][3]+=5000;
    }

    for(int i=0;i<n;i++){
        for(int j=i+1;j<n;j++){
            if(points[i][0]==points[i][2] && points[j][1]==points[j][3] ){
                if(min(points[j][0],points[j][2])<=points[i][0] &&  max(points[j][0],points[j][2])>=points[i][0]){
                    if(min(points[i][1],points[i][3])<=points[j][1] &&  max(points[i][1],points[i][3])>=points[j][1]){
                        inter.push_back(make_pair(points[i][0],points[j][1]));
                        rec.push_back(make_pair(i,j));
                        mat[points[i][0]][points[j][1]]=true;
                    }
                }
            }
            if(points[j][0]==points[j][2] && points[i][1]==points[i][3] ){
                if(min(points[i][0],points[i][2])<=points[j][0] &&  max(points[i][0],points[i][2])>=points[j][0]){
                    if(min(points[j][1],points[j][3])<=points[i][1] &&  max(points[j][1],points[j][3])>=points[i][1]){
                        inter.push_back(make_pair(points[j][0],points[i][1]));
                        rec.push_back(make_pair(j,i));
                        mat[points[j][0]][points[i][1]]=true;
                    }
                }
            }
        }
    }
    int ans=0;
    for( int i=0;i<inter.size();i++){
        for(int j=0;j<inter.size();j++){
            if(inter[i].first> inter[j].first && inter[i].second> inter[j].second && mat[ inter[i].first][inter[j].second]==true &&  mat[ inter[j].first][inter[i].second]==true ){
                int x=rec[i].first;
                int y=rec[j].second;
                 int x1=rec[j].first;
                int y1=rec[i].second;
                if(min(points[y][0],points[y][2])<=points[x][0] &&  max(points[y][0],points[y][2])>=points[x][0])
                    if(min(points[x][1],points[x][3])<=points[y][1] &&  max(points[x][1],points[x][3])>=points[y][1])
                        if(min(points[y1][0],points[y1][2])<=points[x1][0] &&  max(points[y1][0],points[y1][2])>=points[x1][0])
                           if(min(points[x1][1],points[x1][3])<=points[y1][1] &&  max(points[x1][1],points[x1][3])>=points[y1][1])
                                ans++;
            }
        }

    }
    printf("%d\n",ans);

	//freopen("in.txt","r",stdin);
	//freopen("out.txt","w",stdout);
	return 0;
}


#include<bits/stdc++.h>
#define ms(a,v) memset(a,v,sizeof a)
#define ll long long
using namespace std;

//Code By Stephan Ramirez dsramirezc@unal.edu.co
int main(){
    int n;
    scanf("%d",&n);
    int points[n][4];
    for(int i=0;i<n;i++){
        scanf("%d %d %d %d",&points[i][0],&points[i][1],&points[i][2],&points[i][3]);
        points[i][0]+=5000;
        points[i][1]+=5000;
        points[i][2]+=5000;
        points[i][3]+=5000;
    }
    map<int,bool> mat[5000*2+4];

    vector< pair<int,int> >inter;
    vector< pair<int,int> >rec;

    for(int i=0;i<n;i++){
        for(int j=i+1;j<n;j++){
            if(points[i][0]==points[i][2] && points[j][1]==points[j][3] ){
                if(min(points[j][0],points[j][2])<=points[i][0] &&  max(points[j][0],points[j][2])>=points[i][0]){
                    if(min(points[i][1],points[i][3])<=points[j][1] &&  max(points[i][1],points[i][3])>=points[j][1]){
                        inter.push_back(make_pair(points[i][0],points[j][1]));
                        rec.push_back(make_pair(i,j));
                        mat[points[i][0]][points[j][1]]=true;
                    }
                }
            }
            if(points[j][0]==points[j][2] && points[i][1]==points[i][3] ){
                if(min(points[i][0],points[i][2])<=points[j][0] &&  max(points[i][0],points[i][2])>=points[j][0]){
                    if(min(points[j][1],points[j][3])<=points[i][1] &&  max(points[j][1],points[j][3])>=points[i][1]){
                        inter.push_back(make_pair(points[j][0],points[i][1]));
                        rec.push_back(make_pair(j,i));
                        mat[points[j][0]][points[i][1]]=true;
                    }
                }
            }
        }
    }
    int ans=0;
    for( int i=0;i<inter.size();i++){
        for(int j=0;j<inter.size();j++){
            if(inter[i].first> inter[j].first && inter[i].second> inter[j].second && mat[ inter[i].first][inter[j].second]==true &&  mat[ inter[j].first][inter[i].second]==true ){
                int x=rec[i].first;
                int y=rec[j].second;
                 int x1=rec[j].first;
                int y1=rec[i].second;
                if(min(points[y][0],points[y][2])<=points[x][0] &&  max(points[y][0],points[y][2])>=points[x][0])
                    if(min(points[x][1],points[x][3])<=points[y][1] &&  max(points[x][1],points[x][3])>=points[y][1])
                        if(min(points[y1][0],points[y1][2])<=points[x1][0] &&  max(points[y1][0],points[y1][2])>=points[x1][0])
                           if(min(points[x1][1],points[x1][3])<=points[y1][1] &&  max(points[x1][1],points[x1][3])>=points[y1][1])
                                ans++;
            }
        }

    }
    printf("%d\n",ans);

	//freopen("in.txt","r",stdin);
	//freopen("out.txt","w",stdout);
	return 0;
}


#include<bits/stdc++.h>
#define ms(a,v) memset(a,v,sizeof a)
#define ll long long
using namespace std;
short points[5000][4];
set<short> adj[5000];
int ans=0;
bool visited[5000];
bool mt[5000][5000];
int root;

void dfs(int node,int p){
    visited[node]=true;

    if(p==3){
        bool flag=false;
            if(mt[node][root]){
                    flag=true;

            }
        if(flag){
            //cout<<"hjk "<<node+1<<" "<<root+1<<endl;
            ans++;
        }
        visited[node]=false;
        return ;
    }
    for(int i=root+1;i<5000;i++)
            if(mt[node][i])
                if(!visited[i])
                    dfs(i,p+1);

    visited[node]=false;
}
//Code By Stephan Ramirez dsramirezc@unal.edu.co
int main(){
    //freopen("in.txt","r",stdin);
    int n;
    scanf("%d",&n);
    //cout<<n<<endl;
    for(int i=0;i<n;i++)
        scanf("%d %d %d %d",&points[i][0],&points[i][1],&points[i][2],&points[i][3]);
    for(int i=0;i<n;i++){
        for(int j=0;j<n;j++){
            if(points[i][0]==points[i][2] && points[j][1]==points[j][3] ){
                if(min(points[j][0],points[j][2])<=points[i][0] &&  max(points[j][0],points[j][2])>=points[i][0]){
                    if(min(points[i][1],points[i][3])<=points[j][1] &&  max(points[i][1],points[i][3])>=points[j][1]){
                            mt[i][j]=true;
                            mt[j][i]=true;

                           // cout<<"inter "<<i<<" "<<j<<endl;

                    }
                }
            }else if(points[j][0]==points[j][2] && points[i][1]==points[i][3] ){
                if(min(points[i][0],points[i][2])<=points[j][0] &&  max(points[i][0],points[i][2])>=points[j][0]){
                    if(min(points[j][1],points[j][3])<=points[i][1] &&  max(points[j][1],points[j][3])>=points[i][1]){
                           // cout<<"inter "<<i<<" "<<j<<endl;
                           mt[i][j]=true;
                            mt[j][i]=true;
                    }
                }
            }
        }
    }

    for(int i=0;i<n;i++){
        root =i;

        dfs(root,0);

    }

    printf("%d\n",ans/2);

	return 0;
}


#include<bits/stdc++.h>
#define ms(a,v) memset(a,v,sizeof a)
#define ll long long
using namespace std;
short points[5005][4];
vector<short> adj[5005];
int ans=0;
bool visited[5005];

int root;

void dfs(int node,int p){
    visited[node]=true;

    if(p==3){
        bool flag=false;
        for(int i :adj[node])
            if(i==root){
                flag=true;
                break;
            }
        if(flag){
            //cout<<"hjk "<<node+1<<" "<<root+1<<endl;
            ans++;
        }
        visited[node]=false;
        return ;
    }
    for(int i: adj[node]){
        if(!visited[i])
            dfs(i,p+1);
    }
    visited[node]=false;
}
//Code By Stephan Ramirez dsramirezc@unal.edu.co
int main(){
    //freopen("in.txt","r",stdin);
    int n;
    scanf("%d",&n);
    //cout<<n<<endl;
    for(int i=0;i<n;i++)
        scanf("%d %d %d %d",&points[i][0],&points[i][1],&points[i][2],&points[i][3]);
    for(int i=0;i<n;i++){
        for(int j=0;j<n;j++){
            if(points[i][0]==points[i][2] && points[j][1]==points[j][3] ){
                if(min(points[j][0],points[j][2])<=points[i][0] &&  max(points[j][0],points[j][2])>=points[i][0]){
                    if(min(points[i][1],points[i][3])<=points[j][1] &&  max(points[i][1],points[i][3])>=points[j][1]){
                            adj[i].insert(j);
                            adj[j].insert(i);

                           // cout<<"inter "<<i<<" "<<j<<endl;

                    }
                }
            }
            if(points[j][0]==points[j][2] && points[i][1]==points[i][3] ){
                if(min(points[i][0],points[i][2])<=points[j][0] &&  max(points[i][0],points[i][2])>=points[j][0]){
                    if(min(points[j][1],points[j][3])<=points[i][1] &&  max(points[j][1],points[j][3])>=points[i][1]){
                           // cout<<"inter "<<i<<" "<<j<<endl;
                            adj[j].insert(i);
                            adj[i].insert(j);
                    }
                }
            }
        }
    }

    for(int i=0;i<n;i++){
        root =i;
        ms(visited,false);
        dfs(root,0);

    }

    printf("%d\n",max(ans,0)/8);

	return 0;
}


#include<bits/stdc++.h>
#define ms(a,v) memset(a,v,sizeof a)
#define ll long long
using namespace std;
short points[5005][4];
set<int> adj[5005];
int ans=0;
bool visited[5005];

int root;

void dfs(int node,int p){
    visited[node]=true;

    if(p==3){
        bool flag=false;
        for(int i :adj[node])
            if(i==root){
                flag=true;
                break;
            }
        if(flag){
            //cout<<"hjk "<<node+1<<" "<<root+1<<endl;
            ans++;
        }
        visited[node]=false;
        return ;
    }
    for(int i: adj[node]){
        if(!visited[i])
            dfs(i,p+1);
    }
    visited[node]=false;
}
//Code By Stephan Ramirez dsramirezc@unal.edu.co
int main(){
    //freopen("in.txt","r",stdin);
    int n;
    scanf("%d",&n);
    //cout<<n<<endl;
    for(int i=0;i<n;i++)
        scanf("%d %d %d %d",&points[i][0],&points[i][1],&points[i][2],&points[i][3]);
    for(int i=0;i<n;i++){
        for(int j=0;j<n;j++){
            if(points[i][0]==points[i][2] && points[j][1]==points[j][3] ){
                if(min(points[j][0],points[j][2])<=points[i][0] &&  max(points[j][0],points[j][2])>=points[i][0]){
                    if(min(points[i][1],points[i][3])<=points[j][1] &&  max(points[i][1],points[i][3])>=points[j][1]){
                            adj[i].insert(j);
                            adj[j].insert(i);

                           // cout<<"inter "<<i<<" "<<j<<endl;

                    }
                }
            }
            if(points[j][0]==points[j][2] && points[i][1]==points[i][3] ){
                if(min(points[i][0],points[i][2])<=points[j][0] &&  max(points[i][0],points[i][2])>=points[j][0]){
                    if(min(points[j][1],points[j][3])<=points[i][1] &&  max(points[j][1],points[j][3])>=points[i][1]){
                           // cout<<"inter "<<i<<" "<<j<<endl;
                            adj[j].insert(i);
                            adj[i].insert(j);
                    }
                }
            }
        }
    }

    for(int i=0;i<n;i++){
        root =i;
        ms(visited,false);
        dfs(root,0);

    }

    printf("%d\n",max(ans,0)/8);

	return 0;
}


#include<bits/stdc++.h>
#define ms(a,v) memset(a,v,sizeof a)
#define ll long long
using namespace std;
map<int,bool> mat[10002];
//Code By Stephan Ramirez dsramirezc@unal.edu.co
int main(){
    int n;
    scanf("%d",&n);
    int points[n][4];
    for(int i=0;i<n;i++){
        scanf("%d %d %d %d",&points[i][0],&points[i][1],&points[i][2],&points[i][3]);
        points[i][0]+=5000;
        points[i][1]+=5000;
        points[i][2]+=5000;
        points[i][3]+=5000;
    }

    vector< pair<int,int> >inter;
    vector< pair<int,int> >rec;

    for(int i=0;i<n;i++){
        for(int j=i+1;j<n;j++){
            if(points[i][0]==points[i][2] && points[j][1]==points[j][3] ){
                if(min(points[j][0],points[j][2])<=points[i][0] &&  max(points[j][0],points[j][2])>=points[i][0]){
                    if(min(points[i][1],points[i][3])<=points[j][1] &&  max(points[i][1],points[i][3])>=points[j][1]){
                        inter.push_back(make_pair(points[i][0],points[j][1]));
                        rec.push_back(make_pair(i,j));
                        mat[points[i][0]][points[j][1]]=true;
                    }
                }
            }
            if(points[j][0]==points[j][2] && points[i][1]==points[i][3] ){
                if(min(points[i][0],points[i][2])<=points[j][0] &&  max(points[i][0],points[i][2])>=points[j][0]){
                    if(min(points[j][1],points[j][3])<=points[i][1] &&  max(points[j][1],points[j][3])>=points[i][1]){
                        inter.push_back(make_pair(points[j][0],points[i][1]));
                        rec.push_back(make_pair(j,i));
                        mat[points[j][0]][points[i][1]]=true;
                    }
                }
            }
        }
    }
    int ans=0;
    for( int i=0;i<inter.size();i++){
        for(int j=0;j<inter.size();j++){
            if(inter[i].first> inter[j].first && inter[i].second> inter[j].second && mat[ inter[i].first][inter[j].second]==true &&  mat[ inter[j].first][inter[i].second]==true ){
                int x=rec[i].first;
                int y=rec[j].second;
                 int x1=rec[j].first;
                int y1=rec[i].second;
                if(min(points[y][0],points[y][2])<=points[x][0] &&  max(points[y][0],points[y][2])>=points[x][0])
                    if(min(points[x][1],points[x][3])<=points[y][1] &&  max(points[x][1],points[x][3])>=points[y][1])
                        if(min(points[y1][0],points[y1][2])<=points[x1][0] &&  max(points[y1][0],points[y1][2])>=points[x1][0])
                           if(min(points[x1][1],points[x1][3])<=points[y1][1] &&  max(points[x1][1],points[x1][3])>=points[y1][1])
                                ans++;
            }
        }

    }
    printf("%d\n",ans);

	//freopen("in.txt","r",stdin);
	//freopen("out.txt","w",stdout);
	return 0;
}


//Code By Stephan Ramirez dsramirezc@unal.edu.co
#include<bits/stdc++.h>
#define ms(a,v) memset(a,v,sizeof a)
#define ll long long
using namespace std;

const int N=10005;
int sg[N*2];
int operation(int a, int b){
    return a+b;
}
int query(int l,int r){
    l+=N;
    r+=N+1;
    int ans=0;
    for(;l < r;l>>=1,r>>=1) {
        if (l & 1) ans=operation(ans,sg[l++]);
        if (r & 1) ans=operation(ans,sg[--r]);
    }
    return ans;
}
void actualizar(int position,int value){
    sg[position+N]+=value;
    for(int pos=(N+position)/2;pos>0;pos/=2)
        sg[pos]=operation(sg[pos*2],sg[pos*2+1]);
}
int corrimiento=5001;
int n;
vector< pair< int , pair< int,int > > >ver;
vector< pair< pair< int,int >,int > >hor;

int main(){
    //freopen("in.txt","r",stdin);
    //freopen("out.txt","w",stdout);
    scanf("%d",&n);
    for(int i=0;i<n;i++){
        int x1,y1,x2,y2;
        scanf("%d %d %d %d",&x1,&y1,&x2,&y2);
        if(x1==x2)
            ver.push_back(make_pair(x1+corrimiento,make_pair(corrimiento+min(y1,y2),corrimiento+max(y1,y2))));
        else
            hor.push_back(make_pair(make_pair(corrimiento+max(x1,x2),corrimiento+min(x1,x2)),y1+corrimiento));
    }
    sort(ver.begin(),ver.end());
    sort(hor.begin(),hor.end());
    ms(sg,0);
    int ans=0;
    deque<pair<int,int>> aux;
    for(int i=0;i<ver.size();i++){

        for(int j=0;j<hor.size();j++){
            if(hor[j].first.second<=ver[i].first){
                aux.push_back(make_pair(hor[j].second,hor[j].first.first));
                actualizar(hor[j].second,1);
            }
        }
        for(int j=i+1;j<ver.size();j++){
            while(aux.size()>0 && aux[0].second<ver[j].first){
                actualizar(aux[0].first,-1);
                aux.pop_front();
            }
            int x=query(max(ver[i].second.first,ver[j].second.first),min(ver[i].second.second,ver[j].second.second));
            ans+=((x)*(x-1))/2;
        }
        while(aux.size()>0){
                actualizar(aux[0].first,-1);
                aux.pop_front();
        }
    }
    cout<<ans<<endl;
	return 0;
}


//Code By Stephan Ramirez dsramirezc@unal.edu.co
#include<bits/stdc++.h>
#define ms(a,v) memset(a,v,sizeof a)
#define ll long long
using namespace std;

const int N=10005;
int sg[N*2];
int operation(int a, int b){
    return a+b;
}
int query(int l,int r){
    l+=N;
    r+=N+1;
    int ans=0;
    for(;l < r;l>>=1,r>>=1) {
        if (l & 1) ans=operation(ans,sg[l++]);
        if (r & 1) ans=operation(ans,sg[--r]);
    }
    return ans;
}
void actualizar(int position,int value){
    sg[position+N]+=value;
    for(int pos=(N+position)/2;pos>0;pos/=2)
        sg[pos]=operation(sg[pos*2],sg[pos*2+1]);
}
int corrimiento=5001;
int n;
vector< pair< int , pair< int,int > > >ver;
vector< pair< pair< int,int >,int > >hor;

int main(){
    //freopen("in.txt","r",stdin);
    //freopen("out.txt","w",stdout);
    scanf("%d",&n);
    for(int i=0;i<n;i++){
        int x1,y1,x2,y2;
        scanf("%d %d %d %d",&x1,&y1,&x2,&y2);
        if(x1==x2)
            ver.push_back(make_pair(x1+corrimiento,make_pair(corrimiento+min(y1,y2),corrimiento+max(y1,y2))));
        else
            hor.push_back(make_pair(make_pair(corrimiento+max(x1,x2),corrimiento+min(x1,x2)),y1+corrimiento));
    }
    sort(ver.begin(),ver.end());
    sort(hor.begin(),hor.end());
    ms(sg,0);
    ll ans=0;
    deque<pair<int,int>> aux;
    for(int i=0;i<ver.size();i++){

        for(int j=0;j<hor.size();j++){
            if(hor[j].first.second<=ver[i].first){
                aux.push_back(make_pair(hor[j].second,hor[j].first.first));
                actualizar(hor[j].second,1);
            }
        }
        for(int j=i+1;j<ver.size();j++){
            while(aux.size()>0 && aux[0].second<ver[j].first){
                actualizar(aux[0].first,-1);
                aux.pop_front();
            }
            int x=query(max(ver[i].second.first,ver[j].second.first),min(ver[i].second.second,ver[j].second.second));
            ans+=((x)*(x-1))/2;
        }
        while(aux.size()>0){
                actualizar(aux[0].first,-1);
                aux.pop_front();
        }
    }
    cout<<ans<<endl;
	return 0;
}


#include<bits/stdc++.h>
#define ms(a,v) memset(a,v,sizeof a)
#define ll long long
using namespace std;
short points[5005][4];
set<short> adj[5005];
int ans=0;
bool visited[5005];

int root;

void dfs(int node,int p){
    visited[node]=true;

    if(p==3){
        bool flag=false;
        for(int i :adj[node])
            if(i==root){
                flag=true;
                break;
            }
        if(flag){
            //cout<<"hjk "<<node+1<<" "<<root+1<<endl;
            ans++;
        }
        visited[node]=false;
        return ;
    }
    for(int i: adj[node]){
        if(!visited[i])
            dfs(i,p+1);
    }
    visited[node]=false;
}
//Code By Stephan Ramirez dsramirezc@unal.edu.co
int main(){
    freopen("in.txt","r",stdin);
    int n;
    scanf("%d",&n);
    //cout<<n<<endl;
    for(int i=0;i<n;i++)
        scanf("%d %d %d %d",&points[i][0],&points[i][1],&points[i][2],&points[i][3]);
    for(int i=0;i<n;i++){
        for(int j=0;j<n;j++){
            if(points[i][0]==points[i][2] && points[j][1]==points[j][3] ){
                if(min(points[j][0],points[j][2])<=points[i][0] &&  max(points[j][0],points[j][2])>=points[i][0]){
                    if(min(points[i][1],points[i][3])<=points[j][1] &&  max(points[i][1],points[i][3])>=points[j][1]){
                            adj[i].insert(j);
                            adj[j].insert(i);

                           // cout<<"inter "<<i<<" "<<j<<endl;

                    }
                }
            }
            if(points[j][0]==points[j][2] && points[i][1]==points[i][3] ){
                if(min(points[i][0],points[i][2])<=points[j][0] &&  max(points[i][0],points[i][2])>=points[j][0]){
                    if(min(points[j][1],points[j][3])<=points[i][1] &&  max(points[j][1],points[j][3])>=points[i][1]){
                           // cout<<"inter "<<i<<" "<<j<<endl;
                            adj[j].insert(i);
                            adj[i].insert(j);
                    }
                }
            }
        }
    }

    for(int i=0;i<n;i++){
        root =i;
        ms(visited,false);
        dfs(root,0);

    }

    printf("%d\n",max(ans,0)/8);

	return 0;
}