import java.util.HashMap;
import java.util.Map;

public class Euler508 {
    private static final long MOD = 1000000007L;
    private static final long BRUTE_LIMIT = 1024L;

    static class Key {
        long a, b, c, d;

        Key(long a, long b, long c, long d) {
            this.a = a;
            this.b = b;
            this.c = c;
            this.d = d;
        }

        @Override
        public boolean equals(Object o) {
            if (this == o)
                return true;
            if (!(o instanceof Key))
                return false;
            Key key = (Key) o;
            return a == key.a && b == key.b && c == key.c && d == key.d;
        }

        @Override
        public int hashCode() {
            int result = (int) (a ^ (a >>> 32));
            result = 31 * result + (int) (b ^ (b >>> 32));
            result = 31 * result + (int) (c ^ (c >>> 32));
            result = 31 * result + (int) (d ^ (d >>> 32));
            return result;
        }
    }

    private static long floorDiv(long a, long b) {
        long q = a / b;
        long r = a % b;
        if (r != 0 && ((a < 0) ^ (b < 0))) {
            q--;
        }
        return q;
    }

    private static long ceilDiv(long a, long b) {
        return -floorDiv(-a, b);
    }

    private static long[] countEvenOdd(long l, long r) {
        if (l > r)
            return new long[] { 0, 0 };
        long firstEven = (l % 2 == 0) ? l : l + 1;
        long lastEven = (r % 2 == 0) ? r : r - 1;
        long even = 0;
        if (firstEven <= lastEven) {
            even = (lastEven - firstEven) / 2 + 1;
        }
        long odd = (r - l + 1) - even;
        return new long[] { even, odd };
    }

    private static long modAdd(long a, long b) {
        a += b;
        if (a >= MOD)
            a -= MOD;
        return a;
    }

    private static long onesInBase(long a, long b) {
        long count = 0;
        while (a != 0 || b != 0) {
            long r = (a - b) & 1L;
            count += r;
            long na = (b - a + r) / 2;
            long nb = (r - a - b) / 2;
            a = na;
            b = nb;
        }
        return count;
    }

    static class Solver {
        Map<Key, Long> memoB = new HashMap<>();
        Map<Key, Long> memoA = new HashMap<>();

        long bruteB(long amin, long amax, long bmin, long bmax) {
            long total = 0;
            for (long a = amin; a <= amax; ++a) {
                for (long b = bmin; b <= bmax; ++b) {
                    total += onesInBase(a, b);
                }
            }
            return total % MOD;
        }

        long sumB(long amin, long amax, long bmin, long bmax) {
            if (amin > amax || bmin > bmax)
                return 0;
            Key key = new Key(amin, amax, bmin, bmax);
            if (memoB.containsKey(key))
                return memoB.get(key);

            long width = amax - amin + 1;
            long height = bmax - bmin + 1;
            if (width <= BRUTE_LIMIT && height <= BRUTE_LIMIT && width * height <= BRUTE_LIMIT) {
                long res = bruteB(amin, amax, bmin, bmax);
                memoB.put(key, res);
                return res;
            }

            long[] aCounts = countEvenOdd(amin, amax);
            long[] bCounts = countEvenOdd(bmin, bmax);

            long aEven = aCounts[0], aOdd = aCounts[1];
            long bEven = bCounts[0], bOdd = bCounts[1];

            long oddPairs1 = (aEven % MOD) * (bOdd % MOD) % MOD;
            long oddPairs2 = (aOdd % MOD) * (bEven % MOD) % MOD;
            long res = (oddPairs1 + oddPairs2) % MOD;

            long u0Min = -amax;
            long u0Max = -amin;
            long u1Min = 1 - amax;
            long u1Max = 1 - amin;

            res = modAdd(res, sumA(u0Min, u0Max, bmin, bmax));
            res = modAdd(res, sumA(u1Min, u1Max, bmin, bmax));

            memoB.put(key, res);
            return res;
        }

        long sumA(long umin, long umax, long vmin, long vmax) {
            if (umin > umax || vmin > vmax)
                return 0;
            Key key = new Key(umin, umax, vmin, vmax);
            if (memoA.containsKey(key))
                return memoA.get(key);

            long[] uCounts = countEvenOdd(umin, umax);
            long[] vCounts = countEvenOdd(vmin, vmax);

            long uEven = uCounts[0], uOdd = uCounts[1];
            long vEven = vCounts[0], vOdd = vCounts[1];

            long res = (uOdd % MOD) * (vOdd % MOD) % MOD;

            if (uEven > 0 && vEven > 0) {
                long xMin = ceilDiv(umin, 2);
                long xMax = floorDiv(umax, 2);
                long yMin = ceilDiv(vmin, 2);
                long yMax = floorDiv(vmax, 2);
                if (xMin <= xMax && yMin <= yMax) {
                    res = modAdd(res, sumB(-yMax, -yMin, -xMax, -xMin));
                }
            }

            if (uOdd > 0 && vOdd > 0) {
                long xMin = ceilDiv(umin - 1, 2);
                long xMax = floorDiv(umax - 1, 2);
                long yMin = ceilDiv(vmin - 1, 2);
                long yMax = floorDiv(vmax - 1, 2);
                if (xMin <= xMax && yMin <= yMax) {
                    res = modAdd(res, sumB(-yMax, -yMin, -xMax, -xMin));
                }
            }

            memoA.put(key, res);
            return res;
        }

        long computeSquare(long L) {
            return sumB(-L, L, -L, L);
        }
    }

    public static void main(String[] args) {
        long L = 1000000000000000L;
        Solver solver = new Solver();
        System.out.println(solver.computeSquare(L));
    }
}
