For given $n$ segments which are parallel to X-axis or Y-axis, find the number of intersections of them.

Constraints

* $1 \leq n \leq 100,000$
* $ -1,000,000,000 \leq x_1, y_1, x_2, y_2 \leq 1,000,000,000$
* Two parallel segments never overlap or touch.
* The number of intersections $\leq 1,000,000$

Input

In the first line, the number of segments $n$ is given. In the following $n$ lines, the $i$-th segment is given by coordinates of its end points in the following format:

$x_1 \; y_1 \; x_2 \; y_2$

The coordinates are given in integers.

Output

Print the number of intersections in a line.

Example

Input

6
2 2 2 5
1 3 5 3
4 1 4 4
5 2 7 2
6 1 6 3
6 5 6 7


Output

3
#include <iostream>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <algorithm>
#include <functional>
#include <vector>
#include <queue>
#include <deque>
#include <stack>
#include <map>
#include <set>
#include <bitset>
#include <tuple>
#include <cassert>
#include <exception>
#include <iomanip>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<ll,ll> P;
typedef vector<int> vi;
typedef vector<ll> vll;
typedef vector<string> vs;
typedef vector<P> vp;
#define rep(i,a,n) for(ll i = (a);i < (n);i++)
#define per(i,a,n) for(ll i = (a);i > (n);i--)
#define lep(i,a,n) for(ll i = (a);i <= (n);i++)
#define pel(i,a,n) for(ll i = (a);i >= (n);i--)
#define clr(a,b) memset((a),(b),sizeof(a))
#define pb push_back
#define mp make_pair
#define all(c) (c).begin(),(c).end()
#define sz size()
#define print(X) cout << (X) << endl
#define fprint(NUM,X) cout << fixed << setprecision(NUM) << (X) << endl
#define fprints(NUM,X,Y) cout << fixed << setprecision(NUM) << (X) << " " << (Y) << endl
const ll INF = 1e+9+7;
ll n,m,l;
string s,t;
ll d[200010],dp[550][550];
double w[1000],v[1000];
double box[200010];

namespace Geometry{
  #define EPS (1e-10)
  #define equals(a,b) (fabs((a)-(b)) < EPS)

  class Point{
  public:
    double x,y;

    Point(double x = 0,double y = 0): x(x),y(y){}
    Point operator + (Point p){ return Point(x + p.x , y + p.y); }
    Point operator - (Point p){ return Point(x - p.x , y - p.y); }
    Point operator * (double a){ return Point(a * x , a * y); }
    Point operator / (double a){ return Point(x / a , y / a); }

    double abs(){ return sqrt(norm()); }
    double norm(){ return x * x + y * y; }

    bool operator < (const Point &p) const{
      return x != p.x ? x < p.x : y < p.y;
    }

    bool operator == (const Point &p) const{
      return (fabs(x - p.x) < EPS) && (fabs(y - p.y) < EPS);
    }

    friend ostream& operator << (ostream &os,Point &p){
      return os << p.x << " " << p.y;
    }

    friend istream& operator >> (istream &is,Point &p){
      return is >> p.x >> p.y;
    }
  };
  typedef Point Vector;

  struct Segment{
    Point p1,p2;
    Segment(){};
    Segment(Point p1,Point p2): p1(p1) , p2(p2){};
    friend ostream& operator << (ostream &os,Segment &p){
      return os << p.p1.x << " " << p.p1.y << " " << p.p2.x << " " << p.p2.y;
    }

    friend istream& operator >> (istream &is,Segment &p){
      return is >> p.p1.x >> p.p1.y >> p.p2.x >> p.p2.y;
    }
  };
  typedef Segment Line;

  class Circle{
  public:
    Point c;
    double r;
    Circle(Point c = Point(),double r = 0.0): c(c),r(r){}
    friend ostream& operator << (ostream &os,Circle &c){
      return os << c.c.x << c.c.y << c.r;
    }

    friend istream& operator >> (istream &is,Circle &c){
      return is >> c.c.x >> c.c.y >> c.r;
    }
  };

  typedef vector<Point> Polygon;

  double norm(Vector a){
    return  a.x * a.x + a.y * a.y;
  }

