import java.util.ArrayList;
import java.util.List;

public class Euler630 {
    static class Point {
        int x, y;

        Point(int x, int y) {
            this.x = x;
            this.y = y;
        }
    }

    static long gcd(long a, long b) {
        while (b != 0) {
            long t = b;
            b = a % b;
            a = t;
        }
        return a;
    }

    static List<Point> generatePoints(int n) {
        List<Point> pts = new ArrayList<>(n);
        long S = 290797;
        for (int k = 0; k < n; k++) {
            S = (S * S) % 50515093;
            int x = (int) (S % 2000) - 1000;
            S = (S * S) % 50515093;
            int y = (int) (S % 2000) - 1000;
            pts.add(new Point(x, y));
        }
        return pts;
    }

    static long[] computeMS(int n) {
        List<Point> pts = generatePoints(n);
        long[] keysTmp = new long[n * (n - 1) / 2];
        int idx = 0;

        for (int i = 0; i < n; i++) {
            Point p1 = pts.get(i);
            for (int j = i + 1; j < n; j++) {
                Point p2 = pts.get(j);
                int dx = p2.x - p1.x;
                int dy = p2.y - p1.y;
                if (dx == 0 && dy == 0)
                    continue;
                int g = (int) Math.abs(gcd(Math.abs(dx), Math.abs(dy)));
                dx /= g;
                dy /= g;

                int A = dy;
                int B = -dx;
                long C = (long) A * p1.x + (long) B * p1.y;
                if (A < 0 || (A == 0 && B < 0)) {
                    A = -A;
                    B = -B;
                    C = -C;
                }

                long Co = C + 4000000L;
                long Ao = A;
                long Bo = B + 2048;
                long val = (Ao << 35) | (Bo << 23) | Co;
                keysTmp[idx++] = val;
            }
        }

        long[] keysStr = new long[idx];
        System.arraycopy(keysTmp, 0, keysStr, 0, idx);
        java.util.Arrays.sort(keysStr);

        int uniqueCount = 0;
        if (keysStr.length > 0) {
            uniqueCount = 1;
            for (int i = 1; i < keysStr.length; i++) {
                if (keysStr[i] != keysStr[i - 1]) {
                    keysStr[uniqueCount++] = keysStr[i];
                }
            }
        }

        long M = uniqueCount;
        long parallel2 = 0;
        for (int i = 0; i < uniqueCount;) {
            long slope = keysStr[i] >> 23;
            int j = i + 1;
            while (j < uniqueCount && (keysStr[j] >> 23) == slope)
                j++;
            long m = j - i;
            parallel2 += m * (m - 1);
            i = j;
        }

        long S = M * (M - 1) - parallel2;
        return new long[] { M, S };
    }

    public static String solve() {
        return Long.toString(computeMS(2500)[1]);
    }

    public static void main(String[] args) {
        System.out.println(solve());
    }
}
