You are given a positive integer n greater or equal to 2. For every pair of integers a and b (2 ≤ |a|, |b| ≤ n), you can transform a into b if and only if there exists an integer x such that 1 < |x| and (a ⋅ x = b or b ⋅ x = a), where |x| denotes the absolute value of x.

After such a transformation, your score increases by |x| points and you are not allowed to transform a into b nor b into a anymore.

Initially, you have a score of 0. You can start at any integer and transform it as many times as you like. What is the maximum score you can achieve?

Input

A single line contains a single integer n (2 ≤ n ≤ 100 000) — the given integer described above.

Output

Print an only integer — the maximum score that can be achieved with the transformations. If it is not possible to perform even a single transformation for all possible starting integers, print 0.

Examples

Input

4


Output

8

Input

6


Output

28

Input

2


Output

0

Note

In the first example, the transformations are 2 → 4 → (-2) → (-4) → 2.

In the third example, it is impossible to perform even a single transformation.
import java.util.*;
import java.io.*;
public class helloworld {
 static long fact[];
 static long max;
 static int ans;
	static class Reader 
    { 
        final private int BUFFER_SIZE = 1 << 16; 
        private DataInputStream din; 
        private byte[] buffer; 
        private int bufferPointer, bytesRead; 
  
        public Reader() 
        { 
            din = new DataInputStream(System.in); 
            buffer = new byte[BUFFER_SIZE]; 
            bufferPointer = bytesRead = 0; 
        } 
  
        public Reader(String file_name) throws IOException 
        { 
            din = new DataInputStream(new FileInputStream(file_name)); 
            buffer = new byte[BUFFER_SIZE]; 
            bufferPointer = bytesRead = 0; 
        } 
  
        public String readLine() throws IOException 
        { 
            byte[] buf = new byte[64]; // line length 
            int cnt = 0, c; 
            while ((c = read()) != -1) 
            { 
                if (c == '\n') 
                    break; 
                buf[cnt++] = (byte) c; 
            } 
            return new String(buf, 0, cnt); 
        } 
  
        public int nextInt() throws IOException 
        { 
            int ret = 0; 
            byte c = read(); 
            while (c <= ' ') 
                c = read(); 
            boolean neg = (c == '-'); 
            if (neg) 
                c = read(); 
            do
            { 
                ret = ret * 10 + c - '0'; 
            }  while ((c = read()) >= '0' && c <= '9'); 
  
            if (neg) 
                return -ret; 
            return ret; 
        } 
  
        public long nextLong() throws IOException 
        { 
            long ret = 0; 
            byte c = read(); 
            while (c <= ' ') 
                c = read(); 
            boolean neg = (c == '-'); 
            if (neg) 
                c = read(); 
            do { 
                ret = ret * 10 + c - '0'; 
            } 
            while ((c = read()) >= '0' && c <= '9'); 
            if (neg) 
                return -ret; 
            return ret; 
        } 
  
        public double nextDouble() throws IOException 
        { 
            double ret = 0, div = 1; 
            byte c = read(); 
            while (c <= ' ') 
                c = read(); 
            boolean neg = (c == '-'); 
            if (neg) 
                c = read(); 
  
            do { 
                ret = ret * 10 + c - '0'; 
            } 
            while ((c = read()) >= '0' && c <= '9'); 
  
            if (c == '.') 
            { 
                while ((c = read()) >= '0' && c <= '9') 
                { 
                    ret += (c - '0') / (div *= 10); 
                } 
            } 
  
            if (neg) 
                return -ret; 
            return ret; 
        } 
  
        private void fillBuffer() throws IOException 
        { 
            bytesRead = din.read(buffer, bufferPointer = 0, BUFFER_SIZE); 
            if (bytesRead == -1) 
                buffer[0] = -1; 
        } 
  
        private byte read() throws IOException 
        { 
            if (bufferPointer == bytesRead) 
                fillBuffer(); 
            return buffer[bufferPointer++]; 
        } 
  
        public void close() throws IOException 
        { 
            if (din == null) 
                return; 
            din.close(); 
        } 
    } 
	