  double abs(Vector a){
    return sqrt(norm(a));
  }

  double dot(Vector a,Vector b){
    return a.x * b.x + a.y * b.y;
  }

  double cross(Vector a,Vector b){
    return a.x * b.y - a.y * b.x;
  }

  bool isOrthogonal(Vector a,Vector b){
    return equals(dot(a,b),0.0);
  }

  bool isOrthogonal(Point a1,Point a2,Point b1,Point b2){
    return isOrthogonal(a1 - a1,b1 - b2);
  }

  bool isOrthogonal(Segment s1,Segment s2){
    return equals(dot(s1.p2 - s1.p1,s2.p2 - s2.p1) , 0.0);
  }

  bool isParallel(Vector a,Vector b){
    return equals(cross(a,b),0.0);
  }

  bool isParallel(Point a1,Point a2,Point b1,Point b2){
    return isParallel(a1 - a2 , b1 - b2);
  }

  bool isParallel(Segment s1,Segment s2){
    return equals(cross(s1.p2 - s1.p1 , s2.p2 - s2.p1),0.0);
  }

  Point project(Segment s,Point p){
    Vector base = s.p2 - s.p1;
    double r = dot(p - s.p1 , base) / norm(base);
    return s.p1 + base * r;
  }

  Point reflect(Segment s,Point p){
    return p + (project(s,p) - p) * 2.0;
  }

  static const int COUNTER_CLOCKWISE = 1;
  static const int CLOCKWISE = -1;
  static const int ONLINE_BACK = 2;
  static const int ONLINE_FRONT = -2;
  static const int ON_SEGMENT = 0;

  int ccw(Point p0,Point p1,Point p2){
    Vector a = p1 - p0;
    Vector b = p2 - p0;
    if(cross(a,b) > EPS)return COUNTER_CLOCKWISE;
    if(cross(a,b) < -EPS)return CLOCKWISE;
    if(dot(a,b) < -EPS)return ONLINE_BACK;
    if(a.norm() < b.norm())return ONLINE_FRONT;
    return ON_SEGMENT;
  }

  bool intersect(Point p1,Point p2,Point p3,Point p4){
    return (ccw(p1,p2,p3) * ccw(p1,p2,p4) <= 0 && 
            ccw(p3,p4,p1) * ccw(p3,p4,p2) <= 0);
  }

  bool intersect(Segment s1,Segment s2){
    return intersect(s1.p1 , s1.p2 , s2.p1 , s2.p2);
  }

  double getDistance(Vector a,Vector b){
    return abs(a - b);
  }

  double getDistanceLP(Line l,Point p){
    return abs(cross(l.p2 - l.p1 , p - l.p1) / abs(l.p2 - l.p1));
  }

  double getDistanceSP(Segment s,Point p){
    if(dot(s.p2 - s.p1,p - s.p1) < 0.0) return abs(p - s.p1);
    if(dot(s.p1 - s.p2,p - s.p2) < 0.0) return abs(p - s.p2);
    return getDistanceLP(s,p);
  }

  double getDistance(Segment s1,Segment s2){
    if(intersect(s1,s2))return 0.0;
    return min(min(getDistanceSP(s1,s2.p1),getDistanceSP(s1,s2.p2)),
              min(getDistanceSP(s2,s1.p1),getDistanceSP(s2,s1.p2)));
  }

  Point getCrossPoint(Segment s1,Segment s2){
    Vector base = s2.p2 - s2.p1;
    double d1 = abs(cross(base,s1.p1 - s2.p1));
    double d2 = abs(cross(base,s1.p2 - s2.p1));
    double t = d1 / (d1 + d2);
    return s1.p1 + (s1.p2 - s1.p1) * t;
  }

  pair<Point,Point> getCrossPoints(Circle c,Line l){
    // cassert(intersect(c,l));
    Vector pr = project(l,c.c);
    Vector e = (l.p2 - l.p1) / abs(l.p2 - l.p1);
    double base = sqrt(c.r * c.r - norm(pr - c.c));
    return make_pair(pr + e * base , pr - e * base);
  }

  double arg(Vector p){
    return atan2(p.y,p.x);
  }

