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

public class Euler902 {
    static final long MOD = 1000000007L;
    static final long A = 1000000007L;

    static class PairData {
        int g;
        long mul;
        int[] counts;
    }

    static int gcd(int a, int b) {
        return b == 0 ? a : gcd(b, a % b);
    }

    static int[] computeCounts(List<Integer> Acyc, List<Integer> Bcyc, int g) {
        int s = Acyc.size();
        int t = Bcyc.size();

        List<List<Integer>> aR = new ArrayList<>(g);
        List<List<Integer>> bR = new ArrayList<>(g);
        for (int i = 0; i < g; i++) {
            aR.add(new ArrayList<>());
            bR.add(new ArrayList<>());
        }
        for (int i = 0; i < s; i++)
            aR.get(i % g).add(Acyc.get(i));
        for (int i = 0; i < t; i++)
            bR.get(i % g).add(Bcyc.get(i));

        int[][] aArr = new int[g][];
        int[][] bArr = new int[g][];
        for (int r = 0; r < g; r++) {
            aArr[r] = aR.get(r).stream().mapToInt(Integer::intValue).toArray();
            bArr[r] = bR.get(r).stream().mapToInt(Integer::intValue).toArray();
            Arrays.sort(aArr[r]);
            Arrays.sort(bArr[r]);
        }

        int[][] f = new int[g][g];
        for (int r = 0; r < g; r++) {
            for (int rp = 0; rp < g; rp++) {
                int cnt = 0;
                int[] a = aArr[r];
                int[] b = bArr[rp];
                int j = 0;
                for (int x : a) {
                    while (j < b.length && b[j] < x) {
                        j++;
                    }
                    cnt += j;
                }
                f[r][rp] = cnt;
            }
        }

        int[] counts = new int[g];
        for (int rd = 0; rd < g; rd++) {
            int total = 0;
            for (int r = 0; r < g; r++) {
                total += f[r][(r + rd) % g];
            }
            counts[rd] = total;
        }
        return counts;
    }

    public static String solve() {
        int m = 100;
        int n = m * (m + 1) / 2;

        int[] tau = new int[n + 1];
        int[] tauInv = new int[n + 1];
        int[] sigma = new int[n + 1];
        int[] pi = new int[n + 1];

        for (int i = 1; i <= n; ++i) {
            tau[i] = (int) ((A * i) % n) + 1;
        }
        for (int i = 1; i <= n; ++i) {
            tauInv[tau[i]] = i;
        }

        for (int i = 1; i < n; ++i) {
            sigma[i] = i + 1;
        }
        int prev = 0;
        for (int k = 1; k <= m; ++k) {
            int t = k * (k + 1) / 2;
            sigma[t] = prev + 1;
            prev = t;
        }

        for (int i = 1; i <= n; ++i) {
            pi[i] = tauInv[sigma[tau[i]]];
        }

        List<List<Integer>> cycles = new ArrayList<>();
        int[] cycleId = new int[n + 1];
        int[] posIn = new int[n + 1];
        boolean[] visited = new boolean[n + 1];

        for (int i = 1; i <= n; ++i) {
            if (visited[i])
                continue;
            List<Integer> cyc = new ArrayList<>();
            int cur = i;
            while (!visited[cur]) {
                visited[cur] = true;
                posIn[cur] = cyc.size();
                cycleId[cur] = cycles.size();
                cyc.add(cur);
                cur = pi[cur];
            }
            cycles.add(cyc);
        }

        long[] fact = new long[n + 1];
        long[] weight = new long[n + 1];
        fact[0] = 1;
        for (int i = 1; i <= n; ++i)
            fact[i] = (fact[i - 1] * i) % MOD;
        for (int i = 1; i <= n; ++i)
            weight[i] = fact[n - i];

        long mFact = 1;
        for (int i = 1; i <= m; ++i)
            mFact = (mFact * i) % MOD;

        int numCycles = cycles.size();
        int[] cycleLen = new int[numCycles];
        for (int i = 0; i < numCycles; ++i)
            cycleLen[i] = cycles.get(i).size();

        int maxL = 1;
        for (int i = 0; i < numCycles; ++i) {
            for (int j = 0; j < numCycles; ++j) {
                int g = gcd(cycleLen[i], cycleLen[j]);
                int L = cycleLen[i] / g * cycleLen[j];
                maxL = Math.max(maxL, L);
            }
        }

        long[] inv = new long[maxL + 1];
        inv[1] = 1;
        for (int i = 2; i <= maxL; ++i) {
            inv[i] = MOD - (MOD / i) * inv[(int) (MOD % i)] % MOD;
        }

        PairData[][] pairData = new PairData[numCycles][numCycles];
        for (int ci = 0; ci < numCycles; ++ci) {
            for (int cj = 0; cj < numCycles; ++cj) {
                int s = cycleLen[ci];
                int t = cycleLen[cj];
                int g = gcd(s, t);
                int L = s / g * t;
                PairData pd = new PairData();
                pd.g = g;
                pd.mul = (mFact * inv[L]) % MOD;
                pd.counts = computeCounts(cycles.get(ci), cycles.get(cj), g);
                pairData[ci][cj] = pd;
            }
        }

        long total = mFact % MOD;
        int threads = Math.max(1, Runtime.getRuntime().availableProcessors());
        if (threads > 8)
            threads = 8;
        long[] partial = new long[threads];
        Thread[] workers = new Thread[threads];

        int block = (n + threads - 1) / threads;

        for (int th = 0; th < threads; th++) {
            final int tIdx = th;
            final int start = th * block + 1;
            final int end = Math.min(n, (th + 1) * block);

            workers[th] = new Thread(() -> {
                long local = 0;
                if (start <= end) {
                    for (int i = start; i <= end; ++i) {
                        long wi = weight[i];
                        int ci = cycleId[i];
                        int posI = posIn[i];
                        for (int j = i + 1; j <= n; ++j) {
                            int cj = cycleId[j];
                            int posJ = posIn[j];
                            PairData pd = pairData[ci][cj];
                            int g = pd.g;
                            int r = (posJ - posI) % g;
                            if (r < 0)
                                r += g;
                            int cnt = pd.counts[r];
                            long add = (wi * (cnt * pd.mul % MOD)) % MOD;
                            local += add;
                            if (local >= MOD)
                                local -= MOD;
                        }
                    }
                }
                partial[tIdx] = local;
            });
            workers[th].start();
        }

        try {
            for (Thread t : workers) {
                if (t != null)
                    t.join();
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        for (long v : partial) {
            total = (total + v) % MOD;
        }

        return Long.toString(total);
    }

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