	static int getSum(int index , int BITree[]) 
    { 
		index++;
        int  sum = 0; // Iniialize result 
      
        // index in BITree[] is 1 more than 
        // the index in arr[] 
    
      
        // Traverse ancestors of BITree[index] 
        while(index>0) 
        { 
            // Add current element of BITree  
            // to sum 
            sum += BITree[index]; 
      
            // Move index to parent node in  
            // getSum View 
            index -= index & (-index); 
        } 
        return sum; 
    } 
  
	static int getMid(int s, int e) 
    { 
        return s + (e - s) / 2; 
    } 
  
    /* 
    * A recursive function to get the sum  
    of values in given range of the array. 
    * The following are parameters for this function. 
    *  
    * st -> Pointer to segment tree 
    * node -> Index of current node in 
    *         the segment tree. 
    * ss & se -> Starting and ending indexes 
    *         of the segment represented 
    *         by current node, i.e., st[node] 
    * l & r -> Starting and ending indexes 
    *         of range query 
    */
    static int MaxUtil(int[] st, int ss, int se,  
                        int l, int r, int node)  
    { 
          
        // If segment of this node is completely 
        // part of given range, then return 
        // the max of segment 
        if (l <= ss && r >= se) 
            return st[node]; 
  
        // If segment of this node does not 
        // belong to given range 
        if (se < l || ss > r) 
            return -1; 
  
        // If segment of this node is partially 
        // the part of given range 
        int mid = getMid(ss, se); 
  
        return Math.max(MaxUtil(st, ss, mid, l, r, 2 * node + 1), 
                    MaxUtil(st, mid + 1, se, l, r, 2 * node + 2)); 
    } 
  
    /* 
    * A recursive function to update the  
    nodes which have the given index in their 
    * range. The following are parameters  
    st, ss and se are same as defined above 
    * index -> index of the element to be updated. 
    */
    static void updateValue(int arr[], int[] st, int ss, 
                    int se, int index, int value, int node) 
    { 
        if (index < ss || index > se) 
        { 
            System.out.println("Invalid Input"); 
            return; 
        } 
  
        if (ss == se) 
        { 
  
            // update value in array and in segment tree 
            arr[index] = value; 
            st[node] = value; 
        }  
        else
        { 
            int mid = getMid(ss, se); 
  
            if (index >= ss && index <= mid) 
                updateValue(arr, st, ss, mid, index, value, 2 * node + 1); 
            else
                updateValue(arr, st, mid + 1, se, index, value, 2 * node + 2); 
  
            st[node] = Math.max(st[2 * node + 1], st[2 * node + 2]); 
        } 
        return; 
    } 
  
    // Return max of elements in range from 
    // index l (query start) to r (query end). 
    static int getMax(int[] st, int n, int l, int r) 
    { 
  
        // Check for erroneous input values 
        if (l < 0 || r > n - 1 || l > r)  
        { 
            System.out.printf("Invalid Input\n"); 
            return -1; 
        } 
  
        return MaxUtil(st, 0, n - 1, l, r, 0); 
    } 
  
    // A recursive function that constructs Segment 
    // Tree for array[ss..se]. si is index of 
    // current node in segment tree st 
    static int constructSTUtil(int arr[], int ss, 
                        int se, int[] st, int si)  
    { 
          
        // If there is one element in array, store 
        // it in current node of segment tree and return 
        if (ss == se)  
        { 
            st[si] = arr[ss]; 
            return arr[ss]; 
        } 
  
        // If there are more than one elements, then 
        // recur for left and right subtrees and 
        // store the max of values in this node 
        int mid = getMid(ss, se); 
  
        st[si] = Math.max(constructSTUtil(arr, ss, mid, st, si * 2 + 1), 
                constructSTUtil(arr, mid + 1, se, st, si * 2 + 2)); 
  
        return st[si]; 
    } 
  