  Vector polar(double a,double r){
    return Point(cos(r) * a, sin(r) * a);
  }

  pair<Point,Point> getCrossPoints(Circle c1,Circle c2){
    // assert(intersect(c1,c2));
    double d = abs(c1.c - c2.c);
    double a = acos((c1.r * c1.r + d * d - c2.r * c2.r) / (2 * c1.r * d));
    double t = arg(c2.c - c1.c);
    return make_pair(c1.c + polar(c1.r,t + a),c1.c + polar(c1.r,t - a));
  }

  int contains(Polygon g,Point p){
    int n = g.size();
    bool x = false;
    for(int i = 0;i < n;i++){
      Point a = g[i] - p, b = g[(i + 1) % n] - p;
      if(abs(cross(a,b)) < EPS && dot(a,b) < EPS)return 1;
      if(a.y > b.y)swap(a,b);
      if(a.y < EPS && EPS < b.y && cross(a,b) > EPS)x = !x;
    }
    return (x ? 2 : 0);
  }

  int ccl(Point p0,Point p1,Point p2){
    Vector a = p1 - p0;
    Vector b = p2 - p0;
    if(cross(a,b) > EPS)return 1;
    return -1;
  }

  Polygon andrewScan(Polygon &s){
    Polygon u,l;
    if(s.size() < 3)return s;
    sort(s.begin(),s.end());

    u.push_back(s[0]);
    u.push_back(s[1]);
    l.push_back(s[s.size() - 1]);
    l.push_back(s[s.size() - 2]);

    for(int i = 2;i < s.size();i++){
      for(int n = u.size();n >= 2 && ccl(u[n-2],u[n-1],s[i]) != CLOCKWISE;n--){
        u.pop_back();
      }
      u.push_back(s[i]);
    }

    for(int i = s.size() - 3; i >= 0;i--){
      for(int n = l.size();n >= 2 && ccl(l[n-2],l[n-1],s[i]) != CLOCKWISE;n--){
        l.pop_back();
      }
      l.push_back(s[i]);
    }
    reverse(l.begin(),l.end());
    for(int i = u.size() - 2;i >= 1;i--)l.push_back(u[i]);
    return l;
  }

  #define BOTTOM 0
  #define LEFT 1
  #define RIGHT 2
  #define TOP 3

  class EndPoint{
  public:
    Point p;
    int seg,st;
    EndPoint(){}
    EndPoint(Point p,int seg,int st): p(p),seg(seg),st(st){}

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

  EndPoint EP[2 * 100000];

  int manhattanIntersection(vector<Segment> S){
    int n = S.size();
    for(int i = 0,k = 0;i < n;i++){
      if(S[i].p1.y == S[i].p2.y){
        if(S[i].p1.x > S[i].p2.x)swap(S[i].p1,S[i].p2);
      }else if(S[i].p1.y > S[i].p2.y){
        swap(S[i].p1,S[i].p2);
      }

      if(S[i].p1.y == S[i].p2.y){
        EP[k++] = EndPoint(S[i].p1,i,LEFT);
        EP[k++] = EndPoint(S[i].p2,i,RIGHT);
      }else{
        EP[k++] = EndPoint(S[i].p1,i,BOTTOM);
        EP[k++] = EndPoint(S[i].p2,i,TOP);
      }
    }

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

    set<int> BT;
    BT.insert(1000000001);
    int cnt = 0;
    for(int i = 0;i < 2 * n;i++){
      if(EP[i].st == TOP){
        BT.erase(EP[i].p.x);
      }else if(EP[i].st == BOTTOM){
        BT.insert(EP[i].p.x);
      }else if(EP[i].st == LEFT){
        set<int>::iterator b = lower_bound(BT.begin(),BT.end(),S[EP[i].seg].p1.x);
        set<int>::iterator e = upper_bound(BT.begin(),BT.end(),S[EP[i].seg].p2.x);
        cnt += distance(b,e);
      }
    }
    return cnt;
  }
};

using namespace Geometry;

int main(){
  Line a;
  cin >> n;
  vector<Segment> vec;
  rep(i,0,n){
    cin >> a;
    vec.pb(a);
  }
  print(manhattanIntersection(vec));
  return 0;
}
