Everything red frightens Nian the monster. So do red paper and... you, red on Codeforces, potential or real.Big Banban has got a piece of paper with endless lattice points, where lattice points form squares with the same area. His most favorite closed shape is the circle because of its beauty and simplicity. Once he had obtained this piece of paper, he prepares it for paper-cutting.  He drew n concentric circles on it and numbered these circles from 1 to n such that the center of each circle is the same lattice point and the radius of the k-th circle is  times the length of a lattice edge.Define the degree of beauty of a lattice point as the summation of the indices of circles such that this lattice point is inside them, or on their bounds. Banban wanted to ask you the total degree of beauty of all the lattice points, but changed his mind.Defining the total degree of beauty of all the lattice points on a piece of paper with n circles as f(n), you are asked to figure out .

The first line contains one integer m (1 ≤ m ≤ 1012).

In the first line print one integer representing .

NoteA piece of paper with 5 circles is shown in the following.  There are 5 types of lattice points where the degree of beauty of each red point is 1 + 2 + 3 + 4 + 5 = 15, the degree of beauty of each orange point is 2 + 3 + 4 + 5 = 14, the degree of beauty of each green point is 4 + 5 = 9, the degree of beauty of each blue point is 5 and the degree of beauty of each gray point is 0. Therefore, f(5) = 5·15 + 4·14 + 4·9 + 8·5 = 207.Similarly, f(1) = 5, f(2) = 23, f(3) = 50, f(4) = 102 and consequently .

import java.io.*;
import java.util.*;

public class Codeforces933D {
	public static void main(String[] args) throws IOException {
		// TODO Auto-generated method stub
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		StringTokenizer st = new StringTokenizer(br.readLine());
		long n = Long.parseLong(st.nextToken());

		int counter = 0;
		int N = 1000000007;

		for (int i = 0; i < 500000; i++) {
			counter += firstsum(n, 4*i+1);
			counter -= firstsum(n, 4*i+3);
			counter %= N;
		}

		for (int b = 1; b <= n/2000000; b++) {
			counter += secondsum(n, b);
			counter %= N;
		}

		int ans = (2*((2*counter)%N))%N;
		long k = ((((((n%N)*(n%N+1))%N)*(n%N+2))%N)*166666668)%N;
		ans = (ans + (int) k)%N;
		System.out.println(ans);
	}

	//1/2 = 500000004
	//1/3 = 333333336
	//1/6 = 166666668
	//lmao
	public static int firstsum(long n, long q) {
		int N = 1000000007;
		long floornq = (n/q)%N;
		n %= N;
		q %= N;
		long sum = ((floornq*(floornq+1))/2)%N;
		long sumsquare = (((sum*(2*floornq+1))%N)*333333336)%N;
		long sumcube = (sum*sum)%N;
		long nsquare = (n*n)%N;
		long qsquare = (q*q)%N;
		long qcube = (q*qsquare)%N;

		long k1 = (nsquare*floornq - qsquare*sumsquare + n*floornq + q*sum)%N;
		if (k1 < 0)
			k1 += N;
		k1 = (k1*(n+1))%N;
		k1 = (k1*500000004)%N;

		long k2 = (((((n*(n+1))%N)*(2*n+1))%N)*166666668)%N;
		k2 = (k2*floornq)%N;

		long k3 = (((qcube*sumcube)%N)*333333336)%N;
		k3 -= (((qsquare*sumsquare)%N)*500000004)%N;
		k3 += (((q*sum)%N)*166666668)%N;

		long ans = (k1-k2+k3)%N;
		if (ans < 0)
			ans += N;
		return (int) ans;
	}

	//wtf who successfully codes this up in a real round?
	public static int secondsum(long n, long b) {
		int N = 1000000007;
		long bsquare = (b*b)%N;
		long bcube = (b*bsquare)%N;
		long max = (n/(4*b)-1)%N;
		long numk = (max + N + 1 - 500000)%N;
		long sumk = ((max)*(max+1)/2 + 250875)%N;
		long sumksquare = ((((long) max * (long) (max+1))%N * (long) (2*max + 1))%N * 166666668)%N-375084213;
		if (sumksquare < 0)
			sumksquare += N;

		long k1 = (((bcube*sumksquare)%N)*32)%N;
		long k2 = (((bsquare*sumk)%N * (4*b-1)%N)%N *8)%N;
		long k3 = ((26*bcube - 12*bsquare + b)%N * 333333336)%N;
		if (k3 < 0)
			k3 += N;
		k3 = (k3*numk)%N;
		long k4 = (((n+1)%N)*(b*(numk*(((4*b*500000 + 4*b*max)+4*b-1)%N)%N)%N))%N;

		long k5 = 0;
		long k6 = 0;

		if (n%(4*b) >= b) {
			long min2 = ((4*b)*(n/(4*b))+b)%N;
			long max2 = (Math.min((4*b)*(n/(4*b))+3*b-1, n))%N;
			//sum from min2 to max2 of (n+1-i)*i
			k5 = (((((max2*(max2+1))%N)*(2*max2+1))%N)*166666668)%N;
			k5 -= (((((((min2-1)*min2)%N)*(2*min2-1))%N)*166666668)%N);
			k6 = ((max2*(max2+1) - min2*(min2-1))/2)%N;
			k6 = (k6*((n+1)%N))%N;
		}

		return (int) ((k4-k1-k2-k3-k5+k6+7*(long)N)%N);
	}

}

