Let n be an integer. Consider all permutations on integers 1 to n in lexicographic order, and concatenate them into one big sequence p. For example, if n = 3, then p = [1, 2, 3, 1, 3, 2, 2, 1, 3, 2, 3, 1, 3, 1, 2, 3, 2, 1]. The length of this sequence will be n ⋅ n!.

Let 1 ≤ i ≤ j ≤ n ⋅ n! be a pair of indices. We call the sequence (p_i, p_{i+1}, ..., p_{j-1}, p_j) a subarray of p. Its length is defined as the number of its elements, i.e., j - i + 1. Its sum is the sum of all its elements, i.e., ∑_{k=i}^j p_k. 

You are given n. Find the number of subarrays of p of length n having sum (n(n+1))/(2). Since this number may be large, output it modulo 998244353 (a prime number). 

Input

The only line contains one integer n (1 ≤ n ≤ 10^6), as described in the problem statement.

Output

Output a single integer — the number of subarrays of length n having sum (n(n+1))/(2), modulo 998244353.

Examples

Input


3


Output


9


Input


4


Output


56


Input


10


Output


30052700

Note

In the first sample, there are 16 subarrays of length 3. In order of appearance, they are:

[1, 2, 3], [2, 3, 1], [3, 1, 3], [1, 3, 2], [3, 2, 2], [2, 2, 1], [2, 1, 3], [1, 3, 2], [3, 2, 3], [2, 3, 1], [3, 1, 3], [1, 3, 1], [3, 1, 2], [1, 2, 3], [2, 3, 2], [3, 2, 1]. 

Their sums are 6, 6, 7, 6, 7, 5, 6, 6, 8, 6, 7, 5, 6, 6, 7, 6. As (n(n+1))/(2) = 6, the answer is 9.
import java.util.*;

import java.io.*;

public class Main{

    public static void main(String[] args) {

        InputStream inputStream = System.in;
        OutputStream outputStream = System.out;
        InputReader inp = new InputReader(inputStream);
        PrintWriter out = new PrintWriter(outputStream);
        Solver solver = new Solver();
        solver.solve(inp, out);
        out.close();
        
          }



    static class Solver {


        class Node implements Comparable<Node>{
            int i;
            int j;
            long c;
          
            Node(int i,int j,long c)
            {
                this.i=i;
                this.j=j;
                this.c=c;
                

            }

           public int compareTo(Node n)
            {
                return Long.compare(this.c, n.c);
            }
        }

        public boolean done(int[] sp,int[] par)
        {
            int root;

            root=findSet(sp[0],par);
            
           for(int i=1;i<sp.length;i++)
           {
                if(root!=findSet(sp[i], par))
                    return false;
           }
           return true;
        }
       public int findSet(int i,int[] par)
       {
           int x =i;
            boolean flag =false;
            while(par[i]>=0)
            {
                flag = true;
                i=par[i];
            }
            if(flag)
                par[x]=i;
            return i;
       }

       public void unionSet(int i,int j,int[] par)
       {
            int x = findSet(i, par);
            int y = findSet(j, par);
            if(x<y)
            {
                par[y]=x;
            }
            else
            {
                par[x]=y;
            }
       }

       public  long pow(long a, long b, long MOD) {
            if (b == 0) {
                return 1;
            }
            if (b == 1) {
                return a;
            }
            long val = pow(a, b / 2, MOD);
            if (b % 2 == 0) {
                return val * val % MOD;
            } else {
                return val * (val * a % MOD) % MOD;

            }
           
        }


        public void minPrimeFactor(int n,int[] s)
        {
            boolean prime[] = new boolean[n+1];
            Arrays.fill(prime, true);
            s[1]=1;
            s[2]=2;
            for(int i=4;i<=n;i+=2)
            {
                prime[i]=false;
                s[i]=2;
            }

            for(int i=3;i<=n;i+=2)
            {
                if(prime[i])
                {
                    s[i]=i;
                    for(int j=2*i;j<=n;j+=i)
                    {
                        prime[j]=false;
                        s[j]=i;
                    }
                }
            }
            
        }

        
        // public void findAllPrime(int n,ArrayList<Node> al,int s[])
        // {
        //     int curr = s[n];
        //     int cnt = 1;
        //     while(n>1)
        //     {
        //         n/=s[n];
        //         if(curr==s[n])
        //         {
        //             cnt++;
        //             continue;

