//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 = 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);
	}

}

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;
	}

}