//package round462;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.util.Arrays;
import java.util.InputMismatchException;

public class D3 {
	InputStream is;
	PrintWriter out;
	String INPUT = "";

	void solve()
	{
		long m = nl();
		int mod = 1000000007;
		long mm = m%mod;
		long ans = 0;
		for(long x = 1;x*x <= m;x++){
			long n = (long)Math.sqrt(m-x*x);
			ans += invl(420, mod) * (n+1) % mod
					* ((70*mm%mod*mm%mod*mm+210*mm%mod*mm
							-42*mm%mod*n%mod*n%mod*n%mod*n%mod
							-63*mm%mod*n%mod*n%mod*n%mod
							-140*mm%mod*n%mod*n%mod*x%mod*x%mod
							+63*mm%mod*n%mod*n%mod
							-70*mm%mod*n%mod*x%mod*x%mod
							+42*mm%mod*n%mod
							-210*mm%mod*x%mod*x%mod*x%mod*x%mod
							+210*mm%mod*x%mod*x%mod
							+140*mm%mod
							+20*n%mod*n%mod*n%mod*n%mod*n%mod*n%mod
							+50*n%mod*n%mod*n%mod*n%mod*n%mod
							+84*n%mod*n%mod*n%mod*n%mod*x%mod*x%mod
							-64*n%mod*n%mod*n%mod*n%mod
							+126*n%mod*n%mod*n%mod*x%mod*x%mod
							-146*n%mod*n%mod*n%mod
							+140*n%mod*n%mod*x%mod*x%mod*x%mod*x%mod
							-266*n%mod*n%mod*x%mod*x%mod
							+76*n%mod*n%mod
							+70*n%mod*x%mod*x%mod*x%mod*x%mod
							-154*n%mod*x%mod*x%mod
							+64*n%mod
							+140*x%mod*x%mod*x%mod*x%mod*x%mod*x%mod
							-420*x%mod*x%mod*x%mod*x%mod
							+280*x%mod*x%mod
							)%mod)%mod;
		}
		ans = ans * 4 + mm*(mm+1)%mod*(mm+2)%mod*invl(6,mod)%mod;
		ans %= mod;
		if(ans < 0)ans += mod;
		out.println(ans);
	}

	public static long invl(long a, long mod) {
		long b = mod;
		long p = 1, q = 0;
		while (b > 0) {
			long c = a / b;
			long d;
			d = a;
			a = b;
			b = d % b;
			d = p;
			p = q;
			q = d - c * q;
		}
		return p < 0 ? p + mod : p;
	}

	void run() throws Exception
	{
		is = oj ? System.in : new ByteArrayInputStream(INPUT.getBytes());
		out = new PrintWriter(System.out);

		long s = System.currentTimeMillis();
		solve();
		out.flush();
		tr(System.currentTimeMillis()-s+"ms");
	}

	public static void main(String[] args) throws Exception { new D3().run(); }

	private byte[] inbuf = new byte[1024];
	public int lenbuf = 0, ptrbuf = 0;

	private int readByte()
	{
		if(lenbuf == -1)throw new InputMismatchException();
		if(ptrbuf >= lenbuf){
			ptrbuf = 0;
			try { lenbuf = is.read(inbuf); } catch (IOException e) { throw new InputMismatchException(); }
			if(lenbuf <= 0)return -1;
		}
		return inbuf[ptrbuf++];
	}

	private boolean isSpaceChar(int c) { return !(c >= 33 && c <= 126); }
	private int skip() { int b; while((b = readByte()) != -1 && isSpaceChar(b)); return b; }

	private double nd() { return Double.parseDouble(ns()); }
	private char nc() { return (char)skip(); }

	private String ns()
	{
		int b = skip();
		StringBuilder sb = new StringBuilder();
		while(!(isSpaceChar(b))){ // when nextLine, (isSpaceChar(b) && b != ' ')
			sb.appendCodePoint(b);
			b = readByte();
		}
		return sb.toString();
	}

	private char[] ns(int n)
	{
		char[] buf = new char[n];
		int b = skip(), p = 0;
		while(p < n && !(isSpaceChar(b))){
			buf[p++] = (char)b;
			b = readByte();
		}
		return n == p ? buf : Arrays.copyOf(buf, p);
	}

