public void solve() throws IOException {
    int n = nextInt();

    Map<String, List<Line>> linemap = new HashMap<String, List<Line>>();

    for (int x = 0; x < n; x++) {
      Line line = new Line(nextInt(), nextInt(), nextInt(), nextInt());
      String slope = line.slopeCode();
      //System.out.println(line.a + " " + line.b + " " + line.c);
      if (!linemap.containsKey(slope)) {
        linemap.put(slope, new ArrayList<Line>());
      }
      linemap.get(slope).add(line);
    }

    Map<String, Map<Double, Integer>> distmap = 
        new HashMap<String, Map<Double, Integer>>();
    for (String slope : linemap.keySet()) {
      HashMap<Double, Integer> distcount = new HashMap<Double, Integer>();
      List<Line> lines = linemap.get(slope);
      for (int x = 0; x < lines.size(); x++) {
        for (int y = x + 1; y < lines.size(); y++) {
          double dist = getDistance(lines.get(x), lines.get(y));
          //System.out.println(slope + " " + x + " " + y + " " + dist);
          if (!distcount.containsKey(dist)) {
            distcount.put(dist, 0);
          }
          distcount.put(dist, distcount.get(dist) + 1);
        }
      }
      distmap.put(slope, distcount);
    }

    long squares = 0;
    for (String slope : distmap.keySet()) {
      //System.out.println(slope);
      String reci = reci(slope);
      if (distmap.containsKey(reci)) {
        //System.out.println(slope + " " + reci);
        Map<Double, Integer> slopemap = distmap.get(slope);
        Map<Double, Integer> recimap = distmap.get(reci);
        Set<Double> shared = new HashSet<Double>(slopemap.keySet());
        shared.retainAll(recimap.keySet());
        for (double dist : shared) {
          //System.out.println(dist + " " + slopemap.get(dist) + " " + recimap.get(dist));
          squares += slopemap.get(dist) * recimap.get(dist);
        }
      }
    }
    squares /= 2;
    System.out.println(squares);
  }