#include <bits/stdc++.h>
using namespace std;
inline long long read() {
  long long f = 1, ans = 0;
  char c = getchar();
  while (c < '0' || c > '9') {
    if (c == '-') f = -1;
    c = getchar();
  }
  while (c >= '0' && c <= '9') {
    ans = ans * 10 + c - '0';
    c = getchar();
  }
  return f * ans;
}
const long long MAXN = 10001;
const long long Maxn = 5001;
struct Node {
  long long x1, y1, x2, y2, id;
} row[MAXN], col[MAXN];
bool cmp(Node r1, Node r2) { return r1.y2 < r2.y2; }
bool cmp1(Node r1, Node r2) { return r1.x2 < r2.x2; }
long long cr, cl, N1, N2, tmp0[MAXN], tmp1[MAXN], N, ans;
inline long long H1(long long w) {
  return lower_bound(tmp0 + 1, tmp0 + N1 + 1, w) - tmp0;
}
inline long long H2(long long w) {
  return lower_bound(tmp1 + 1, tmp1 + N2 + 1, w) - tmp1;
}
struct BIT {
  long long Ans[MAXN];
  inline void clear() {
    memset(Ans, 0, sizeof(Ans));
    return;
  }
  inline long long lowbit(long long x) { return x & -x; }
  inline void Modify(long long x, long long w) {
    for (; x <= N; x += lowbit(x)) Ans[x] += w;
    return;
  }
  inline long long Que(long long x) {
    long long res = 0;
    for (; x; x -= lowbit(x)) res += Ans[x];
    return res;
  }
  inline long long Query(long long l, long long r) {
    return Que(r) - Que(l - 1);
  }
} bit;
long long Que[MAXN];
namespace Q1 {
inline void Main() {
  N = N1;
  for (register long long i = 1; i <= cr; i++) {
    bit.clear();
    Que[0] = 0;
    for (long long j = 1; j <= cl; j++) {
      if (row[i].y1 >= col[j].y1 && col[j].y2 >= row[i].y1 &&
          row[i].x1 <= col[j].x1 && col[j].x1 <= row[i].x2)
        bit.Modify(col[j].x1, 1), Que[++Que[0]] = j;
    }
    long long top = 1;
    for (register long long j = i + 1; j <= cr; j++) {
      while (top <= Que[0] && col[Que[top]].y2 < row[j].y1)
        bit.Modify(col[Que[top]].x1, -1), top++;
      long long L = max(row[i].x1, row[j].x1), R = min(row[i].x2, row[j].x2);
      if (L > R) continue;
      long long res = bit.Query(L, R);
      res = (res * (res - 1)) / 2;
      ans += res;
    }
  }
  return;
}
}  // namespace Q1
long long n, q;
signed main() {
  n = read();
  for (register long long i = 1; i <= n; ++i) {
    long long x1 = read(), y1 = read(), x2 = read(), y2 = read();
    if (x1 > x2) swap(x1, x2);
    if (y1 > y2) swap(y1, y2);
    if (y1 == y2)
      row[++cr].x1 = x1, row[cr].y1 = y1, row[cr].x2 = x2, row[cr].y2 = y2,
      row[cr].id = cr;
    else
      col[++cl].x1 = x1, col[cl].y1 = y1, col[cl].x2 = x2, col[cl].y2 = y2,
      col[cl].id = cl;
    tmp0[++tmp0[0]] = x1, tmp0[++tmp0[0]] = x2;
    tmp1[++tmp1[0]] = y1, tmp1[++tmp1[0]] = y2;
  }
  sort(tmp0 + 1, tmp0 + tmp0[0] + 1);
  sort(tmp1 + 1, tmp1 + tmp1[0] + 1);
  N1 = unique(tmp0 + 1, tmp0 + tmp0[0] + 1) - tmp0 - 1;
  N2 = unique(tmp1 + 1, tmp1 + tmp1[0] + 1) - tmp1 - 1;
  for (register long long i = 1; i <= cr; ++i)
    row[i].x1 = H1(row[i].x1), row[i].x2 = H1(row[i].x2),
    row[i].y1 = H2(row[i].y1), row[i].y2 = H2(row[i].y2);
  for (register long long i = 1; i <= cl; ++i)
    col[i].x1 = H1(col[i].x1), col[i].x2 = H1(col[i].x2),
    col[i].y1 = H2(col[i].y1), col[i].y2 = H2(col[i].y2);
  sort(row + 1, row + cr + 1, cmp);
  sort(col + 1, col + cl + 1, cmp);
  Q1::Main();
  printf("%lld\n", ans);
  return 0;
}

### Prompt

Please formulate a CPP solution to the following problem:

There are n segments drawn on a plane; the i-th segment connects two points (x_{i, 1}, y_{i, 1}) and (x_{i, 2}, y_{i, 2}). Each segment is non-degenerate, and is either horizontal or vertical — formally, for every i ∈ [1, n] either x_{i, 1} = x_{i, 2} or y_{i, 1} = y_{i, 2} (but only one of these conditions holds). Only segments of different types may intersect: no pair of horizontal segments shares any common points, and no pair of vertical segments shares any common points.

We say that four segments having indices h_1, h_2, v_1 and v_2 such that h_1 < h_2 and v_1 < v_2 form a rectangle if the following conditions hold:

  * segments h_1 and h_2 are horizontal; 
  * segments v_1 and v_2 are vertical; 
  * segment h_1 intersects with segment v_1; 
  * segment h_2 intersects with segment v_1; 
  * segment h_1 intersects with segment v_2; 
  * segment h_2 intersects with segment v_2. 