	private char[][] nm(int n, int m)
	{
		char[][] map = new char[n][];
		for(int i = 0;i < n;i++)map[i] = ns(m);
		return map;
	}

	private int[] na(int n)
	{
		int[] a = new int[n];
		for(int i = 0;i < n;i++)a[i] = ni();
		return a;
	}

	private int ni()
	{
		int num = 0, b;
		boolean minus = false;
		while((b = readByte()) != -1 && !((b >= '0' && b <= '9') || b == '-'));
		if(b == '-'){
			minus = true;
			b = readByte();
		}

		while(true){
			if(b >= '0' && b <= '9'){
				num = num * 10 + (b - '0');
			}else{
				return minus ? -num : num;
			}
			b = readByte();
		}
	}

	private long nl()
	{
		long num = 0;
		int b;
		boolean minus = false;
		while((b = readByte()) != -1 && !((b >= '0' && b <= '9') || b == '-'));
		if(b == '-'){
			minus = true;
			b = readByte();
		}

		while(true){
			if(b >= '0' && b <= '9'){
				num = num * 10 + (b - '0');
			}else{
				return minus ? -num : num;
			}
			b = readByte();
		}
	}

	private boolean oj = System.getProperty("ONLINE_JUDGE") != null;
	private void tr(Object... o) { if(!oj)System.out.println(Arrays.deepToString(o)); }
}

import java.io.OutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.io.PrintStream;
import java.util.Arrays;
import java.io.BufferedWriter;
import java.util.InputMismatchException;
import java.io.IOException;
import java.io.File;
import java.util.ArrayList;
import java.io.Writer;
import java.io.OutputStreamWriter;
import java.io.BufferedReader;
import java.io.FileReader;
import java.util.Collections;
import java.io.InputStream;

/**
 * Built using CHelper plug-in
 * Actual solution is at the top
 */
public class Main {
    public static void main(String[] args) {
        InputStream inputStream = System.in;
        OutputStream outputStream = System.out;
        InputReader in = new InputReader(inputStream);
        OutputWriter out = new OutputWriter(outputStream);
        TaskD solver = new TaskD();
        solver.solve(1, in, out);
        out.close();
    }

    static class TaskD {
        public int mod = 1000000007;
        public long inv6 = Utils.inv(6, mod);
        public long inv60 = Utils.inv(60, mod);

        public long sum2(long from, long to, long X, long a) {
            long ret = inv6;
            ret = ret * (from - to - 1 + mod) % mod;
            long a1 = 2 * from * from % mod - from + to + 2 * to * to % mod + 2 * from * to % mod;
            a1 %= mod;
            if (a1 < 0) a1 += mod;
            a1 = a1 * a % mod;
            a1 = a1 - 3 * X * (from + to) % mod;
            a1 %= mod;
            if (a1 < 0) a1 += mod;
            return ret * a1 % mod;

        }

        public long sum1(long from, long to, long m, long a) {
            long ret = inv60;
            ret = ret * a % mod * (a + 1) % mod * (2 * a + 1) % mod * (from - to - 1 + mod) % mod;
            long inner = 6 * a * a % mod + 6 * a % mod + 5 * from % mod - 10 * m % mod + 5 * to % mod - 12;
            inner %= mod;
            if (inner < 0) inner += mod;
            return ret * inner % mod;
        }

        public void solve(int testNumber, InputReader in, OutputWriter out) {
            long m = in.nextLong();
            long mm = m % mod;
            long base = mm * (mm + 1) % mod * (mm + 2) % mod * inv6 % mod;
            ArrayList<Long> a1 = new ArrayList<>();
            ArrayList<Long> a2 = new ArrayList<>();
            long sk = 0, sa = 0;
            for (int k = 1; 1L * k * k <= m; k++) {
                a1.add(1L * k * k);
                a2.add(m - 1L * k * k + 1);
                sa++;
                sk = (sk + 1L * k * k) % mod;
            }
            a1.add(m + 1);
            Collections.reverse(a2);
            long start = System.currentTimeMillis();
            ArrayList<Long> ss = new ArrayList<>();
            int i1 = 0, i2 = 0;
            while (i1 < a1.size() && i2 < a2.size()) {
                if (a1.get(i1) < a2.get(i2)) ss.add(a1.get(i1++));
                else ss.add(a2.get(i2++));
            }
            while (i1 < a1.size()) ss.add(a1.get(i1++));
            while (i2 < a2.size()) ss.add(a2.get(i2++));
            Collections.sort(ss);
            Debug.print(System.currentTimeMillis() - start);

            long sqrtval = 1;
            long ans = 0;
            for (int i = 0; i < ss.size() - 1; i++) {
                long from = ss.get(i), to = ss.get(i + 1) - 1;
                if (from > to) continue;

                while ((sqrtval + 1) * (sqrtval + 1) <= to) sqrtval++;
                while ((m - sa * sa) < to) {
                    sk = (sk - sa * sa) % mod;
                    if (sk < 0) sk += mod;
                    sa--;
                }
                from %= mod;
                to %= mod;
                long X = (sa + 1) * (mm + 1) % mod - sk;
                if (X < 0) X += mod;
                long add = sum1(from, to, mm, sa) + sum2(from, to, X, sa + 1);
                add = add * sqrtval % mod;
                add %= mod;
                ans = (ans + add) % mod;

            }
//        for (int n = 1; n <= m; n++) {
//            for (int k = 0; k * k <= n; k++) {
//                ans += (int)(Math.sqrt(n-k*k)) * n * (m - n + 1);
//            }
//        }
            ans *= 4;
            ans += base;
            out.println(ans % mod);
        }

    }