        //         }
        //         Node n1 = new Node(curr,cnt);
        //         al.add(n1);

        //         curr=s[n];
        //         cnt=1;
        //     }
        // }

        

        public int binarySearch(int n,int k)
        {
            int left=1;
            int right=100000000+5;
            int ans=0;
            while(left<=right)
            {
                int mid = (left+right)/2;
                if(n/mid>=k)
                {
                    left = mid+1;
                    ans=mid;
                }
                else
                {
                    right=mid-1;
                }
            }

            return ans;
        }
        public boolean checkPallindrom(String s)
        {
            char ch[] = s.toCharArray();

            for(int i=0;i<s.length()/2;i++)
            {
                if(ch[i]!=ch[s.length()-1-i])
                    return false;
            }
            return true;
        }


        public void dfs_util(ArrayList<Integer>[] al,boolean vis[],int x,int cnt[],int sts[],int fts[],ArrayList<Integer> fi)
        {
               vis[x] = true;
               fi.add(x);
                sts[cnt[0]]=x+1;
                boolean flag = false;
                for(int i=0;i<al[x].size();i++)
                {
                    if(!vis[al[x].get(i)])
                    {   flag =true;
                        cnt[0]++;
                        dfs_util(al, vis, al[x].get(i),cnt,sts,fts,fi);
                    }    
                    
                }
            
            cnt[0]++;
            fts[cnt[0]]=x+1;
            return;
        }

        public void dfs(ArrayList[] al,int sts[],int fts[],ArrayList<Integer> fi)
        {
            int count[]=new int[1];
            count[0]=0;
           boolean vis[] = new boolean[al.length];
           for(int i=0;i<al.length;i++)
           {
                if(!vis[i])
                {
                    count[0]++;
                    dfs_util(al,vis,i,count,sts,fts,fi);
                }
           }
        }
   
        public void remove(ArrayList<Integer>[] al,int x)
        {
            for(int i=0;i<al.length;i++)
            {
                for(int j=0;j<al[i].size();j++)
                {

                    if(al[i].get(j)==x)
                        al[i].remove(j);

                }
            }
        }

        public double gcd(double a, double b) 
        { 
            if (a == 0) 
                return b; 
            return gcd(b % a, a); 
        }


        public void printDivisors(long n,ArrayList<Long> al) 
        { 
            // Note that this loop runs till square root 
            for (long i=1; i<=Math.sqrt(n); i++) 
            { 
                if (n%i==0) 
                { 
                    // If divisors are equal, print only one 
                    if (n/i == i) 
                        al.add(i);
           
                    else // Otherwise print both 
                        al.add(i);
                        al.add(n/i);
                } 
            } 
        } 

        private void solve(InputReader inp, PrintWriter out1) {
             
            long n = inp.nextLong();
            if(n==1)
            {
                out1.println(1);
                return;
            }
            long pos= n;
            long last  = 1;
            long ans =0;
            for(long i=n-1;i>=1;i--)
            {
                pos*=i;
                pos%=998244353;
                
            }

            for(long i=n;i>=1;i--)
            {
                last *=i;
                last%=998244353;
                ans += 998244353+((pos-last)%998244353);

            }
            

           

           ans+=pos;
            ans%=998244353;
            out1.println(ans);
            


              



        }
}





    static class InputReader {
        BufferedReader reader;
        StringTokenizer tokenizer;

        InputReader(InputStream stream) {
            reader = new BufferedReader(new InputStreamReader(stream), 32768);
            tokenizer = null;
        }

        String next() {
            while (tokenizer == null || !tokenizer.hasMoreTokens()) {
                try {
                    tokenizer = new StringTokenizer(reader.readLine());
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }
            return tokenizer.nextToken();
        }

        public int nextInt() {
            return Integer.parseInt(next());
        }

        public long nextLong() {
            return Long.parseLong(next());
        }
    }
}
class ele{
    long value;
    long i;
    boolean flag;
    public ele(long value,long i)
    {
        this.value = value;
        this.i=i;
        this.flag = false;
    }
}