Please calculate the number of ways to choose four segments so they form a rectangle. Note that the conditions h_1 < h_2 and v_1 < v_2 should hold.

Input

The first line contains one integer n (1 ≤ n ≤ 5000) — the number of segments.

Then n lines follow. The i-th line contains four integers x_{i, 1}, y_{i, 1}, x_{i, 2} and y_{i, 2} denoting the endpoints of the i-th segment. All coordinates of the endpoints are in the range [-5000, 5000].

It is guaranteed that each segment is non-degenerate and is either horizontal or vertical. Furthermore, if two segments share a common point, one of these segments is horizontal, and another one is vertical.

Output

Print one integer — the number of ways to choose four segments so they form a rectangle.

Examples

Input


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


Output


7


Input


5
1 5 1 0
0 1 5 1
5 4 0 4
4 2 4 0
4 3 4 5


Output


0

Note

The following pictures represent sample cases:

<image> <image>

### Response

```cpp
#include <bits/stdc++.h>
using namespace std;
inline long long read() {
  long long f = 1, ans = 0;
  char c = getchar();
  while (c < '0' || c > '9') {
    if (c == '-') f = -1;
    c = getchar();
  }
  while (c >= '0' && c <= '9') {
    ans = ans * 10 + c - '0';
    c = getchar();
  }
  return f * ans;
}
const long long MAXN = 10001;
const long long Maxn = 5001;
struct Node {
  long long x1, y1, x2, y2, id;
} row[MAXN], col[MAXN];
bool cmp(Node r1, Node r2) { return r1.y2 < r2.y2; }
bool cmp1(Node r1, Node r2) { return r1.x2 < r2.x2; }
long long cr, cl, N1, N2, tmp0[MAXN], tmp1[MAXN], N, ans;
inline long long H1(long long w) {
  return lower_bound(tmp0 + 1, tmp0 + N1 + 1, w) - tmp0;
}
inline long long H2(long long w) {
  return lower_bound(tmp1 + 1, tmp1 + N2 + 1, w) - tmp1;
}
struct BIT {
  long long Ans[MAXN];
  inline void clear() {
    memset(Ans, 0, sizeof(Ans));
    return;
  }
  inline long long lowbit(long long x) { return x & -x; }
  inline void Modify(long long x, long long w) {
    for (; x <= N; x += lowbit(x)) Ans[x] += w;
    return;
  }
  inline long long Que(long long x) {
    long long res = 0;
    for (; x; x -= lowbit(x)) res += Ans[x];
    return res;
  }
  inline long long Query(long long l, long long r) {
    return Que(r) - Que(l - 1);
  }
} bit;
long long Que[MAXN];
namespace Q1 {
inline void Main() {
  N = N1;
  for (register long long i = 1; i <= cr; i++) {
    bit.clear();
    Que[0] = 0;
    for (long long j = 1; j <= cl; j++) {
      if (row[i].y1 >= col[j].y1 && col[j].y2 >= row[i].y1 &&
          row[i].x1 <= col[j].x1 && col[j].x1 <= row[i].x2)
        bit.Modify(col[j].x1, 1), Que[++Que[0]] = j;
    }
    long long top = 1;
    for (register long long j = i + 1; j <= cr; j++) {
      while (top <= Que[0] && col[Que[top]].y2 < row[j].y1)
        bit.Modify(col[Que[top]].x1, -1), top++;
      long long L = max(row[i].x1, row[j].x1), R = min(row[i].x2, row[j].x2);
      if (L > R) continue;
      long long res = bit.Query(L, R);
      res = (res * (res - 1)) / 2;
      ans += res;
    }
  }
  return;
}
}  // namespace Q1
long long n, q;
signed main() {
  n = read();
  for (register long long i = 1; i <= n; ++i) {
    long long x1 = read(), y1 = read(), x2 = read(), y2 = read();
    if (x1 > x2) swap(x1, x2);
    if (y1 > y2) swap(y1, y2);
    if (y1 == y2)
      row[++cr].x1 = x1, row[cr].y1 = y1, row[cr].x2 = x2, row[cr].y2 = y2,
      row[cr].id = cr;
    else
      col[++cl].x1 = x1, col[cl].y1 = y1, col[cl].x2 = x2, col[cl].y2 = y2,
      col[cl].id = cl;
    tmp0[++tmp0[0]] = x1, tmp0[++tmp0[0]] = x2;
    tmp1[++tmp1[0]] = y1, tmp1[++tmp1[0]] = y2;
  }
  sort(tmp0 + 1, tmp0 + tmp0[0] + 1);
  sort(tmp1 + 1, tmp1 + tmp1[0] + 1);
  N1 = unique(tmp0 + 1, tmp0 + tmp0[0] + 1) - tmp0 - 1;
  N2 = unique(tmp1 + 1, tmp1 + tmp1[0] + 1) - tmp1 - 1;
  for (register long long i = 1; i <= cr; ++i)
    row[i].x1 = H1(row[i].x1), row[i].x2 = H1(row[i].x2),
    row[i].y1 = H2(row[i].y1), row[i].y2 = H2(row[i].y2);
  for (register long long i = 1; i <= cl; ++i)
    col[i].x1 = H1(col[i].x1), col[i].x2 = H1(col[i].x2),
    col[i].y1 = H2(col[i].y1), col[i].y2 = H2(col[i].y2);
  sort(row + 1, row + cr + 1, cmp);
  sort(col + 1, col + cl + 1, cmp);
  Q1::Main();
  printf("%lld\n", ans);
  return 0;
}

```