    static class Debug {
        public static boolean DEBUG;

        static {
            try {
                DEBUG = System.getProperty("user.dir").contains("Dropbox");
            } catch (Exception e) {
                DEBUG = false;
            }
        }

        private static ArrayList<String> getParams() {
            StackTraceElement[] t = new Exception().getStackTrace();
            StackTraceElement up = t[2];

            ArrayList<String> ret = new ArrayList<>();
            ret.add(up.getFileName() + "/" + up.getMethodName());
            try {
                BufferedReader br = new BufferedReader(new FileReader(
                        new File("src/" + up.getClassName().replaceAll("\\.", "/") + ".java")));
                int g = up.getLineNumber();
                while (--g > 0) br.readLine();
                String q = br.readLine();
                String[] ss = q.split("Debug\\.print\\(");
                String[] qq = ss[1].substring(0, ss[1].indexOf(")")).split(",");
                for (int i = 0; i < qq.length; i++) {
                    ret.add(qq[i].trim());
                }
            } catch (Exception e) {
            }
            for (int i = 0; i < 100; i++) ret.add("???");
            return ret;
        }

        private static String toString(Object o) {
            if (o instanceof Object[]) {
                return Arrays.toString((Object[]) o);
            } else if (o instanceof char[]) {
                return new String((char[]) o);
            } else if (o instanceof int[]) {
                return Arrays.toString((int[]) o);
            } else if (o instanceof long[]) {
                return Arrays.toString((long[]) o);
            } else if (o instanceof double[]) {
                return Arrays.toString((double[]) o);
            } else {
                return o.toString();
            }
        }

        public static void print(Object x) {
            if (!DEBUG) return;
            ArrayList<String> s = getParams();
            System.out.println(s.get(0) + ": " + s.get(1) + " = " + toString(x));
        }

    }

    static class OutputWriter {
        private final PrintWriter writer;

        public OutputWriter(OutputStream outputStream) {
            writer = new PrintWriter(new BufferedWriter(new OutputStreamWriter(outputStream)));
        }

        public OutputWriter(Writer writer) {
            this.writer = new PrintWriter(writer);
        }

        public void close() {
            writer.close();
        }

        public void println(long i) {
            writer.println(i);
        }

    }

    static class Utils {
        public static long inv(long N, long M) {
            long x = 0, lastx = 1, y = 1, lasty = 0, q, t, a = N, b = M;
            while (b != 0) {
                q = a / b;
                t = a % b;
                a = b;
                b = t;
                t = x;
                x = lastx - q * x;
                lastx = t;
                t = y;
                y = lasty - q * y;
                lasty = t;
            }
            return (lastx + M) % M;
        }

    }

    static class InputReader {
        private InputStream stream;
        private byte[] buf = new byte[1 << 16];
        private int curChar;
        private int numChars;

        public InputReader(InputStream stream) {
            this.stream = stream;
        }

        public int read() {
            if (this.numChars == -1) {
                throw new InputMismatchException();
            } else {
                if (this.curChar >= this.numChars) {
                    this.curChar = 0;

                    try {
                        this.numChars = this.stream.read(this.buf);
                    } catch (IOException var2) {
                        throw new InputMismatchException();
                    }

                    if (this.numChars <= 0) {
                        return -1;
                    }
                }

                return this.buf[this.curChar++];
            }
        }

        public long nextLong() {
            int c;
            for (c = this.read(); isSpaceChar(c); c = this.read()) {
                ;
            }

            byte sgn = 1;
            if (c == 45) {
                sgn = -1;
                c = this.read();
            }

            long res = 0L;

            while (c >= 48 && c <= 57) {
                res *= 10L;
                res += (long) (c - 48);
                c = this.read();
                if (isSpaceChar(c)) {
                    return res * (long) sgn;
                }
            }

            throw new InputMismatchException();
        }

        public static boolean isSpaceChar(int c) {
            return c == 32 || c == 10 || c == 13 || c == 9 || c == -1;
        }

    }
}

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.util.Arrays;

public class Div1_462D {

	static final long MOD = 1_000_000_007;