    /* 
    * Function to construct segment tree from 
    given array. This function allocates 
    * memory for segment tree. 
    */
    static int[] constructST(int arr[], int n) 
    { 
  
        // Height of segment tree 
        int x = (int) Math.ceil(Math.log(n) / Math.log(2)); 
  
        // Maximum size of segment tree 
        int max_size = 2 * (int) Math.pow(2, x) - 1; 
  
        // Allocate memory 
        int[] st = new int[max_size]; 
  
        // Fill the allocated memory st 
        constructSTUtil(arr, 0, n - 1, st, 0); 
  
        // Return the constructed segment tree 
        return st; 
    } 
    public static void updateBIT(int n, int index,  
                                        int val , int BITree[] ) 
    { 
        // index in BITree[] is 1 more than  
        // the index in arr[] 
        index++;
        // Traverse all ancestors and add 'val' 
        while(index <= n) 
        { 
        // Add 'val' to current node of BIT Tree 
        BITree[index] += val; 
      
        // Update index to that of parent  
        // in update View 
        index += index & (-index); 
        } 
    } 
    static long mod = 1000000007;
   static long pow(long a , long b , long c)
   {
	   
	   if(b==0)
		   return 1;
	   
	   long ans = pow(a,b/2,c);
	   if(b%2 == 0)
		   return ans*ans%c;
	   
	   return ans*ans%c*a%c;
   }
   
   static long modInverse(long a , long b)
   {
	   return pow(a,b-2,mod);
   }
   
   
   static double d(int x1 , int y1 , int x2 , int y2)
   {
	   double d1 = x1-x2;
	   double d2 = y1-y2;
	   
	   return Math.sqrt(d1*d1-d2*d2);
   }
  

static int low[];
static int p[];
static int parent(int x , int k , int dp[][])
{
	if(k==0)
		return x;
while(k > 0)
{
	if(x == -1)
		break;
	
	int up = low[k];
	k -= p[up];
	x = dp[x][up];
}
return x;
}


static void dfs(int n , LinkedList<Integer> arr[] , boolean visited[] , int dp[][] , int h[] , int p,int lev)
{
	visited[n] = true;
	int lim = low[visited.length];
	
	dp[n][0] = p;
	int temp = n;
	for(int j = 1 ; j <= lim ; j++)
	{
		if(dp[n][j-1] == -1)
			break;
		
		dp[n][j] = dp[dp[n][j-1]][j-1];
	}
	
	h[n] = lev;
	
	for(Integer i : arr[n])
	{
		if(!visited[i])
		{
			dfs(i,arr,visited,dp,h,n,lev+1);
		}
	}
}

static int lca(int a , int b , int dp[][] , int h[])
{
	if(h[a] > h[b])
	{
		a = parent(a,h[a]-h[b],dp);
		
	}
	
	else if(h[b] > h[a])
	{
		b = parent(b,h[b]-h[a],dp);
	}
	
	if(a==b)
		return a;
	
	
	int l = 1 , r = h.length;
	
	while(l < r)
	{
		int mid = (l+r)/2;
		if(parent(a,mid,dp) == parent(b,mid,dp))
			r = mid;
		
		else
			l = mid+1;
	}
	
	return parent(a,l,dp);
}


static int check(int s , int f , int t , int dp[][] , int h[])
{
	int sf = lca(s,f,dp,h);
	
	if(lca(sf,t,dp,h) != sf)
	{
		
		
		return h[f]-h[sf]+1;
		
		
	}
	
	if(sf != s && sf != f)
	{
		int ans =  h[lca(s,t,dp,h)]-h[lca(s,f,dp,h)]+h[f]-h[lca(f,t,dp,h)]+1;
		
		
		
		return ans;
	}
	
	else
	{
		int ans = -1;
		
		if(sf == s)
		ans =  h[f]-h[lca(f,t,dp,h)]+1;
		
		else
		ans =   h[lca(s,t,dp,h)] - h[f]+1;
		
		
		
		return ans;
	}
}


public static void main(String []args) throws IOException
{
	Reader sc = new Reader();


	low = new int[100005];
	for(int i = 1 ; i <= 100004 ; i++)
	{
		low[i] = (int)(Math.log(i)/Math.log(2));
	}
	
	p = new int[31];
	p[0] = 1;
	for(int i = 1 ; i <= 30 ; i++)
	{
		p[i] = p[i-1]*2;
	}
	

int n = sc.nextInt();
long ans = 0;

for(int i = 2 ; i <= n ; i++)
{
      for(int j = i ; j <= n ; j += i)
      {
             if(j != i)
             {
                    ans += j/i;
             }
      }
}
System.out.println(4*ans);
}

}