	static final long INV6 = 166_666_668;
	static final long INV30 = 233_333_335;
	static final long INV42 = 23_809_524;

	static long[] polyC;

	static final long[][] comb = { { 1 }, { 1, 1 }, { 1, 2, 1 }, { 1, 3, 3, 1 } };

	public static void main(String[] args) throws IOException {
		BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
		PrintWriter printer = new PrintWriter(new BufferedWriter(new OutputStreamWriter(System.out)));
		long N = Long.parseLong(reader.readLine());
		long SQRTN = (long) Math.sqrt(N);

		long nModded = N % MOD;

		polyC = new long[] { nModded * (nModded + 1) % MOD * (nModded + 2) % MOD * INV6 % MOD,
				(3 * nModded % MOD + 4) % MOD * INV6 % MOD, (-3 * nModded % MOD - 6 + 4 * MOD) % MOD * INV6 % MOD,
				2 * INV6 % MOD };

		long[] powC = new long[4];

		long[] powXSQ = new long[4];

		long sum = 0;
		for (long x = -SQRTN; x <= SQRTN; x++) {
			Arrays.fill(powC, 0);
			long XSQ = x * x % MOD;

			powXSQ[0] = 1;
			powXSQ[1] = XSQ;
			powXSQ[2] = powXSQ[1] * XSQ % MOD;
			powXSQ[3] = powXSQ[2] * XSQ % MOD;

			for (int term = 0; term <= 3; term++) {
				for (int subT = 0; subT <= term; subT++) {
					// subT is power of y^2
					long cCoeff = powXSQ[term - subT] * comb[term][subT] * polyC[term] % MOD;
					powC[subT] = (powC[subT] + cCoeff) % MOD;
				}
			}

			long YMAX = (long) Math.sqrt(N - x * x);
			sum = (sum + powC[3] * 2 * sumSixths(YMAX)) % MOD;
			sum = (sum + powC[2] * 2 * sumFourths(YMAX)) % MOD;
			sum = (sum + powC[1] * 2 * sumSquares(YMAX)) % MOD;
			sum = (sum + powC[0] * ((2 * YMAX + 1) % MOD)) % MOD;
		}
		printer.println(sum);
		printer.close();
	}

	static long sumSquares(long N) {
		return N * (N + 1) % MOD * (2 * N + 1) % MOD * INV6 % MOD;
	}

	static long sumFourths(long N) {
		return N * (N + 1) % MOD * (2 * N + 1) % MOD * ((3 * N * (N + 1) - 1) % MOD) % MOD * INV30 % MOD;
	}

	static long sumSixths(long N) {
		return N * (N + 1) % MOD * (2 * N + 1) % MOD * ((3 * N * (N + 1) % MOD * ((N * N + N - 1) % MOD) + 1) % MOD)
				% MOD * INV42 % MOD;
	}
}

import java.io.*;
import java.util.*;

public class Codeforces933D {
	public static void main(String[] args) throws IOException {
		// TODO Auto-generated method stub
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		StringTokenizer st = new StringTokenizer(br.readLine());
		long n = Integer.parseInt(st.nextToken());

		int counter = 0;
		int N = 1000000007;

		for (int i = 0; i < 500000; i++) {
			counter += firstsum(n, 4*i+1);
			counter -= firstsum(n, 4*i+3);
			counter %= N;
		}

		for (int b = 1; b <= n/2000000; b++) {
			counter += secondsum(n, b);
			counter %= N;
		}

		int ans = (2*((2*counter)%N))%N;
		ans = ans + (int) (((n%N)*(n%N + 1))/2)%N;
		System.out.println(ans);
	}

	//1/2 = 500000004
	//1/3 = 333333336
	//1/6 = 166666668
	//lmao
	public static int firstsum(long n, long q) {
		int N = 1000000007;
		long floornq = (n/q)%N;
		n %= N;
		q %= N;
		long sum = ((floornq*(floornq+1))/2)%N;
		long sumsquare = (((sum*(2*floornq+1))%N)*333333336)%N;
		long sumcube = (sum*sum)%N;
		long nsquare = (n*n)%N;
		long qsquare = (q*q)%N;
		long qcube = (q*qsquare)%N;

		long k1 = (nsquare*floornq - qsquare*sumsquare + n*floornq + q*sum)%N;
		if (k1 < 0)
			k1 += N;
		k1 = (k1*(n+1))%N;
		k1 = (k1*500000004)%N;

		long k2 = (((((n*(n+1))%N)*(2*n+1))%N)*166666668)%N;
		k2 = (k2*floornq)%N;

		long k3 = (((qcube*sumcube)%N)*333333336)%N;
		k3 -= (((qsquare*sumsquare)%N)*500000004)%N;
		k3 += (((q*sum)%N)*166666668)%N;

		long ans = (k1-k2+k3)%N;
		if (ans < 0)
			ans += N;
		return (int) ans;
	}

	//wtf who successfully codes this up in a real round?
	public static int secondsum(long n, long b) {
		int N = 1000000007;
		long bsquare = (b*b)%N;
		long bcube = (b*bsquare)%N;
		long max = (n/(4*b)-1)%N;
		long numk = (max + N + 1 - 500000)%N;
		long sumk = ((max)*(max+1)/2 + 250875)%N;
		long sumksquare = ((((long) max * (long) (max+1))%N * (long) (2*max + 1))%N * 166666668)%N-375084213;
		if (sumksquare < 0)
			sumksquare += N;

		long k1 = (((bcube*sumksquare)%N)*32)%N;
		long k2 = (((bsquare*sumk)%N * (4*b-1)%N)%N *8)%N;
		long k3 = ((26*bcube - 12*bsquare + b)%N * 333333336)%N;
		if (k3 < 0)
			k3 += N;
		k3 = (k3*numk)%N;
		long k4 = (((n+1)%N)*(b*(numk*(((4*b*500000 + 4*b*max)+4*b-1)%N)%N)%N))%N;

		long k5 = 0;
		long k6 = 0;

		if (n%(4*b) >= b) {
			long min2 = ((4*b)*(n/(4*b))+b)%N;
			long max2 = (Math.min((4*b)*(n/(4*b))+3*b-1, n))%N;
			System.out.println(min2 + " " + max2);
			//sum from min2 to max2 of (n+1-i)*i
			k5 = (((((max2*(max2+1))%N)*(2*max2+1))%N)*166666668)%N;
			k5 -= (((((((min2-1)*min2)%N)*(2*min2-1))%N)*166666668)%N);
			k6 = ((max2*(max2+1) - min2*(min2-1))/2)%N;
			k6 = (k6*((n+1)%N))%N;
			System.out.println(k6);
		}

		return (int) ((k4-k1-k2-k3-k5+k6+7*(long)N)%N);
	}

}

import java.io.*;
import java.util.*;

public class Codeforces933D {
	public static void main(String[] args) throws IOException {
		// TODO Auto-generated method stub
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		StringTokenizer st = new StringTokenizer(br.readLine());
		long n = Long.parseLong(st.nextToken());

		int counter = 0;
		int N = 1000000007;

		for (int i = 0; i < 500000; i++) {
			counter += firstsum(n, 4*i+1);
			counter -= firstsum(n, 4*i+3);
			counter %= N;
		}

		for (int b = 1; b <= n/2000000; b++) {
			counter += secondsum(n, b);
			counter %= N;
		}

		int ans = (2*((2*counter)%N))%N;
		long k = ((((((n%N)*(n%N+1))%N)*(n%N+2))%N)*166666668)%N;
		ans = (ans + (int) k)%N;
		System.out.println(ans);
	}

	//1/2 = 500000004
	//1/3 = 333333336
	//1/6 = 166666668
	//lmao
	public static int firstsum(long n, long q) {
		int N = 1000000007;
		long floornq = (n/q)%N;
		n %= N;
		q %= N;
		long sum = ((floornq*(floornq+1))/2)%N;
		long sumsquare = (((sum*(2*floornq+1))%N)*333333336)%N;
		long sumcube = (sum*sum)%N;
		long nsquare = (n*n)%N;
		long qsquare = (q*q)%N;
		long qcube = (q*qsquare)%N;

		long k1 = (nsquare*floornq - qsquare*sumsquare + n*floornq + q*sum)%N;
		if (k1 < 0)
			k1 += N;
		k1 = (k1*(n+1))%N;
		k1 = (k1*500000004)%N;

		long k2 = (((((n*(n+1))%N)*(2*n+1))%N)*166666668)%N;
		k2 = (k2*floornq)%N;

		long k3 = (((qcube*sumcube)%N)*333333336)%N;
		k3 -= (((qsquare*sumsquare)%N)*500000004)%N;
		k3 += (((q*sum)%N)*166666668)%N;

		long ans = (k1-k2+k3)%N;
		if (ans < 0)
			ans += N;
		return (int) ans;
	}

	//wtf who successfully codes this up in a real round?
	public static int secondsum(long n, long b) {
		int N = 1000000007;
		long bsquare = (b*b)%N;
		long bcube = (b*bsquare)%N;
		long max = (n/(4*b)-1)%N;
		long numk = (max + N + 1 - 500000)%N;
		long sumk = ((max)*(max+1)/2 + 250875)%N;
		long sumksquare = ((((long) max * (long) (max+1))%N * (long) (2*max + 1))%N * 166666668)%N-375084213;
		if (sumksquare < 0)
			sumksquare += N;

		long k1 = (((bcube*sumksquare)%N)*32)%N;
		long k2 = (((bsquare*sumk)%N * (4*b-1)%N)%N *8)%N;
		long k3 = ((26*bcube - 12*bsquare + b)%N * 333333336)%N;
		if (k3 < 0)
			k3 += N;
		k3 = (k3*numk)%N;
		long k4 = (((n+1)%N)*(b*(numk*(((4*b*500000 + 4*b*max)+4*b-1)%N)%N)%N))%N;

		long k5 = 0;
		long k6 = 0;

		if (n%(4*b) >= b) {
			long min2 = ((4*b)*(n/(4*b))+b)%N;
			long max2 = (Math.min((4*b)*(n/(4*b))+3*b-1, n))%N;
			//sum from min2 to max2 of (n+1-i)*i
			k5 = (((((max2*(max2+1))%N)*(2*max2+1))%N)*166666668)%N;
			k5 -= (((((((min2-1)*min2)%N)*(2*min2-1))%N)*166666668)%N);
			k6 = ((max2*(max2+1) - min2*(min2-1))/2)%N;
			k6 = (k6*((n+1)%N))%N;
			System.out.println(k6);
		}

		return (int) ((k4-k1-k2-k3-k5+k6+7*(long)N)%N);
	}

}

//package round462;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.util.Arrays;
import java.util.InputMismatchException;

public class D3 {
	InputStream is;
	PrintWriter out;
	String INPUT = "";

	void solve()
	{
		long m = nl();
		int mod = 1000000007;
		long mm = m%mod;
		long ans = 0;
		for(long x = 1;x*x <= m;x++){
			long n = (long)Math.sqrt(m-x*x);
			ans += invl(420, mod) * (n+1) % mod
					* (70*mm%mod*mm%mod*mm+210*mm%mod*mm
							-42*mm%mod*n%mod*n%mod*n%mod*n%mod
							-63*mm%mod*n%mod*n%mod*n%mod
							-140*mm%mod*n%mod*n%mod*x%mod*x%mod
							+63*mm%mod*n%mod*n%mod
							-70*mm%mod*n%mod*x%mod*x%mod
							+42*mm%mod*n%mod
							-210*mm%mod*x%mod*x%mod*x%mod*x%mod
							+210*mm%mod*x%mod*x%mod
							+140*mm%mod
							+20*n%mod*n%mod*n%mod*n%mod*n%mod*n%mod
							+50*n%mod*n%mod*n%mod*n%mod*n%mod
							+84*n%mod*n%mod*n%mod*n%mod*x%mod*x%mod
							-64*n%mod*n%mod*n%mod*n%mod
							+126*n%mod*n%mod*n%mod*x%mod*x%mod
							-146*n%mod*n%mod*n%mod
							+140*n%mod*n%mod*x%mod*x%mod*x%mod*x%mod
							-266*n%mod*n%mod*x%mod*x%mod
							+76*n%mod*n%mod
							+70*n%mod*x%mod*x%mod*x%mod*x%mod
							-154*n%mod*x%mod*x%mod
							+64*n%mod
							+140*x%mod*x%mod*x%mod*x%mod*x%mod*x%mod
							-420*x%mod*x%mod*x%mod*x%mod
							+280*x%mod*x%mod
							)%mod;
		}
		ans = ans * 4 + mm*(mm+1)%mod*(mm+2)%mod*invl(6,mod)%mod;
		ans %= mod;
		if(ans < 0)ans += mod;
		out.println(ans);
	}

	public static long invl(long a, long mod) {
		long b = mod;
		long p = 1, q = 0;
		while (b > 0) {
			long c = a / b;
			long d;
			d = a;
			a = b;
			b = d % b;
			d = p;
			p = q;
			q = d - c * q;
		}
		return p < 0 ? p + mod : p;
	}

	void run() throws Exception
	{
		is = oj ? System.in : new ByteArrayInputStream(INPUT.getBytes());
		out = new PrintWriter(System.out);

		long s = System.currentTimeMillis();
		solve();
		out.flush();
		tr(System.currentTimeMillis()-s+"ms");
	}

	public static void main(String[] args) throws Exception { new D3().run(); }

	private byte[] inbuf = new byte[1024];
	public int lenbuf = 0, ptrbuf = 0;

	private int readByte()
	{
		if(lenbuf == -1)throw new InputMismatchException();
		if(ptrbuf >= lenbuf){
			ptrbuf = 0;
			try { lenbuf = is.read(inbuf); } catch (IOException e) { throw new InputMismatchException(); }
			if(lenbuf <= 0)return -1;
		}
		return inbuf[ptrbuf++];
	}

	private boolean isSpaceChar(int c) { return !(c >= 33 && c <= 126); }
	private int skip() { int b; while((b = readByte()) != -1 && isSpaceChar(b)); return b; }

	private double nd() { return Double.parseDouble(ns()); }
	private char nc() { return (char)skip(); }

	private String ns()
	{
		int b = skip();
		StringBuilder sb = new StringBuilder();
		while(!(isSpaceChar(b))){ // when nextLine, (isSpaceChar(b) && b != ' ')
			sb.appendCodePoint(b);
			b = readByte();
		}
		return sb.toString();
	}

	private char[] ns(int n)
	{
		char[] buf = new char[n];
		int b = skip(), p = 0;
		while(p < n && !(isSpaceChar(b))){
			buf[p++] = (char)b;
			b = readByte();
		}
		return n == p ? buf : Arrays.copyOf(buf, p);
	}

	private char[][] nm(int n, int m)
	{
		char[][] map = new char[n][];
		for(int i = 0;i < n;i++)map[i] = ns(m);
		return map;
	}

	private int[] na(int n)
	{
		int[] a = new int[n];
		for(int i = 0;i < n;i++)a[i] = ni();
		return a;
	}

	private int ni()
	{
		int num = 0, b;
		boolean minus = false;
		while((b = readByte()) != -1 && !((b >= '0' && b <= '9') || b == '-'));
		if(b == '-'){
			minus = true;
			b = readByte();
		}

		while(true){
			if(b >= '0' && b <= '9'){
				num = num * 10 + (b - '0');
			}else{
				return minus ? -num : num;
			}
			b = readByte();
		}
	}

	private long nl()
	{
		long num = 0;
		int b;
		boolean minus = false;
		while((b = readByte()) != -1 && !((b >= '0' && b <= '9') || b == '-'));
		if(b == '-'){
			minus = true;
			b = readByte();
		}

		while(true){
			if(b >= '0' && b <= '9'){
				num = num * 10 + (b - '0');
			}else{
				return minus ? -num : num;
			}
			b = readByte();
		}
	}

	private boolean oj = System.getProperty("ONLINE_JUDGE") != null;
	private void tr(Object... o) { if(!oj)System.out.println(Arrays.deepToString(o)); }
}

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.util.Arrays;

public class Div1_462D {

	static final long MOD = 1_000_000_007;

	static final long INV2 = 500_000_004;
	static final long INV3 = 333_333_336;
	static final long INV5 = 400_000_003;
	static final long INV6 = 166_666_668;
	static final long INV30 = 233_333_335;
	static final long INV42 = 23_809_524;

	static long[] polyC;

	static final long[][] comb = { { 1 }, { 1, 1 }, { 1, 2, 1 }, { 1, 3, 3, 1 } };

	static long[] powC;

	public static void main0(String[] args) {
		System.out.println(sumSquares(1000000000000L));
	}

	public static void main(String[] args) throws IOException {
		BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
		PrintWriter printer = new PrintWriter(new BufferedWriter(new OutputStreamWriter(System.out)));
		long N = Long.parseLong(reader.readLine());
		long SQRTN = (long) Math.sqrt(N);

		long nModded = N % MOD;

		polyC = new long[] { nModded * (nModded + 1) % MOD * (nModded + 2) % MOD * INV6 % MOD,
				(3 * N + 4) % MOD * INV6 % MOD, (-3 * nModded - 6 + 4 * MOD) % MOD * INV6 % MOD, 2 * INV6 % MOD };

		powC = new long[4];

		long sum = 0;
		for (long x = -SQRTN; x <= SQRTN; x++) {
			Arrays.fill(powC, 0);
			long XSQ = x * x % MOD;

			for (int term = 0; term <= 3; term++) {
				for (int subT = 0; subT <= term; subT++) {
					// subT is power of y^2
					long cCoeff = pow(XSQ, term - subT) * comb[term][subT] % MOD * polyC[term] % MOD;
					powC[subT] = (powC[subT] + cCoeff) % MOD;
				}
			}

			long YMAX = (long) Math.sqrt(N - XSQ);
			sum = (sum + powC[3] * 2 * sumSixths(YMAX)) % MOD;
			sum = (sum + powC[2] * 2 * sumFourths(YMAX)) % MOD;
			sum = (sum + powC[1] * 2 * sumSquares(YMAX)) % MOD;
			sum = (sum + powC[0] * (2 * YMAX + 1)) % MOD;
		}
		printer.println(sum);
		printer.close();
	}

	static long pow(long b, long e) {
		b %= MOD;
		long c = 1;
		while (e-- > 0) {
			c = c * b % MOD;
		}
		return c;
	}

	static long sumSquares(long N) {
		N %= MOD;
		return N * (N + 1) % MOD * (2 * N + 1) % MOD * INV6 % MOD;
	}

	static long sumFourths(long N) {
		N %= MOD;
		return N * (N + 1) % MOD * (2 * N + 1) % MOD * ((3 * N * (N + 1) - 1) % MOD) % MOD * INV30 % MOD;
	}

	static long sumSixths(long N) {
		N %= MOD;
		return N * (N + 1) % MOD * (2 * N + 1) % MOD * ((3 * N * (N + 1) % MOD * ((N * N + N - 1) % MOD) + 1) % MOD)
				% MOD * INV42 % MOD;
	}

}