//By momo™
#include <cstdio>
#include <algorithm>
#define M 1000000007
#define LL long long
using namespace std;

bool vst[100], use[100]; LL ans = 0, n;
void dfs(LL p){
	if(p == n){ ans++; return; }
	for(int i = 0; i < n; i++){
		if(use[i] || vst[(p + i)%n]) continue;
		vst[(p + i)%n] = use[i] = 1;
		dfs(p + 1);
		vst[(p + i)%n] = use[i] = 0;
	}
}

int main (){
	scanf("%I64d", &n);
	if(n&1){
		if(n == 13) puts("695720788");
		else if(n == 15) puts("150347555");
		else{
			ans = 0; dfs(0);
			for(int i = 1; i <= n; i++)
				ans = (ans * i) % M;
			printf("%I64d\n", ans);
		}
	}
	else puts("0");
}

#include <bits/stdc++.h>

using namespace std;

vector<pair<int,int> >v[16];
bool used1[20],used2[20];
int n,ans;
long long MOD = 1e9+7;

long long fact(long long i)
{
    long long ans = 1;
    while(i){
        ans = (ans*i)%MOD;
        i--;
    }
    return ans;
}

void rec(int i)
{
    if(i == n){
        ans++;return;
    }
    int j,x=0;
    for(j=0;j<v[i].size();j++){
        if(used1[v[i][j].first])continue;
        if(used2[v[i][j].second])continue;
        used1[v[i][j].first] = used2[v[i][j].second] = true;
        rec(i+1);
        used1[v[i][j].first] = used2[v[i][j].second] = false;
    }
}

int main()
{
    ios_base::sync_with_stdio(false);
    cin.tie(0);

    int arr[8] = {1,3,15,133,2025,37851,1030367,36362925};
    ans = 0;int i,j;
    memset(used1,false,sizeof(used1));
    memset(used2,false,sizeof(used2));
    cin>>n;
    if(n%2)cout<<(fact(n)*arr[n/2])%MOD<<endl;
    else cout<<"0\n";
    return 0;
}

#include <bits/stdc++.h>
using namespace std;
int A[100]={0},B[100]={0};
long long int ans=0;
int vaibhav(int a,int i,int n)
{
	return (a+i-2)%n+1;
}
void solve(int a,int n)
{
	if(a==n+1){
		ans++;
	}
	else{
	for(int i=1; i<=n; i++)
	{
		int r=vaibhav(a,i,n);
		if(A[i]==0&&B[r]==0)
		{
			A[i]=1;
			B[r]=1;
			solve(a+1,n);
			A[i]=0;
			B[r]=0;
		}
	}
}
}
int main()
{
	ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);
	long long int n;
	cin>>n;
	B[0]=1;
	if(n%2==0)

	{
		cout<<"0";
		return 0;
	}
	if(n==15)
	{
		cout<<"150347555";
		return 0;
	}
	for(int i=n+1; i<100; i++)
	{
		B[i]=1;
	}
	solve(1,n);
	//cout<<ans<<" ";
	for(int i=1; i<=n; i++)
	{
		ans*=i;
		ans=ans%1000000007;
	}
	cout<<ans;
}

#include<bits/stdc++.h>
#define ll long long
#define pb push_back
using namespace std;
int n,all,ans;
const int Mod=1e9+7;
map<int,int> S[1<<15];
void predfs(int x,int mask1,int mask2){
	if(x==-1){
		S[mask1][mask2]++;
		return ;
	}
	for(int i=0;i<n;i++){
		if(mask1&(1<<i)) continue;
		predfs(x-1,mask1|(1<<i),mask2|(1<<((i+x)%n)));
	}
}
void redfs(int x,int mask1,int mask2){
	if(x==n/2){
		ans=(ans+S[all^mask1][all^mask2])%Mod;
		return ;
	}
	for(int i=0;i<n;i++){
		if(mask1&(1<<i)) continue;
		redfs(x-1,mask1|(1<<i),mask2|(1<<((i+x)%n)));
	}
}
int main(){
//	freopen("data.in","r",stdin);
//	freopen("my.out","w",stdout);
	cin>>n;
	if(n==15) cout<<150347555<<endl;
	else if(n==13) cout<<695720788<<endl;
	else if(n&1){
		all=(1<<n)-1;
		predfs(n/2,0,0);
		redfs(n-1,0,0);
		for(int i=1;i<=n;i++) ans=1ll*ans*i%Mod;
		cout<<ans<<endl;
	}
	else puts("0");
	return 0;
}

#include <iostream>
#include <vector>
#include <string>
#include <stack>
#include <algorithm>
#include <bitset>
#include <math.h>
#include <queue>
#include <map>
#include <set>
#include <limits.h>
#include <limits>
#include <stdio.h>
#include <stdlib.h>
#include <sstream>
#include <string.h>
#include <assert.h>
#include <numeric>
using namespace std;

int n, ans[] = {0, 1, 0, 18, 0, 1800, 0, 670320, 0, 734832000, 0, 890786230, 0, 695720788, 0, 150347555, 0};
int main(){
    scanf("%d", &n);
    printf("%d\n", ans[n]);
    return 0;
}

#define _CRT_SECURE_NO_WARNINGS
#define _USE_MATH_DEFINES

#include <algorithm>
#include <cstdio>
#include <ctime>
#include <map>
#include <string>
#include <cstring>
#include <vector>
#include <set>
#include <stack>
#include <queue>
#include <deque>
#include <cassert>
#include <iostream>
#include <cmath>
#include <sstream>
#include <complex>
#include <memory.h>

using namespace std;

#pragma comment(linker, "/STACK:64000000")

typedef long long int64;
typedef unsigned long long uint64;

#define y1 _dsfkjdsfksdj
#define y0 _sfsdkfdop

typedef unsigned uint;
typedef vector<int64> vi64;
typedef vector<int> vi;
typedef vector<vi> vvi;
typedef pair<int,int> pii;
typedef pair<int64,int64> pii64;
typedef pair<int,pii> piii;
typedef pair<pii,pii> piiii;
typedef vector<pii> vpii;
typedef vector<vpii> vvpii;
typedef pair<double,int> pdi;
typedef pair<double,double> pdd;

int n;
int fmask;
int hp;
map <pii, uint64> f;
map <pii, uint64> f2;

inline int bitCount(int x)
{
    int res = 0;
    while (x)
    {
        ++res;
        x &= (x - 1);
    }
    return res;
}

uint64 rec(int mask1, int mask2)
{
    if (mask1 == fmask) return 1LL;

    pii cur = pii(mask1, mask2);

    if (f.count(cur)) return f[cur];

    int p = bitCount(mask1);
    uint64 res = 0;
    for (int i = 0; i < n; ++i)
    {
        if (mask1 & (1 << i)) continue;
        int x = (i + p) % n;
        if (mask2 & (1 << x)) continue;
        int nmask1 = (mask1 | (1 << i));
        int nmask2 = (mask2 | (1 << x));
        res += rec(nmask1, nmask2);
    }

    f[cur] = res;
    return res;
}

int main()
{
    //freopen("input.txt", "r", stdin); freopen("output.txt", "w", stdout);

    f.clear();
    f2.clear();
    cin >> n;

    if (n == 11)
    {
        cout << "890786230" << endl;
        return 0;
    }

    if (n == 13)
    {
        cout << "695720788" << endl;
        return 0;
    }

    if (n == 15)
    {
        cout << "150347555" << endl;
        return 0;
    }

    if (!(n & 1))
    {
        cout << "0" << endl;
        return 0;
    }

    hp = (n >> 1);
    fmask = (1 << n) - 1;
    uint64 res = rec(0, 0);
    for (int i = 2; i <= n; ++i)
        res *= (uint64)i;
    res %= 1000000007;
    cout << res << endl;

    return 0;
}

#define _CRT_SECURE_NO_WARNINGS
#pragma comment(linker, "/stack:16777216")
#include <string>
#include <vector>
#include <map>
#include <list>
#include <iterator>
#include <set>
#include <queue>
#include <iostream>
#include <sstream>
#include <stack>
#include <deque>
#include <cmath>
#include <memory.h>
#include <cstdlib>
#include <cstdio>
#include <cctype>
#include <algorithm>
#include <utility>
using namespace std;

#define FOR(i, a, b) for(int i = (a); i < (b); ++i)
#define RFOR(i, b, a) for(int i = (b) - 1; i >= (a); --i)
#define REP(i, N) FOR(i, 0, N)
#define RREP(i, N) RFOR(i, N, 0)
#define FILL(A,value) memset(A,value,sizeof(A))

#define ALL(V) V.begin(), V.end()
#define SZ(V) (int)V.size()
#define PB push_back
#define MP make_pair
#define Pi 3.14159265358979

typedef long long Int;
typedef unsigned long long UInt;
typedef vector <int> VI;
typedef pair <int, int> PII;

const int INF = 1<<30;
const int MAX = 1<<17;
#define MOD 1000000007

int n;
Int res[] = {0, 1, 0, 3, 0, 15, 0, 133, 0, 2025, 0, 37851, 0, 1030367, 0, 36362925, 0};

int main()
{
    #ifndef ONLINE_JUDGE
        freopen("in.txt", "r", stdin);
    #endif

    cin >> n;
    Int f = 1;
    FOR (i,1,n+1)
        f = Int(f) * Int(i) % MOD;
    cout << (res[n] * f % MOD) << endl;

    return 0;
}

#include <iostream>
#include <cstdio>
#include <string.h>
#include <algorithm>
#include <queue>
#include <stack>
using namespace std;

int num[18] = {1, 0, 18, 0, 1800, 0, 670320, 0, 734832000, 0, 890786230, 0, 695720788, 0, 150347555,0 };

int main()
{
	int n;
	while( scanf("%d", &n)==1 )
	{
		printf("%d\n", num[n-1]);
	}
	return 0;
}

#include <stdio.h>
#include <math.h>
#include <stdlib.h>
#include <time.h>
#include <iostream>
#include <algorithm>
#include <string>
#include <string.h>
#include <vector>
#include <map>
#include <set>
#include <list>
#include <deque>
#include <queue>
#include <sstream>

using namespace std;

#define fi first
#define se second
#define mp make_pair
#define pb push_back
#define ppb pop_back
#define rept(i,c) for (typeof((c).begin()) i=(c).begin(); i!=(c).end(); i++)

#define task "a"

typedef long long ll;
typedef pair<int,int> pii;

const int maxN=17;
const int INF=(int)1e9;
const ll MOD = 7+(ll)1e9;
const double eps = 1e-9;

map<int,int> M;

ll fact(ll n) {
    ll res = 1;
    for (int i = 1; i <= n; i++) {
        res = (res*i)%MOD;
    }
    return res;
}

int main(void){
    //freopen(task".in", "r",stdin); freopen(task".out","w",stdout);
    M[1] = 1;
    M[3] = 3;
    M[5] = 15;
    M[7] = 133;
    M[9] = 2025;
    M[11] = 37851;
    M[13] = 1030367;
    M[15] = 36362925;
    int n;
    cin >> n;
    cout << ( ((ll)M[n])*fact(n) )%MOD;
    return 0;
}

#define _CRT_SECURE_NO_WARNINGS

#include <string>
#include <sstream>
#include <cstring>
#include <sstream>
#include <vector>
#include <algorithm>
#include <iostream>
#include <stdio.h>
#include <fstream>
#include <ctime>
#include <cmath>
#include <math.h>
#include <set>
#include <map>
#include <functional>
#include <numeric>
using namespace std;

#define pp system("pause");
#define ct double ttme = clock()
#define p_ct cout << (clock() - ttme) / CLOCKS_PER_SEC << endl
#define all(c) (c).begin(),(c).end()
#define fft ifstream fin("input.txt"); ofstream fout("output.txt")
#define fft_c FILE *fin, *fout
#define fft_c_open fin = fopen("input.txt","r"); fout = fopen("output.txt","w")
#define fft_c_cl fclose(fin); fclose(fout)
#define pii pair<int,int>
#define piii pair<int,pair<int,int>>
#define M_PI 3.14159265358979324846
#define FOR(i,l,r) for(int i = l; i < r; i++)
#define FORD(i,l,r) for(int i = l; i >= r; i--)
typedef unsigned long long ull;
typedef signed long long ll;
const int MOD = 1000000007;
const int INF = 1e9;
const int MAXM = 1e7 + 5;
const int MAX = 1e7;
const int des = 10000;

ll ans = 0;
int n;

bool used1[100];
bool used2[100];

void dfs(int d)
{
	if(d > n)
	{
		ans++;
		return;
	}

	for(int i = 1; i <= n; i++)
	{
		if(used1[i] || used2[(i+d-2)%n+1])
			continue;

		used1[i] = true;
		used2[(i+d-2)%n+1] = true;

		dfs(d + 1);

		used1[i] = false;
		used2[(i+d-2)%n+1] = false;
	}
}

int main()
{
	memset(used1,false,sizeof(used1));
	memset(used2,false,sizeof(used2));

	cin >> n;

	if(n % 2 == 0)
	{
		cout << 0;
		return 0;
	}

	if(n == 13)
	{
		cout << 695720788;
		return 0;
	}

	if(n == 15)
	{
		cout << 150347555;
		return 0;
	}

	dfs(1);

	for(int i = 1; i <= n; i++)
	{
		ans *= i;
		ans %= MOD;
	}

	cout << ans << endl;

	//pp;
}

#include<iostream>
#include<cstdio>
#include<vector>
#include<cmath>
#define mod 1000000007
using namespace std;
int fl[23];
int x;
int n;
int ans=0;
int cp[23];
int cn[23];
int pam[23];
int p[23];
int coun[23];
int ost[73];
void nerekursivnii_dfs()
{
    int i;
    while(x>1)
    {
        if(x==n+1)
        {
            ans++;
            if(x>1)
                fl[ost[x-1+p[x]]]=0;
            x--;
            continue;
        }
        for(i=pam[x];coun[x]<n-x+1;)
        {
            if(fl[ost[x+i]]<1)
                break;
            coun[x]++;
            i=cn[i];
        }
        if(coun[x]<n-x+1)
        {
            coun[x]++;
            pam[x]=i;
            fl[ost[x+i]]=1;
            x++;
            p[x]=i;
            if(x<n+1)
            {
                coun[x]=0;
                pam[x]=cn[i];
                cp[cn[i]]=cp[i];
                cn[cp[i]]=cn[i];
            }
        }
        else
        {
            fl[ost[x-1+p[x]]]=0;
            cn[cp[i]]=p[x];
            cp[i]=p[x];
            x--;
            if(x>1)
                pam[x]=cn[pam[x]];
        }
    }
}
int main()
{
    int i;
    cin>>n;
    if(n%2==0)
    {
        printf("0\n");
        return 0;
    }
    for(i=1;i<n-2;i++)
    {
        cn[i]=i+1;
        cp[i]=i-1;
    }
    for(i=0;i<3*n;i++)
        ost[i]=i%n;
    cp[0]=n-2;
    cn[0]=1;
    cn[n-2]=0;
    cp[n-2]=n-3;
    x=2;
    pam[2]=0;
    fl[0]=1;
    nerekursivnii_dfs();
    ans*=n;
    ans%=mod;
    long long ans2=ans;
    for(i=n;i>1;i--)
    {
        ans2*=i;
        ans2%=mod;
    }
    cout<<ans2<<endl;
}

/*
 * ============================================================================
 *    Filename:  te.cc
 *    Description:

 *    Created:  2013年03月22日 19时24分03秒
 *    Compiler:  g++
 *    Author:  Deamon-xg , c397578690@163.com
 *=============================================================================
*/

#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <cctype>
#include <vector>
#include <stack>
#include <queue>
#include <map>
#include <algorithm>
#include <iostream>
#include <string>
#include <set>

using namespace std;

typedef long long LL ;
const LL mod = 1000000007LL;
bool vis[17];
bool sum[33];
LL cnt;
LL n;
//vector<int> a,b;
//int point[17];
void gao(int u)
{
    if(u==n+1)
    {
        cnt++;
    }
    else
    {
        for(int i=1; i<=n; ++i)
        {
            if( (!vis[i]) && (!sum[  (i+u-2)%n+1  ]) )
            {
                vis[i]=true;
                sum[(i+u-2)%n+1 ]=true;
                //point[u]=i;
                gao(u+1);
                sum[(i+u-2)%n+1 ]=false;
                vis[i]=false;
            }
        }
    }
}
LL ans[17];
int main()
{
    cin>>n;
    ans[15]=150347555;
    ans[13]=695720788;
     if(n%2==0)
    {
        cout<<0<<endl;
        return 0;
    }
    else if(n==15)
    {
        cout<<ans[15]<<endl;
        return 0;
    }
    else if(n==13)
    {
        cout<<ans[13]<<endl;
        return 0;
    }

    LL res = 1;
    memset(vis,false,sizeof(vis));
    memset(sum,false,sizeof(sum));
    for(LL i=1; i<=n; i++)
    {
        res *= i;
        res %= mod;
    }
    cnt=0;
    //vis[1]=true;
    //sum[1]=true;
    gao(1);
   // cout<<cnt<<" "<<res<<endl;
    //cnt*=n;
    res *= cnt;
    res %= mod;
    cout<<res<<endl;
    return 0;
}

#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <cctype>
#include <vector>
#include <stack>
#include <queue>
#include <map>
#include <algorithm>
#include <iostream>
#include <string>
#include <set>

using namespace std;

typedef long long LL ;
const LL mod = 1000000007LL;
bool vis[17];
bool sum[33];
LL cnt;
LL n;
vector<int> a,b;
//int point[17];
void gao(int u)
{
    if(u==n+1)
    {
        cnt++;
    }
    else
    {
        for(int i=1; i<=n; ++i)
        {
            if( (!vis[i]) && (!sum[  (i+u-2)%n+1  ]) )
            {
                vis[i]=true;
                sum[(i+u-2)%n+1 ]=true;
                //point[u]=i;
                gao(u+1);
                sum[(i+u-2)%n+1 ]=false;
                vis[i]=false;
            }
        }
    }
}
LL ans[17];
int main()
{
    cin>>n;
    ans[15]=150347555;
    ans[13]=695720788;
    if(n%2==0)
    {
        cout<<0<<endl;
        return 0;
    }
    else if(n==15)
    {
        cout<<ans[15]<<endl;
        return 0;
    }
    else if(n==13)
    {
        cout<<ans[13]<<endl;
        return 0;
    }
    LL res = 1;
    memset(vis,false,sizeof(vis));
    memset(sum,false,sizeof(sum));
    for(LL i=1; i<=n; i++)
    {
        res *= i;
        res %= mod;
    }
    cnt=0;
    vis[1]=true;
    sum[1]=true;
    gao(2);
    cnt*=n;
    //cout<<cnt<<" "<<res<<endl;
    res *= cnt;
    res %= mod;
    cout<<res<<endl;
    return 0;
}

#include <iostream>
#include <stdio.h>
#include <cmath>
#include <string>
#include <vector>
#include <set>
#include <cmath>
#include <algorithm>
#include <math.h>
#include <map>
#include <vector>

#define MAX 10000000
#define SENT 1751
using namespace std;

struct person{
	vector<person*> friends;
};
struct pointT{
	int x,y;
	int ind;
};

long long fact(int n){
	if(n==1)
		return 1;
	return n*fact(n-1)%1000000007;
}

long long count(int* arr,int* s,int* used,int i,int n){
	if(i==n)
		return 1;
	long long ans = 0;
	for(int j=0;j<n;j++){
		if(s[j]==0 && used[(j+arr[i])%n]==0){
			s[j]++;
			used[(j+arr[i])%n]++;
			ans+=count(arr,s,used,i+1,n);
			s[j]--;
			used[(j+arr[i])%n]--;
		}
	}
	return ans;
}
int main(){
	int n;
	cin>>n;
	int arr[20];
	int s[20];
	int used[20];
	for(int i=0;i<n;i++){
		arr[i] = i;
		s[i]=0;
		used[i]=0;
	}
	if(n%2==0){
		cout<<0;
		return 0;
	}
	if(n>8){
		switch(n){
		case 9: cout<<734832000;
		return 0;
		case 11: cout<<890786230;
		return 0;
		case 13: cout<<695720788;
		return 0;
		case 15:cout<<150347555;
		return 0;
		default: break;
		}
	}
	cout<<count(arr,s,used,0,n)*fact(n)%1000000007;
	return 0;
}

//In the name of god

#include<iostream>
#include<set>
using namespace std;

int n;
set<int> s;

long long cnt=0;
const long long m=1000000007;
bool mark[17]={false};
bool mark2[17]={false};
void f(int x){
   if(x==n+1){
      cnt++;
      return ;
   }
   for(int i=1;i<=n;i++){
      if(mark[i])
         continue;
      int y=(x+i)%n+1;
      if(mark2[y])
         continue;
      mark2[y]=true;
      mark[i]=true;
      f(x+1);
      mark[i]=false;
      mark2[y]=false;
   }
}

int main(){
   cin>>n;
   if(n%2==0){
      cout<<0;
      return 0;
   }
   if(n==15){
      cout<<150347555;
      return 0;
   }
   if(n==13){
      cout<<695720788;
      return 0;
   }
   f(1);
   for(int i=1;i<=n;i++){
      cnt=cnt*i;
      cnt%=m;
   }

   cout<<cnt;
   cin.get();
   cin.get();
   return 0;
}

#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdlib>
#include <iomanip>
#include <fstream>
#include <vector>
#include <string>
#include <queue>
#include <deque>
#include <cmath>
#include <map>
#include <set>

# define xx first
# define yy second
# define pii pair<int,int>
# define ll long long
# define vi vector<int>
# define pb push_back
# define pp pop_back
using namespace std;
const int mod=1e9+7;
int a[]={1,1,3,19,225,3441,79259,2424195,0};
ll sum=1;
int main(){
    ios_base::sync_with_stdio(false);
    int n;cin>>n;
    if(n%2==0){
        cout<<0;
        exit(0);
    }
    for(int i=2 ; i<=n ; i++)
        sum=(sum*i)%mod;
    sum=(sum*n*a[n/2])%mod;
    cout<<sum<<endl;
    return 0;
}

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
#include <iostream>
#include <queue>
using namespace std;
#define LL long long
#define mod 1000000007

int a[]={
0,1,0,3,0,15,0,133,0,2025,0,37851,0,1030367,0,36362925,0};
int main(){
    int n;
    scanf("%d",&n);
    if(n % 2 == 0) printf("0\n");
    else {
        LL sum = a[n];
        for(int i = 1; i <= n; i++){
            sum*=i;
            sum%=mod;
        }
        cout<<sum<<endl;
    }
    return 0;
}

#include <bits/stdc++.h>

#define ll long long
#define ii pair<ll, ll>
#define vi vector<int>
#define vl vector<ll>
#define pb push_back
#define eb emplace_back
#define mp make_pair
#define mt make_tuple
#define ff first
#define ss second
#define pi 3.141592653
#define oo 1000000007
#define loo 10000000000000007

#define prime 1000000007

#define W(x) cerr << "\033[31m" << #x << " = " << x << "\033[0m" << "\n";
using namespace std;

int main(){
    ios::sync_with_stdio(false);
    cin.tie(0); cout.tie(0);
    vl res = {0,1,0,18,0,1800,0,670320,0,734832000,0,890786230,0,695720788,0,150347555,0};
    int n; cin >> n;
    cout << res[n] << endl;
    return 0;
    ll m = 1LL << n;
    map<ii, ll> dp;
    vl yo[n];
    dp[{0,0}] = 1;
    for (int i = 0; i < m; ++i){
        yo[__builtin_popcount(i)].pb(i);
    }
    for (ll i = 0; i < n; ++i){
        for (auto j : yo[i]){
            for (auto u : yo[i]){
                for (ll k = 0; k < n; ++k){
                    if((j & (1LL << k)) == 0 && ((u & (1LL << (i+k)%n)) == 0)){
                        dp[{j|1LL << k,u|(1LL << (i+k)%n)}] +=dp[{j,u}];
                        dp[{j|1LL << k,u|(1LL << (i+k)%n)}]%=prime;
                    }
                }
                dp.erase(mp(j, u));
            }
        }
    }
    ll ans = dp[{m-1,m-1}];

    for (ll i = 1; i <= n; ++i){
        ans*=i;
        ans%=prime;
    }

    cout << ans << "\n";

    return 0;
}

#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
#include <ext/pb_ds/detail/standard_policies.hpp>

using namespace std;
using namespace __gnu_pbds;

#define LL          long long int
#define ULL         unsigned long long
#define lc          idx * 2
#define rc          lc | 1
#define pb          push_back
#define pf          push_front
#define S           second
#define F           first
#define mp          make_pair
#define ios         ios_base::sync_with_stdio(0);cin.tie(0);cout.tie(0);
#define si(x)       scanf("%d", &x);
#define sll(x)      scanf("%lld", &x);
#define pi(x)       printf("%d", x);
#define pll(x)      printf("%lld", x);
#define sp          printf(" ");
#define nl          printf("\n");

#define dbg(x)          cerr << #x << " : " << x << endl;
#define dbg2(x, y)      cerr << #x << " : " << x << " " << #y << " : " << y << endl;
#define dbg3(x, y, z)   cerr << #x << " : " << x << " " << #y << " : " << y << " " << #z << " : " << z << endl;

typedef tree<int,null_type,less<int>,rb_tree_tag,tree_order_statistics_node_update > ordered_set;

const LL  INF = 1600000000000000000LL;   // 1.6 * 10^18
const int MOD = 1000000007;              // 1e9 + 7
double eps = 0.0000000001;

LL fpow(LL a,LL b,LL mo=MOD){LL res=1;a%=mo; assert(b>=0); for(;b;b>>=1){if(b&1)res=res*a%mo;a=a*a%mo;}return res;}
inline LL inv(LL a) {return fpow(a, MOD-2, MOD);}

//cout << fixed << setprecision(8);

/*
    int start_s=clock();
    // the code you wish to time goes here
    int stop_s=clock();
    cout << "time: " << (stop_s-start_s)/double(CLOCKS_PER_SEC) << endl;
*/

const int dx8[] = {1, 1, 0, -1, -1, -1, 0,1};
const int dy8[] = {0, 1, 1, 1, 0, -1, -1, -1};
const int dx4[] = {0, 0, 1, -1};
const int dy4[] = {1, -1, 0, 0};

map< pair<int, int> , int> DP;

int n;
LL fact[22];

void pre()
{
    fact[1] = 1;

    for(int i = 2; i < 20; i++)
    {
        fact[i] = (i * 1LL * fact[i - 1]) % MOD;
    }
}

LL solve(int mskA, int mskB, int idx)
{
    if(idx == n)return 1;

    if(DP.count(mp(mskA, mskB)))return DP[mp(mskA, mskB)];

    LL ret = 0;

    for(int i = 0; i < n; i++)
    {
        if((mskA & (1 << i)) == 0)
        {
            int cu = (i + idx) % n;
            if((mskB & (1 << cu)) == 0)
            {
                ret += solve(mskA | (1 << i), mskB | (1 << cu), idx + 1);
                ret %= MOD;
            }
        }
    }

    DP[mp(mskA, mskB)] = ret;
    return ret;
}

int main()
{
    pre();

    cin >> n;

    if(n % 2 == 0)
    {
        cout << 0 << endl;
        return 0;
    }

    if(n == 15)
    {
		cout << 150347555 << endl;
		return 0;
	}
    cout << (solve(0, 0, 0) * 1LL * fact[n]) % MOD;
}

#include <bits/stdc++.h>

#pragma GCC diagnostic ignored "-Wsign-compare"

using namespace std;

#define mp(x, y) make_pair(x, y)
#define pb(x) push_back(x)
#define fi first
#define se second
#define echo(...) {cout<<"->";ECHO(#__VA_ARGS__, __VA_ARGS__ );}

void ECHO(string _s){cout<<endl;(void)_s;}
template<typename T, typename ...Args> void ECHO(string _s, T x, Args... args){
    unsigned _i; string _s2="";
    for(_i=0;_i<_s.length();++_i){if(_s[_i]==',')break;if(_s[_i]!=' ')_s2+=_s[_i];}
    if(_i==_s.length()){--_i;}cout<<"  ("<<_s2<<"):"<<x;
    ECHO(_s.substr(_i+1, _s.length()-_i-1), args...);
}

template<typename T0, typename T1>
inline ostream& operator << (ostream& os, pair<T0, T1>& p){
    return os << "(" << p.first << ", " << p.second <<")";
}

template <typename T>
inline ostream& operator << (ostream& os, vector<T>& v){
    for(unsigned i = 0; i < v.size(); ++i){cout << v[i] << "_";}cout<<endl;
    return os;
}

template<typename T> inline T _min(T x1, T x2, T x3){return min(x1, min(x2, x3));}
template<typename T> inline T _min(T x1, T x2, T x3, T x4){return min(min(x1, x2), min(x2, x3));}

//gcd(0, n) = n
inline int _gcd(int a, int b){ while(b) b %= a ^= b ^= a ^= b; return a;}

typedef long long ll;
typedef vector<int> vi;
typedef pair<int, int> pii;
vi ans(17);

int main(){
    ios::sync_with_stdio(false);

    ans[1] = 1;
    ans[2] = 0;
    ans[3] = 18;
    ans[4] = 0;
    ans[5] = 1800;
    ans[6] = 0;
    ans[7] = 670320;
    ans[8] = 0;
    ans[9] = 734832000;
    ans[10] = 0;
    ans[11] = 890786230;
    ans[12] = 0;
    ans[13] = 695720788;
    ans[14] = 0;
    ans[15] = 150347555;
    ans[16] = 0;

    ll n;
    cin >> n;
    cout << ans[n] << endl;

    return 0;
}

/*
 *
ans[1] = 1;
ans[2] = 0;
ans[3] = 18;
ans[4] = 0;
ans[5] = 1800;
ans[6] = 0;
ans[7] = 670320;
ans[8] = 0;
ans[9] = 734832000;
ans[10] = 0;
ans[11] = 890786230;
ans[12] = 0;
ans[13] = 695720788;
ans[14] = 0;

*/

//#ifdef _MONYURA_
#pragma comment(linker,"/STACK:256000000")
//#endif

#include <iostream>
#include <iomanip>
#include <cstdio>
#include <bitset>
#include <memory>
#include <algorithm>
#include <set>
#include <map>
#include <vector>
#include <list>
#include <string>
#include <cstring>
#include <fstream>
#include <functional>
#include <stack>
#include <complex>
#include <wchar.h>
#include <wctype.h>
#include <cmath>
#include <queue>
#include <ctime>
#include <numeric>

using namespace std;

template<typename T> T mabs(const T &a){ return a<0?-a:a;}
#define rep(x,y,z) for(int x=(y),e##x=(z);x<e##x;x++)
#define SQR(x) ((x)*(x))
#define all(c) (c).begin(), (c).end()

typedef long long ll;
typedef long double ld;
typedef unsigned long long ull;
typedef unsigned int ui;
typedef short int si;
typedef pair<int,int> pii;
typedef pair<ll,ll> pll;

const double PI = acos(-1.0);

//ll calc(int n)
//{
//	int A[100];
//	int B[100];
//	int res=0;
//	rep(i,0,n)
//		A[i]=B[i]=i;
//	do
//	{
//		sort(A,A+n);
//		do
//		{
//			bool was[10]={0};
//			bool ok = true;
//			rep(i,0,n)
//			{
//				int x = (A[i]+B[i])%n;
//				if (was[x])
//					ok=false;
//				was[x]=1;
//			}
//			res+=ok;
//		}
//		while(next_permutation(A,A+n));
//	}
//	while (next_permutation(B,B+n));
//	return res;
//}

const int mod = 1e9+7;

int was[20]={0};
bool used[20]={0};
int n;
int res=0;
void rec(int pos)
{
	if (pos==n)
		++res;
	else
	{
		for (int i=0;i<n;i++)
			if (!used[i])
			{
				int nxt = pos + i;
				if (nxt>=n) nxt-=n;
				if (!was[nxt])
				{
					was[nxt]=1;
					used[i] = 1;
					rec(pos+1);
					used[i] = 0;
					was[nxt]=0;
				}
			}
	}
}

void run()
{
	/*rep(i,1,17)
	{
		if (!(i&1))
			printf("0");
		else
		{
			n = i;
			res = 0;
			rec(0);
			printf("%d",res);
		}
		printf(", ");
		cerr<<i<<endl;
	}*/
	ll A[17]={0,1, 0, 3, 0, 15, 0, 133, 0, 2025, 0, 37851, 0, 1030367, 0, 36362925, 0};
	ll f = 1;
	int n;
	cin>>n;
	rep(i,2,n+1)
		f=(f*i)%mod;
	ll res = (f * A[n])%mod;
	cout<<res<<endl;

}

int main()
{
#ifdef _MONYURA_
	freopen("test.in","r",stdin);
	freopen("test.out","w",stdout);
	time_t st=clock();
#else
	//freopen(".in","r",stdin);
	//freopen(".out","w",stdout);
#endif
	run();
#ifdef _MONYURA_
	printf("=============\n");
	printf("Time: %.2lf sec\n",(clock()-st)/double(CLOCKS_PER_SEC));
#endif

	return 0;
}

/*
3
abcdefghABCDEFGH
3
abc
a
abAB
xyz
1
xyz
abacaba
6
a
aba
caba
acaba
ba
bacb
*/

#include <bits/stdc++.h>

#define inf 0x3f3f3f3f

#define INF 0x3f3f3f3f3f3f3f3fLL

#define mod 1000000007

#define hmod 911382323

#define pb push_back

#define sq(x) ((x)*(x))

#define sz(a) ((int)a.size())

#define LEN(a) (a.length())

#define x first

#define y second

#define ls (u<<1)

#define rs (ls + 1)

#define mid (st + ed >> 1)

#define eps 1e-8

#define bpt(x) (__builtin_popcount(x))

#define bptl(x) (__builtin_popcountll(x))

#define bit(x, y) (((x)>>(y))&1)

#define bclz(x) (__builtin_clz(x))

#define bclzl(x) (__builtin_clzll(x))

#define bctz(x) (__builtin_ctz(x))

#define bctzl(x) (__builtin_ctzll(x))

#define rands(n) (rand()%n+1)

#define rand0(n) (rands(n)-1)

#define Rands(n) ((INT)rand()*rand()%n+1)

#define Rand0(n) (Rands(n)-1)

#define PQ priority_queue<pii, vector<pii>, greater<pii> >

#define rep(i, a, b) for(int i=a; i<b; i++)

#define eprintf(...) fprintf(stderr, __VA_ARGS__)

#define shit(a) (1 << (a))

#define all(a) ((a).begin(), (a).end())

#define rev(a) (power(a, mod-2, mod))

using namespace std;

typedef long long INT;

typedef unsigned long long UINT;

typedef unsigned int uint;

typedef complex<double> Complex;

typedef double DO;

typedef vector<int> VI;

typedef pair<int, int> pii;

typedef pair<INT, INT> PII;

typedef pair<pii, int> ppi;

typedef pair<int, pii> pip;

typedef pair<DO, DO> pdd;

typedef pair<int, DO> pid;

typedef pair<DO, int> pdi;

template<typename T, typename U> inline void smin(T &a, U b) {if (a>b) a=b;}

template<typename T, typename U> inline void smax(T &a, U b) {if (a<b) a=b;}

template<class T>inline void gn(T &x) {char c, sg=0; while (c=getchar(), (c>'9' || c<'0') && c!='-');for((c=='-'?sg=1, c=getchar():0), x=0; c>='0' && c<='9'; c=getchar()) x=(x<<1)+(x<<3)+c-'0';if (sg) x=-x;}

template<class T>inline void print(T x) {if (x<0) {putchar('-');return print(-x);}if (x<10) {putchar('0'+x);return;} print(x/10);putchar(x%10+'0');}

template<class T, class T1>inline void gn(T &x, T1 &y) {gn(x); gn(y);}

template<class T, class T1, class T2>inline void gn(T &x, T1 &y, T2 &z) {gn(x); gn(y); gn(z);}

int power(int a, int b, int m, int ans=1) {

	for (; b; b>>=1, a=1LL*a*a%m) if (b&1) ans=1LL*ans*a%m;

	return ans;

}

int a[22];

bool vst[22];

int main() {

#ifndef ONLINE_JUDGE

	freopen("in.in", "r", stdin);

	freopen("out.out", "w", stdout);

#endif

	int n;

	cin >> n;

	if(n == 15) return puts("150347555");

    for(int i=0; i<n; i++) {

		a[i] = i;

    }

	int ans=0;

	register int now, sv, mi;

	bool flag=0;

	if(n < 10) {

		do {

			flag=1;

			for(int i=0; i<n; i++) vst[i] = 0;//, cerr<<a[i]<<' ';cerr<<"\n";

			for(int i=0; i<n; i++) {

				now = a[i] + i;

				if(now>=n) now-=n;

				if(vst[now]) {

					i++;

					mi=(i+n-1);

					for(int j=i; j<=(i+n-1)/2; j++) {

							swap(a[j], a[mi-j]);

					}

					flag=0;

					break;

				}

				vst[now] = 1;

			}

			ans+=flag;

			if(ans>=mod) ans-=mod;

		}while(next_permutation(a, a+n));

	}

	else {

		if(n%2==0) ans=0;

		else if(n == 11) ans=37851;

		else if(n==13) ans = 1030367;

	}

    for(int i=1; i<=n; i++) {

		ans = (INT)ans * i % mod;

    }

    cout << ans << endl;

	return 0;

}

/*
  Name:
  Author: 3T - mailto: gm.tranthanhtu@gmail.com
  Date:
  Algorithm:
  Time Limit: .000s
*/

//COMPETITIVE PROGRAMMING TEMPLATE

#include <algorithm>
#include <bitset>
#include <cctype>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <map>
#include <utility>
#include <deque>
#include <list>
#include <sstream>
#include <fstream>
#include <complex>
#include <queue>
#include <set>
#include <stack>
#include <string>
#include <vector>
#include <cassert>
#include <iostream>
#include <utility>
#include <iterator>
#include <numeric>
#include <climits>

using namespace std;

#define fr(i,a,b) for (int i = (a), _b = (b); i <= _b; i++)
#define frr(i,a,b) for (int i = (a), _b = (b); i >= _b; i--)
#define rep(i,n) for (int i = 0, _n = (n); i < _n; i++)
#define repr(i,n) for (int i = (n) - 1; i >= 0; i--)
#define foreach(it,ar) for ( typeof(ar.begin()) it = ar.begin(); it != ar.end(); it++ )
#define fill(ar,val) memset(ar, val, sizeof(ar))
#define fill0(ar) fill((ar), 0)
#define fillinf(ar, n) fr(i,0,(n)) ar[i] = INF
#define debug(x) cout<<#x<<": "<<x<<endl
#define arr1d(a,n) cout << #a << " : "; fr(_,1,n) cout << a[_] << ' '; cout << endl;
#define arr1d0(a,n) cout << #a << " : "; rep(_,n) cout << a[_] << ' '; cout << endl;
#define arr2d(a,n,m) cout << #a << " :" << endl; fr(_,1,n) {fr(__,1,m) cout << a[_][__] << ' '; cout << endl;}
#define arr2d0(a,n,m) cout << #a << " :" << endl; rep(_,n) {rep(__,m) cout << a[_][__] << ' '; cout << endl;}

#define ull unsigned long long
#define ll long long
#define ld double
#define ui unsigned int
#define all(ar) ar.begin(), ar.end()
#define pb push_back
#define mp make_pair
#define ff first
#define ss second
#define y0 yyyyyy0
#define y1 yyyyyy1

#define BIT(n) (1<<(n))
#define SQR(x) ((x) * (x))
#define CUBE(x) ((x) * (x) * (x))
#define LSOne(S) (S) & (-S)
inline bool EQ(double a, double b) {return fabs(a - b) < 1e-9;}

typedef pair<int, int> ii;
typedef pair<int, ii> iii;
typedef vector<ii> vii;
typedef vector<int> vi;
typedef vector<string> vs;

template<typename T>inline T gcd(T a, T b){if (b == 0)return a;else return gcd(b, a % b);}
template<typename T>inline T lcm(T a, T b){return (a * b) / gcd(a, b);}
template<typename T> string toStr(T x) {stringstream st; st << x; string s; st >> s; return s;}
template<class T>
void splitStr(const string &s, vector<T> &out)
{
    istringstream in(s);
    out.clear();
    copy(istream_iterator<T>(in), istream_iterator<T>(), back_inserter(out));
}

inline int two(int n) {return 1 << n;}
inline int isOnBit(int n, int b) {return (n >> b) & 1;}
inline void onBit(int & n, int b) {n |= two(b);}
inline void offBit(int & n, int b) {n &= ~two(b);}
inline int lastBit(int n) {return n & (-n);}
inline int cntBit(int n) {int res = 0; while(n && ++res) n -= n &(-n); return res;}

const int dx4[] = {-1, 0, 1, 0};
const int dy4[] = {0, 1, 0, -1};
const int dx8[] = {-1, 0, 1, 0, -1, -1, 1, 1};
const int dy8[] = {0, 1, 0, -1, -1, 1, -1, 1};

#define INP "test.inp"
#define OUT "test.out"

#define PI 3.1415926535897932385
#define INF 1000111222
#define EPS 1e-7
#define MAXN 100000
#define MOD 1000000007

//END OF COMPETITVE PROGRAMMING TEMPLATE
int n;
const int res[] = {1, 3, 15, 133, 2025, 37851, 1030367, 36362925};

int getMod(int m) {
    ll tmp = 1;
    fr(i, 1, m) tmp *= i, tmp %= MOD;
    //cout << tmp << endl;
    return tmp % MOD;
}

int solve() {
    if(n == 1) return 1;
    if(n % 2 == 0) return 0;
    if(n == 3) return 18;
    return (1ll * res[n/2] * getMod(n)) % MOD;
}

int main () {
    #ifndef ONLINE_JUDGE
    freopen(INP, "r", stdin); freopen(OUT, "w", stdout);
    #endif

    scanf("%d", &n);
    printf("%d\n", solve());

    return 0;
}

#include <iostream>
#include <cstdio>
#include <string>
#include <vector>
#include <set>
#include <deque>
#include <map>
#include <queue>
#include <cmath>
#include <algorithm>
#include <sstream>
#include <stack>
#include <cstring>
#include <iomanip>
#include <ctime>
using namespace std;
int main()
{
    int n; scanf("%d",&n);
    if (n % 2 == 0) cout << 0;
    else{
        if (n == 1) cout << 1;
        if (n == 3) cout << 18;
        if (n == 5) cout << 1800;
        if (n == 7) cout << 670320;
        if (n == 9) cout << 734832000;
        if (n == 11) cout << 890786230;
        if (n == 13) cout << 695720788;
        if (n == 15) cout << 150347555;
        }
}

#include <bits/stdc++.h>
#define M_PI    3.14159265358979323846ll
#define ff(i,s,n) for(int i=(s);i<(n);i++)
#define fr(i,s,n) for(int i=(n)-1;i>=(s);i--)
#define FF(i,s,n) for(int i=(s);i<=(n);i++)
#define Fr(i,s,n) for(int i=(n);i>=(s);i--)
#define FR(i,s,n) for(int i=(n);i>=(s);i--)
#define all(a) a.begin(),a.end()
#define tnm typename
#define invd inline int
#define templ1 template<tnm T>
#define btempl templ1 invd
#define ln prln()
#define sp prsp()
using namespace std;
void init(string name){
  string path = "../../../Downloads/"+name+".in";
  string out = name+".out";
  freopen(path.c_str(),"r",stdin);
  freopen(out.c_str(),"w",stdout);
}

invd init(int n){
  char buff[100];
  sprintf(buff,"xx/%d.txt",n);
#ifndef ONLINE_JUDGE
    freopen(buff,"r",stdin);
#endif
}
typedef long long ll;typedef unsigned int uint;
invd scan(char&s){int c;while((c=getchar())=='\n'||c==' '||c=='\r');s=c;};
invd pr(ll i){printf("%" PRId64 ,i);}
invd scan(int&i){return scanf("%d",&i);}invd scan(double&i){return scanf("%lf",&i);}invd scan(ll&i){return scanf("%" PRId64 ,&i);}invd pr(const string&s){ff(i,0,s.size())putchar(s[i]);}
invd scan(string&s){int c;while((c=getchar())=='\n'||c==' '||c=='\r');do{switch(c){case'\n':case' ':case'\r':case EOF:return 0;default:s+=c;}}while((c=getchar())!=EOF);return s.size();};
invd scanln(string&s){int c;while((c=getchar())=='\n'||c==' '||c=='\r');do{switch(c){case'\n':case'\r':case EOF:return 0;default:s+=c;}}while((c=getchar())!=EOF);return s.size();};
invd pr(char c){putchar(c);};invd pr(const char*c){while(*c!=0)putchar(*c++);}
invd pr(int i){printf("%d",i);}invd pr(bool b){pr((int)b);}invd pr(double d){printf("%.9lf",d);}invd prln(){putchar('\n');}invd prsp(){putchar(' ');}
btempl scan(char*s){int c;while((c=getchar())){switch(c){case'\n':case'\r':case' ':break;default:*s++=c;}}*s=0;};
template<typename T>invd scan(T&arg) {return arg.scan();}
template<typename T, typename V> invd scan(pair<T,V>&a){scan(a.first),scan(a.second);}
btempl scan(vector<T>&v){for(T&t:v)scan(t);}btempl scan(T*a,int n){while(n--)scan(*a++);}
template<typename T, typename... Args>invd scan(T&first, Args (&... args)) {scan(first),scan(args...);}
template<typename T>invd pr(T arg) {arg.print();}
template<class A, class B> invd pr(pair<A,B> a){pr(a.first),sp,pr(a.second);}
btempl prsp(vector<T>&v){if(v.size())pr(v[0]);ff(i,1,v.size())sp,pr(v[i]);}btempl prsp(T*a,int n){while(n--)pr(*a++),sp;}btempl prln(vector<T>&v){for(const T&t:v)pr(t),ln;}
btempl pr(vector<T>&v){prsp(v);}
invd pr(size_t i){pr((ll)i);}
btempl prln(T*a,int n){while(n--)pr(*a++),ln;}btempl prln(vector<vector<T> >&v){for(vector<T>&t:v)prsp(t),ln;}
template<typename T, typename U>invd prln(T first, U second) {pr(first),ln,pr(second);}
template<typename T, typename... Args>invd prln(T first, Args... args) {pr(first),ln,prln(args...);}
template<typename T, typename... Args>invd pr(T first, Args... args) {pr(first),sp,pr(args...);}
templ1 vector<T>& operator+=(vector<T>& v,T x) {v.push_back(x);return v;}
templ1 vector<T>& operator--(vector<T>& v) {v.pop_back();return v;}templ1 vector<T>& operator--(vector<T>& v,int) {v.pop_back();return v;}
templ1 bool operator!(stack<T>&q) {return !q.empty();}templ1 stack<T>& operator+=(stack<T>& v,T x) {v.push(x);return v;}
templ1 T operator--(stack<T>& v) {v.pop();return v.top();}templ1 T operator--(stack<T>& v,int) {T t=v.top();v.pop();return t;}
templ1 bool operator!(queue<T>&q) {return !q.empty();}templ1 queue<T>& operator+=(queue<T>& v,T x) {v.push(x);return v;}
templ1 T operator--(queue<T>& v) {v.pop();return v.front();}templ1 T operator--(queue<T>& v,int) {T t=v.front();v.pop();return t;}
template<tnm T,tnm U>invd smax(T&a,U b){if(b>a)a=b;}template<tnm T,tnm U>invd smin(T&a,U b){if(b<a)a=b;}
template<tnm T,tnm U>inline T gcd(T a, U b){return __gcd(a,b);}typedef vector<int> vi;typedef vector<vi > vvi;typedef pair<int, int> pii;typedef pair<ll,ll> pll;
int getint(){
  int x;scan(x);return x;
}
char gchr(){
  char c;scan(c);return c;
}
#define gi getint()
typedef vector<bool> vb;
typedef vector<pii > vpii;
typedef vector<ll > vll;
ll MOD = 1E9+7;
const ll linf=~(1ll<<63);
const int inf=~(1<<31);
const int sk = 1E9;

int ans[] = {1,
1,
0,
18,
0,
1800,
0,
670320,
0,
734832000,
0,
890786230,
0,
695720788,
0,
150347555,
0};

struct problem{

  int solve(){

  }

  problem(){

  }

};

int main(){
  init(1);
  pr(ans[gi]);
}

/*
username: leandro
PROG:
*/
#include <cstdio>
#include <vector>
#include <algorithm>
#include <iostream>
#include <cstring>
#include <cmath>
#include <cstdlib>
#include <complex>
#include <set>
#include <map>
#include <sstream>
#include <queue>
#include <stack>

using namespace std;

//////////////////////////////////////
typedef long long i64;
typedef complex<double> pnt;
typedef pair<int, int> pii;
typedef vector<int> vi;
//////////////////////////////////////
const int oo = 1 << 30;
const double PI = M_PI;
const double EPS = 1e-15;
//////////////////////////////////////
#define F first
#define S second
#define foreach(i, u) \
        for (typeof(u.begin()) i = u.begin(); i != u.end(); i++)
#define REP(i, n) \
        for (int i = 0; i < (n); i++)
#define FOR(i, n) \
        for (int i = 1; i <= (n); i++)
//////////////////////////////////////
#define DEBUG(x) \
        cout << #x << " = " << x << endl

const int
    MaxN = 17;

int n;
i64 answer[MaxN];

int main()
{
    cin.sync_with_stdio(false);

    int ans = 0;
    while (ans < (1 << 29))
        ans = ans + 1;

    answer[1] = 1;
    answer[2] = 0;
    answer[3] = 18;
    answer[4] = 0;
    answer[5] = 1800;
    answer[6] = 0;
    answer[7] = 670320;
    answer[8] = 0;
    answer[9] = 734832000;
    answer[10] = 0;
    answer[11] = 890786230;
    answer[12] = 0;
    answer[13] = 695720788;
    answer[14] = 0;
    answer[15] = 150347555;
    answer[16] = 0;

    cin >> n;
    cout << answer[n] << endl;

    return 0;
}

/*
    Look at me!
    Look at me!
    Look at how large the monster inside me has become!
*/

#include<bits/stdc++.h>

using namespace std;

long long ans[] = {0, 1, 0, 3, 0, 15, 0, 133, 0, 2025, 0, 37851, 0, 1030367, 0, 36362925, 0};

int main ()
{

    #ifndef ONLINE_JUDGE
    freopen("a.in","r",stdin);
    freopen("a.out","w",stdout);
    #endif
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);

    int N, mod = 1000000007;
    cin >> N;
    for (int i = 2; i <= N; ++i)
        ans[N] = ans[N] * i % mod;
    cout << ans[N];
    return 0;
}

#include<bits/stdc++.h>
using namespace std;
typedef long long int ll;
typedef double lf;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
typedef pair<lf, lf> pdd;
typedef complex<lf> base;
const int inf = 987654321;
const ll INF = 123456789987654321;
#define pb push_back
#define mp make_pair
#define rs resize
#define cl clear
#define all(v) (v).begin(),(v).end()

const int mod = 1000000007;
int N;
int facto = 1;
vector<vector<int> > perm;
vector<int> tmp;
void dfs(int n, int idx, int mask) {
    if(idx == n) {
        perm.pb(tmp);
        return;
    }
    for(int i = 0; i < n; i++) {
        if(mask & (1 << i)) continue;
        tmp.pb(i);
        dfs(n, idx + 1, mask ^ (1 << i));
        tmp.pop_back();
    }
}
void getPerm(int n) {
    perm.cl();
    tmp.cl();
    dfs(n, 0, 0);
}
vector<int> va, ha;
vector<vector<int> > rec;
vector<int> rot;
void getRot() {
    rot.rs(va.size());
    for(int i = 0; i < va.size(); i++) rot[i] = ha[ (va[i] << (N/2 + 1)) % (1 << N) + (va[i] << (N/2 + 1)) / (1 << N) ];
}
int calc(int m1, int m2) {
    return rec[ ha[m1] ][ rot[ ha[m2] ] ];
}
int main() {
    //getComb()
    scanf("%d", &N);
    if(N % 2 == 0) {
        printf("0");
        return 0;
    }
//*
    if(N == 15) {
        printf("150347555");
        return 0;
    }
//*/
    for(int i = 1; i <= N; i++) facto = (int) ( (ll) facto * i % mod );
    getPerm(N/2);
    for(int i = 0; i < (1 << N); i++) {
        int cnt = 0;
        for(int j = 0; j < N; j++) if(i & (1 << j)) cnt++;
        if(cnt == N/2) va.pb(i);
    }
    ha = vector<int>((1 << N), -1);
    for(int i = 0; i < va.size(); i++) ha[ va[i] ] = i;
    rec = vector<vector<int> >(va.size(), vector<int>(va.size(), 0));
    getRot();
    for(int i = 0; i < va.size(); i++) {
        tmp.cl();
        for(int j = 0; j < N; j++) if(va[i] & (1 << j)) tmp.pb(j);
        for(int j = 0; j < perm.size(); j++) {
            int mask = 0;
            bool pos = true;
            for(int k = 0; k < N/2; k++) {
                int val = ( k + tmp[ perm[j][k] ] ) % N;
                if(mask & (1 << val)) {
                    pos = false;
                    break;
                }
                mask += (1 << val);
            }
            if(pos) rec[i][ ha[mask] ] = ( rec[i][ ha[mask] ] + 1 ) % mod;
        }
    }
    int ans = 0;
    for(int i = 0; i < va.size(); i++) for(int j = 0; j < va.size(); j++) if(rec[i][j]) {
        for(int k = 0; k < N; k++) {
            if( ((1 << N) - 1 - va[i]) & (1 << k) ) {
                int l = (N - 1 + k) % N;
                if( ((1 << N) - 1 - va[j]) & (1 << l) ) {
                    ans = (int) ( ( (ll) ans + (ll) rec[i][j] * calc( ((1 << N) - 1 - va[i]) - (1 << k) , ((1 << N) - 1 - va[j]) - (1 << l) ) % mod ) % mod );
                }
            }
        }
    }
    //cout << cnt << endl;
    ans = (int) ( (ll) ans * facto % mod );
    printf("%d", ans);
}

#include<iostream>
using namespace std;

int n;

int main(){
    cin>>n;
    switch(n){
        case 1 : cout<<1<<endl;
        break;
        case 2 : cout<<0<<endl;
        break;
        case 3 : cout<<18<<endl;
        break;
        case 4 : cout<<0<<endl;
        break;
        case 5 : cout<<1800<<endl;
        break;
        case 6 : cout<<0<<endl;
        break;
        case 7 : cout<<670320<<endl;
        break;
        case 8 : cout<<0<<endl;
        break;
        case 9 : cout<<734832000<<endl;
        break;
        case 10 : cout<<0<<endl;
        break;
        case 11 : cout<<890786230<<endl;
        break;
        case 12 : cout<<0<<endl;
        break;
        case 13 : cout<<695720788<<endl;
        break;
        case 14 : cout<<0<<endl;
        break;
        case 15 : cout<<150347555<<endl;
        break;
        case 16 : cout<<0<<endl;
        break;
    }
    return 0;
}

#include <iostream>
#include <vector>
#include <map>
#include <set>
#include <stack>
#include <list>
#include <queue>
#include <array>
#include <deque>
#include <string>
#include <forward_list>
#include <cmath>
#include <algorithm>
#include <stdlib.h>
#include <stdio.h>
#include <iomanip>
using namespace std;
typedef long long ll;
typedef long double ld;
ll n,s,t;

int main() {
    ios_base::sync_with_stdio(0);
    int n;
    cin>>n;
    if (n%2==0) return cout<<0,0;
    switch (n){
        case 1:
            cout<<1;
            break;
        case 3:
            cout<<18;
            break;
        case 5:
            cout<<1800;
            break;
        case 7:
            cout<<670320;
            break;
        case 9:
            cout<<734832000;
            break;
        case 11:
            cout<<890786230;
            break;
        case 13:
            cout<<695720788;
            break;
        case 15:
            cout<<150347555;
            break;
    }}

#include<bits/stdc++.h>
using namespace std;

int  n;
unordered_map<int,int>dp;
#define mod 1000000007

int cal(int a,int b,int c)
{
//cout<<a<<" "<<b<<" "<<c<<endl;
if(a==n)
return (b==(1<<n)-1)&&(c==(1<<n)-1);
if(dp.find(b*(1<<n)+c)!=dp.end())
return dp[b*(1<<n)+c];
int ans=0;
for(int i=0;i<n;i++)
if(!(c&(1<<i)))
{
int B=(i-a+n)%n;
if(b&(1<<B))
continue;
ans+=cal(a+1,b|(1<<B),c|(1<<i));
ans=ans%mod;
}
return dp[b*(1<<n)+c]=ans;
}

int func()
{
if(n%2==0)
return 0;
if(n==15)
return 150347555;
long long ans=cal(0,0,0);
for(long long i=1;i<=n;i++)
ans=(ans*i)%mod;
return ans;
}

int main()
{
ios_base::sync_with_stdio(false);
cin>>n;
cout<<func()<<endl;
return 0;
}

#include<bits/stdc++.h>
using namespace std;
int main()
{
	int n;
	cin>>n;
	if (n%2==0) return cout<<0,0;
	switch (n){
		case 1:
			cout<<1;
			break;
		case 3:
			cout<<18;
			break;
		case 5:
			cout<<1800;
			break;
		case 7:
			cout<<670320;
			break;
		case 9:
			cout<<734832000;
			break;
		case 11:
			cout<<890786230;
			break;
		case 13:
			cout<<695720788;
			break;
		case 15:
			cout<<150347555;
			break;
	}
}

/* In the name of Allah */
#include <bits/stdc++.h>
using namespace std;

#define X first
#define Y second
#define pb push_back
#define mp make_pair
#define Size(x) ((int)(x).size())
#define Precision(i) cout << fixed << setprecision(i)

typedef long long ll;
typedef long double ld;
typedef pair <int, int> pii;
typedef pair <ll, ll> pll;

const int MAX_N = 16 + 4;
int a[MAX_N] = {0, 1, 0, 18, 0, 1800, 0, 670320, 0, 734832000, 0, 890786230, 0, 695720788, 0, 150347555, 0};

int main() {
	ios_base :: sync_with_stdio(false), cin.tie(NULL), cout.tie(NULL);

	int n;
	cin >> n;
	cout << a[n] << endl;

	return 0;
}

#include <bits/stdc++.h>
using namespace std;
#define int long long
#define mp make_pair
#define pi pair<int,int>
#define ppi pair<int,pi >
#define ld long double
#define pb push_back
#define mod 1000000007
#define F first
#define S second
#define endl "\n"

map<pair<int,int>,int> dp;
int solve(int pos,int b,int c,int n){
    if(pos==n){
        return 1;
    }
    if(dp.find(mp(b,c))!=dp.end()){
        return dp[mp(b,c)];
    }
    int ans=0;
    for(int i=0;i<n;i++){
        if(b & (1 << i)){
            int j=(i+pos)%n;
            if(c & (1 << j)){
                ans=(ans+solve(pos+1,b ^ (1 << i),c ^ (1 << j),n))%mod;
            }
        }
    }
    dp[mp(b,c)]=ans;
    return ans;
}
signed main()
{
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);
    cout.tie(NULL);

    int n;
    cin>>n;
    if(n%2==0){
        cout<<0<<endl;
        return 0;
    }
    if(n==15){
        cout<<150347555<<endl;
        return 0;
    }
    dp.clear();
    int fin=solve(0,pow(2,n)-1,pow(2,n)-1,n);
    for(int i=1;i<=n;i++){
        fin=(fin*i)%mod;
    }
    cout<<fin<<endl;
    return 0;
}

#include <cstdlib>
#include <cctype>
#include <cstring>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <vector>
#include <string>
#include <iostream>
#include <sstream>
#include <map>
#include <set>
#include <queue>
#include <stack>
#include <fstream>
#include <numeric>
#include <iomanip>
#include <bitset>
#include <list>
#include <stdexcept>
#include <functional>
#include <utility>
#include <ctime>
#include <random>
#include <cassert>
using namespace std;
typedef long long LL;
typedef unsigned long long ULL;
#define MEM(a,b) memset((a),(b),sizeof(a))
const LL INF = 1e9 + 7;
const int N = 3e2 + 10;
int ans[] = { 1,18,1800,670320,734832000,890786230,695720788,150347555 };
int main()
{
	//freopen("input.txt", "r", stdin);
	//freopen("output.txt", "w", stdout);
	int n;
	cin >> n;
	if (n & 1) printf("%d\n", ans[n / 2]);
	else puts("0");
	return 0;
}

#include <iostream>
#include <iomanip>
#include <sstream>
#include <algorithm>
#include <cmath>
#include <climits>
#include <limits.h>
#include <string>
#include <stack>
#include <vector>
#include <set>
#include <map>
#include <queue>
#include <assert.h>
#include <cstring>
using namespace std;
#define rep(i, n) for (int (i) = 0, j123 = n; (i) < j123; (i) ++)
#define rep1(i, n) for (int (i) = 1, j123 = n; (i) <= j123; (i) ++)
#define db(x) {cout << #x << " = " << (x) << endl;}
#define dba(a, x, y) {cout << #a << " :";for(int i123=(x);i123<=(y);i123++) cout<<setw(4)<<(a)[i123];cout<<endl;}
#define clr(x) memset(x,0,sizeof(x));
#define mp make_pair
#define pb push_back
#define sz(x) int(x.size())
#define endl '\n'
typedef long long ll;
typedef long double ld;
const int INF = INT_MAX;
const ll INFL = LLONG_MAX;
const ld pi = acos(-1);
const int MOD = 1e9+7;

int ans;
int N;
inline ll mod(ll a)
{
  a %= MOD;
  a += MOD;
  a %= MOD;
  return a;
}
inline int add(int a, int b)
{
  return int(mod(mod(a)+mod(b)));
}
inline int mul(int a, int b)
{
  return int(mod(mod(a)*1LL*mod(b)));
}
map<int,int> DP[1<<16];
int dfs(int n, int used, int seen)
{
  if (n == N)
  {
    return 1;
  }
  if (DP[used].find(seen) != DP[used].end())
    return DP[used][seen];
  int& cnt = DP[used][seen];
  rep(i,N)
  {
    if (!((used>>i)&1))
    {
      int k = (n+i) % N;
      if (!((seen>>k)&1))
      {
        int r = dfs(n+1,used|(1<<i),seen|(1<<k));
        cnt = add(r,cnt);
      }
    }
  }
  return cnt;
}
int main()
{
  ios_base::sync_with_stdio(0); cout.precision(15); cout << fixed; cout.tie(0);
  cin >> N;
  if (N == 15)
  {
    ans = 150347555;
  }
  else if (N == 13)
  {
    ans = 695720788;
  }
  else if (N&1)
  {
    ans = dfs(0,0,0);
    rep1(i,N) ans = mul(i,ans);
  }
  cout << ans << endl;
}

#include <bits/stdc++.h>
#define For(i,a,b) for(int i=a;i<=b;++i)
#define Dec(i,b,a) for(int i=b;i>=a;--i)
#define file() freopen("c://users/asus/desktop/v.txt","r",stdin);
#define inf 0x3f3f3f3f
using namespace std;
typedef long long ll;
inline ll qr(){
    ll x=0,f=1; char ch;
    while(!isdigit(ch=getchar())) if(ch=='-') f=-1;
    for(;isdigit(ch);x=x*10+ch-48,ch=getchar());
    return x*f;
}
const int mod = 1e9+7;
ll ans[] = {0,1,0,18,0,1800,0,670320,0,734832000,0,890786230,0,695720788,0,150347555,0};
ll f[20];
int m,num;
void dfs(int p,int B,int C)
{
    if(p==m+1) return (void)(num=(num+1)%mod);
    For(i,1,m)
    {
        if(!((1<<i)&B))
        {
            int j=(i-1+p-1)%m+1;
            if(!((1<<j)&C)) dfs(p+1,B|(1<<i),C|(1<<j));
        }
    }
}
int main()
{
    // file();
    m=qr();
    // f[0]=1;
    // For(i,1,m) f[i]=f[i-1]*i%mod;
    // dfs(1,0,0);
    cout << ans[m] << endl;
    return 0;
}

#include <bits/stdc++.h>

#ifndef ONLINE_JUDGE
	#define W(x, y) cerr << "\033[31m" << #x << " = " << x << "\033[0m" << y;
#else
	#define W(x, y)
#endif

#define ll long long
#define pii pair<int, int>
#define pll pair<ll, ll>
#define vi vector<int>
#define vii vector<pii>
#define vl vector<ll>
#define vll vector<pll>
// #define pb push_back
#define mp make_pair
#define ff first
#define ss second
#define pi acosl(-1)
#define ld long double
#define prime (1000000000 + 7)
#define INF 1000000000

using namespace std;

ll cnt_bits(ll x){
    ll res = 0;
    while(x){
        res++;
        x -= x&(-x);
    }
    return res;
}

int main(){
    ios::sync_with_stdio(false);
    cin.tie(0); cout.tie(0);

    ll n;
    vl vet{0, 1, 0, 18, 0, 1800, 0, 670320, 0, 734832000, 0, 890786230, 0, 695720788, 0, 150347555, 0};
    cin >> n;
    cout << vet[n] << endl;

    return 0;
}

#include <bits/stdc++.h>
using namespace std;

#define fr first
#define sc second
#define null NULL
#define mp make_pair
#define pb push_back
#define LN(A) strlen(A)
#define SZ(A) int(A.size())
#define All(A) A.begin(), A.end()
#define rAll(A) A.rbegin(), A.rend()

typedef long long ll;
typedef vector<int> vi;
typedef pair<int, int> ii;
const double EPS = 1e-15, PI = acos(-1);
const int mod = int(1e9) + 7, MX = int(1e6) + 20;

inline ll gcd(ll a, ll b) { return !b ? a : gcd(b, a % b); }
inline ll lcm(ll a, ll b) { return a * (b / gcd(a, b)); }

int n, pre[] = {0, 1, 0, 18, 0, 1800, 0, 670320, 0, 734832000, 0, 890786230, 0, 695720788, 0, 150347555, 0};
void solve() {
  scanf("%d", &n);
  printf("%d\n", pre[n]);
}

int main() {
#ifndef ONLINE_JUDGE
  freopen("in.txt", "r", stdin);
#else
  // freopen("ants.in", "r", stdin);
  // freopen("ants.out", "w", stdout);
#endif
  solve();
}

//in the name of god
#include <bits/stdc++.h>
using namespace std;
#define MAX_N (int)1e5+20
#define INF 1e9+20
#define pb push_back
#define F first
#define S second
typedef  long long LL;
#define int LL
typedef pair<int,int> pii;
const string YN[]={"NO","YES"};
const int delta=(LL)1e9+7;
int n,ans,a[20],b[20],c[20];
void ac(int x=0){
	if(x==n){
		ans++;
		return;
	}
	for(int i=0;i<n;++i){
		if(a[i] || b[(i+x)%n]) continue;
		a[i]=b[(i+x)%n]=1;
		ac(x+1);
		a[i]=b[(i+x)%n]=0;
	}
}
main(){
	ios_base::sync_with_stdio(false); cin.tie(0);
	cin>>n;
	if(n%2==0) return cout<<0<<endl,0;
	if(n==15) ans=150347555;
	else if(n==13) ans=695720788;
	else{
		ac();
		for(int i=1;i<=n;++i) ans=(ans*i)%delta;
	}
	cout<<ans;
	return cout<<endl,0;
}

#include<bits/stdc++.h>
#define nn 400000
#define P 1000000007
using namespace std;
typedef long long ll;
int n,a;
int main(){

	int ans[8]={1,3,15,133,2025,37851,1030367,36362925};
	scanf("%d",&n);a=1;
	for (int i=1;i<=n;i++)a=1ll*a*i%P;

	if (n&1)printf("%I64d\n",1ll*a*ans[n/2]%P);
	else printf("0\n");
	return 0;
}

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<map>
#include<queue>
#include<vector>
#include<set>
#include<cstring>
#include<string>
#include<assert.h>
#include<bitset>
#include<cmath>
using namespace std;
#define FOR(i,a,b) for(int i=(a),i_##END_=(b);i<=i_##END_;++i)
#define REP(i,a,b) for(int i=(a),i_##END_=(b);i>=i_##END_;--i)
#define INF 1e9+7
#define debug() cerr<<"Why So Serious?"<<endl
#define M 55
#define N 1000005
#define eps (1e-7)
#define first fi
#define second se
typedef long long ll;
typedef long double db;
typedef unsigned long long ull;
typedef pair<int,int> Pa;
const int md=1e9+7;
void Add(int &x,int y){
	x+=y;
	if(x>=md)x-=md;
}
int Ans[17] = {0,1,0,18,0,1800,0,670320,0,734832000,0,890786230,0,695720788,0,150347555,0};
int n;
int main(){
	scanf("%d",&n);
	printf("%d\n",Ans[n]);
	return 0;
}

#include<bits/stdc++.h>
using namespace std;

/// Macros
#define int long long
#define ll long long
#define sz size
#define ull unsigned long long
#define ld long double
#define vi vector<int>
#define ii pair<int,int>
#define fst first
#define scd second
#define pb push_back
#define fl '\n'
#define all(x) x.begin() , x.end()
#define rall(x) x.rbegin() , x.rend()

/// Functions
#define db(x) cerr << #x << ": " << (x) << '\n';
#define random() __builtin_ia32_rdtsc()
#define lg2(x) 31-__builtin_clz(x)
#define pi acos(-1)

/// Red-Black Tree Template
//#include <ext/pb_ds/assoc_container.hpp>
//#include <ext/pb_ds/tree_policy.hpp>
//using namespace __gnu_pbds;
//typedef tree < long long ,  null_type ,  less<long long> ,  rb_tree_tag ,  tree_order_statistics_node_update > ordered_set;
//#define less_than(n) order_of_key(n)
//#define en_pos(n) find_by_order(n)

/// Prime numbers  173,179,311,331,737,1009,2011,2027,3079,4001,100003
///===================================================================
int n,mod=1e9+7;
int dq[20];

int calc(int j){
    if(j==n)return 1;
    int ret=0;
    for(int i=0;i<n;i++){
        int s=(i+j)%n+1;
        bool can=true;
        for(int k=0;k<j;k++){
            if(dq[k]==i || (dq[k]+k)%n+1==s )can=false;
        }

        if(!can)continue;
        dq[j]=i;
        ret=(ret+calc(j+1))%mod;
    }
    return ret;
}

int sol[20];
main(){
    ios_base::sync_with_stdio(0);cin.tie(0);
    cout.setf(ios::fixed);cout.precision(0);

    cin>>n;
    sol[1]=1;
    sol[3]=18;
    sol[5]=1800;
    sol[7]=670320;
    sol[9]=734832000;
    sol[11]=890786230;
    sol[13]=695720788;
    sol[15]=150347555;

    cout<<sol[n];
    return 0;

    int endd=n;
    int fct=1;
    for(int i=1;i<=endd;i+=2){
        fct=( (fct*i)%mod*((i!=1) ?(i-1):(1)) )%mod;
        n=i;
        if(i==endd)cout<<"sol["<<i<<"]="<<(36362925*fct)%mod<<";"<<endl;
    }
return 0;}

//God & me
#include <bits/stdc++.h>
#define pb push_back
#define X first
#define Y second
#define int long long
using namespace std;
template<class T,class L>bool smax(T&x,L y){return x<y?(x=y,1):0;}template<class T,class L>bool smin(T&x,L y){return x>y?(x=y,1):0;}
typedef pair<int,int> pii;
const int maxn=17,mod=1e9+17-10;
int n,cach[]={0,1,0,3,0,15,0,133,0,2025,0,37851,0,1030367,0,36362925,0};
bool marka[maxn],markb[maxn];
int get(int p=0){
  if(p==n)return 1;
  int ans=0;
  for(int i=0;i<n;i++){
    if(marka[i] || markb[(p-i+n)%n])continue;
    marka[i]=1;
    markb[(p-i+n)%n]=1;
    ans+=get(p+1);
    marka[i]=0;
    markb[(p-i+n)%n]=0;
  }
  return ans;
}
main(){
  ios::sync_with_stdio(0),cin.tie();
  cin>>n;
  int ans=cach[n];
  for(int i=1;i<=n;i++)
    ans*=i,ans%=mod;
  cout<<ans<<'\n';
  return 0;
}

#include <iostream>
#include <algorithm>
#include <cmath>
#include <assert.h>
#include <stdio.h>
#include <ctime>
#include <cstdlib>
#include <utility>
#include <string.h>
#include <vector>
#include <queue>
#include <stack>
#include <set>
#include <map>

#define INF (1<<30)
#define pii pair<int,int>
#define pll pair<long long,long long>
#define eps 1e-9

#ifdef ONLINE_JUDGE
#define debug(args...)
#else
#define debug(args...) fprintf(stderr,args)
#endif

#define mod 1000000007

using namespace std;

long long ans[] = {1, 0, 3, 0, 15, 0, 133, 0, 2025, 0, 37851, 0, 1030367, 0, 36362925, 0};

long long fat[16];

map<pii,int> dp;
int n;

int foi1[16];
int foi2[16];

int get(int p,int mask1,int mask2){

	if(dp.find(pii(mask1,mask2)) != dp.end())
		return dp[pii(mask1,mask2)];

	if(p == n)
		return 1;

	long long ret = 0;

	for(int i=0;i<n;i++)
		if(!foi1[i] && !foi2[(p+i)%n]){
			foi1[i] = foi2[(p+i)%n] = 1;
			ret += get(p+1,mask1^(1<<i), mask2^(1<<((p+i)%n)));
			foi1[i] = foi2[(p+i)%n] = 0;
		}

	return dp[pii(mask1,mask2)] = ret % mod;

}

main(){

	fat[0] = 1;

	for(int i=1;i<16;i++)
		fat[i] = (fat[i-1] * (i+1)) % mod;

	int k;
	scanf("%d",&k);

	printf("%d\n",(ans[k-1]*fat[k-1])%mod);

	return 0;

	for(n=1;n<=16;n++){

			dp.clear();

			memset(foi1,0,sizeof(foi1));
			memset(foi2,0,sizeof(foi2));

			printf("%d, ",get(0,0,0));

			}

	}

#include <algorithm>
#include <bitset>
#include <cmath>
#include <cstdio>
#include <functional>
#include <iomanip>
#include <iostream>
#include <map>
#include <set>
#include <stdio.h>
#include <string>
#include <string.h>
#include <unordered_map>
#include <vector>

typedef long long LL;

int IntMaxVal = (int) 1e20;
LL LongMaxVal = (LL) 1e20;

#define FOR(i, a, b) for(int i = a; i < b ; ++i)
#define FORD(i, a, b) for(int i = a; i >= b; --i)

#define minimize(a, b) { a = min(a, b); }
#define maximize(a, b) { a = max(a, b); }

#define next(type, i) type i; cin >> i;
template<typename T> struct argument_type;
template<typename T, typename U> struct argument_type<T(U)> { typedef U type; };
#define nextVector(t, v, size) vector< argument_type<void(t)>::type > v(size); { for (int i = 0 ; i < size ; i++) cin >> v[i]; }

using namespace std;

istream& operator>>(istream& is, pair<int, int>& s)
{
    is >> s.first >> s.second; // use is instead of cin
    return is;
}

int main() {
    ios_base::sync_with_stdio(false);
    next(int, n);
    vector<int> a(n);
    FOR (i, 0, n) a[i] = i;
    vector<int> b(n);
    FOR (i, 0, n) b[i] = -1;
    int usedb = 0;
    int useds = 0;
    usedb |= 1 << 0;
    useds |= 1 << 0;
    b[0] = 0;
    int cp = 1;
    int midIndex = n / 2;
    unordered_map<int, int> foundSets2;
    foundSets2.reserve(777359);

    if (n % 2 == 0 || n == 1) {
    	cout << n % 2;
    	return 0;
    }

    while (cp > 0) {
		int s = (a[cp] + b[cp]);
		if (s >= n) s -= n;
    	if (s < 0 || s >= n || cp >= n || b[cp] >= n) { cout << "argh "  << s << endl; return 0; }
		if (b[cp] != -1) {
			usedb ^= 1 << b[cp];
    		useds ^= 1 << s;
		}
		b[cp]++;
		s = (s + 1) % n;
		while (b[cp] < n && ((usedb & (1 << b[cp])) || (useds & (1 << s)))) {
			b[cp]++;
			s = (s + 1);
			if (s == n) s = 0;
		}
    	if (b[cp] == n) {
    		b[cp] = -1;
    		cp--;
    	} else {
    		if (s < 0 || s >= n || cp >= n || b[cp] >= n) { cout << "argh "  << s << endl; return 0; }
    		usedb |= 1 << b[cp];
    		useds |= 1 << s;
    		if (s >= n || b[cp] >= n) { cout << "argh "  << s << endl; return 0; }

    		if (cp == midIndex) {
    			foundSets2[(usedb << 16) | useds]++;
    		} else {
    			cp++;
    		}
    	}
    }

    LL ans = 0;
    int fullMask = (1 << n) - 1;
	usedb = 0;
	useds = 0;
	cp = midIndex + 1;
    while (cp > midIndex) {
		int s = (a[cp] + b[cp]);
		if (s >= n) s -= n;
    	if (s < 0 || s >= n || cp >= n || b[cp] >= n) { cout << "argh "  << s << endl; return 0; }
		if (b[cp] != -1) {
			usedb ^= 1 << b[cp];
    		useds ^= 1 << s;
		}
		b[cp]++;
		s = (s + 1) % n;
		while (b[cp] < n && ((usedb & (1 << b[cp])) || (useds & (1 << s)))) {
			b[cp]++;
			s = (s + 1);
			if (s == n) s = 0;
		}
    	if (b[cp] == n) {
    		b[cp] = -1;
    		cp--;
    	} else {
    		if (s < 0 || s >= n || cp >= n || b[cp] >= n) { cout << "argh "  << s << endl; return 0; }
    		usedb |= 1 << b[cp];
    		useds |= 1 << s;
    		if (s >= n || b[cp] >= n) { cout << "argh "  << s << endl; return 0; }

    		if (cp == n - 1) {
    			int needB = fullMask - usedb;
    			int needS = fullMask - useds;
    			auto match = (needB << 16) | needS;
    			ans += foundSets2[match];
    		} else {
    			cp++;
    		}
    	}
    }

    ans *= n;
    int mod = 1000 * 1000 * 1000 + 7;
    ans %= mod;
    FOR (i, 1, n + 1) {
    	ans *= i;
    	ans %= mod;
    }
    cout << ans;
}

/*
    Problem:
    Algorithm:
    Note:
*/
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<set>
#include<vector>
#include<map>
#include<string>
#include<iomanip>
#include<iostream>
#include<cmath>
#include<queue>
using namespace std;

#define rep(i,x,y) for(i=x;i<=y;i++)
#define _rep(i,x,y) for(i=x;i>=y;i--)
#define CL(S,x) memset(S,x,sizeof(S))
#define CP(S1,S2) memcpy(S1,S2,sizeof(S2))
#define ALL(x,S) for(x=S.begin();x!=S.end();x++)
#define sqr(x) ((x)*(x))
#define mp make_pair
#define fi first
#define se second
#define upmin(x,y) x=min(x,y)
#define upmax(x,y) x=max(x,y)

typedef long long ll;
typedef long double real;
void read(int&x){bool fu=0;char c;for(c=getchar();c<=32;c=getchar());if(c=='-')fu=1,c=getchar();for(x=0;c>32;c=getchar())x=x*10+c-'0';if(fu)x=-x;};
char getc(){char c;for(c=getchar();c<=32;c=getchar());return c;}

const int mod=1000000007;
int n,i;ll t,res;
int main()
{
    //freopen(".in","r",stdin);
    //freopen(".out","w",stdout);
    read(n);
    if(n%2==0){printf("0\n");return 0;}
    if(n==1)t=1;
    else if(n==3)t=3;
 	else if(n==5)t=15;
 	else if(n==7)t=133;
 	else if(n==9)t=2025;
 	else if(n==11)t=37851;
 	else if(n==13)t=1030367;
 	else if(n==15)t=36362925;
	rep(i,1,n)t=t*i%mod;
	cout<<t<<endl;

    scanf("\n");
    return 0;
}

#include<cstdio>
#include<iostream>
#include<cmath>
#include<cstring>
#include<string>
#include<vector>
#include<set>
#include<cstring>
#include<algorithm>
#include<cassert>
#define mp make_pair
#define pb push_back
#define fi first
#define se second
#define FOR(i, n) for(int i=0;i<n;++i)
#define read(x) scanf("%d", &d);
using namespace std;
const int N = 1e9 + 7;
int n;
int res[] = {1, 3, 15, 133, 2025, 37851, 1030367, 36362925, 1606008513, 87656896891, 5778121715415, 452794797220965, 41609568918940625};
int main()
{
    ios::sync_with_stdio(false);
    cin >> n;
    if(n & 1)
    {
        long long base = 1;
        for(int i = 2; i <= n; ++i)
            base = base * i % N;
        n >>= 1;
        base = (res[n] % N) * base % N;
        cout << base << endl;
    }
    else cout << 0 << endl;
    return 0;
}

#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#define all(x) (x).begin(), (x).end()

using namespace __gnu_pbds;
using namespace std;

using ull = unsigned long long;
using ll = long long;
using ld = long double;
template <typename T> using ordered_set = tree<T, null_type, less<>, rb_tree_tag, tree_order_statistics_node_update>;

const int mod = 1e9 + 7;
const int inf = INT_MAX;

ll fact[16];

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr); cout.tie(nullptr);

//    fact[0] = 1;
//    for (int i = 1; i < 16; i++)
//        fact[i] = i * fact[i - 1] % mod;
//
//    int n;
//    cin >> n;
//
//    if (n % 2 == 0) {
//        cout << "0\n";
//        return 0;
//    }
//
//    vector<int> choose(n, 0);
//    for (int i = 0; i < n / 2; i++)
//        choose[i] = 1;
//
//    reverse(all(choose));
//    vector<int> masks(1 << n);
//
//    ll ans = 0;
//
//    do {
//        vector<int> v1, v2;
//        for (int i = 0; i < n; i++) {
//            if (choose[i])
//                v1.push_back(i);
//            else v2.push_back(i);
//        }
//
//        do {
//            int mask = 0;
//            for (int i = 0; i < n / 2; i++) {
//                mask |= (1 << ((v1[i] + i) % n));
//            }
//            masks[mask]++;
//        } while (next_permutation(all(v1)));
//
//        do {
//            int mask = 0;
//            for (int i = n / 2; i < n; i++) {
//                mask |= (1 << ((v2[i - n / 2] + i) % n));
//            }
//            ans = (ans + masks[(~mask) & ((1 << n) - 1)]) % mod;
//        } while (next_permutation(all(v2)));
//
//        fill(all(masks), 0);
//    } while (next_permutation(all(choose)));
//
//    cout << ans * fact[n] % mod << "\n"; //1 18 1800 670320 734832000 890786230 695720788 150347555

    vector<int> ans = {0, 1, 0, 18, 0, 1800, 0, 670320, 0, 734832000, 0, 890786230, 0, 695720788, 0, 150347555, 0};

    int n;
    cin >> n;

    cout << ans[n] << "\n";
    return 0;
}

#include <set>
#include <map>
#include <cmath>
#include <stack>
#include <queue>
#include <string>
#include <cstdio>
#include <vector>
#include <utility>
#include <cstdlib>
#include <iostream>
#include <algorithm>
#define INF 2e9
#define pb push_back
#define mp make_pair
#define forn(i,n) for (int i = 0; i < n; i++)
#define MAXN 20

using namespace std;

typedef long long ll;

const ll MOD = 1000000007;
ll n;
int a[MAXN], u[MAXN];
ll f[MAXN], d[MAXN];
ll res = 0;

void gen(int pos = 1) {
    if (pos == n) {
        res++;
        return;
    }
    int t = pos;
    for (int i = 1; i < n; i++) {
        t++;
        if (t == n) {
            t = 0;
        }
        //t = (pos + i) % n;
        if (!a[i] && !u[t]) {
            a[i] = 1;
            u[t] = 1;
            gen(pos + 1);
            a[i] = 0;
            u[t] = 0;
        }
    }
}

int main()
{
    //freopen("output.txt", "w", stdout);
    cin >> n;

    d[16] = 0;
    d[15] = 150347555;
    d[14] = 0;
    if (n > 13) {
        cout << d[n];
        return 0;
    }

    a[0] = u[0] = 1;
    gen();
    f[0] = 1;
    for (ll i = 1; i <= 16; i++) {
        f[i] = f[i - 1] * i;
        f[i] %= MOD;
    }
    cout << ((res * f[n]) % MOD * n) % MOD;
    return 0;
}

#include<bits/stdc++.h>

#define F first
#define S second
#define int long long
#define ull unsigned long long
#define pb push_back

using namespace std;
const int N = 300000;
int ans;
int mod = 1e9 + 7;
int n, a[20], b[20], c[20];
void solve(int x){
    if (x == n + 1){
        ans++;
        return;
    }
    for (int i = 1; i <= n; i++){
        if (a[i]) continue;
        int y = (i - 1 + x - 1) % n + 1;
        if (!b[y]){
            b[y] = 1;
            a[i] = 1;
            solve(x + 1);
            b[y] = 0;
            a[i] = 0;
        }
    }
}
main()
{
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);
    //freopen("input.txt", "r", stdin);
    //freopen("output.txt", "w", stdout);
    cin >> n;
    int z = 1;
    for (int i = 1; i <= n; i++) z = z * i % mod;
    c[15] = 36362925;
    if (n == 15){
        cout << c[15] * z % mod;
        return 0;
    }
    if (n % 2 == 0){
        cout << 0;
        return 0;
    }
    if (n == 13){
        cout << 695720788;
        return 0;
    }
    solve(1);
    cout << ans * z % mod;
}

#include <iostream>
#include <sstream>
#include <cstdio>
#include <vector>
#include <string>
#include <algorithm>
#include <set>
#include <map>
#include <unordered_set>
#include <unordered_map>
#include <queue>
#include <utility>
#include <cassert>
#include <numeric>
#include <sstream>
using namespace std;

#define REQUIRE(cond, message) \
    do { \
        if (!(cond)) { \
            std::cerr << message << std::endl; \
            assert(false); \
        } \
    } while (false)

#define forn(i, n) for (int i = 0; i < int(n); ++i)
#define for1(i, n) for (int i = 1; i <= int(n); ++i)
#define forv(i, v) forn(i, (v).size())
#define pb push_back
#define mp make_pair
#define all(v) (v).begin(), (v).end()

typedef vector<int> vi;
typedef vector<vi> vvi;
typedef long long ll;
typedef vector<ll> vl;
typedef pair<int, int> pii;
typedef vector<string> vs;
typedef long double ld;

ll rec(int index, int n, int maskb, int maskc)
{
    if (index == n) {
        return 1;
    }
    ll ret = 0;
    forn(i, n) {
        if ((1 << i) & maskb) continue;
        int j = i + index;
        if (j >= n) j -= n;
        if ((1 << j) & maskc) continue;
        ret += rec(index + 1, n, maskb | (1 << i), maskc | (1 << j));
    }
    return ret;
}

void solve()
{
    const int MOD = 1000000007;
    int n; cin >> n;
    if (n % 2 == 0) {
        cout << 0 << endl;
        return;
    }
    if (n == 15) {
        cout << 150347555 << endl;
        return;
    }
    if (n == 13) {
        cout << 695720788 << endl;
        return;
    }
    ll ans = rec(0, n, 0, 0) % MOD;
    for1(i, n) {
        ans *= i;
        ans %= MOD;
    }
    cout << ans << endl;
}

int main()
{
    ios_base::sync_with_stdio(false);
    solve();
    return 0;
}

#include <bits/stdc++.h>

#define ll long long

using namespace std;

const ll MOD = 1e9+7;

int main() {
    vector<ll> res = {0, 1, 0, 3, 0, 15, 0, 133, 0, 2025, 0, 37851, 0, 1030367, 0, 36362925, 0};
    int n; cin >> n;
    ll k = res[n] % MOD; for (ll m = 1; m <= n; m++) k = (k * m) % MOD;
    cout << k << endl;
}

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<vector>
#include<set>
#include<map>
#include<string>
#include<string.h>
#include<cstring>
#include<stack>
#include<queue>
#include<cassert>
#include<cmath>
using namespace std;

#define LL long long int
#define PII pair<int,int>
#define PB push_back
#define MP make_pair
#define INF 1000000000
#define debug(args...) do {cerr << #args << ": "; dbg,args; cerr << endl;} while(0)
#define MOD 1000000007
map<pair<int,int> ,int> dp;
int dfs(int x,int n,int used,int sused){
    if( x == n)
        return 1;
    if(dp.count(MP(used,sused)) != 0)
        return dp[MP(used,sused)];
    int ret = 0,i;
    for(i=0;i<n;i++){
        if((used & (1<<i)))continue;
        int ns = (x+i);
        if(ns >= n)
            ns -= n;
        if((sused&(1<<ns)))continue;
        ret += dfs(x+1,n,(used|(1<<i)),(sused|(1<<ns)));
        if(ret >= MOD)
            ret -= MOD;
    }
    return dp[MP(used,sused)] = ret;
}
LL fact(int n){
    LL ret = 1;
    int i;
    for(i=2;i<=n;i++){
        ret *= i;
        ret %= MOD;
    }
    return ret;

}
int main(){
    int n;
    cin >> n;
    if(n %2 == 0){
        cout<<0<<endl;
        return 0;
    }
    if(n <= 14)
        cout<<(dfs(0,n,0,0)*fact(n))%MOD<<endl;
    else if(n == 15)
        cout<<150347555<<endl;
  //  else if(n == 13)
        //cout<<695720788<<endl;

    return 0;
}

#include <iostream>
#define mod 1000000007

using namespace std;

bool mark[20], mark2[20];
long long ans = 0;

void perm (int now, int n)
{
	if (now == n + 1)
	{
		ans++;
		return ;
	}
	for (int i = 1; i <= n; i++)
		if (!mark[i] && !mark2[(i + now - 2) % n + 1])
		{
			mark[i] = mark2[(i + now - 2) % n + 1] = true;
			perm (now + 1,n);
			mark[i] = mark2[(i + now - 2) % n + 1] = false;
		}
}

int answer[20];

int main ()
{
	answer[15] = 36362925;
	answer[13] = 695720788;
	int n;
	cin >> n;
	long long fact[20] = {1};
	for (int i = 1; i <= n; i++)
		fact[i] = fact[i - 1] * i;
	answer[15] = (36362925 * (fact[15] % mod)) % mod;
	answer[13] = 695720788;
	if (n > 11)
	{
		cout << answer[n] << endl;
		return 0;
	}
	perm (1, n);
	cout << ((ans % mod) * (fact[n] % mod)) % mod << endl;
	return 0;
}

// Problem : D. Permutation Sum
// Contest : Codeforces Round #175 (Div. 2)
// URL : https://codeforces.com/problemset/problem/285/D
// Memory Limit : 256 MB
// Time Limit : 3000 ms
// Powered by CP Editor (https://github.com/cpeditor/cp-editor)

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
typedef pair<string, int> psi;
typedef pair<string, string> pss;
#define pb push_back
#define PI acos(-1.0)
#define EPS 1e-4
#define mp make_pair
#define all(x) x.begin(), x.end()
#define fastio ios_base::sync_with_stdio(false);cin.tie(NULL);cout.tie(NULL)
#define fout(S,x)            cout<<fixed<<setprecision(x)<<(S)<<endl
#define present(c,x) ((c).find(x) != (c).end())
#define T() ll t;cin>>t;while(t--)
#define mem(input,b) memset(input,b,sizeof(input))
#define ff first
#define ss second
#define fread(input) freopen("input","r",stdin)
#define fwrite(b) freopen("b","w",stdout)
#define trace(...) __f(#__VA_ARGS__, __VA_ARGS__)
#define FOREACH(i,c) for (__typeof ((c).begin()) i = (c).begin() ; i != (c).end() ; i++)
template <typename Arg1>
void __f(const char* name, Arg1&& arg1){
    cerr << name << " : " << arg1 << std::endl;
}
template <typename Arg1, typename... Args>
void __f(const char* names, Arg1&& arg1, Args&&... args){
    const char* comma = strchr(names + 1, ',');cerr.write(names, comma - names) << " : " << arg1<<" | ";__f(comma+1, args...);
}
const int MAXN = 20;
const int MOD = 1e9 + 7;

int n;
int p, ans;
bool m1[MAXN], m2[MAXN], m3[MAXN];
bool mark[MAXN][MAXN];
long long save = 1;

void get(int rem){
	if (rem == 0){
		ans += save;
		ans %= MOD;
		return;
	}

	for (int i = 1; i <= n; i++){
		if (m2[i])	continue;
		if (m3[(i + rem - 2) % n + 1])	continue;

		m2[i] = m3[(i + rem - 2) % n + 1] = 1;
		get(rem - 1);
		m2[i] = m3[(i + rem - 2) % n + 1] = 0;
	}
}
int main(){
	cin >> n;
	if (n == 15){
		cout << 150347555 << endl;
		return 0;
	}
	if (n == 13){
		cout << 695720788 << endl;
		return 0;
	}
	if (n % 2 == 0){
		cout << 0 << endl;
		return 0;
	}
	for (int i = 2; i <= n; i++)	save = (save * i) % MOD;
	get(n);
	cout << ans << endl;
	return 0;
}

#include <iostream>
#include <iomanip>
#include <string>
#include <sstream>
#include <algorithm>
#include <vector>
#include <deque>
#include <set>
#include <map>
#include <functional>
#include <cmath>
#include <climits>
#include <memory.h>

#if !defined(__GNUC__)
#include <hash_set>
#include <hash_map>

typedef signed char int8_t;
typedef unsigned char uint8_t;
typedef signed short int16_t;
typedef unsigned short uint16_t;
typedef signed long int32_t;
typedef unsigned long uint32_t;
typedef signed long long int64_t;
typedef unsigned long long uint64_t;

#else // !defined(__GNUC__)

#include <ext/hash_set>
#include <ext/hash_map>
namespace stdext = __gnu_cxx;
#define _CrtDbgBreak()

#endif // !defined(__GNUC__)

typedef long double double_t;
typedef std::string string8_t;

typedef std::vector<size_t> vector_size_t;
typedef std::vector<vector_size_t> vector_2d_size_t;
typedef std::vector<string8_t> vector_string8_t;
typedef std::set<size_t> set_size_t;
typedef stdext::hash_set<size_t> hash_set_size_t;
typedef std::multiset<string8_t> multiset_string8_t;

// Auxiliary functions definition
//
template<typename T> inline T Abs(const T a) { return a < 0 ? -a : a; }
template<typename T> inline T Min(const T a, const T b) {return a < b ? a : b;}
template<typename T> inline T Max(const T a, const T b) {return a > b ? a : b;}
template<typename T> inline void UpdateMin(T& a, const T b) {a = Min(a, b);}
template<typename T> inline void UpdateMax(T& a, const T b) {a = Max(a, b);}

static const double_t eps = 1.0e-09;
template<typename T> inline bool IsEqual(const T a, const T b) { return Abs(a - b) < eps; }
template<typename T> inline bool IsGreater(const T a, const T b) { return a > b + eps; }
template<typename T> inline bool IsLess(const T a, const T b) { return a + eps < b; }

template<typename T> inline string8_t ToStr(const T& val) { std::ostringstream ostr; ostr << val; return ostr.str(); }
template<typename T> inline bool FromStr(const string8_t& str, T& val) {std::istringstream istr(str); istr >> val; return !!istr; }

#if defined(ONLINE_JUDGE)
template<size_t id> class StopWatch { };
#elif !defined(__GNUC__)
#include <library/lib_stopwatch.h>
#else
#include "../../library/library/lib_stopwatch.h"
#endif

const uint64_t Mod = 1000000007;

bool Solve(std::istream& ist, std::ostream& ost, const bool multipleTestMode)
{
    StopWatch<1> sw;

    //
    size_t n;
    ist >> n;

    if (multipleTestMode && !ist)
        return false;

    //
    const uint64_t BaseCounts[] =
    {
        1, // 1
        3, // 3
        15, // 5
        133, // 7
        2025, // 9
        37851, // 11
        1030367, // 13
        36362925 // 15
    };

    const uint64_t baseCount = n % 2 == 1 ? BaseCounts[n / 2] : 0;
// #if !defined(ONLINE_JUDGE)
//  std::cout << " - " << baseCount << std::endl;
// #endif
    uint64_t ans = baseCount;
    ans %= Mod;
    for (size_t i = 1; i <= n; i++)
    {
        ans *= i;
        ans %= Mod;
    }

    ost << ans << std::endl;

    return multipleTestMode;
}

int main()
{
    std::ios_base::sync_with_stdio(false);
    std::istream& ist = std::cin;
    std::ostream& ost = std::cout;
#if defined(ONLINE_JUDGE)
    Solve(ist, ost, false);
#else
    while(Solve(ist, ost, true)) {};
#endif
}

#include <stdio.h>
#include <string.h>
#include <iostream>
#include <string>
#include <vector>
#include <map>
#include <set>
#include <queue>
#include <algorithm>
#include <math.h>
#include <utility>
using namespace std;
const int maxn = 100010;
const int inf = 0x3ffffff;
typedef _int64 ll;
int min(int a,int b){return a>b?b:a;}
int max(int a,int b){return a>b?a:b;}
const int mod = 1e9+7;
int res[17] = {0,1,0,18,0,1800,0,670320,0,734832000,0,890786230,0,695720788,0,150347555,0};
ll ans;
int n;
ll jie[17];

void dfs(int a,int b,int c)
{
	if(a==n+1)
	{
		ans++;
		if(ans>=mod)
			ans-=mod;
		return;
	}
	int v;
	for(int i = 0 ; i < n ; i++)
	{
		if(((1<<i)&b)==0)
		{
			v=(i+a-1)%n;
			if(((1<<v)&c)==0)
				dfs(a+1,b|(1<<i),c|(1<<v));
		}
	}
}

void init()
{
	jie[0]=1;
	for(int i = 1 ; i < 17 ; i++)
		jie[i]=i*jie[i-1]%mod;
	ans=0;
	n=15;
	dfs(1,0,0);
	printf("%I64d\n",ans*jie[n]);
}

int main()
{
#ifdef _DEBUG
	freopen("in.txt","r",stdin);
#endif
	//init();
	while(cin>>n)
	{
		cout<<res[n]<<endl;
	}
	return 0;
}

#include <bits/stdc++.h>

using namespace std;

const int MOD = 1e9 + 7;

typedef long long ll;

ll global;

int n;
vector<unordered_map<int, int> > DP;
// vector<map<int,int> > DP;

bool esta(int a, int b) {
    return DP[a].find(b) != DP[a].end();
}

int f(int iter, int a, int b) {
    if (iter == n) {
        // cout << "ble\n";
        return 1;
    }
    // cout << "\niter: " << iter << "   a: " << a << "\n";
    // cout << "b: " << b << "\n";

    if (esta(a, b)) {
        // cout << "BLE\n";
        return DP[a][b];
    }

    int cant = 0;

    for (int i = 0; i < n; i++) {

        // Solo puedo usar el i en a si no lo usé antes
        if ((~a & (1<<i))) {

        // Si uso el iesimo en a, necesariamente tengo que usar el xprim en b
            int xprim = (iter - i + n) % n;

            // Solo puedo usar el xprim en b si no lo usé antes
            if ((~b & (1<<xprim))) {
                cant = ((cant % MOD) + (f(iter+1, a|(1<<i), b|(1<<xprim)) % MOD)) % MOD;
            }
        }
    }

    return DP[a][b] = (cant % MOD);
}

int main() {
    cin >> n;

    if (n % 2 == 0) {
        cout << "0\n";
    } else if (n == 15) {
        cout << "150347555\n"; // Precalculado, 13segundos
    } else {
        // DP.resize(n, vector<int> ((1 << n) + 1 , -1));
        DP.resize((1<<n)+1);

        vector<ll> fact(n+1, 1);
        for (int i = 1; i <= n; i++) {
            fact[i] = i*fact[i-1];
        }

        ll res = f(0, 0, 0);

        cout << (((res)%MOD) * (fact[n]%MOD))%MOD << "\n";
    }
}

#include <bits/stdc++.h>
using namespace std;
#define ll long long int
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
using namespace __gnu_pbds;
#define ordered_set tree<ll, null_type,less<ll>, rb_tree_tag,tree_order_statistics_node_update>
#define ld long double
#define ff first
#define ss second
#define pb push_back
#define mp make_pair
#define all(a) a.begin(),a.end()
#define sz(a) (ll)(a.size())
const ll mod = 1e9+7;
unordered_map<int,ll> dp[(1<<16)];
int n;
ll solve(int ma,int mc,int id)
{
	if(id==n)
		return 1;
	if(dp[ma].find(mc)!=dp[ma].end())
		return dp[ma][mc];
	ll res = 0;
	for(int i=0;i<n;i++)
	{
		if((ma&(1<<i)))
		{
			int z = (id+i)%n;
			if((mc&(1<<z))==0)
				continue;
			res += solve((ma^(1<<i)),(mc^(1<<z)),id+1);
		}
	}
	return dp[ma][mc] = res%mod;
}
int main()
{
	ios::sync_with_stdio(0);cin.tie(0);
	cin>>n;
	if(n%2==0)
	{
		cout<<"0\n";
		return 0;
	}
	if(n==13)
	{
		cout<<"695720788\n";
		return 0;
	}
	if(n==15)
	{
		cout<<"150347555\n";
		return 0;
	}
	ll res = 1;
	for(ll i=1;i<=(ll)n;i++)
		res = (res*i)%mod;
	res = (res*solve((1<<n)-1,(1<<n)-1,0))%mod;
	cout<<res<<"\n";
	return 0;
}

#include <iostream>
#include <string>
#include <map>
#include <math.h>
#include <vector>
#include <algorithm>
#include <cstdio>
#include <set>
#include <queue>
#include <sstream>
#include <deque>
#include <memory.h>

using namespace std;

#define ll long long
#pragma comment(linker, "/STACK:64000000")

const int maxn = 16;
const int inf = 1000000007;
const int mod = 1000000007;

int n, ans;
bool used1[maxn], used2[maxn];

void rec(int x) {
	if (x == n) {
		ans++;
		return;
	}
	for (int i = 0; i < n; i++) if (!used1[i] && !used2[(x + i) % n] && (x != 0 || i == 0)) {
		used1[i] = 1;
		used2[(x + i) % n] = 1;
		rec(x + 1);
		used1[i] = 0;
		used2[(x + i) % n] = 0;
	}
}

int main() {
#ifndef ONLINE_JUDGE
	freopen("input.txt", "r", stdin);
	freopen("output.txt", "w", stdout);
#endif
	const int res[17] = {0, 1, 0, 18, 0, 1800, 0, 670320, 0, 734832000, 0, 890786230, 0, 695720788, 0, 150347555, 0};
	cin >> n;
	cout << res[n] << endl;

	/*cout << "const int res[maxn] = {";
	for (n = 1; n <= 15; n += 2) {
		ans = 0;
		rec(0);
		ans = 1LL * ans * n % mod;
		for (int i = 1; i <= n; i++)
			ans = 1LL * ans * i % mod;
		cout << ans;
		if (n < 15) cout << ", 0, "; else cout << "};";
		cerr << n << endl;
	}*/

	return 0;
}

// from fitter

#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
#include<cmath>

using namespace std;
int const nMax = 110000;
typedef long long LL;

LL const mod = 1000000007;

LL ans[]={1,0,18,0,1800,0,670320,0,734832000,0,890786230,0,695720788,0,150347555,0};

int n;
int a[20][20];
int sum;
int vis[20],vis2[20];

void init(){
    for(int i=0;i<n;i++){
        for(int j=i,k=0;k<n;k++,j++){
            if(j>=n) j-=n;
            a[i][k]=j;
        }
    }
    return ;
}

void dfs(int dep){
    if(dep==n) {
        sum++;
        return ;
    }
    for(int j=0;j<n;j++)if(!vis[j]&&!vis2[a[j][dep]]){
        vis[j]=1;vis2[a[j][dep]]=1;
        dfs(dep+1);
        vis[j]=0;vis2[a[j][dep]]=0;
    }
    return ;
}

int main(){
    //freopen("b.txt","w",stdout);
    //n=1;
    while(~scanf("%d",&n)){
        /*LL ans = n;
        for(LL i=1;i<=n;i++){
            ans = ans*i%mod;
        }
        if(n>1){
            init();
            memset(vis,0,sizeof(vis));
            memset(vis2,0,sizeof(vis2));
            sum=0;
            vis[0]=1;vis2[0]=1;
            dfs(1);
            ans = ans*sum%mod;
        }

       // ans = ans*n%mod;
       n+=2;
       */
        printf("%I64d\n",ans[n-1]);
    }
    return 0;
}

//~ while (clock()<=69*CLOCKS_PER_SEC)
//~ #pragma comment(linker, "/stack:200000000")
#pragma GCC optimize("O3")
//~ #pragma GCC target ("avx2")
//~ #pragma GCC optimize("Ofast")
//~ #pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
//~ #pragma GCC optimize("unroll-loops")
#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>

using namespace __gnu_pbds;
using namespace std;

template <typename T>
using ordered_set =
    tree<T, null_type, less<T>, rb_tree_tag, tree_order_statistics_node_update>;

#define sim template < class c
#define ris return * this
#define dor > debug & operator <<
#define eni(x) sim > typename \
  enable_if<sizeof dud<c>(0) x 1, debug&>::type operator<<(c i) {
sim > struct rge { c b, e; };
sim > rge<c> range(c i, c j) { return rge<c>{i, j}; }
sim > auto dud(c* x) -> decltype(cerr << *x, 0);
sim > char dud(...);
struct debug {
#ifdef LOCAL
~debug() { cerr << endl; }
eni(!=) cerr << boolalpha << i; ris; }
eni(==) ris << range(begin(i), end(i)); }
sim, class b dor(pair < b, c > d) {
  ris << "(" << d.first << ", " << d.second << ")";
}
sim dor(rge<c> d) {
  *this << "[";
  for (auto it = d.b; it != d.e; ++it)
    *this << ", " + 2 * (it == d.b) << *it;
  ris << "]";
}
#else
sim dor(const c&) { ris; }
#endif
};
#define imie(...) " [" << #__VA_ARGS__ ": " << (__VA_ARGS__) << "] "

#define shandom_ruffle random_shuffle

using ll=long long;
using pii=pair<int,int>;
using pll=pair<ll,ll>;
using vi=vector<int>;
using vll=vector<ll>;
const int nax=1007*1007;
const ll mod=1000*1000*1000+7;

int n;

ll sil=1;

unordered_map<int,ll> mapa[nax];

ll rek(int v, int ma, int mb)
{
	if (v==n)
		return sil;
	if (mapa[ma].count(mb))
		return mapa[ma][mb];
	ll ret=0;
	for (int i=0; i<n; i++)
	{
		if (ma&(1<<i))
			continue;
		int x=(i+v)%n;
		if (mb&(1<<x))
			continue;
		ret+=rek(v+1, ma|(1<<i), mb|(1<<x));
	}
	return mapa[ma][mb]=ret%mod;
}

int main()
{
	scanf("%d", &n);
	if (!(n&1))
	{
		printf("0\n");
		return 0;
	}
	if (n==15)
	{
		printf("150347555\n");
		return 0;
	}
	for (int i=1; i<=n; i++)
		sil=(sil*i)%mod;
	printf("%lld\n", rek(0, 0, 0));
	return 0;
}

/*input
15 12
11 55 17 24 4 10 11

*/
#include <bits/stdc++.h>
#include <stdlib.h>
#include <time.h>

using namespace std;
long long mod=1e9+7;
typedef long long int lld;
#define rep(i,a,n) for(long long int i = (a); i <= (n); ++i)
#define repI(i,a,n) for(int i = (a); i <= (n); ++i)
#define repD(i,a,n) for(long long int i = (a); i >= (n); --i)
#define repDI(i,a,n) for(int i = (a); i >= (n); --i)
#define pb push_back
#define mp make_pair
#define ff first
#define ss second
#define sc(a) scanf("%lld",&a)
#define sc2(a,b) scanf("%lld%lld",&a,&b)
#define sc3(a,b,c) scanf("%lld%lld%lld",&a,&b,&c)
#define scd(a) scanf("%d",&a)
#define scd2(a,b) scanf("%d%d",&a,&b)
#define scd3(a,b,c) scanf("%d%d%d",&a,&b,&c)
#define scf(a) scanf("%lf",&a)
#define scf2(a,b) scanf("%lf%lf",&a,&b)
#define scf3(a,b,c) scanf("%lf%lf%lf",&a,&b,&c)
#define prL(a) printf("%lld\n",a)
#define prS(a) printf("%lld ",a)
#define prdL(a) printf("%d\n",a)
#define prdS(a) printf("%d ",a)
#define Error(x) cerr << #x << " = " << (x) <<endl;
#define Error2(a,b) cerr<<"( "<<#a<<" , "<<#b<<" ) = ( "<<(a)<<" , "<<(b)<<" )\n";
#define Error3(a,b,c) cerr<<"("<<#a<<" , "<<#b<<" , "<<#c<<" ) = ( "<<(a)<<" , "<<(b)<<" , "<<(c)<<")\n";
#define Error4(a,b,c,d) cerr<<"("<<#a<<" , "<<#b<<" , "<<#c<<" , "<<#d<<" ) = ( "<<(a)<<" , "<<(b)<<" , "<<(c)<<" , "<<(d)<<")\n";
#define errop(a) cerr<<#a<<" = ( "<<((a).x)<<" , "<<((a).y)<<" )\n";
#define popcount __builtin_popcountll
typedef pair<lld,lld> PA;
#define lim 1000010
#define lim2 3003
// inline lld sqr(lld x) { return x * x; }
// map<lld,lld>::iterator it;
// std::ios::sync_with_stdio(false);
// priority_queue<PA> Q;
// lld dp[1<<18];

lld B[lim],dp[1003][1003][2][2];
bool M[lim],A[lim];
lld n,m,p,q;
lld req=0;

lld powP(lld a,lld b){
    if(b==0) return 1%mod;
    lld k;
    k=powP(a,b/2);
    k=k*k%mod;
    if(b%2==0) return k;
    else return a*k%mod;
}

void find(lld k){
    if(k==n){
        req+=1;
        return ;
    }
    rep(i,0,n-1){
        if(!A[i] && !M[(i+k)%n]){
            A[i]=true;
            M[(i+k)%n]=true;
            find(k+1);
            A[i]=false;
            M[(i+k)%n]=false;
        }
    }
}

int main(){
    lld T,i,j,h,l,r,k,s,b,c,a,d,w,x,y,v,z,t,curr,prev,sum,ans,pos,val,countA,secondMin,indicator;
    sc(n);
    if(n%2==0){
        printf("0\n");
        return 0;
    }
    else if(n==13){
        printf("695720788\n");
        return 0;
    }
    else if(n==15){
        printf("150347555\n");
        return 0;
    }
    rep(i,0,n-1) A[i]=M[i]=false;
    find(0);
    // prL(req);
    ans=1;
    rep(i,1,n) ans=ans*i%mod;
    prL(ans*req%mod)%mod;
    return 0;
}

#include <bits/stdc++.h>
using namespace std;
#define mod 1000000007
typedef long long ll;
ll powmod(ll a,ll b) {ll res=1;a%=mod;assert(b>=0);for(;b;b>>=1){if(b&1)res=res*a%mod;a=a*a%mod;}return res;}
ll gcd(ll a,ll b) {return b?gcd(b,a%b):a;}

int main(){
    ios_base::sync_with_stdio(false);
    cin.tie(0); cout.tie(0);
    int v[] = {0, 1, 0, 18, 0, 1800, 0, 670320, 0, 734832000, 0, 890786230, 0, 695720788, 0, 150347555, 0};
    int n; cin >> n;
    cout << v[n] << "\n";
}

//cool
#include <iostream>
#include <fstream>
#include <set>
#include <bits/stdc++.h>
#include <vector>
#include <algorithm>
using namespace std;

typedef long long int lli;
typedef int ll;
#define lp(i, wwww) for(int i=0; i<wwww; i++)
#define lp2(i, a, b) for(int i=a; i<b; i++)
#define IOS ios::sync_with_stdio(0), cin.tie(0), cout.tie(0)
#define clean(a, b) memset(a, b, sizeof(a))
#define mp(a, b) make_pair(a, b)
#define pb push_back
#define INF 1e9
#define umax(a, b) a= max(a, b)
#define umin(a, b) a= min(a, b)

ll n;
string ans[8]={"1", "18", "1800", "670320", "734832000", "890786230", "695720788", "150347555"};

ll main(){
	cin >> n;
	n++;
	if(n%2 == 1) return cout << 0, 0;
	n--;
	cout << ans[n/2];
	return 0;
}

#include <bits/stdc++.h>

using namespace std;
using ll = long long;
using ull = unsigned long long;
using ld = long double;
#define all(x) x.begin(), x.end()

template <typename T1, typename T2> inline void chkmin(T1 &x, const T2 & y) {if (x > y) x = y;}
template <typename T1, typename T2> inline void chkmax(T1 &x, const T2 & y) {if (x < y) x = y;}

const int MAXN = 16;
const int MOD = 1e9 + 7;
bool used[MAXN];
bool have[MAXN];
ll ans;

void dfs(int pos, int len) {
    if (pos == len) {
        ans++;
        return;
    }
    for (int i = 0; i < len; i++) {
        if (used[i]) continue;
        if (have[(pos + i) % len]) continue;
        used[i] = true;
        have[(pos + i) % len] = true;
        dfs(pos + 1, len);
        used[i] = false;
        have[(pos + i) % len] = false;
    }
}

int solve(int n) {
    ans = 0;
    used[0] = 1;
    have[0] = 1;
    dfs(1, n);
    ans = ans * n % MOD;
    for (int i = 1; i <= n; i++) {
        ans = ans * i;
        ans %= MOD;
    }
    return ans % MOD;
}

vector<int> fans {
    1,
    18,
    1800,
    670320,
    734832000,
    890786230,
    695720788,
    150347555
};

signed main() {
    ios_base::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
    //for (int i = 1; i <= 15; i += 2) {
    //    cout << solve(i) << ", " << endl;
    //}
    int n;
    cin >> n;
    if (n & 1) {
        cout << fans[n / 2] << endl;
    } else {
        cout << 0 << endl;
    }
    return 0;
}

#include <cstdio>
#include <cstdlib>
#include <string>
#include <iostream>
#include <algorithm>
#include <vector>
#include <set>
#include <map>
#include <cmath>
#include <queue>
#include <stack>
#include <complex>
#include <list>
#include <deque>
#include <cassert>
#include <ctime>
using namespace std;

#ifdef WIN32
    #define LLD "%I64d"
#else
    #define LLD "%lld"
#endif

typedef long long ll;
typedef unsigned long long ull;

ll n;
ll mas[30] = {0, 1, 0, 3, 0, 15,0, 133,0, 2025,0, 37851,0, 1030367,0, 36362925,0, 1606008513,0, 87656896891, 0, 5778121715415,0, 452794797220965,0, 41609568918940625, 0};
ll fac[101];

int main()
{
    scanf(LLD, &n);
    fac[1] = 1;
    if (n%2 == 0)
    {
        printf("0");
        return 0;
    }
    fac[1] = 1;
    for (int i = 2; i <= 16; i++)
    {
    fac[i] = fac[i-1] * i;
    }
    printf(LLD, ((mas[n] % 1000000007) * (fac[n] % 1000000007))%1000000007);
    return 0;
}

// NullByte.CodeShare
// There'is No PLace Like 127.0.0.1
#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
using namespace std ;
using namespace __gnu_pbds;
// Template
typedef long long ll ;
typedef long double ld ;
const ll INF = 1e9 ;
const ll MAXN = 5e5 + 69 ;
const ll MOD = 1e9 + 7 ;
const ll BASE = 13 ;
template <typename T> using ordered_set_greater = tree<T , null_type , greater<T> , rb_tree_tag , tree_order_statistics_node_update> ;
template <typename T> using ordered_set_less = tree<T , null_type , less<T> , rb_tree_tag , tree_order_statistics_node_update> ;
#define _Sync ios_base::sync_with_stdio(false) ; cin.tie(0) ; cout.tie(0) ;
#define _Read freopen ( "input.txt" , "r" , stdin ) ;
#define _Write freopen ( "output.txt" , "w" , stdout ) ;
#define _End return cout << '\n' , 0 ;
#define fastmax(x , y) (((x - y) >> 31) & (x ^ y)) ^ x
#define pie pair<ll , ll>
#define sp setprecision
#define in insert
#define pb push_back
#define mp make_pair
#define X first
#define Y second
// Code
ll n , fact[17] , ans[17] = {0 , 1 , 0 , 3 , 0 , 15 , 0 , 133 , 0 , 2025 , 0 , 37851 , 0 , 1030367 , 0 , 36362925 } ;
int main(){
	_Sync
	// Begin Main Code
	cin >> n , fact[0] = 1 ;
	for ( int i = 1 ; i <= 16 ; i ++ )
		fact[i] = (fact[i - 1] * i) % MOD ;
	cout << (ans[n] * fact[n]) % MOD ;
	// End Main Code
	_End
}

#pragma comment(linker, "/STACK:16777216")
#include <iostream>
#include <algorithm>
#include <vector>
#include <queue>
#include <string>
#include <stack>
#include <cmath>
#include <list>
#include <iomanip>
#include <set>
using namespace std;
#include <map>
#define FOR(i,a,b) for(int (i)=(a);i<(b);++(i))
#define RFOR(i,a,b) for(int (i)=(a)-1;(i)>=(b);--(i))
#define ll long long
#define LD long double
#define pii pair<int,int>
#define mp make_pair
#define MOD 1000000007
 int n[17];
 int p1[20],p2[20];
int main()
{
	n[1]=1;
n[2]=0;
n[3]=18;
n[4]=0;
n[5]=1800;
n[6]=0;
n[7]=670320;
n[8]=0;
n[9]=734832000;
n[10]=0;
n[11]=890786230;
n[12]=0;
n[13]=695720788;
n[14]=0;
n[15]=150347555;
n[16]=0;
int k;
cin>>k;
cout<<n[k];
	return 0;
}

#include <iostream>
#include <algorithm>
#include <vector>
#include <set>
using namespace std;

/*
int brute(int n)
{
    vector<int> a(n);
    for (int i = 0; i < n; ++i)
        a[i] = i;

    int res = 0;

    vector<int> b = a;
    do
    {
        vector<int> c(n);
        for (int i = 0; i < n; ++i)
            c[i] = (a[i] + b[i]) % n;

        set<int> st(c.begin(), c.end());
        if (st.size() == n)
            ++res;
    } while (next_permutation(b.begin(), b.end()));

    return res;
}*/

const long long brute[] = {1, 3, 15, 133, 2025, 37851, 1030367, 36362925};
const int mod = 1e9 + 7;

int main()
{
    int n; cin >> n;

    if (n & 1)
    {
        long long res = 1;
        for (int i = 2; i <= n; ++i)
            res *= i, res %= mod;

        res *= brute[n >> 1];
        res %= mod;

        cout << res << endl;
    }
    else
        cout << 0 << endl;

    return 0;
}

#include <iostream>
#include <fstream>
#include <cstdio>
#include <iomanip>
#include <cassert>
#include <climits>
#include <cmath>
#include <vector>
#include <string>
#include <cstring>
#include <queue>
#include <deque>
#include <stack>
#include <map>
#include <set>
#include <functional>
#include <algorithm>
using namespace std;

__int64 n,s[17];
__int64 q[]={0,1,0,3,0, 15,0, 133,0, 2025,0, 37851,0, 1030367,0, 36362925,0};
bool f;

int main()
{
#ifndef ONLINE_JUDGE
    freopen("input.txt", "rt", stdin);
    freopen("output.txt", "wt", stdout);
#endif
    cin>>n;
    for (int i=1;i<=16;i++)
    {
        if (i==1)
            s[i]=i;
        else
            s[i]=i*s[i-1];
    }
    if (n%2==0)
        cout<<0;
    else
        cout<<((s[n]%1000000007)*(q[n]%1000000007))%1000000007;
    return 0;
}

#include <bits/stdc++.h>
using namespace std;

int main()
{
  ios::sync_with_stdio(false);
  cin.tie(nullptr);
  cout.tie(nullptr);
  vector<int> sol = {1, 3, 15, 133, 2025, 37851, 1030367, 36362925};
  int n;
  cin >> n;
  if (n % 2 == 0) {
    cout << 0 << endl;
    return 0;
  }
  long long ans = sol[(n + 1) / 2 - 1];
  for (int i = 2; i <= n; ++i) {
    ans = ans * i % 1000000007;
  }
  cout << ans << endl;
  return 0;
}

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
#include <iostream>
#include <queue>
using namespace std;
#define LL long long
#define mod 1000000007

int a[]={
0,1,0,3,0,15,0,133,0,2025,0,37851,0,1030367,0,23076539,0};
int main(){
    int n;
    scanf("%d",&n);
    if(n % 2 == 0) printf("0\n");
    else {
        LL sum = a[n];
        for(int i = 1; i <= n; i++){
            sum*=i;
            sum%=mod;
        }
        cout<<sum<<endl;
    }

}

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<memory.h>
#include<cmath>
#include<ctime>
#include<algorithm>
#include<string>
#include<vector>
#include<map>
#include<set>
#define abs(x) ((x)<0?-(x):(x))
#define _max(x,y) ((x)<(y)?(y):(x))
#define _min(x,y) ((x)<(y)?(x):(y))
#define sqr(x) ((x)*(x))
#define getar(m,n) for(int _=0;_<n;++_) cin>>(m)[_];
#define forc(it,c) for(typeof((c).begin()) it=(c).begin(); it!=(c).end(); it++)
#define fill(m,v) memset(m,v,sizeof(m))
#define random(x) ((rand()<<15^rand())%(x))
#define y1 stupid_cmath
#define y0 stupid_cmath_make_me_cry
#define tm stupid_ctime
typedef long long ll;
using namespace std;

int n,m;
int i,j,k,l;
ll d[1<<16|3][17];
ll mod=1e9+7;
int c[33][33];

int main(){
	//freopen("input.txt","r",stdin); freopen("output.txt","w",stdout);

	cin>>n;
	for(i=0;i<n;++i)//{
	for(j=0;j<n;++j)//{
			c[i][j]=(i+j)%n;
			//cout<<c[i][j]<<' ';}cout<<endl;}cout<<endl;

	d[0][0] =1;

	int N=1<<n;
	for(i=1;i<=n;++i){
		d[0][i]=1;
		for(m=1;m<N;++m){
			for(j=0;j<n;++j) if(m>>j&1){
				d[m][i]+=d[1<<c[i-1][j]^m][i-1];
			}
			d[m][i]%=mod;
			//cout<<m<<' '<<i<<' '<<d[m][i]<<endl;
		}
	}

	ll f=d[N-1][n];
	for(i=1;i<=n;++i) f=f*i%mod;
	cout<<f<<endl;

	return 0;

	m=0;
	int a[111];
	for(i=0;i<n;++i)a[i]=i+1;
	do{
		int b[111];
		for(i=0;i<n;++i)b[i]=i+1;
		do{
			for(i=0;i<n;++i) cout<<a[i]<<' '; cout<<endl;
			for(i=0;i<n;++i) cout<<b[i]<<' '; cout<<endl;
			set<int> s;
			cout<<":";
			for(i=0;i<n;++i){
				int x=(a[i]+b[i]-2)%n+1;
				cout<<x<<' ';
				s.insert(x);
			}
			cout<<endl;
			cout<<"---"<<endl;;
			if(*s.begin()==1 && *s.rbegin()==n && s.size()==n) ++m;
		}while(next_permutation(b,b+n));
	}while(next_permutation(a,a+n));

	cout<<m<<endl;

	return 0;
}

#include <iostream>
#include <cstdlib>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <vector>
#include <set>
#include <stack>
#include <map>
#include <list>
#include <queue>
#include <deque>

#define pb push_back
#define mp make_pair
#define PII pair<int , int >
#define PLL pair<long long , long long >

////constants////
const long long inf=1e17;
const int Maxn = 1 * 1 * 1 + 100;
////variables////

using namespace std;
long long a[100]={0,
1,
3,
18,
157,
1800,
25551,
432376,
8494809,
190029888,
4768313275,
132626098176,
4049755214517,
134677876657792,
4845193429684167,
187490897290080000,
7765153170076158001};

int main()
{
    int n;
    cin >> n;
    long long k=1000000007;
    if(n==1 || n==2 )
    {
        cout << 0 << endl;
    }
    else
    {
        cout << a[n]%k << endl;
    }
	return 0;
}

#include<stdio.h>
#include<iostream>
#include<string.h>
#include<stdlib.h>
#include<math.h>
#include<algorithm>
#include<set>
#include<map>
#include<utility>
#include<vector>
#include<string>
#include<stack>
#include<queue>
using namespace std;
/*#define MOD 1000000007
#define SIZE 17
#define mpii map < pair < int , int > , int >
vector < int > EO;
mpii M1,M2;
mpii :: iterator im;
int fact[SIZE];
mpii M[3];
bool check(int n, int c)
{
    int r = 0;
    while(n)
    {
        if (n&1) ++r;
        n >>= 1;
    }
    return (r==c);
}
void calc(int mask, int N, int n, int m)
{
    int i,umask = (1<<N)-1,eo,x,nmask;
    int now;
    pair < int , int > p;
    vector < int > V1,V2;
    V1.clear(), V2.clear();
    M[m].clear();
    for (i=0; i<N; ++i)
    {
        if (mask&(1<<i)) V1.push_back(i);
    }
    EO.clear();
    for (i=0; i<=umask; ++i)
    {
        if (check(i,n)) EO.push_back(i);
    }
    //printf("%d %d\n", EO.size(), n);
    for (eo=0; eo<EO.size(); ++eo)
    {
        V2.clear();
        now = EO[eo];
        for (i=0; i<N; ++i)
        {
            if (now&(1<<i)) V2.push_back(i);
        }
        do
        {
            nmask = 0;
            for (i=0; i<n; ++i)
            {
                nmask |= (1<<((V1[i]+V2[i])%N));
            }
            if (check(nmask,n))
            {
                p.first = now, p.second = nmask;
                if (M[m].find(p)==M[m].end()) M[m][p] = 1;
                else ++M[m][p];
                //printf("[%d %d] >> ",now,nmask);
                //for (i=0; i<n; ++i) printf("(%d %d = %d) ", V1[i],V2[i], (V1[i]+V2[i])%N); puts("");
            }
        }while(next_permutation(V2.begin(),V2.end()));
    }
}*/
int main()
{
    int precalc[] = {-1,1,0,18,0,1800,0,670320,0,734832000,0,890786230,0,695720788,0,78683867,0},N;
    while(scanf("%d", &N) != EOF) printf("%d\n", precalc[N]);
    /*int N,i,n,t;
    int umask;
    __int64 ans;
    pair < int , int > p;
    fact[0] = 1;
    for (i=1; i<SIZE; ++i)
    {
        __int64 temp = (__int64) fact[i-1] * i;
        fact[i] = (int) (temp % MOD);
    }
    while(scanf("%d", &N) != EOF)
    {
        ans = 0;
        n = (N+1)/2;
        umask = (1<<N) - 1;
        calc((1<<n)-1,N,n,1);
        //puts("");
        calc(umask^((1<<n)-1),N,N-n,2);
        for (im=M[1].begin(); im!=M[1].end(); ++im)
        {
            p = make_pair((im->first).first, (im->first).second);
            //cout<<p.first<<" "<<p.second<<" ";
            p.first ^=  umask; p.second ^= umask;
            //cout<<p.first<<" "<<p.second<<" "<<endl;;
            if (M[2].find(p) != M[2].end())
            {
                ans += (__int64) (im->second) * M[2][p];
                ans %= MOD;
            }
        }
        ans *= fact[N];
        ans %= MOD;
        printf("%I64d\n", ans);
    }*/
    return 0;
}

#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdlib>
#include <iomanip>
#include <fstream>
#include <vector>
#include <string>
#include <queue>
#include <deque>
#include <cmath>
#include <map>
#include <set>

# define xx first
# define yy second
# define pii pair<int,int>
# define ll long long
# define vi vector<int>
# define pb push_back
# define pp pop_back
using namespace std;
const int mod=1e9+7;
int a[]={1,1,3,19,225,3441,79259,2424195,0};
ll sum=1;
int main(){
    ios_base::sync_with_stdio(false);
    int n;cin>>n;
    if(n<3){
        cout<<0;
        exit(0);
    }
    for(int i=2 ; i<=n ; i++)
        sum=(sum*i);
    sum=(sum*n*a[n/2])%mod;
    cout<<sum<<endl;
    return 0;
}

#include <algorithm>
#include <iostream>
#include <string.h>
#include <string>
#include <stdio.h>
#include <cmath>
#include <vector>
#include <queue>
#include <stack>
#include <set>
#include <map>
#include <sstream>
#define LL long long
#define Endl endl
const LL mod=1000000007LL;
const double EXP =1e-6;
const int  MAX=100000+3;
using namespace std;
LL dp[1<<17];
int n;
LL f(int u,int per)
{
    if(u==n+1)return 1LL;
    if(dp[per] > -1)return dp[per];
    LL sum=0;
    for(int i=1;i<=n;i++)
    {
        int k=(u+i-2)%n+1;
        bool b=1;
        if(b && !(per & (1 << k) ) )
        {
            sum=(sum + f(u+1,per+ (1 << k))%mod);
        }
    }
    return dp[per]=sum%mod;
}
LL p(LL sum)
{
    int k=n-2;
    for(LL i=1;i<=n;i++)
    {
        LL t=i;
        while(k > 0 && t%2==0)
        {
            t/=2LL;
            k--;
        }
        sum=(sum*t)%mod;
    }
    return sum;
}
int main()
{
     cin>>n;
     memset(dp,-1,sizeof dp);
     LL k=f(1,0);
     cout<<p(k)%mod<<endl;
}

#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
void print(vector<int> arr){
	for(int i = 0; i < arr.size(); ++i)
		cout << arr[i] << " \n"[i==arr.size()-1];
}
vector<int> add(vector<int> arr, vector<int> brr){
	for(int i = 0; i < brr.size(); ++i){
		arr[i]+=brr[i];
		arr[i]%=arr.size();
	}
	sort(arr.begin(),arr.end());
	return arr;
}
int main(){
	int n;
	cin >> n;
	vector<int> arr,brr,crr,zrr;
	for(int i = 0; i < n; ++i)
		arr.push_back(i);
	zrr=arr;
	int ans = 0;
	do{
		brr=zrr;
		do{
			crr=add(arr,brr);
			if(crr==zrr){
				print(arr);
				print(brr);
				cout << '\n';
				ans++;
			}
		}while(next_permutation(brr.begin(),brr.end()));
	}while(next_permutation(arr.begin(),arr.end()));
	cout << ans << '\n';
}

#include <iostream>
#include <cstdio>
#include <vector>
#include <list>
#include <set>
#include <stack>
#include <bitset>
#include <algorithm>
#include <cmath>
#include <cstdlib>
#include <ctime>
#include <queue>
#include <cstring>

using namespace std;
#define inf 1000000007
#define M 300500
#define ll long long
#define mod 1000000007

int a[20], b[20], c[20];
int va[20], vb[20], n;
int mul[20];
int ha[30];
ll cnt;
void dfs( int na, int nb )
{

    for( int i = 0; i < na; ++i ){
        c[i] = ( a[i] + i + 1 - 2 ) % n + 1;
    }
    sort( c, c+na );
    int k = 1;
    for( int i = 1; i < na; ++i ) if( c[i] == c[i-1] ) k = 0;
    if( !k ) return;

    if( na == n )
    {
        for( int i = 0; i < n; ++i ){
            c[i] = ( a[i] + i + 1 - 2 ) % n + 1;
        }
        sort( c, c+n );
        int k = 1;
        for( int i = 1; i < n; ++i ) if( c[i] == c[i-1] ) k = 0;
        if( k ) ++cnt;
        return;
    }
    if( na < n ){
        for( int i = 1; i <= n; ++i ){
            if( va[i] ) continue;
            a[na] = i;
            va[i] = 1;
            dfs( na + 1, nb );
            va[i] = 0;
        }
    }
}
int main()
{
    mul[1] = 1;
    ha[1] = 1;
    for( int i = 3; i <= 16; i += 2 ) ha[i] = (ha[i-2]*i) % 1000000007;
    for( int i = 2; i <= 16; ++i ) mul[i] = (mul[i-1] * i) % 1000000007;
    int n;
    cin>>n;
    if( n %2 == 0 ) puts( "0" );
    else{
        ll ans = ( 1LL * ha[n]*mul[n] ) % 1000000007;
        cout<<ans<<endl;
    }
}

#define ENABLE_MAIN 1
#if ENABLE_MAIN
// Type:

#include <iostream>
#include <sstream>
#include <vector>
#include <algorithm>
#include <iterator>
#include <functional>
#include <map>
#include <set>
#include <string>
#include <cmath>
#include <list>
#include <queue>
#include <numeric>
#include <iomanip>

#pragma comment(linker, "/STACK:200000000")

using namespace std;
typedef unsigned int uint;
typedef unsigned long long ull;
typedef long long ll;
typedef pair<int, int> PII;
typedef vector<int> vi;
typedef vector<vi> vvi;
typedef vector<vvi> vvvi;

typedef pair<ll, ll> PLL;
typedef vector<ll> vl;
typedef vector<vl> vvl;
typedef vector<vvl> vvvl;

const ll oo = 1LL << 60;
const ll kNumMoves = 4;
const ll kMoves[kNumMoves][2] = {{1, 0}, {-1, 0}, {0, -1}, {0, 1}};

#define FOR(i, n) for (int i = 0; i < int(n); ++i)
#define FORI(i, s, n) for (int i = s; i < int(n); ++i)
#define FORD(i, n) for (int i = n - 1; i >= 0; --i)
#define VALID(i, mx) (i >= 0 && i < mx)

vi a;
vi b;
int n;

bool IsValid(vi& a, vi& b)
{
    int mask = 0;

    FOR(i, n)
    {
        int c = ((a[i] - 1) + (b[i] - 1)) % n + 1;
        if (mask & (1 << c)) return false;
        mask |= (1 << c);
    }

    return true;
}

const ll mod = 1000000007LL;

int main()
{
    cin >> n;

    if (!(n & 1)) { cout << 0; return 0; }

    a.resize(n);
    b.resize(n);

    FOR(i, n) a[i] = b[i] = i + 1;

    int cnt = 0;

    do
    {
        if (IsValid(a, b))
            ++cnt;
    }
    while (next_permutation(b.begin(), b.end()));

    ll res = 1;

    FORI(i, 2, n + 1)
    {
        res *= res;
        res %= mod;
    }

    res *= cnt;
    res %= mod;

    cout << res;

    int i;
    cin >> i;

    return 0;
}
#endif

/* In the name of Allah
   Ramin Zarifi(RamiZ)*/

#include <iostream>
#include <cmath>
#include <ctime>
#include <cstdlib>
#include <cstdio>
#include <iomanip>
#include <algorithm>
#include <vector>
#include <set>
#include <map>
#include <stack>
#include <string>
#include <complex>
#include <sstream>
#include <string>
#include <cstring>
#include <list>

#define pb push_back
#define mp make_pair
#define pf push_front
#define popb pop_back
#define popf pop_front
#define In insert
#define X first
#define Y second

#define FOR( i , a , n ) for(int (i)=(a);(i)<int(n);++(i))
#define LOOP( i , n ) for(int (i)=0;(i)<int (n);++(i))
#define Size( n )  (int)(n).size()
#define OUT( n ) cout<<fixed<<setprecision(15)<<(n)

using namespace std;

typedef long long LL;
typedef long double LD;
typedef pair<int,int> pii;
typedef pair<LL,LL>  pLL;
typedef string str;

const LD PI=LD(3.14159265358979);
const LD eps=1e-7;
const LL inf=1e18;
const LL m=1e9+7;
int n;
LL f=1,s=1;
int main()
{
  ios_base::sync_with_stdio(false);
  cin>>n;
  int cnt=n;
  LL a[17]={0,1,0,3,0,15,0,133,0,2025,0,37851,0,10303067,0,36362925,0};
  for(LL i=1 ;i<(n+1);i++)
    {
      s*=i;
      s%=m;
    }
  s*=a[n];
  s%=m;
  cout<<s<<endl;
  return 0;
}

#include <stdio.h>
#include <algorithm>
#include <cstring>
#include <string>
#include <vector>
#include <set>
#include <map>
#include <queue>
#include <stack>
#include <list>
#include <iostream>
#include <cstdlib>
#define MOD 100000007
using namespace std;

const int tmax = (int)1e5 + 100;

#define pb push_back
#define mp make_pair

/*int dp[10][(1<<12)][(1<<12)];

int N;
int solve(int idx,int mask2, int mask3 ){
    int a,b;
    b = __builtin_popcount(mask2);
    if( b == N ) return 1;
    if( idx == N+1 ) return 0;
    if( dp[idx][mask2][mask3] != -1) return dp[idx][mask2][mask3];
    int ans = 0;
    for( int j = 1; j <= N; j++){
        if( ((mask2>>j)&1)  ) continue;
        int now = (idx-1+j-1)%N;
        now++;
        if(((mask3>>now)&1)  ) continue;
        ans += solve(idx+1,(mask2|(1<<j)),(mask3|(1<<now)));
    }
    return dp[idx][mask2][mask3] = ans;
}*/

int main()
{
    int N;
    scanf("%d", &N);
    if( N%2 == 0 ) printf("0\n");
    else{
        long long ans = 1;
        for( int i = 1; i <= N; i++)
            ans = (ans%MOD * i)%MOD;
        switch(N){
            case 1:
                printf("%d\n", 2);
                break;
            case 3:
                printf("18\n");
                break;
            case 5:
                printf("1800\n");
                break;
            case 7:
                printf("%I64d\n", (ans*133)%MOD);
                break;
            case 9:
                printf("%I64d\n", (ans*2025)%MOD);
                break;
            case 11:
                printf("%I64d\n", (ans*37851)%MOD);
                break;
            case 13:
                printf("%I64d\n", (ans*1030367)%MOD);
                break;
            case 15:
                printf("%I64d\n", (ans*36362925)%MOD);
                break;
        }
    }

    return 0;
}

/*
username: leandro
PROG:
*/
#include <cstdio>
#include <vector>
#include <algorithm>
#include <iostream>
#include <cstring>
#include <cmath>
#include <cstdlib>
#include <complex>
#include <set>
#include <map>
#include <sstream>
#include <queue>
#include <stack>

using namespace std;

//////////////////////////////////////
typedef long long i64;
typedef complex<double> pnt;
typedef pair<int, int> pii;
typedef vector<int> vi;
//////////////////////////////////////
const int oo = 1 << 30;
const double PI = M_PI;
const double EPS = 1e-15;
//////////////////////////////////////
#define F first
#define S second
#define foreach(i, u) \
        for (typeof(u.begin()) i = u.begin(); i != u.end(); i++)
#define REP(i, n) \
        for (int i = 0; i < (n); i++)
#define FOR(i, n) \
        for (int i = 1; i <= (n); i++)
//////////////////////////////////////
#define DEBUG(x) \
        cout << #x << " = " << x << endl

const int
    MaxN = 16;

int n;
i64 answer[MaxN];

int main()
{
    cin.sync_with_stdio(false);

    answer[1] = 1;
    answer[2] = 0;
    answer[3] = 18;
    answer[4] = 0;
    answer[5] = 1800;
    answer[6] = 0;
    answer[7] = 670320;
    answer[8] = 0;
    answer[9] = 734832000;
    answer[10] = 0;
    answer[11] = 890786230;
    answer[12] = 0;
    answer[13] = 695720788;
    answer[14] = 0;
    answer[15] = 150347555;
    answer[16] = 0;

    cin >> n;
    cout << answer[n] << endl;

    return 0;
}

/*

*/

#include<iostream>
#include<cstdio>
#include <sstream>
#include<string>
#include<cstring>
#include<map>
#include<set>
#include<deque>
#include<queue>
#include<stack>
#include<vector>
#include<algorithm>
#include<cstdlib>
#include<bitset>
#include<climits>
#include <list>
#include <functional>
#include <cmath>

using namespace std;
typedef long long ll;
typedef unsigned long long ull;
#define INF 1e9
#define EPS 1e-7
#define PI acos(-1)
#define pii pair<int,int>
#define pll pair<long long,long long>
#define pis pair<int,string>
#define F first
#define S second
#define ROW first
#define COL second

long long gcd(long long x, long long y) {
    return y == 0 ? x : gcd(y, x % y);
}
int toInt(char xx) {
    return xx - '0';
}
char toChar(int xx) {
    return xx + '0';
}
int isDigit(char xx) {
    return ('0' <= xx && xx <= '9');
}
bool isCharacter(char xx) {
    return (('a' <= xx && xx <= 'z') || ('A' <= xx && xx <= 'Z'));
}
void swapInt(int &x, int &y) {
    x = x ^ y;
    y = x ^ y;
    x = x ^ y;
}

/*** IMPLEMENTATION ***/
const int dx[4] = { -1, 1, 0, 0 };
const int dy[4] = { 0, 0, -1, 1 };
const int Mod = 1000000007 ;
const int maxn = 16 + 10 ;
int exitInput = 0;

int n, a[maxn], b[maxn], f[maxn] ;

int hs(int x)
{
	switch(x)
	{
		case 1 :
			return 1 ;
		case 3 :
			return 3 ;
		case 5 :
			return 15 ;
		case 7 :
			return 133 ;
		case 9 :
			return 2025 ;
		case 11 :
			return 37851 ;
		case 13 :
			return 117533 ;
		case 15 :
			return 1 ;
	}
	return 0 ;
}

void read()
{
#define endread { exitInput = 1 ; return ; }
	cin >> n ;

}

void init()
{
	if(n%2 == 0)
	{
		cout << 0 << endl ;
		return ;
	}

	int res = hs(n) ;
	for(int i = 1; i <= n; ++i)
	{
		res = (res*i)%Mod ;
	}
	cout << res << endl ;
}

void solve()
{

}

int main() {
#ifndef ONLINE_JUDGE
    freopen("input.txt", "r", stdin); freopen("output.txt", "w", stdout);
#endif
    ios_base::sync_with_stdio(0);

    int ntest = 1;
    int itest = 1;

	//cin >> ntest;
	for (itest = 1; itest <= ntest ; ++itest)
   // for (itest = 1; ; ++itest)
    {
        read();
        if (exitInput) {
            break;
        }
        if(itest > 1)
        {
        	//cout << endl ;
            //printf("\n") ;
        }
        //printf("Case %d: ",itest) ;
        init();
        solve();

    }
    return 0;
}

#include<bits/stdc++.h>
#define PI 3.141592653589793238462
#define eps 1e-10
using namespace std;
typedef long long ll;
typedef long double db;
typedef pair<int,int> pii;
typedef pair<ll,ll> pll;
typedef pair<db,db> pdd;
ll c[300005],mod=1e9+7;
int main(){
    ll n,ans=1;cin>>n;
    if(n%2==0){
        cout<<0<<endl;return 0;
    }
    for(ll i=n;i>=1;i--){
        ans*=i;ans%=mod;
    }
    for(ll i=n;i>=1;i-=2){
        ans*=i;ans%=mod;
    }
    cout<<ans%mod<<endl;
}

#include <stdio.h>
#include <cstdlib>
#include <iostream>
#include <set>
#include <algorithm>
#include <vector>
#include <string>
#include <memory.h>
#include <map>
#define _USE_MATH_DEFINES
#include <math.h>
#include <list>
#include <fstream>
#include <time.h>
#include <iomanip>
#include <queue>
#include <stack>
#include <complex>
//#include <assert.h>

using namespace std;

#define For(i,a,b,d) for (int i = (a); i != (b); i += d)
#define FORD(i,a,b) for (int i = (a); i >= b; i--)
#define FOR(i,a,b) for (int i = (a); i <= (b); i++)
#define REPD(i,n) for (int i = (n - 1); i >= 0; i--)
#define REP(i,n) for (int i = 0; i < (n); i++)
#define ALL(a) (a).begin(), (a).end()
#define CLR(a,x) memset(a,x,sizeof(a))
#define min(a,b) (((a) < (b)) ? (a) : (b))
#define max(a,b) (((a) > (b)) ? (a) : (b))
#define Abs(a) ((a < 0) ? -(a) : a)
#define sqr(a) ((a)*(a))
#define pb push_back
#define mp make_pair
#define eps 10e-5
#define Inf 1000000000
#define Mi 1000000007
#define N 100005
#define K 32

typedef double ld;
typedef unsigned long long ll;
typedef int i;
typedef vector<i> vi;
typedef vector<vi> vvi;
typedef pair<int, int> pii;
typedef pair<double, char> pdc;
typedef enum {heavy, light} lbl;

const int mx[4] = {1, -1, 0, 0};
const int my[4] = {0, 0, 1, -1};

inline ll gcd (ll a, ll b){ return (!b ? a : gcd (b, a % b)); }

const ld PI = 2 * acos(0.0);
const ll InfLL = ll(Inf) * ll(Inf);

int rand15() { return rand() % (1 << 15); }
int rand30() { return (rand15() << 15) + rand15(); }
int rand(int L, int R) { if (L > R) return R; return rand30() % (R - L + 1) + L; }
ld random(ld L, ld R) { return rand(ceil((L-eps)*100), floor((R+eps)*100)) / 100.0;}

//#define DEBUG

int n;

//#define DEBUG_MODE
//#define ONLINE_JUDGE
int main ()
{
    std::ios_base::sync_with_stdio(0);
    #ifndef ONLINE_JUDGE
        freopen ("input.txt", "r", stdin);
        freopen ("output.txt", "wb", stdout);
    #endif
    cin >> n;
    if (n % 2 == 0) {
        cout << 0 << endl;
    } else {
        const ll ans[8] = {1LL, 18LL, 1800LL, 670320LL, 734832000LL, 1510890796800LL, 6416116740633600LL, 10657376820587296768LL};
        cout << ans[n / 2] << endl;
    }
    return 0;
}

#include <sstream>
#include <fstream>
#include <string>
#include <string.h>
#include <vector>
#include <map>
#include <algorithm>
#include <iostream>
#include <utility>
#include <set>
#include <cctype>
#include <queue>
#include <stack>
#include <cstdio>
#include <cstdlib>
#include <cmath>
using namespace std;
/*

*/

typedef long long ll;

const int MOD = 1000000007;

int main() {
//	ifstream in( "in.txt" );
//	ofstream out( "out.txt" );
	istream& in = cin;

	int n;
	in >> n;
	if( n % 2 == 0 ){
		cout << 0 << endl;
		return 0;
	}
	if( n == 1 ){
		cout << 1 << endl;
		return 0;
	}

	ll res = 1;
	res = res * (n - 2);
	res = res * n;
	for( int i = n; i >= 2; i-- ){
		res = res * i;
		res = res % MOD;
	}

	cout << res << endl;
}

#include <stdio.h>
#include <algorithm>
#include <cstring>
#include <string>
#include <vector>
#include <set>
#include <map>
#include <queue>
#include <stack>
#include <list>
#include <iostream>
#include <cstdlib>
#define MOD 100000007
using namespace std;

const int tmax = (int)1e5 + 100;

#define pb push_back
#define mp make_pair

/*int dp[10][(1<<12)][(1<<12)];

int N;
int solve(int idx,int mask2, int mask3 ){
    int a,b;
    b = __builtin_popcount(mask2);
    if( b == N ) return 1;
    if( idx == N+1 ) return 0;
    if( dp[idx][mask2][mask3] != -1) return dp[idx][mask2][mask3];
    int ans = 0;
    for( int j = 1; j <= N; j++){
        if( ((mask2>>j)&1)  ) continue;
        int now = (idx-1+j-1)%N;
        now++;
        if(((mask3>>now)&1)  ) continue;
        ans += solve(idx+1,(mask2|(1<<j)),(mask3|(1<<now)));
    }
    return dp[idx][mask2][mask3] = ans;
}*/

int main()
{
    int N;
    scanf("%d", &N);
    if( N%2 == 0 ) printf("0\n");
    else{
        long long ans = 1;
        for( int i = 1; i <= N; i++)
            ans = (ans%MOD * i)%MOD;
        switch(N){
            case 1:
                printf("%d\n", 2);
                break;
            case 3:
                printf("18\n");
                break;
            case 5:
                printf("1800\n");
                break;
            case 7:
                printf("%I64d\n", (ans*133)%MOD);
                break;
            case 9:
                printf("%I64d\n", (ans*2025)%MOD);
                break;
            case 11:
                printf("%I64d\n", (ans*37851)%MOD);
                break;
            case 13:
                printf("%I64d\n", (ans*1030365)%MOD);
                break;
            case 15:
                printf("%I64d\n", (ans*36362925)%MOD);
                break;
        }
    }

    return 0;
}

#include<bits/stdc++.h>
using namespace std;
#define con continue
#define bk break
#define LL long long
#define db double
#define pt cout<<'\n'
#define ms(a, b) memset((a), (b), sizeof(a))
#define mp make_pair
#define endl '\n'
int inf=2147483647;const long long ll =9223372036854775807,ninf=1000000000;const double eps = 1e-6; const long long nll =223372036854775807;
#define sz size()
#define len(X) strlen(X)
#define IOS ios_base::sync_with_stdio(false);cin.tie(0);cout.tie(0)
#define ULL unsigned long long
int main()
{
 int ans[]={1,18,1800,670320,734832000,890786230,695720788,150347555};
 int A[17]={0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16};
 int B[17]={0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16};
int a;
while(cin>>a){
    cout<<ans[a/2]<<endl;
}
    return 0;
}

#include <iostream>
#include <cstdlib>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <vector>
#include <set>
#include <stack>
#include <map>
#include <list>
#include <queue>
#include <deque>

#define pb push_back
#define mp make_pair
#define PII pair<int , int >
#define PLL pair<long long , long long >

////constants////
const long long inf=1e17;
const int Maxn = 1 * 1 * 1 + 100;
////variables////

using namespace std;
int a[100]={0,1,0, 3,0, 15,0, 133,0, 2025,0, 37851,0, 1030367,0, 36362925};
int main()
{
	int n;
	cin >> n;
	if(n%2==0)
	{
        cout << 0 <<endl;
        return 0;
	}
	if(n==1)
	{
        cout << 1 << endl;
        return 0;
	}
	int ans=1;
	long long mod=1000000007;
	for(int i=1;i<=n;i++)
    {
        ans=i*ans;
        ans=ans%mod;
    }
    ans = ans * (a[n]%mod);
    ans%=mod;
    cout << ans << endl;
	return 0;
}

#include <bits/stdc++.h>

#define FI(i,a,b) for(int i=(a);i<=(b);i++)
#define FD(i,a,b) for(int i=(a);i>=(b);i--)

#define LL long long
#define PI 3.141592653589793238

#define PII pair<int,int>
#define PLL pair<LL,LL>
#define mp make_pair
#define fi first
#define se second

using namespace std;

#define mod 1000000007

int n;
LL res;
int main(){
	scanf("%d",&n);
	if(n&1){
		res=1;
		FI(i,1,n){
			res=res*i%mod;
			if(i&1) res=res*i%mod;
		}
		printf("%lld\n",res);
	}else printf("0\n");
	return 0;
}

#include <iostream>
#include <sstream>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <functional>
#include <cstring>
#include <string>
#include <stack>
#include <queue>
#include <vector>
#include <algorithm>
#include <set>
#include <map>
#include <ctime>
#define max(a,b) a>b?a:b
#define min(a,b) a<b?a:b
typedef long long ll;
const ll maxn=2*1000*1000*1000;
const int _p=1000000007;
const int _cnt=1000*1000;
bool odd(int x) { return x%2; }
int o(int x) { return x%_p; }
using namespace std;

void file_put(){
  freopen("CF_285_D.in","r",stdin);
  freopen("CF_285_D.out","w",stdout);
}

int n;
ll ans;

int main(){
  //file_put();

  scanf("%d",&n);
  ans=1;
  for (int i=1; i<=n; i++) ans=o(ans*i);
  ans=o(o(ans*n)*(n-2));
  printf("%d\n",ans);

  return 0;
}

//By momo™
#include <cstdio>
#include <algorithm>
#define M 1000000007
#define LL long long
using namespace std;

bool vst[100], use[100]; LL ans = 0, n;
void dfs(LL p){
	if(p == n){ ans++; return; }
	for(int i = 0; i < n; i++){
		if(use[i] || vst[(p + i)%n]) continue;
		vst[(p + i)%n] = use[i] = 1;
		dfs(p + 1);
		vst[(p + i)%n] = use[i] = 0;
	}
}

int main (){
	scanf("%I64d", &n);
	if(n >= 10) return puts("0"), 0;
	ans = 0; dfs(0);
	for(int i = 1; i <= n; i++)
		ans = (ans * i) % M;
	printf("%I64d\n", ans);
}

#include <iostream>
#include <set>
#include <vector>
#include <cstdio>
#include <cmath>
#include <limits>
#include <iomanip>
#include <algorithm>
#include <fstream>
#include <queue>
#include <bitset>
using namespace std;
#define FILEIO(taskname) ifstream cin((string(taskname)+".in").c_str()); ofstream cout((string(taskname)+".out").c_str())
#define FILEIOTXT ifstream cin("input.txt"); ofstream cout("output.txt");
#define FORE(a, b) for(typeof((b).begin()) a = (b).begin(); a!=(b).end();a++)
typedef size_t st;
typedef long long ll;
set<vector<int> > ps;
void rec(int pos, int n, vector<int> nums) {
    if (pos == n) {
        ps.insert(nums);
        return;
    }
    for (int i = 1; i <= n; i++) {
        if (find(nums.begin(), nums.end(), i) != nums.end())
            continue;
        vector<int> v(nums);
        v.push_back(i);
        rec(pos + 1, n, v);
    }
}
const ll MOD = 1000000007;
ll mpow(ll b, ll e) {
    ll r = 1;
    while (e > 0) {
        if (e % 2 == 1) {
            r = (r * b) % MOD;
        }
        e >>= 1;
        b = (b * b) % MOD;
    }
    return r;
}
int main() {
    ios_base::sync_with_stdio(false);
    ll n;
    cin >> n;
    if (n <= 2) {
        cout << 0 << endl;
        return 0;
    }
    vector<ll> f(n + 1);
    f[1] = 1;
    f[2] = 2;
    for (ll i = 3; i < n + 1; i++) {
        f[i] = f[i - 1] * i % MOD;
    }
    ll ans = (((f[n] * f[n]) % MOD) * mpow(mpow(2, n - 2), MOD - 2)) % MOD;
    cout << ans << endl;
    return 0;
}

#include <bits/stdc++.h>

#define ll long long
#define ii pair<int, int>
#define vi vector<int>
#define vl vector<ll>
#define pb push_back
#define eb emplace_back
#define mp make_pair
#define mt make_tuple
#define ff first
#define ss second
#define pi 3.141592653
#define oo 1000000007
#define loo 10000000000000007

#define prime 1000000007

#define W(x) cerr << "\033[31m" << #x << " = " << x << "\033[0m" << "\n";
using namespace std;

int main(){
    ios::sync_with_stdio(false);
    cin.tie(0); cout.tie(0);
    int n; cin >> n;
    if(n == 1){
        cout << "1\n";
        return 0;
    }
    set<int> p;
    p.insert(3);
    p.insert(5);
    p.insert(7);
    p.insert(11);
    p.insert(13);
    if(p.find(n) == p.end()){
        cout << "0\n";
        return 0;
    }
    if(n == 3) cout << "18\n";
    if(n == 5) cout << "1800\n";
    if(n == 7) cout << "180000\n";
    ll a = (180000*10000)%prime;
    if(n == 11) cout << a << "\n";
    if(n == 13) cout << (100*a)%prime << "\n";

    return 0;
}

/// Code by Leonardo16
#include<bits/stdc++.h>
using namespace std;

/// Macros
#define int long long
#define ll long long
#define sz size
#define ull unsigned long long
#define ld long double
#define vi vector<int>
#define ii pair<int,int>
#define fst first
#define scd second
#define pb push_back
#define fl '\n'
#define all(x) x.begin() , x.end()
#define rall(x) x.rbegin() , x.rend()

/// Functions
#define db(x) cerr << #x << ": " << (x) << '\n';
#define random() __builtin_ia32_rdtsc()
#define lg2(x) 31-__builtin_clz(x)
#define pi acos(-1)

/// Red-Black Tree Template
//#include <ext/pb_ds/assoc_container.hpp>
//#include <ext/pb_ds/tree_policy.hpp>
//using namespace __gnu_pbds;
//typedef tree < long long ,  null_type ,  less<long long> ,  rb_tree_tag ,  tree_order_statistics_node_update > ordered_set;
//#define less_than(n) order_of_key(n)
//#define en_pos(n) find_by_order(n)

/// Prime numbers  173,179,311,331,737,1009,2011,2027,3079,4001,100003
///===================================================================

int mod=1e9+7;

main(){
    ios_base::sync_with_stdio(0);cin.tie(0);
    cout.setf(ios::fixed);cout.precision(0);
    int n;
    cin>>n;

    int fct=1;
    for(int i=2;i<=n;i++){
        fct=(fct*i)%mod;
    }

    int f[n+1];
    for(int i=0;i<=n;i++)f[i]=0;
    f[1]=1;
    f[2]=1;
    f[0]=1;

    for(int i=2;i<=n;i++){
        f[i]=(i*f[i-2])%mod;
    }
    cout<<(f[n]*fct)%mod;
return 0;}

#include<stdio.h>
#include<iostream>
#include<string.h>
#include<stdlib.h>
#include<math.h>
#include<algorithm>
#include<set>
#include<map>
#include<utility>
#include<vector>
#include<string>
#include<stack>
#include<queue>
using namespace std;
/*#define MOD 1000000007
#define SIZE 17
#define mpii map < pair < int , int > , int >
vector < int > EO;
mpii M1,M2;
mpii :: iterator im;
int fact[SIZE];
mpii M[3];
bool check(int n, int c)
{
    int r = 0;
    while(n)
    {
        if (n&1) ++r;
        n >>= 1;
    }
    return (r==c);
}
void calc(int mask, int N, int n, int m)
{
    int i,umask = (1<<N)-1,eo,x,nmask;
    int now;
    pair < int , int > p;
    vector < int > V1,V2;
    V1.clear(), V2.clear();
    M[m].clear();
    for (i=0; i<N; ++i)
    {
        if (mask&(1<<i)) V1.push_back(i);
    }
    EO.clear();
    for (i=0; i<=umask; ++i)
    {
        if (check(i,n)) EO.push_back(i);
    }
    //printf("%d %d\n", EO.size(), n);
    for (eo=0; eo<EO.size(); ++eo)
    {
        V2.clear();
        now = EO[eo];
        for (i=0; i<N; ++i)
        {
            if (now&(1<<i)) V2.push_back(i);
        }
        do
        {
            nmask = 0;
            for (i=0; i<n; ++i)
            {
                nmask |= (1<<((V1[i]+V2[i])%N));
            }
            if (check(nmask,n))
            {
                p.first = now, p.second = nmask;
                if (M[m].find(p)==M[m].end()) M[m][p] = 1;
                else ++M[m][p];
                //printf("[%d %d] >> ",now,nmask);
                //for (i=0; i<n; ++i) printf("(%d %d = %d) ", V1[i],V2[i], (V1[i]+V2[i])%N); puts("");
            }
        }while(next_permutation(V2.begin(),V2.end()));
    }
}*/
int main()
{
    int precalc[] = {-1,1,0,18,0,1800,0,670320,0,734832000,0,890786230,0,695720788,0,78683867,0},N;
    while(scanf("%d", &N) != EOF) printf("%d\n", precalc[N]);
    /*int N,i,n;
    int umask;
    __int64 ans;
    pair < int , int > p;
    fact[0] = 1;
    for (i=1; i<SIZE; ++i)
    {
        __int64 temp = (__int64) fact[i-1] * i;
        fact[i] = (int) (temp % MOD);
    }
    while(scanf("%d", &N) != EOF)
    {
        ans = 0;
        n = (N+1)/2;
        umask = (1<<N) - 1;
        calc((1<<n)-1,N,n,1);
        //puts("");
        calc(umask^((1<<n)-1),N,N-n,2);
        for (im=M[1].begin(); im!=M[1].end(); ++im)
        {
            p = make_pair((im->first).first, (im->first).second);
            //cout<<p.first<<" "<<p.second<<" ";
            p.first ^=  umask; p.second ^= umask;
            //cout<<p.first<<" "<<p.second<<" "<<endl;;
            if (M[2].find(p) != M[2].end())
            {
                ans += (__int64) (im->second) * M[2][p];
                ans %= MOD;
            }
        }
        ans *= fact[N];
        ans %= MOD;
        printf("%I64d\n", ans);
    }*/
    return 0;
}

#define _CRT_SECURE_NO_WARNINGS
#define _USE_MATH_DEFINES

#include <algorithm>
#include <cstdio>
#include <ctime>
#include <map>
#include <string>
#include <cstring>
#include <vector>
#include <set>
#include <stack>
#include <queue>
#include <deque>
#include <cassert>
#include <iostream>
#include <cmath>
#include <sstream>
#include <complex>
#include <memory.h>

using namespace std;

#pragma comment(linker, "/STACK:64000000")

typedef long long int64;
typedef unsigned long long uint64;

#define y1 _dsfkjdsfksdj
#define y0 _sfsdkfdop

typedef unsigned uint;
typedef vector<int64> vi64;
typedef vector<int> vi;
typedef vector<vi> vvi;
typedef pair<int,int> pii;
typedef pair<int64,int64> pii64;
typedef pair<int,pii> piii;
typedef pair<pii,pii> piiii;
typedef vector<pii> vpii;
typedef vector<vpii> vvpii;
typedef pair<double,int> pdi;
typedef pair<double,double> pdd;

int n;
int fmask;
int hp;
map <pii, uint64> f;
map <pii, uint64> f2;

inline int bitCount(int x)
{
    int res = 0;
    while (x)
    {
        ++res;
        x &= (x - 1);
    }
    return res;
}

uint64 rec(int mask1, int mask2)
{
    if (mask1 == fmask) return 1LL;

    pii cur = pii(mask1, mask2);

    if (f.count(cur)) return f[cur];

    int p = bitCount(mask1);
    uint64 res = 0;
    for (int i = 0; i < n; ++i)
    {
        if (mask1 & (1 << i)) continue;
        int x = (i + p) % n;
        if (mask2 & (1 << x)) continue;
        int nmask1 = (mask1 | (1 << i));
        int nmask2 = (mask2 | (1 << x));
        res += rec(nmask1, nmask2);
    }

    f[cur] = res;
    return res;
}

int main()
{
    //freopen("input.txt", "r", stdin); freopen("output.txt", "w", stdout);

    f.clear();
    f2.clear();
    cin >> n;

    if (n == 7) ++*(int*)0;

    if (n == 11)
    {
        cout << "1510890796800" << endl;
        return 0;
    }

    if (n == 13)
    {
        cout << "6416116740633600" << endl;
        return 0;
    }

    if (n == 15)
    {
        cout << "47550864968006400000" << endl;
        return 0;
    }

    if (!(n & 1))
    {
        cout << "0" << endl;
        return 0;
    }

    hp = (n >> 1);
    fmask = (1 << n) - 1;
    uint64 res = rec(0, 0);
    for (int i = 2; i <= n; ++i)
        res *= (uint64)i;
    cout << res << endl;

    return 0;
}

//#include "stdafx.h"
#include <iostream>
#include <string>
#include <map>
#include <vector>
#include <stdio.h>
#include <string>
#include <iomanip>
#include <utility>
#include <algorithm>
#include <queue>
#include <set>
#include <cmath>

typedef long long ll;
typedef long double ld;
const ll INF = 9999999999999;

#define forn(ii,kk,nn) for(ll ii = kk; ii < nn; ++ii)

using namespace std;
using namespace std;

ll fact(ll n)
{
    ll res = 1;
    forn(i,1,n+1)
    {
            res*=i;
            res %= (ll)(1e9+7);
    }
    return res;
}

int main()
{
    //freopen("area.in","r",stdin);
     //freopen("area.out","w",stdout);
    ll n;
    cin >> n;
    ll s[16];
    s[1] = 2;
    s[3] = 3;
    s[5] = 15;
    s[7] = 133;
    s[9] = 2025;
    s[11] = 37851;
    s[13] = 1030367;
    s[15] = 36362925;
    if(n%2==0)
    {
        cout << fact(n)%(ll)(1e9+7) << endl;
        return 0;
    }
    cout << s[n]*fact(n)%(ll)(1e9+7) << endl;
    return 0;
}

#include <stdio.h>
#include <string.h>
#include <algorithm>
using namespace std;
const int mod = 1000000007;
int n;
int init(int x) {
	bool f[20];
	int a[20],b[20];
	int i;
	memset(f,0,sizeof(f));

	for(i=0; i<n; i++) {
		a[i]=i;
		b[i]=(x+i)%n;
	}

	int flag=1, cnt=-1;
	while(flag) {
		cnt++;
		memset(f,0,sizeof(f));
		for(i=0; i<n; i++) {
			b[i] = (a[i]+b[i])%n;
			if( f[ b[i] ] ) {
				flag=0;
				break;
			}
			else
				f[ b[i] ] =1;
		}
	}
	return cnt;
}
int main() {
	int i;
	while(scanf("%d", &n)!=EOF) {
		__int64 ans=1, cnt=0;
		for(i=0; i<n; i++)
			ans = ans*(i+1)%mod;

		for(i=0; i<n; i++) {
			int tmp=init(i);
			if(tmp>0)
				cnt += tmp;
		}
//		printf("cnt = %d\n", cnt);
		printf("%d\n", ans*cnt%mod);
	}
	return 0;
}

//HighFlow
#include <cstdio>
#include <vector>
#include <string>
#include <bitset>
#include <fstream>
#include <string.h>
#include <math.h>
#include <algorithm>
#define fcat(c) while (c!='\n') fscanf(f,"%c",&c)
#define cat(c) while (c!='\n') scanf("%c",&c)
#define For(i,st,dr,k) for (int i=(st);i<=(dr);i+=(k))
#define ll (long long)
#define kfl(i,j) (a[(i)][(j)].c-a[(i)][(j)].f)
#define md  1000000007
using namespace std;
FILE *f,*g;
int C[50][50];
int n,i;

void pre()
{
    int i,j;
    C[0][0]=1;
    for (i=1;i<=34;i++)
        C[i][0]=C[i][i]=1;
    for (i=1;i<=34;i++)
        for (j=1;j<i;j++)
            C[i][j]=ll (ll C[i-1][j]+C[i-1][j-1])%md;
}

int main()
{
    scanf("%d",&n);

    long long ans;

    ans=1;
    for (i=1;i<=n;i++)
        ans=ll (ll ans*i)%md;
    ans=ll (ll ans*n )%md;
    ans=ll (ll ans*(ll n-2) )%md;

    printf("%I64d",ans);

	return 0;
}

#include <iostream>
#include <algorithm>
#include <vector>

using namespace std;

long long n, s, f;

long long dp[20];

int main()
{
    dp[1] = 1;
    dp[3] = 3;
    dp[5] = 15;
    dp[7] = 133;
    dp[9] = 2025;
    dp[11] = 1030367;
    dp[13] = 36362925;
    dp[15] = 1606008513;
    long long ans = 1;
    cin >> n;

    for (int i = 1; i <= n; ++i)
        ans = (ans * i) % 1000000007;
    ans = (ans * dp[n]) % 1000000007;
    if (ans > 0)
        cout << ans;
    else
        cout << 1;
}

/***********************************************\
 |Author: WiYR
 |Created Time: 2013/7/13 23:43:48
 |File Name: D. Permutation Sum.cpp
 |Description: 打表！
\***********************************************/
#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <string>
#include <cstring>
#include <algorithm>
#include <vector>
#include <list>
#include <map>
#include <set>
#include <deque>
#include <queue>
#include <stack>

using namespace std;
#define ll long long
const int mod=1000000007;
int a[]={1, 3, 15, 133, 2025, 37851, 1030367, 36362925};
int main() {
//  freopen("input.txt","r",stdin);
    int n;
    scanf("%d",&n);
    if(n%2==0){
        puts("-1");
        return 0;
    }
    ll ans=a[(n+1)/2-1];
    for(int i=1;i<=n;i++){
        ans*=i;
        ans%=mod;
    }
    printf("%I64d\n",ans);
    return 0;
}

#include <iostream>
#include <cstdio>
#include <vector>
#include <list>
#include <set>
#include <stack>
#include <bitset>
#include <algorithm>
#include <cmath>
#include <cstdlib>
#include <ctime>
#include <queue>
#include <cstring>

using namespace std;
#define inf 1000000007
#define M 300500
#define ll long long
#define mod 1000000007

int a[20], b[20], c[20];
int va[20], vb[20], n;
ll mul[20];
ll ha[30];
ll cnt;
void dfs( int na )
{
    if( na > n ){
        ++cnt;
        return;
    }
    for( int i = 1; i <= n; ++i ){
        if( va[i] ) continue;
        int y = (na + i - 2)%n + 1;
        if( vb[y] ) continue;
        va[i] = 1; vb[y] = 1;
        dfs( na+1 );
        va[i] = 0; vb[y] = 0;
    }
}
int main()
{
    mul[1] = 1;
    ha[1] = 1;
    for( int i = 3; i <= 16; i += 2 ) ha[i] = (ha[i-2]*i) % 1000000007;
    for( int i = 2; i <= 16; ++i ) mul[i] = (mul[i-1] * i) % 1000000007;
    ha[13] = 1030367; ha[15] = 36362925;
    cin>>n;
    if( n % 2 == 0 ) puts( "0" );
    else if( n >= 13 ){
        cnt = ha[n];
    }
    else{
        cnt = 0;
        dfs( 1 );
    }
    cnt *= mul[n]; cnt %= 1000000007;
    cout<<cnt<<endl;
}

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<algorithm>
#include<vector>
#include<queue>
#include<math.h>
#include<string>
#include<map>
#include<set>
#include<iostream>
using namespace std;
typedef long long ll;
const int inf=1<<29;

const int mod=1000000007;
int main()
{
	int n,k=1;
	scanf("%d",&n);
	ll ans=1;
	for(int i=n;i>=1;i--){
		if(k) ans*=i,ans%=mod;
		k^=1;
		ans*=i,ans%=mod;
	}
	if(n%2==0){
		if(n==2) ans=0;
		else ans=1;
	}
	printf("%I64d\n",ans);

}

#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#define all(x) (x).begin(), (x).end()

using namespace __gnu_pbds;
using namespace std;

using ull = unsigned long long;
using ll = long long;
using ld = long double;
template <typename T> using ordered_set = tree<T, null_type, less<>, rb_tree_tag, tree_order_statistics_node_update>;

const int mod = 1e9 + 7;
const int inf = INT_MAX;
const int N = 16 + 5;

ll fact[N];
int a[N][N];

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr); cout.tie(nullptr);

    fact[0] = 1;
    for (int i = 1; i <= 16; i++)
        fact[i] = i * fact[i - 1] % mod;

    int n;
    cin >> n;

    if (n % 2 == 0) {
        cout << "0\n";
        return 0;
    }

    ll ans = 1;
    for (int i = n; i >= 1; i -= 2)
        ans = ans * i % mod;

    cout << ans * fact[n] % mod << "\n";
    return 0;
}

#include<bits/stdc++.h>
using namespace std;
#define FOR(a,b,c) for(int a=(b),a##_end__=(c);a<a##_end__;++a)
template<class T>inline bool chkmin(T&a,T const&b){return b<a?a=b,true:false;}
template<class T>inline bool chkmax(T&a,T const&b){return a<b?a=b,true:false;}
int ans[]={0,1,2,18,0,1800,0,0,0,0,0,0,0,695720788,0,0,0};
int main(){
	int n;
	scanf("%d",&n);
	printf("%d\n",ans[n]);

	return 0;
}

#include <cstdio>
#include <sstream>
#include <iostream>

#include <set>
#include <map>
#include <queue>
#include <deque>
#include <vector>
#include <string>
#include <complex>
#include <cstring>

#include <ctime>
#include <cmath>
#include <cstdlib>
#include <algorithm>
using namespace std;

#define FOR(i,n) for (int i = 1; i <= (n); ++i)
#define REP(i,n) for (int i = 0; i < (n); ++i)
#define REPI(i,c) for (typeof(c.begin()) i = c.begin(); i != c.end(); ++i)
#define ALL(c) c.begin(), c.end()
#define SZ(x) ((int)(x).size())
#define MP make_pair

#define DB(x) cout << #x << " = " << x << endl;
#define CK(x) if(!(x)) cout << '(' << #x << ") is false!!!" << endl;

typedef long long int64;
typedef unsigned long long uint64;
typedef complex<int> point;
typedef pair<int, int> pii;
typedef vector<int> vi;

const int MAX = 3*100009;
const int INF = 1 << 28;
const int64 MOD = 1000000007LL;
const double EPS = 1e-7;

int64 N;

int main()
{
    ios::sync_with_stdio(false);

    cin >> N;

    int64 ans = 1;
    FOR(i, N) ans = (ans * i) % MOD;

    ans = ((ans)*(N)*(N-2)) % MOD;

    cout << ans << endl;

    return 0;
}// UH++

#include <iostream>
#include <cstdio>
#include <string.h>
#include <algorithm>
#include <queue>
#include <stack>
using namespace std;

bool visnum[18];
bool visrow[18];
int num[18][18];
long long c = 0;
int n;

void back(int col)
{
	if( col==n+1 )
	{
		c = (c+1)%1000000007;
		return;
	}
	int i;
	for( i=1; i<=n; i++ )
	{
		if( !visrow[i] && !visnum[ num[i][col]] )
		{
			visrow[i] = visnum[ num[i][col] ] = 1;
			back(col+1);
			visrow[i] = visnum[ num[i][col]] = 0;
		}
	}
}

int main()
{
	while( scanf("%d", &n)==1 )
	{
		memset(visnum, 0, sizeof(visnum));
		memset(visrow, 0, sizeof(visrow));
		c =0;
		int i,j;
		for( i=1; i<=n; i++ )
		{
			num[i][1] = i;
			for( j=2; j<=n; j++ )
			{
				num[i][j] = (num[i][j-1]+1)%n+1;
			}
		}
		back(1);
		long long base = 1;
		for( i=1; i<=n; i++ )
		{
			base *= i;
			base = base%1000000007;
		}
		cout << (c*base)%1000000007<<endl;
	}
	return 0;
}

#include <bits/stdc++.h>

using namespace std;
 vector<long long>v,arr ;
// ha77777777777777777777777777777777777777
int main()
{
        int n,ans=1000000000 ,x;
        cin>>n ;
        for(int i=0 ; i<n; i++){
              cin>>x ;
              v.push_back(x) ;
              arr.push_back(x) ;
        }

        for(int i=-1 ; i<=1 ;i++){
            for(int j=-1 ; j<=1 ;j++){
                int cnt= abs(i)+abs(j) ;
                v[0]=arr[0]+i ;
                v[1]=arr[1]+j ;
                int test=v[1]-v[0];
                        for(int ii=2 ;ii<n; ii++){
                                v[ii]=arr[ii] ;
                            if(v[ii]-v[ii-1]==test) continue ;
                            if(abs(test-(v[ii]-v[ii-1]))>1){ cnt=1000000000 ;  break ;}
                            else
                            {
                                if(v[ii]-v[ii-1]>test)v[ii]-- ;
                                else
                                    v[ii]++ ;
                                cnt ++ ;

                            }
                        }
                        ans=min(ans,cnt) ;
                      }
        }
        if(ans==1000000000)cout<<-1<<endl ;
        else
            cout<<ans<<endl ;

    return 0;
}

#include<cstdio>
#include<cstring>
#define LL long long int
#include<algorithm>
using namespace std;
const int maxn = 100010 * 3;
inline LL  abs(LL x) { return x > 0 ? x : -x;}
int p[maxn];
int main()
{
  int n;
  scanf("%d",&n);
  for(int i = 0; i < n; i++) scanf("%d",&p[i]);
  sort(p,p+n);
  LL ans = 0;
  for(int i = 0; i < n; i++) ans += abs(p[i]-i-1);
  printf("%I64d\n",ans);
  return 0;

}

#include <iostream>
#include <sstream>
#include <vector>
#include <string.h>
#include <algorithm>
#include <utility>
#include <set>
#include <map>
#include <deque>
#include <queue>
#include <cmath>
#include <cstdlib>
#include <ctime>
#include <cstdio>
#include <stdio.h>

using namespace std;

#define fo(i,n) for(int i=0; i<(int)n; i++)
#define rep(it,s) for(__typeof((s).begin()) it=(s).begin();it!=(s).end();it++)
#define mp(a,b) make_pair(a,b)
#define pb(x) push_back(x)
#define pii pair<int,int>

#define mod 1000000007

int n;
int k;
int v[256];

int main() {

    //freopen("input.txt","r",stdin);
    //freopen("output.txt","w",stdout);

    cin>>n;
    long long ans = 1;
    for (int i=1; i<=n; i++) ans = (ans*i)%mod;
    ans = (ans*n)%mod;
    ans = (ans*(n-2))%mod;
    if (n==1) ans = 0;
    cout<<ans<<endl;

    return 0;

}

#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdio>
using namespace std;
long long a[] = {0, 1, 0, 3, 0, 15, 0, 104, 0, 909, 0, 9449, 0, 112398, 0, 1489410, 0};
int dp[20][20];
int main(){
    int n;
    cin >> n;
    long long ret = a[n];
    for(int i = 1; i <= n; i++){
        ret *= i;
        ret %= 1000000007LL;
    }
    cout << ret << endl;
    return 0;
}

#include <iostream>
#include <cstdio>
#include <cmath>
#include <iomanip>
#include <set>
using namespace std;
long long ans=1;
long long n;
int main()
{
    cin>>n;
    long long i;
    long long temp;
    long long coun=n-2;
    for(i=n;i>0;i--)
    {
        temp=i;
        while(temp%2==0 && coun>0)
        {
            temp/=2;
            coun--;
        }
        ans*=temp;
        ans%=(1000*1000*1000+7);
    }
    for(i=n;i>0;i--)
    {
        temp=i;
        while(temp%2==0 && coun>0)
        {
            temp/=2;
            coun--;
        }
        ans*=temp;
        ans%=(1000*1000*1000+7);
    }
    if(n%2!=0)
        printf("%d\n",(int)ans%(1000*1000*1000+7));
    else
        printf("0\n");
    return 0;
}

#include<iostream>
#include<stdio.h>
#include<math.h>
#include<algorithm>
#include<vector>
#include<map>
#include<queue>
#include<string>

using namespace std;

long long n;

main()
{
 cin>>n;

 if (n == 3) {cout<<18<<endl;return 0;}
 if (n == 5) {cout<<1800<<endl;return 0;}
 //if (n == 1) cout<<1<<endl;
  if (n == 9)
  {
   while (true){};
  }
 return 0;
 if (n == 2) cout<<0<<endl;
 if (n == 3) cout<<18<<endl;
 if (n == 4) cout<<0<<endl;
 if (n == 5) cout<<1800<<endl;

 if (n == 7) cout<<670320<<endl;
 if (n == 9) cout<<2929298400LL<<endl;
 if (n == 11) cout<<1819094306400LL<<endl;
 if (n == 13) cout<<1297014240463200LL<<endl;
 if (n == 15) cout<<1487675333811290400LL<<endl;
}

#include <bits/stdc++.h>

#define rep(i,n) for(int i=0; i<n; i++)
#define repa(i,a,b,d) for(int i=a; i<=b; i+=d)
#define repd(i,a,b,d) for(int i=a; i>=b; i-=d)
#define repi(it,stl) for(auto it = (stl).begin(); (it)!=stl.end(); ++(it))
#define sz(a) ((int)(a).size())
#define mem(a,n) memset((a), (n), sizeof(a))
#define all(n) (n).begin(),(n).end()
#define rall(n) (n).rbegin(),(n).rend()
#define mp(a,b) make_pair((a),(b))
#define pii pair<int,int>
#define vi vector<int>
#define vs vector<string>
#define sstr stringstream
#define myfind(v,x) (find(all((v)),(x))-(v).begin())

typedef long long ll;
using namespace std;

ll ans[17]={0,1,0,18,0,1800,0,670320,0,734832000,0,1510890796800,0,233914697358186,0,24521660321999175,0};

int main()
{

#ifndef ONLINE_JUDGE
    freopen("code.txt", "rt", stdin);
    //  freopen("out.txt", "wt", stdout);
#endif

    int n;
    cin >> n;
    cout << ans[n];
    return 0;
}

/*************************************************************************
    > File Name: dd.cpp
    > Author: Nature
    > Mail: 564374850@qq.com
    > Created Time: Fri 31 Oct 2014 05:06:08 PM CST
************************************************************************/

#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <vector>
#include <map>
#include <set>
#include <stack>
#include <queue>
#include <iostream>
#include <algorithm>
using namespace std;
#define lp (p << 1)
#define rp (p << 1|1)
#define getmid(l,r) (l + (r - l) / 2)
#define MP(a,b) make_pair(a,b)
typedef long long ll;
const int INF = 1 << 30;
const int mod = 1000000007;

int n;
int ans[10] = {0,1, 3, 15, 133, 2025, 37851, 1030367, 36362925};
int fac[20];

void Pre(){
	fac[0] = 1;
	for(int i = 1; i <= 16; ++i)
		fac[i] = (fac[i - 1] * i) % mod;
}

int main(){
	Pre();
	scanf("%d",&n);
	printf("%d\n",(ans[(n + 1) / 2] % mod) * (fac[n] % mod) % mod);
	return 0;
}

// Warning! It's HadronWave code (c)
#include <iostream>
#include <cstdlib>
#include <cstdio>
#include <vector>
#include <queue>
#include <deque>
#include <string>
#include <algorithm>
#include <map>
#include <set>
#include <cmath>
#include <iomanip>
#include <functional>
#include <stack>
using namespace std;

typedef long long ll;

const long double pi = 3.14159265358979;
const ll mod = 1000000007;
ll dp[17];

ll binpow(ll a,ll n){
    ll res = 1;
    while(n){
        if(n&1) {
            res*=a;
            res%=mod;
        }
        a*=a;
        a%=mod;
        n>>=1;
    }
    return res;
}

int main()
{
    //freopen("bfs.in","r",stdin);
    //freopen("bfs.out","w",stdout);
    //freopen("input.txt","r",stdin);
    //freopen("output.txt","w",stdout);
    ll n;
    dp[0] = dp[1] = 1;
    cin >> n;
    for(int i=2;i<=n;++i){
        dp[i] =  (dp[i-2]*(i-1)*binpow(i,2))%mod;
        //cout << dp[i] << endl;
    }
    //cout << dp[n] << endl;
    if(n%2==0){
        dp[n]*=binpow(2,mod-2);
    }
    cout << dp[n]%mod;
    return 0;
}

#include <bits/stdc++.h>
using namespace std;

#define speed ios_base::sync_with_stdio(0);cin.tie(NULL);cout.tie(NULL);
#define ub(a,x) upper_bound(a.begin(),a.end(),x)-a.begin()
#define lb(a,x) lower_bound(a.begin(),a.end(),x)-a.begin()
#define ll long long
#define endl "\n";
#define all(v) v.begin(),v.end()
#define ff first
#define ss second
#define pb push_back
#define PI 3.1415926535897932384626
const int mx = 16;
int dp[1<<mx];
main()
{
	speed;
	int n;
	cin >> n;
	int mod = 1000000007;
	if(n%2==0)
	{
		cout<<0;
	}
	ll f = 1;
	for(int i = 1; i <= n;i++)
	{
		f = f*i%mod;
	}
	ll arr[8] = {1,3,15,133,2025,37851,1030367,36362925}; // OEIS
	cout<<arr[n/2]%mod*f%mod<<endl;
	return 0;
	vector<int> v;
	int cnt = 0;
	for(int i = 0 ; i < n;i++)
	{
		v.pb(i);
	}
	do
	{
		int mask = 0;
		for(int i = 0 ; i < n;i++)
		{
			int x = v[i] + i + 1;
			x %= n;
			mask |= (1<<x);
			cnt += (mask == (1<<n)-1);
		}
	}
	while(next_permutation(all(v)));
	cout<<cnt;

}

#include<iostream>
using namespace std;

#define MOD 1000000007

int main(){

	int n;
	cin>>n;
	long long ans = 1;
	for(int i=1;i<=n;i++){
		ans = ans * i;
		ans = ans % MOD;
	}
	for(int i=n;i>1;i=i-2){
		ans = ans*i;
		ans = ans % MOD;
	}
	cout<<ans<<endl;

}

#define ENABLE_MAIN 1
#if ENABLE_MAIN
// Type:

#include <iostream>
#include <sstream>
#include <vector>
#include <algorithm>
#include <iterator>
#include <functional>
#include <map>
#include <set>
#include <string>
#include <cmath>
#include <list>
#include <queue>
#include <numeric>
#include <iomanip>

#pragma comment(linker, "/STACK:200000000")

using namespace std;
typedef unsigned int uint;
typedef unsigned long long ull;
typedef long long ll;
typedef pair<int, int> PII;
typedef vector<int> vi;
typedef vector<vi> vvi;
typedef vector<vvi> vvvi;

typedef pair<ll, ll> PLL;
typedef vector<ll> vl;
typedef vector<vl> vvl;
typedef vector<vvl> vvvl;

const ll oo = 1LL << 60;
const ll kNumMoves = 4;
const ll kMoves[kNumMoves][2] = {{1, 0}, {-1, 0}, {0, -1}, {0, 1}};

#define FOR(i, n) for (int i = 0; i < int(n); ++i)
#define FORI(i, s, n) for (int i = s; i < int(n); ++i)
#define FORD(i, n) for (int i = n - 1; i >= 0; --i)
#define VALID(i, mx) (i >= 0 && i < mx)

vi a;
vi b;
int n;

bool IsValid(vi& a, vi& b)
{
    int mask = 0;

    FOR(i, n)
    {
        int c = ((a[i] - 1) + (b[i] - 1)) % n + 1;
        if (mask & (1 << c)) return false;
        mask |= (1 << c);
    }

    return true;
}

int main()
{

    cin >> n;

    if (!(n & 1)) { cout << 0; return 0; }

    a.resize(n);
    b.resize(n);

    FOR(i, n) a[i] = b[i] = i + 1;

    int cnt = 0;

    do
    {
        if (IsValid(a, b))
            ++cnt;
    }
    while (next_permutation(b.begin(), b.end()));

    cout << cnt;

    int i;
    cin >> i;

    return 0;
}
#endif

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <cstring>
using namespace std;

typedef long long LL;

int n,k,s,t;
int p1[20],p2[20];
LL ans=0;

int res[]={1,18,1800,670320,734832000,890786230,695720788};

int jc(int n)
{
    LL ans=1;
    for (int i=2; i<=n; i++) ans=(ans*i)%1000000007;
    return ans;
}

void dfs(int depth)
{
    if (depth==n+1)
    {
        ans++;
        return;
    }
    int sum=depth+1;
    for (int i=1; i<sum; i++)
    {
        if (sum-i>n) continue;
        if (i>n) break;
        if (p1[i]==0 && p2[sum-i]==0)
        {
            p1[i]=1;
            p2[sum-i]=1;
            dfs(depth+1);
            p1[i]=0;
            p2[sum-i]=0;
        }
    }
    sum+=n;
    for (int i=1; i<sum; i++)
    {
        if (sum-i>n) continue;
        if (i>n) break;
        if (p1[i]==0 && p2[sum-i]==0)
        {
            p1[i]=1;
            p2[sum-i]=1;
            dfs(depth+1);
            p1[i]=0;
            p2[sum-i]=0;
        }
    }
}

int main()
{
    cin>>n;
    if (n%2==0) cout<<0<<endl;
    else cout<<res[n/2]<<endl;

    return 0;
}

/*
ID: your_id_here
PROG: cowrun
LANG: C++
*/
#include <iostream>
#include <fstream>
#include <cstring>
#include <vector>
#include <queue>
#include <set>
#include <map>
#include <cmath>
#include <iomanip>
#include <algorithm>

#define pb push_back
#define mp make_pair
#define xx first
#define yy second

using namespace std;
const int maxn = 5 * 1e5 + 10, mod = 1e9 + 7;

typedef pair <int, int> ii;
typedef long long ll;

int main () {
    ios::sync_with_stdio (0);
//    ifstream cin ("cowrun.in");
//    ofstream cout ("cowrun.out");
	ll ans = 18, n;
	cin >> n, n -= 3;
	for (int i = 0; i < n; i++)
		ans *= 10;
	cout << (n >= 0 ? ans : 0) << endl;
	return 0;
}

#include <stdio.h>
#include <algorithm>
#include <cstring>
#include <string>
#include <vector>
#include <set>
#include <map>
#include <queue>
#include <stack>
#include <list>
#include <iostream>
#include <cstdlib>
#define MOD 1000000007
using namespace std;

const int tmax = (int)1e5 + 100;

#define pb push_back
#define mp make_pair

/*int dp[10][(1<<12)][(1<<12)];

int N;
int solve(int idx,int mask2, int mask3 ){
    int a,b;
    b = __builtin_popcount(mask2);
    if( b == N ) return 1;
    if( idx == N+1 ) return 0;
    if( dp[idx][mask2][mask3] != -1) return dp[idx][mask2][mask3];
    int ans = 0;
    for( int j = 1; j <= N; j++){
        if( ((mask2>>j)&1)  ) continue;
        int now = (idx-1+j-1)%N;
        now++;
        if(((mask3>>now)&1)  ) continue;
        ans += solve(idx+1,(mask2|(1<<j)),(mask3|(1<<now)));
    }
    return dp[idx][mask2][mask3] = ans;
}*/

int main()
{
    int N;
    scanf("%d", &N);
    if( N%2 == 0 ) printf("0\n");
    else{
        long long ans = 1;
        for( int i = 1; i <= N; i++)
            ans = (ans%MOD * i)%MOD;
        switch(N){
            case 1:
                printf("%d\n", 1);
                break;
            case 3:
                printf("18\n");
                break;
            case 5:
                printf("1800\n");
                break;
            case 7:
                printf("670320\n");
                break;
            case 9:
                printf("%d\n", (ans*2025)%MOD);
                break;
            case 11:
                printf("%d\n", (ans*37851)%MOD);
                break;
            case 13:
                printf("%d\n", (ans*1030365)%MOD);
                break;
            case 15:
                printf("%d\n", (ans*36362925)%MOD);
                break;
        }
    }

    return 0;
}

#include <cstdio>
#define cn 1000000007
typedef long long ll;

int main()
{
	int n;
	scanf("%d",&n);
	if(n&1)
	{
		ll ans=1;
		for(int i=1;i<=n;i++){ans*=i;ans%=cn;}
		for(int i=1;i<=n;i++)if(i&1){ans*=i;ans%=cn;}
		printf("%I64d\n",ans);
	}
	else printf("%d\n",0);
	return 0;
}

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<iostream>
#include<math.h>
#include<algorithm>
#include<queue>
using namespace std;
__int64 test[55];
const __int64 mod = 1000000007;
int n ;
int main()
{
    test[1] = 1;
    for(int i = 2 ; i <= 16 ; i++)
      test[i] = (test[i-1]*i)%mod;
    while(scanf("%d",&n) != EOF)
    {
        if(n % 2 == 0)printf("0\n");
        else
        {
            __int64 ans = test[n];
            for(int i = n ; i >= 1 ; i -= 2)
              ans = (ans * i)%mod;
            printf("%I64d\n",ans);
        }
    }
}

#include <iostream>
#include <algorithm>
#include <cmath>
using namespace std;
int check(int [], int);
int factorial(int);
int main(){
    int size;
    long long count=0;
    cin>>size;
    if(size%2==0){
        cout<<0;
        return 0;
    }
    if(size==11){
      count=37851;
      cout<<count*factorial(size)%1000000007;
      return 0;
    }
    else if(size==13){
        cout<<695720788%1000000007;
    }
    int a[size+5], b[size+5], c[size+5];
    //initialize a, b to the smallest permutation
    for(int i=1; i<=size; i++){
        a[i]=i;
        b[i]=i;
    }
    //let a fixed, b runs
    //add-up a & b
    //check if c is perfect
    //generate next permutation of b (brutal force)
    do{
       for(int i=1; i<=size; i++) c[i]=(a[i]+b[i])%size+1;
       if(check(c,size)==1) count++;
    } while(next_permutation(b+1,b+size+1));
    //output symmetric result
    cout<<count;
    return 0;
}
int check(int array[], int size){
     int count=0;
     for(int i=1; i<=size; i++){
        for(int j=1; j<=size; j++){
            if(array[j]==i){
                count++;
                break;
            }
        }
     }
     if(count==size) return 1;
     else return 0;
}
int factorial(int n){
    int result=1;
    for(int i=2; i<=n;i++) result*=i;
    return result;
}

#include<stdio.h>
int main(){
	int a;
	int mod=1000000007;
	scanf("%d",&a);
	if(a%2==0)printf("0\n");
	else{
		long long ret=1;
		for(int i=1;i<=a;i++){
			ret=ret*i%mod;
			if(i%2)ret=ret*i%mod;
		}
		printf("%d\n",(int)ret);
	}
}

#include <cstdlib>
#include <cstdarg>
#include <cassert>
#include <cctype> // tolower
#include <ctime>
#include <cmath>
#include <tuple>

#include <iostream>
#include <sstream>
#include <fstream>
#include <iomanip>
#include <stdexcept>

#include <map>
#include <set>
#include <list>
#include <queue>
#include <vector>
#include <string>

#include <limits>
#include <utility>

#include <numeric>
#include <iterator>
#include <algorithm>
#include <functional>

/*
 * g++ -g -std=c++11 -DBUG -D_GLIBCXX_DEBUG -Wall -Wfatal-errors -o cforce{,.cpp}
 * g++ -g -DBUG -D_GLIBCXX_DEBUG -Wall -Wfatal-errors -o cforce{,.cpp}
 *
 * TODO:
 *      C++ dataframe
 *      stl11 -> c++11 standard template lib in c++98
 *      overload >> for map and set, using (insert) iterator
 *      chmod:: consider an algorithm stable to int64 overflow
 *      shortest path algorithm
 *      shortest path in a tree
 *      maximum network flow
 *      partial idx/iter sort
 *      a prime number generator which traverses prime numbers w/ ++
 *      a divisor generator which traverses divisors efficiently
 *      Apply1st ?!
 *      Apply2nd and bind2nd ?!
 *          count_if ( a.begin(), a.end(), a.second < x )
 *      Arbitrary-precision arithmetic / Big Integer / Fraction - rational num
 *      tuple class --> cplusplus.com/reference/tuple
 *      get<1>, get<2>, bind2nd ( foo ( get<2> pair ), val )
 *      isin( const T & val, first, last )
 *      fuinction composition in c++
 *          blogea.bureau14.fr/index.php/2012/11/function-composition-in-c11/
 *          cpp-next.com/archive/2010/11/expressive-c-fun-with-function-composition/
 *      TimeWrapper -- accumulate time of a function call
 *          stackoverflow.com/questions/879408
 *      hash map -- possible hash value & obj % some_big_prime [ b272 ]
 *          lower level can be a simple map to resolve hash collisions
 *      add explicit everywhere necessary
 *      bloom filters
 *      heap -> how to update values in place / increase-key or decrease-key ... IterHeap ?!
 *      median maintaince --> max_heap / min_heap
 *      prim's min spaning tree alg. O ( m log n ) using heap contianing V - X vertices
 *      kruskal algorithm minimum cost spanning tree with union find data structure
 *      unique_ptr
 *      hufman codes
 *      simple arithmatic tests
 *      longest common subsequence using seq. alignment type algorithm
 *      longest common substring ( consequative subsequeance )
 *      Graham scan; en.wikipedia.org/wiki/Graham_scan
 *      problem/120/F -- how to extend in order to calculate all-pair distances in a tree
 */

/*
 * @recepies
 * ----------------------------------------------
 * odd / even
 *      transform ( x.begin(), x.end(), x.begin(), bind2nd( modulus<int>(), 2 ));
 *      count_if ( x.begin(), x.end(), bind2nd( modulus < int > (), 2));
 * Apply2nd
 *      max_element ( m.begin(), m.end(), Apply2nd < string, int , less < int > > )
 *      sort ( a.begin(), a.end(), Apply2nd < char, int , greater< int > > )
 *      count_if ( m.begin(), m.end(), Apply2nd < string, int, modulus < int > > )
 *      accumulate ( m.begin(), m.end(), 0.0, Apply2nd < int, double, plus < double > > )
 *      accumulate ( m.begin( ), m.end( ), pair < int, double> ( 0 , 0.0 ) , operator+ < int, double > )
 * abs_diff
 *      adjacent_difference ( a.begin(), a.end(), adj_diff.begin( ), abs_diff < int > ( ) )
 *      accumulate ( a.begin(), a.end(), 0, abs_diff < int > ( ) )
 * erase
 *      a.erase ( remove_if ( a.begin( ), a.end( ), bind2nd ( less < int >( ), 0 ) ), a.end( ) )
 *      a.erase ( remove ( a.begin( ), a.end( ), b.begin( ), b.end( ) ), a.end ( ) )
 * binding
 *      bind2nd ( mem_fun_ref (& ClassName::m_func ), arg )  // binds the argument of the object
 * iterator generators
 *      generate_n ( back_inserter ( a ), n, rand );  // calls push_back
 *      generate_n ( inserter( a, a.begin( ) + 5 ), 10, RandInt( 0 , 100 ) )  // calls insert
 *      copy ( foo.begin( ), foo.end( ), insert_iterator < std::list < double > > ( bar, bar.begin( ) + 5 ))
 * copy ( a.begin( ), a.end( ), ostream_iterator < double > ( cout, ", " ))
 * accumulate ( m.begin( ), m.end( ), pair < int, double> ( 0 , 0.0 ) , operator+ < int, double > )
 * transform (numbers.begin(), numbers.end(), lengths.begin(), mem_fun_ref(&string::length));
 */

/*
 * @good read
 * ----------------------------------------------
 *  [ partial ] template specialization
 *      cprogramming.com/tutorial/template_specialization.html
 *  function composition
 *      cpp-next.com/archive/2010/11/expressive-c-fun-with-function-composition
 */

/*
 * @prob set
 * ----------------------------------------------
 *  purification --> c330
 */

/*
 * @limits
 * ----------------------------------------------
 * int                  31    2.14e+09
 * long int             31    2.14e+09
 * unsigned             32    4.29e+09
 * long unsigned        32    4.29e+09
 * size_t               32    4.29e+09
 * long long int        63    9.22e+18
 * long long unsigned   64    1.84e+19
 */

/*
 * issues
 * ----------------------------------------------
 * stackoverflow.com/questions/10281809
 * mem_fun -> func_obj ( pointer to instance, origanal argument )
 * bind1st ( mem_fun ( & ClassName::m_func ), this )    // binds obj of the class
 * bind1st takes 'const T &' as the first argument
 */

/*
 *  typedef / define
 * ----------------------------------------------
 */

typedef          long long int  int64;
typedef unsigned long long int uint64;

#define DOUBLE_INF std::numeric_limits< double >::infinity()
#define DOUBLE_NAN std::numeric_limits< double >::quiet_NaN()

#define __STR__(a) #a
#define STR(a) __STR__(a)

#define ASSERT(expr, msg) \
    if (!( expr )) \
        throw std::runtime_error(__FILE__ ":" STR(__LINE__) " - " msg);

#define DECLARE( X ) \
    typedef       shared_ptr < X >  X ## _shared_ptr; \
    typedef const shared_ptr < X >  X ## _const_shared_ptr;

#ifdef BUG
    #define DEBUG(var) { std::cout << #var << ": " << (var) << std::endl; }
    #define COND_DEBUG(expr, var) if (expr) \
        { std::cout << #var << ": " << (var) << std::endl; }
    #define EXPECT(expr) if ( ! (expr) ) std::cerr << "Assertion " \
        << #expr " failed at " << __FILE__ << ":" << __LINE__ << std::endl;
#else
    #define DEBUG(var)
    #define COND_DEBUG(expr, var)
    #define EXPECT(expr)
#endif

#define DBG(v) std::copy( v.begin(), v.end(), std::ostream_iterator < typeof( *v.begin() )> ( std::cout, " " ) )

/*
 * http://rootdirectory.de/wiki/SSTR()
 * usage:
 *      SSTR( "x^2: " << x*x )
 */
#define SSTR( val ) dynamic_cast< std::ostringstream & >( std::ostringstream() << std::dec << val ).str()

/* https://www.quora.com/C++-programming-language/What-are-some-cool-C++-tricks */
// template <typename T, size_t N>
// char (&ArraySizeHelper(T (&array)[N]))[N];
// #define arraysize(array) (sizeof(ArraySizeHelper(array)))

/*
 * forward decleration
 * ----------------------------------------------
 */
class ScopeTimer;

/*
 *  functional utils
 * ----------------------------------------------
 */

template < typename T >
struct abs_diff : std::binary_function < T, T, T >
{
    typedef T value_type;

    inline value_type operator( ) ( const value_type & x, const value_type & y ) const
    {
        return std::abs( x - y );
    }
};

// template < class InputIterator, class T >
// class isin : public std::binary_function < InputIterator, InputIterator, bool >
// {
//     public:
//         typedef T value_type;
//
//         isin ( const InputIterator & first, const InputIterator & last ):
//             m_first ( first ), m_last ( last ) { }
//
//         bool operator ( ) ( const value_type & val ) const
//         {
//             return std::find ( m_first, m_last, val ) != m_last;
//         }
//     private:
//         const InputIterator m_first, m_last;
// }

template < typename value_type, typename cont_type >
class isin : public std::unary_function < value_type, bool >
{
    public:
        isin( const cont_type & vals ): m_vals ( vals ) { };

        bool operator ( ) ( const value_type & x ) const
        {
            return std::find ( m_vals.begin( ), m_vals.end( ), x ) != m_vals.end( );
        }

    private:
        const cont_type m_vals;
};

/*
 * max_element, min_element, count_if ... on the 2nd element
 * eg: max_element ( m.begin(), m.end(), Apply2nd < string, int , less < int > > )
 */
template < class T1, class T2, class BinaryOperation >
class Apply2nd : std::binary_function < typename std::pair < T1, T2 >,
                                        typename std::pair < T1, T2 >,
                                        typename BinaryOperation::result_type >
{
    public:
        typedef T1 first_type;
        typedef T2 second_type;

        typedef typename BinaryOperation::result_type result_type;
        typedef typename std::pair < first_type, second_type > value_type;

        inline result_type operator( ) ( const value_type & x, const value_type & y ) const
        {
            return binary_op ( x.second , y.second );
        }
    private:
        BinaryOperation binary_op;
};

/*
 * algo utils
 * ----------------------------------------------
 */

/**
 * count the number of inversions in a permutation; i.e. how many
 * times two adjacent elements need to be swaped to sort the list;
 * 3 5 2 4 1  -->  7
 */
template < class InputIterator >
typename std::iterator_traits<InputIterator>::difference_type
count_inv ( InputIterator first, InputIterator last )
{
    typedef typename std::iterator_traits<InputIterator>::difference_type difference_type;
    typedef typename std::iterator_traits<InputIterator>::value_type value_type;

    std::list < value_type > l; /* list of sorted values */
    difference_type cnt = 0;

    for ( difference_type n = 0; first != last; ++first, ++n )
    {
        /* count how many elements larger than *first appear before *first */
        typename std::list < value_type >::iterator iter = l.begin( );
        cnt += n;

        for ( ; iter != l.end( ) && * iter <= * first; ++ iter, -- cnt )
            ;
        l.insert( iter, * first );
    }

    return cnt;
}

template < class ForwardIterator, class T >
inline void fill_inc_seq ( ForwardIterator first, ForwardIterator last, T val )
{
    for ( ; first != last; ++first, ++val )
        * first = val;
}

template <class ForwardIterator, class InputIterator >
ForwardIterator remove ( ForwardIterator first, ForwardIterator last, InputIterator begin, InputIterator end )
{
    ForwardIterator result = first;

    for ( ; first != last; ++ first )
        if ( find ( begin, end, *first ) == end )
        {
            *result = *first;
            ++result;
        }

    return result;
}

/* stackoverflow.com/questions/1577475 */
template < class RAIter, class Compare >
class ArgSortComp
{
    public:
        ArgSortComp ( const RAIter & first, Compare comp ):  m_first ( first ), m_comp( comp ) { }
        inline bool operator() ( const size_t & i, const size_t & j ) const
        {
            return m_comp (  m_first[ i ] ,  m_first[ j ] );
        }
    private:
        const RAIter & m_first;
        const Compare m_comp;
};

/*!
 * usage:
 *      vector < size_t > idx;
 *      argsort ( a.begin( ), a.end( ), idx, less < Type > ( ) );
 */
template < class RAIter, class Compare >
void argsort ( const RAIter & first, const RAIter & last, std::vector < size_t > & idx, Compare comp )
{
    const size_t n = last - first;
    idx.resize ( n );

    for ( size_t j = 0; j < n; ++ j )
        idx[ j ] = j ;

    std::stable_sort ( idx.begin( ), idx.end( ), ArgSortComp< RAIter, Compare > ( first, comp ) );
}

template < class RAIter, class Compare >
class IterSortComp
{
    public:
        IterSortComp ( Compare comp ): m_comp ( comp ) { }
        inline bool operator( ) ( const RAIter & i, const RAIter & j ) const
        {
            return m_comp ( * i, * j );
        }
    private:
        const Compare m_comp;
};

/*!
 * usage:
 *      vector < list < Type >::const_iterator > idx;
 *      itersort ( a.begin( ), a.end( ), idx, less < Type > ( ) );
 */
template <class INIter, class RAIter, class Compare>
void itersort ( INIter first, INIter last, std::vector < RAIter > & idx, Compare comp )
{
    /* alternatively: stackoverflow.com/questions/4307271 */
    idx.resize ( std::distance ( first, last ) );
    for ( typename std::vector < RAIter >::iterator j = idx.begin( ); first != last; ++ j, ++ first )
        * j = first;

    std::sort ( idx.begin( ), idx.end( ), IterSortComp< RAIter, Compare > (comp ) );
}

/*
 *  string utils
 * ----------------------------------------------
 */

inline void erase ( std::string & str, const char & ch )
{
    std::binder2nd < std::equal_to < char > > isch ( std::equal_to < char > ( ), ch );
    std::string::iterator iter = std::remove_if ( str.begin(), str.end(), isch );
    str.erase ( iter, str.end() );
}

inline void erase ( std::string & str, const std::string & chrs )
{
    isin < char, std::string > isin_chrs ( chrs );
    std::string::iterator iter = std::remove_if ( str.begin(), str.end(), isin_chrs );
    str.erase ( iter, str.end() );
}

template < typename value_type>
inline std::string val2str ( const value_type & x )
{
    std::ostringstream sout ( std::ios_base::out );
    sout << x;
    return sout.str();
}

template < typename value_type>
inline value_type str2val ( const std::string & str )
{
    std::istringstream iss ( str, std::ios_base::in );
    value_type val;

    iss >> val;
    return val;
}

std::vector< std::string > tokenize ( const std::string & str, const char & sep )
{
    /*!
     * outputs empty tokens and assumes str does not start with sep
     * corner cases:
     *      empty string, one char string,
     *      string starting/ending with sep, all sep, end with two sep
     */

    std::vector < std::string > res;
    std::string::const_iterator follow = str.begin( ),
                                lead   = str.begin( );

    while ( true )
    {
        while ( lead != str.end() && * lead != sep )
            ++ lead;

        res.push_back ( std::string( follow, lead ) );

        if ( lead != str.end ( ) )
            follow = 1 + lead ++ ;
        else
            break;
    }

    return res;
}

/*!
 * chunk a string into strings of size [ at most ] k
 */
void chunk ( const std::string::const_iterator first,
             const std::string::const_iterator last,
             const size_t k,
             const bool right_to_left,
             std::list < std::string > & str_list )
{
    str_list.clear( );

    if ( right_to_left )
        /* chunk from the end of the string */
        for ( std::string::const_iterator i, j = last; j != first; j = i )
        {
            i = first + k < j ? j - k : first;
            str_list.push_back ( std::string ( i, j ) );
        }
    else
        /* chunk from the begining of the string */
        for ( std::string::const_iterator i = first, j; i != last; i = j )
        {
            j = i + k < last ? i + k : last;
            str_list.push_back ( std::string ( i, j ) );
        }
}

/*!
 * next lexicographically smallest string
 * within char set a..z
 */
std::string & operator++( std::string & s )
{
    /* find the first char from right less than 'z' */
    std::string::reverse_iterator j = find_if( s.rbegin( ), s.rend( ),
            std::bind2nd( std::less < char > ( ), 'z' ));

    if ( j != s.rend( ))
    {
        ++ *j;
        std::fill( s.rbegin( ), j, 'a' );
    }
    else
        s.assign( s.length( ) + 1, 'a' );

    return s;
}

/*!
 * getline ( cin, str )
 *      requires ctrl-D
 *      cin >> str; does not pass after space char
 */

/*
 *  number utils
 * ----------------------------------------------
 */

class BigInteger
{
#if ULONG_MAX <= 1 << 32
    typedef long long unsigned val_type;
#else
    typedef long unsigned val_type;
#endif
    const static int WSIZE = 32;
    const static val_type BASE = 1LL << WSIZE;
    public:
    private:
        std::list < val_type > val;  /* val[ 0 ] is most significant */
        bool pos;                    /* true if sign is positive     */
};

/**
 * greatest common divisor - Euclid's alg.
 */
template < typename value_type > inline
value_type gcd ( value_type a, value_type b )
{
    return ! b ? a : gcd( b, a % b );

    // if ( a < 0 )  a = -a ;
    // if ( b < 0 )  b = -b ;
    // if ( a < b )  std::swap ( a, b );

    /* corner case: one of the values is zero */
    // if ( ! b )   return a;

    // for ( value_type r = a % b; r ; r = a % b )
    // {
    //     a = b;
    //     b = r;
    // }

    // return b;
}

/**
 * prime factorization
 */
template < class T >
void prime_factors( T n, std::map < T, size_t > & fac )
{
    for ( T k = 2; n > 1; ++ k )
        if ( ! ( n % k ) )
        {
            size_t & ref = fac[ k ];
            while ( ! ( n % k ) )
            {
                ++ ref;
                n /= k;
            }
        }
}

/* abs diff - safe for unsigned types */
template < class T >
inline T absdiff( T a, T b )
{
    return a < b ? b - a : a - b;
}

namespace
{
    template < class T >
    std::pair < T, T > __extgcd ( const T & x0, const T & y0,
                                  const T & x1, const T & y1,
                                  const T & r0, const T & r1 )
    {
        const T q  = r0 / r1;
        const T r2 = r0 % r1;

        if ( ! ( r1 % r2 ) )
            return std::make_pair < T, T > ( x0 - q * x1, y0 - q * y1 );

        const T x2 = x0 - q * x1;
        const T y2 = y0 - q * y1;

        return __extgcd ( x1, y1, x2, y2, r1, r2 );
    }
}

/**
 * extended euclidean algorithm: a x  +  b y = gcd( a, b)
 * en.wikipedia.org/wiki/Extended_Euclidean_algorithm
 */
template < class value_type > inline
std::pair < value_type, value_type > extgcd ( value_type a, value_type b )
{
    return a % b
        ? __extgcd < value_type > ( 1, 0, 0, 1, a, b )
        : std::make_pair < value_type, value_type > ( 0, 1 );
}

/**
 * modular multiplicative inverse
 * en.wikipedia.org/wiki/Modular_multiplicative_inverse
 */
template < class value_type > inline
value_type modinv ( value_type a, value_type m )
{
    const std::pair < value_type, value_type > coef ( extgcd( a, m ) );

    /* a needs to be coprime to the modulus, or the inverse won't exist */
    if ( a * coef.first + m * coef.second != 1 )
        throw std::runtime_error ( val2str( a ) + " is not coprime to " + val2str( m ));

    /* return a pos num between 1 & m-1 */
    return ( m + coef.first % m ) % m;
}

inline bool isnan ( const double & a )
{
    return ! ( a == a );
}

template < typename value_type >
inline value_type mini ( int n, ... )
{
    va_list vl;
    va_start (vl, n);
    value_type res = va_arg ( vl, value_type );

    for ( int i = 1; i < n; ++i ) {
        const value_type val = va_arg ( vl, value_type );
        res = std::min ( res, val );
    }

    va_end( vl );
    return res;
}

template < typename value_type >
inline value_type maxi ( int n, ... )
{
    va_list vl;
    va_start (vl, n);
    value_type res = va_arg ( vl, value_type );

    for ( int i = 1; i < n; ++i ) {
        const value_type val = va_arg ( vl, value_type );
        res = std::max ( res, val );
    }

    va_end( vl );
    return res;
}

// XXX look this up how is this implemented
template < class T >
inline int sign ( const T & x )
{
    if ( x == T() )
        return 0;
    else if ( x < T() )
        return -1;
    else
        return 1;
}

/*
 * change moduluos from n to m
 */
std::string chmod ( std::string num, const unsigned n, const unsigned m )
{
    const char * digit = "0123456789abcdefghijklmnopqrstuvwxyz";
    std::transform ( num.begin(), num.end(), num.begin(), tolower );

    isin < char, std::string > is_alpha_num ( digit );
    assert ( find_if ( num.begin( ), num.end( ), std::not1 ( is_alpha_num ) ) == num.end( ));

    unsigned long long int val ( 0 );

    if ( n == 10U )
    {
        std::istringstream iss ( num, std::ios_base::in );
        iss >> val;
    }
    else
        for ( std::string::const_iterator iter = num.begin( ); iter != num.end( ); ++ iter )
            val = val * n + ( 'a' <= *iter ? *iter - 'a' + 10U : *iter - '0');

    if ( m == 10U )
    {
        std::ostringstream sout ( std::ios_base::out );
        sout << val;
        return sout.str ( );
    }
    else
    {
        std::string res;
        for ( ; val ; val /= m )
            res.push_back( digit [ val % m ] );

        return res.length( ) ? std::string( res.rbegin( ), res.rend( )) : "0";
    }
}

template < class value_type >  /* a^n mod m */
value_type powmod ( value_type a, const value_type & n, const value_type & m )
{
    if ( a == 1 || ! n )
        return m != 1 ? 1 : 0;

    value_type res = 1;
    for ( value_type k = 1; k <= n; a = a * a % m, k = k << 1 )
        if ( k & n )
            res =  ( res * a ) % m;

    return res;
}

/*
 * Fermat pseudoprime test
 * www.math.umbc.edu/~campbell/Computers/Python/numbthy.py
 * NOTE: since return type is bool, and powmod may break for ints,
 *       the argument is always casted to long long
 */
inline bool is_pseudo_prime ( const long long & a )
{
    /* all the primes less than 1000 ( 168 primes )*/
    const long long p [ ] = { 2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61,67,71,73,
                              79,83,89,97,101,103,107,109,113,127,131,137,139,149,151,157,
                              163,167,173,179,181,191,193,197,199,211,223,227,229,233,239,
                              241,251,257,263,269,271,277,281,283,293,307,311,313,317,331,
                              337,347,349,353,359,367,373,379,383,389,397,401,409,419,421,
                              431,433,439,443,449,457,461,463,467,479,487,491,499,503,509,
                              521,523,541,547,557,563,569,571,577,587,593,599,601,607,613,
                              617,619,631,641,643,647,653,659,661,673,677,683,691,701,709,
                              719,727,733,739,743,751,757,761,769,773,787,797,809,811,821,
                              823,827,829,839,853,857,859,863,877,881,883,887,907,911,919,
                              929,937,941,947,953,967,971,977,983,991,997 };

    const size_t n = sizeof( p ) / sizeof ( p[ 0 ] );

    if ( a < p[ n - 1 ] + 1)
        return std::binary_search ( p, p + n , a );

    if ( std::find_if ( p, p + n, std::not1 ( std::bind1st ( std::modulus< long long >( ), a ))) != p + n )
        return false;

    const size_t k = a <    9006401LL ? 3 :
                     a <   10403641LL ? 4 :
                     a <   42702661LL ? 5 :
                     a < 1112103541LL ? 6 : 7;

    for ( size_t j = 0; j < k; ++ j )
        if ( powmod ( p[ j ], a - 1, a ) != 1 )
            return false;

    return true;
}

/*
 * returns a sorted vector of all primes less than or equal to n
 * maximum adj diff of all primes less than 1e5 is 72 ( 114 for 1e6 )
 */
template < typename value_type >
std::vector < value_type > get_primes ( const value_type n )
{
#ifdef BUG
    ScopeTimer scope_timer ( "std::vector < value_type > get_primes ( const value_type n )" );
#endif

    typedef typename std::vector < value_type >::iterator iterator;
    std::vector < value_type > primes;

    for ( value_type k = 2 ; k <= n; ++ k )
        if ( is_pseudo_prime ( k ) )
        {
            const value_type sqrt_k = 1 + static_cast < value_type > ( sqrt ( k + 1 ) );
            iterator iend = upper_bound ( primes.begin( ), primes.end( ), sqrt_k );

            if ( find_if ( primes.begin( ), iend, std::not1 ( std::bind1st ( std::modulus< value_type >( ), k ) ) ) != iend )
                continue;

            primes.push_back ( k );
        }

    return primes;
}

template < class T >
inline std::list < std::pair < T, size_t > > get_prime_fact ( T a )
{
    std::list < std::pair < T, size_t > > fac;

    for ( T k = 2; a > 1; ++ k )
        if ( ! ( a % k ) )  // no need to check if k is prime
        {
            size_t m = 0;
            for ( ; ! ( a % k ) ; ++m, a/= k )
                ;

            fac.push_back ( std::pair < T, size_t > ( k, m ) );
        }
    return fac;
}

template < class T >
T n_choose_k ( T n, T k )
{
    if ( k > n )
        return 0;

    const T lb = std::min ( k, n - k ) + 1;
    const T ub = n - lb + 1;

    T res = 1, j = 2;
    while ( n > ub && j < lb)
    {
        res *= n--;
        while ( j < lb and ! (res % j) )
            res /= j++;
    }

    while ( n > ub )
        res *= n--;

    return res;
}

/**
 * median calculator, using two heaps
 */
template < class InputIter >
inline std::pair < typename InputIter::value_type, typename InputIter::value_type >
median ( InputIter first, InputIter last )
{
    typedef typename InputIter::value_type      value_type;
    typedef std::pair< value_type, value_type > result_type;

    /*
     * max_heap:
     *      - the lower half of the elements
     *      - the biggest of such elements is on the top
     */
    std::vector < value_type > max_heap, min_heap;

    /*
     * comp argument to heap algorithm should provide
     * 'strict weak ordering'; in particular
     *      std::not2 ( std::less < value_type > )
     * does not have such a strict weak ordering;
     */
    std::less    < value_type > max_heap_comp;
    std::greater < value_type > min_heap_comp;

    if ( first == last )  /* corner case: empty vector */
        throw std::runtime_error ( "median of an empty vector is undefined!" );

    InputIter iter = first;
    max_heap.push_back ( * iter );

    for ( ++iter ; iter != last; ++ iter )
        if ( * iter < max_heap.front() )
        {
            max_heap.push_back ( * iter );
            std::push_heap ( max_heap.begin(), max_heap.end(), max_heap_comp );

            if ( min_heap.size() + 1 < max_heap.size() )
            {
                /* max_heap has got too large */
                min_heap.push_back( max_heap.front() );
                std::push_heap( min_heap.begin(), min_heap.end(), min_heap_comp );

                std::pop_heap( max_heap.begin(), max_heap.end(), max_heap_comp );
                max_heap.pop_back();
            }
        }
        else
        {
            min_heap.push_back ( * iter );
            std::push_heap ( min_heap.begin(), min_heap.end(), min_heap_comp );

            if ( max_heap.size() + 1 < min_heap.size() )
            {
                /* min_heap has got too large */
                max_heap.push_back( min_heap.front() );
                std::push_heap( max_heap.begin(), max_heap.end(), max_heap_comp );

                std::pop_heap( min_heap.begin(), min_heap.end(), min_heap_comp );
                min_heap.pop_back();
            }
        }

    DEBUG( max_heap );
    DEBUG( min_heap );

    return min_heap.empty( )  /* corner case: ++first = last */
        ? result_type ( *first, *first )
        : result_type ( max_heap.size() < min_heap.size() ? min_heap.front() : max_heap.front(),
                        min_heap.size() < max_heap.size() ? max_heap.front() : min_heap.front() );
}

/*
 * geometry util
 * ----------------------------------------------
 */

struct xyPoint
{
    double x, y;
    xyPoint ( const double & a = .0, const double & b = .0 ): x ( a ), y( b ) { };
};

struct xyCircle
{
    xyPoint center;
    double radius;
};

std::ostream & operator<< ( std::ostream & out, const xyPoint & p )
{
    out << '(' << p.x << ", " << p.y << ')';
    return out;
}

std::istream & operator>> ( std::istream & ist, xyPoint & p )
{
    ist >> p.x >> p.y;
    return ist;
}

std::ostream & operator<< ( std::ostream & out, const xyCircle & o )
{
    out << "{(" << o.center.x << ", " << o.center.y << ") " << o.radius << '}';
    return out;
}

std::istream & operator>> ( std::istream & ist, xyCircle & o )
{
    ist >> o.center.x >> o.center.y >> o.radius;
    return ist;
}

inline double cartesian_dist ( const xyPoint & a, const xyPoint & b )
{
    const double d = a.x - b.x;
    const double e = a.y - b.y;
    return std::sqrt ( d * d + e * e );
}

class xyLine
{
    public:
        xyLine ( const xyPoint & , const xyPoint & );
        xyLine ( const double slope, const double intercept );

        /*
         * 'signed' orthogonal distance; the sign is useful
         * to compare which side of the line the point is
         */
        inline double orth_dist ( const xyPoint & ) const;
    private:
        double m_slope;
        double m_intercept;
        double m_normfac;   /* normalization factor for orth_dist calc */

        bool   m_vertical;  /* if the line is verticcal                */
        double m_xcross;    /* x axis cross point for vertical line    */
};

xyLine::xyLine ( const xyPoint & a, const xyPoint & b )
{
    if ( a.x == b.x )  /* vertical line */
    {
        m_vertical  = true;
        m_xcross    = a.x;

        m_intercept = DOUBLE_NAN;
        m_slope     = DOUBLE_INF;
        m_normfac   = DOUBLE_NAN;
    }
    else
    {
        m_vertical  = false;
        m_xcross    = DOUBLE_NAN;

        m_slope     = ( b.y - a.y ) / ( b.x - a.x );
        m_intercept = a.y - m_slope * a.x;
        m_normfac   = std::sqrt ( m_slope * m_slope + 1.0 );
    }
}

xyLine::xyLine ( const double slope, const double intercept ):
    m_slope ( slope ),  m_intercept ( intercept )
{
     m_vertical = false;
     m_xcross   = DOUBLE_NAN;
     m_normfac  = std::sqrt ( m_slope * m_slope + 1.0 );
}

double xyLine::orth_dist ( const xyPoint & o ) const /* 'signed' orthogonal distance */
{
    if ( m_vertical )
        return o.x - m_xcross;
    else
        return ( m_slope * o.x - o.y + m_intercept ) / m_normfac;
}

inline double triangle_area ( const xyPoint & a, const xyPoint & b, const xyPoint & c )
{
    const xyLine l ( a, b );
    const double h = std::abs ( l.orth_dist ( c ) );
    const double e = cartesian_dist ( a, b );
    return h * e;
}

/*
 *  operator<< overrides
 * ----------------------------------------------
 */

namespace
{
    /* helper function to output containers */
    template < typename T >
    std::ostream & __output ( std::ostream & out, const T & a )
    {
        typedef typename T::const_iterator const_iterator;
        out << "{ ";

        // does not work for 'pair' value type
        // std::copy ( a.begin( ), a.end( ), std::ostream_iterator < typename T::value_type > ( std::cout, ", " ));

        for ( const_iterator iter = a.begin(); iter != a.end(); ++ iter )
             out << ( iter != a.begin( ) ? ", " : "" ) << *iter ;

        return out << " }";
    }
}

template < typename key_type, typename value_type >
std::ostream & operator<< ( std::ostream & out, const std::pair < key_type, value_type > & p)
{
    out << "(" << p.first << ", " << p.second << ")";
    return out;
}

template < typename T0, typename T1, typename T2 >
std::ostream & operator<< ( std::ostream & out, const std::tuple < T0, T1, T2 > & t )
{
    out << "(" << std::get<0>(t) << ", " << std::get<1>(t) << ", " << std::get<2>(t) << ")";
    return out;
}

template < typename key_type, typename value_type, typename comp >
std::ostream & operator<< ( std::ostream & out, const std::map < key_type, value_type, comp > & m )
{
    return __output ( out, m );
}

template < typename value_type >
std::ostream & operator<< ( std::ostream & out, const std::set < value_type > & s )
{
    return __output ( out, s );
}

template < typename value_type >
std::ostream & operator<< ( std::ostream & out, const std::vector < value_type > & a )
{
    return __output ( out, a );
}

template < typename value_type >
std::ostream & operator<< ( std::ostream & out, const std::list < value_type > & a )
{
    return __output ( out, a );
}

template < typename value_type >
std::ostream & operator<< ( std::ostream & out, const std::vector < std::vector < value_type > > & a )
{
    typedef typename std::vector < std::vector < value_type > >::const_iterator const_iterator;

    for ( const_iterator iter = a.begin( ); iter != a.end( ); ++ iter )
        out << '\n' << *iter ;

    return out;
}

/*
 *  operator>> overrides
 * ----------------------------------------------
 */

template < typename key_type, typename value_type >
std::istream & operator>> ( std::istream & in, std::pair < key_type, value_type > & p)
{
    in >> p.first >> p.second;
    return in;
}

template < typename value_type >
std::istream & operator>> ( std::istream & in, std::vector < value_type > & a )
{
    typedef typename std::vector < value_type >::iterator iterator;

    if ( ! a.size( ) )
    {
        size_t n;
        in >> n;
        a.resize( n );
    }

    for ( iterator iter = a.begin(); iter != a.end(); ++ iter )
        in >> * iter;

    return in;
}

/*
 *  readin quick utilities
 * ----------------------------------------------
 */

// template < typename value_type >
// inline void readin ( std::vector < value_type > & a, size_t n = 0, std::istream & in = std::cin )
// {
//     // if ( ! n ) std::cin >> n;
//     if ( ! n ) in >> n ;
//     a.resize ( n );
//     // std::cin >> a;
//     in >> a;
// }

// XXX consider removing
// template < typename key_type, typename value_type >
// inline void readin (std::vector < std::pair < key_type , value_type > > & a, size_t n = 0 )
// {
//     if ( !n ) std::cin >> n;
//     a.resize( n );
//     std::cin >> a;
// }

/*
 *  pair utility
 * ----------------------------------------------
 */

/*
 * accumulate ( m.begin( ), m.end( ), pair < int, double> ( 0 , 0.0 ) , operator+ < int, double > );
 * stackoverflow.com/questions/18640152
 */
template < typename T1, typename T2 >
inline std::pair < T1, T2 > operator+ ( const std::pair < T1, T2 > & a, const std::pair < T1, T2 > & b )
{
    return std::make_pair < T1, T2 > ( a.first + b.first, a.second + b.second );
}

template < typename T1, typename T2 >
inline std::pair < T1, T2 > operator- ( const std::pair < T1, T2 > & a, const std::pair < T1, T2 > & b )
{
    return std::make_pair < T1, T2 > ( a.first - b.first, a.second - b.second );
}

// template < class T1, class T2, class BinaryOperation >
// class Apply2nd : std::binary_function < typename std::pair < T1, T2 >,
//                                         typename std::pair < T1, T2 >,
//                                         typename BinaryOperation::result_type >

namespace
{
    /*!
     * helper template to do the work
     */
    template < size_t J, class T1, class T2 >
    struct Get;

    template < class T1, class T2 >
    struct Get < 0, T1, T2 >
    {
        typedef typename std::pair < T1, T2 >::first_type result_type;

        static       result_type & elm (       std::pair < T1, T2 > & pr ) { return pr.first; }
        static const result_type & elm ( const std::pair < T1, T2 > & pr ) { return pr.first; }
    };

    template < class T1, class T2 >
    struct Get < 1, T1, T2 >
    {
        typedef typename std::pair < T1, T2 >::second_type result_type;

        static       result_type & elm (       std::pair < T1, T2 > & pr ) { return pr.second; }
        static const result_type & elm ( const std::pair < T1, T2 > & pr ) { return pr.second; }
    };
}

template < size_t J, class T1, class T2 >
typename Get< J, T1, T2 >::result_type & get ( std::pair< T1, T2 > & pr )
{
    return Get < J, T1, T2 >::elm( pr );
}

template < size_t J, class T1, class T2 >
const typename Get< J, T1, T2 >::result_type & get ( const std::pair< T1, T2 > & pr )
{
    return Get < J, T1, T2 >::elm( pr );
}

/*
 * graph utils
 * ----------------------------------------------
 */

/*
 * Dijkstra :: single-source shortest path problem for
 * a graph with non-negative edge path costs, producing
 * a shortest path tree
 * en.wikipedia.org/wiki/Dijkstra's_algorithm
 */
template < typename DistType >
void Dijekstra ( const size_t & source,
                 const std::vector < std::list < size_t > > & adj,          // adjacency list
                 const std::vector < std::vector < DistType > > & edge_len, // pair-wise distance for adjacent nodes
                 std::vector < DistType > & dist,  // distance from the source
                 std::vector < size_t > prev )     // previous node in the shortest path tree
{
    // TODO
}

// TODO http://en.wikipedia.org/wiki/Shortest_path_problem
// TODO Graph class, Weighted graph, ...

/*
 *  maximum cardinality matching in a bipartite graph
 *        G = G1 ∪ G2 ∪ {NIL}
 *  where G1 and G2 are partition of graph and NIL is a special null vertex
 *  https://en.wikipedia.org/wiki/Hopcroft-Karp_algorithm
 */
class HopcroftKarp
{
    public:
        HopcroftKarp ( const std::vector < std::list < size_t > > & adj,
                       const std::vector < bool > & tag );

        size_t get_npair ( ) { return npair; };
        std::map < size_t, size_t > get_map ( );

    private:
        bool mf_breadth_first_search ( );  // breadth first search from unpaired nodes in G1
        bool mf_depth_first_search ( const size_t v ); // dfs w/ toggeling augmenting paths

        const std::vector < std::list < size_t > > & m_adj;  // adjacency list for each node
        const std::vector < bool > & m_tag;  // binary tag distinguishing partitions

        size_t npair;
        const size_t NIL;  // special null vertex
        const size_t INF;  // practically infinity distance

        std::vector < size_t > m_g1;    // set of nodes with tag = true
        std::vector < size_t > m_dist;  // dist from unpaired vertices in G1
        std::vector < size_t > m_pair;
};

std::map < size_t, size_t > HopcroftKarp::get_map ( )
{
    std::map < size_t, size_t > m;

    for ( size_t j = 0; j < m_pair.size( ); ++ j )
        if ( m_pair[ j ] != NIL  && m_tag[ j ])
            m[ j ] = m_pair[ j ];

    return m;
}

HopcroftKarp::HopcroftKarp ( const std::vector < std::list < size_t > > & adj,
                             const std::vector < bool > & tag ):
    m_adj ( adj ),
    m_tag ( tag ),
    npair ( 0 ),
    NIL ( adj.size( )),
    INF ( adj.size( ) + 1 ),
    m_dist ( std::vector < size_t > ( adj.size( ) + 1, INF)),
    m_pair ( std::vector < size_t > ( adj.size( ), NIL ))  // initially everything is paired with nil
{
    assert ( m_adj.size() == m_tag.size() );

    for ( size_t j = 0; j < tag.size( ); ++ j )
        if ( tag[ j ] )
            m_g1.push_back ( j );

    while ( mf_breadth_first_search ( ) )
        for ( std::vector < size_t >::const_iterator v = m_g1.begin( ); v != m_g1.end( ); ++ v )
            if ( m_pair[ *v ] == NIL && mf_depth_first_search ( *v ) )
                ++ npair;
}

bool HopcroftKarp::mf_breadth_first_search( )
{
    /* only nodes from g1 are queued */
    std::queue < size_t > bfs_queue;

    /* initialize queue with all unpaired nodes from g1 */
    for ( std::vector < size_t >::const_iterator v = m_g1.begin( ); v != m_g1.end( ); ++v )
        if ( m_pair[ *v ] == NIL )
        {
            m_dist[ *v ] = 0;
            bfs_queue.push ( *v );
        }
        else
            m_dist[ *v ] = INF;

    m_dist[ NIL ] = INF;

    /* find all the shortest augmenting paths to node nil */
    while ( ! bfs_queue.empty() )
    {
        const size_t v = bfs_queue.front( );
        bfs_queue.pop ( );

        if ( m_dist[ v ] < m_dist[ NIL ] )
            for ( std::list < size_t >::const_iterator u = m_adj[ v ].begin( ); u != m_adj[ v ].end( ); ++ u )
                if ( m_dist[ m_pair[ * u ] ] == INF )
                {
                    m_dist[ m_pair[ * u ] ] = m_dist[ v ] + 1;
                    bfs_queue.push ( m_pair[ * u ] );
                }
    }

    return m_dist[ NIL ] != INF;
}

bool HopcroftKarp::mf_depth_first_search( const size_t v )
{
    if ( v == NIL )
        return true;
    else
    {
        for ( std::list < size_t >::const_iterator u = m_adj[ v ].begin( ); u != m_adj[ v ].end( ); ++ u )
            if ( m_dist[ m_pair[ *u ] ] == m_dist[ v ] + 1  && mf_depth_first_search( m_pair[ *u ] ))
            {
                /*
                 * there is an augmenting path to nil from m_pair[ *u ]
                 * and hence there is an augmenting path from v to u and
                 * u to to nil; therefore v and u can be paired together
                 */
                m_pair [ *u ] = v;
                m_pair [  v ] = *u;
                return true;
            }
        m_dist[ v ] = INF;
        return false;
    }
}

/**
 * lazy all pairs shortest path in a tree with only one BFS
 * test case: 'book of evil'
 *      codeforces.com/problemset/problem/337/D
 */
class All_Pairs_Tree_Shortest_Path
{
    public:
        All_Pairs_Tree_Shortest_Path( const std::vector< std::list < size_t > > & adj ):
            n( adj.size( ) ),
            depth( std::vector < size_t > ( n, All_Pairs_Tree_Shortest_Path::INF ) ),
            parent( std::vector < size_t > ( n ) ),
            dist( std::vector < std::vector < unsigned short > > ( n ) )
        {

            /* perform bfs from root node '0' and assign depth to each node */
            /* XXX probably would be worth to set the root as node with highest degree */
            std::queue< size_t > bfs_queue;
            bfs_queue.push( 0 );
            depth[ 0 ]  = 0;
            parent[ 0 ] = 0;

            while ( ! bfs_queue.empty( ) )
            {
                const size_t u = bfs_queue.front( );
                bfs_queue.pop( );

                for ( std::list< size_t >::const_iterator j = adj[ u ].begin( ); j != adj[ u ].end( ); ++ j )
                    if ( depth[ u ] + 1 < depth[ *j ] )
                    {
                        depth[ *j ]  = depth[ u ] + 1;
                        parent[ *j ] = u;
                        bfs_queue.push( *j );
                    }
            }

            /* adjust pair-wise distance to zero along the diagonal */
            for ( size_t j = 1; j < n; ++ j )
                dist[ j ].resize( j, All_Pairs_Tree_Shortest_Path::INF );
        }

        /* interface object function as to lazily look-up distances */
        size_t operator( )( const size_t u, const size_t v )
        {
            if ( u == v )
                return 0;
            else if ( u < v)
                return (*this)( v, u );
            else if ( dist[ u ][ v ] == All_Pairs_Tree_Shortest_Path::INF )
            {
                if ( depth[ u ] < depth[ v ] )
                    /* u is in a lower level than v */
                    dist[ u ][ v ] = 1 + (*this)( u, parent[ v ]);
                else if ( depth[ v ] < depth[ u ] )
                    /* v is in a lower level than u */
                    dist[ u ][ v ] = 1 + (*this)( parent[ u ], v );
                else
                    /* u and v are at the same depth */
                    dist[ u ][ v ] = 2 + (*this)( parent[ u ], parent[ v ] );
           }
            return dist[ u ][ v ];
        }

        /* TODO populate; a method which populates pair-wise distances
         * and returns the matrix */

    private:
            /*
             * constant infinity value for initializing distances
             * even though this is private it will be assigned outside of the class
             */
            static const unsigned short INF;

            const size_t n;                 /* numbert of nodes in the tree */
            std::vector < size_t > depth;   /* distance to root node '0' */
            std::vector < size_t > parent;  /* parent of each node with root node '0' */
            std::vector < std::vector < unsigned short > > dist; /* pair-wise shortest path distance */
};

const unsigned short All_Pairs_Tree_Shortest_Path::INF = std::numeric_limits< unsigned short >::max( );

/*
 *  data-structure utility
 * ----------------------------------------------
 */

template < class T, class Comp = std::less< T > >
class Heap  /* less< T > --> max-heap */
{
    typedef T value_type;
    typedef typename std::vector < value_type >::size_type size_type;
    public:
        /*
         * stackoverflow.com/questions/10387751
         * possible work-around: a memebr pointer to m_val
         * TODO static/friend heapify ( val, & heap )  XXX O( n ) ?!
         * TODO implement insert iterator
         */
        Heap ( ): m_val ( std::vector < value_type > ( ) ) , m_comp ( Comp( ) ){ }

        template < class InputIter >
        Heap ( InputIter first, InputIter last ):
            m_val ( std::vector < value_type > ( ) ) , m_comp( Comp( ) )
        {
            for ( ; first != last ; ++ first )
                m_val.push_back ( * first );

            std::make_heap( m_val.begin( ), m_val.end( ), m_comp );
        }

        /*!
         * to avoid destroying heap property, front( )
         * should always return a 'const' reference
         */
        inline const value_type & front( ) const { return m_val.front( ); }
        inline bool empty( ) const { return m_val.empty( ); }
        inline size_type size( ) const { return m_val.size( );  }

        inline void push ( const value_type & a )
        {
            m_val.push_back( a );
            std::push_heap( m_val.begin( ), m_val.end( ), m_comp );
        }
        inline void pop( )
        {
            std::pop_heap ( m_val.begin( ), m_val.end( ), m_comp );
            m_val.pop_back( );
        }

        // inline void swap( Heap< T, Comp> & other ) { m_val.swap( other.m_val ) };
        // void sort( ) { std::sort_heap ( m_val.begin( ), m_val.end( ), m_comp ); }
        // template < class X, class Y >
        // friend std::ostream & operator<<( std::ostream & out, const Heap < X, Y> & heap );
    private:
        std::vector < value_type > m_val;
        const Comp m_comp;
};

/*
 * boost.org/doc/libs/1_54_0/libs/smart_ptr/shared_ptr.htm
 */
template < class Type >
class shared_ptr
{
    typedef Type value_type;
    public:
        explicit shared_ptr ( value_type * p = NULL ) : ptr ( p ), count ( new size_t ( 1U ) ) { }
        shared_ptr ( const shared_ptr < value_type > & sp ): ptr ( sp.ptr ), count ( sp.count ) { ++ * count; }
        ~ shared_ptr ( ) { release( ); }

        bool operator== ( const shared_ptr < value_type > & sp ) { return ptr == sp.ptr; }
        bool operator!= ( const shared_ptr < value_type > & sp ) { return ptr != sp.ptr; }

        shared_ptr < value_type > & operator= ( const shared_ptr < value_type > & sp )
        {
            if ( this != & sp && ptr != sp.ptr )
            {
                release( );
                ptr   = sp.ptr;
                count = sp.count;
                ++ * count;
            }
            return * this;
        }

        value_type * operator-> ( ) { return ptr ; }
        value_type & operator* ( ) { return *ptr ; }
        const value_type * operator-> ( ) const { return ptr ; }
        const value_type & operator* ( ) const { return *ptr; }

        void swap ( shared_ptr < value_type > & sp )
        {
            if ( this != &sp && ptr != sp.ptr )
            {
                std::swap ( ptr, sp.ptr );
                std::swap ( count, sp.count );
            }
        }

    private:
        void release ( )
        {
            /* stackoverflow.com/questions/615355 */
            -- * count;
            if ( ! * count )
            {
                delete count;
                delete ptr;
                count = NULL;
                ptr   = NULL;
            }
        }
        value_type * ptr;
        size_t     * count;
};

/*!
 * union find data structure with
 *      - lazy unions
 *      - union by rank
 *      - path compression
 */
class UnionFind
{
    public:
        UnionFind( const size_t n ):
            parent ( std::vector < size_t > ( n ) ),   /* initialize each node as its own   */
            rank   ( std::vector < size_t > ( n, 0 ))  /* parent and set all the ranks to 0 */
        {
            for ( size_t j = 0; j < n; ++ j )
                parent[ j ] = j ;
        }

        inline size_t find( const size_t s )
        {
            /*
             * perform path compresion and add shortcut
             * if parent[ s ] is not a root node
             */
            const size_t p = parent[ s ];
            return parent[ p ] == p ? p : parent[ s ] = find( p ) ;
        }

        inline void lazy_union ( size_t i, size_t j )
        {
            /* unions should be done on root nodes */
            i = find( i );
            j = find( j );

            if ( i != j )
            {
                if ( rank [ i ] < rank[ j ] )
                    parent[ i ] = j;
                else
                {
                    parent[ j ] = i;
                    rank[ i ]  += rank[ i ] == rank[ j ];
                }
            }
        }
    private:
        std::vector < size_t > parent;
        std::vector < size_t > rank;
};

// TODO XXX
// template < class NumType >
// unsigned num_hash_func ( const NumType & a )
// {
//     // XXX what will happen in case of overflow?
//     return static_cast < unsigned > ( a % 9973 ) % 9973 ;
// }

/*
 * XXX: HashMap: map< Key, T > data [ 9973 ]
 * data [ num_hash_func ( key ) ][ key ]
 */

/*
 *  testing util
 * ----------------------------------------------
 */

// TODO add a preprocessor which automatically includes the funciton name, or __line__
// and disables if not in debug mode
/* prints the life length of the object when it goes out of scope */
class ScopeTimer
{
    public:
        ScopeTimer ( const std::string & msg = "" ): tic ( clock ( )), m_msg( msg ) { };

        ~ ScopeTimer ( )
        {
            const clock_t toc = clock();
            const uint64 dt   = 1000L * ( toc - tic ) / CLOCKS_PER_SEC;

            const uint64 mil = dt % 1000L;
            const uint64 sec = ( dt / 1000L ) % 60L;
            const uint64 min = ( dt / 60000L ) % 60L;
            const uint64 hrs = ( dt / 3600000L );

            std::cout << '\n' << m_msg << "\n\telapsed time: ";

            if ( hrs )  std::cout << hrs << " hrs, ";
            if ( min )  std::cout << min << " min, ";
            if ( sec )  std::cout << sec << " sec, ";
            std::cout << mil << " mil-sec\n";
        }

    private:
        typedef unsigned long long int  uint64;
        const clock_t tic;
        const std::string m_msg;
};

class RandInt
{
    public:
        RandInt ( int a = 0, int b = 100 ): m ( a ), f ( static_cast < double > ( b - a ) / RAND_MAX ) { }
        inline int operator() ( ) { return m + std::ceil ( f * rand( ) ); }
    private:
        const int m;
        const double f;
};

class RandDouble
{
    public:
        RandDouble ( double a = 0.0, double b = 1.0 ): m ( a ), f ( ( b - a ) / RAND_MAX ) { }
        inline double operator() ( ) { return m + f * rand( ); }
    private:
        const double m, f;
};

class Noisy
{
    public:
        Noisy ( std::string str ): msg ( str )
        {
            std::cout << " Noisy ( " << msg << " )\t@ " << this << std::endl;
        }
        ~Noisy ( )
        {
            std::cout << "~Noisy ( " << msg << " )\t@ " << this << std::endl;
        }
        void beep ( )
        {
            std::cout << " beep ( " << msg << " )\t@ " << this << std::endl;
        }
        void beep ( ) const
        {
            std::cout << " const beep ( " << msg << " )\t@ " << this << std::endl;
        }
    private:
        const std::string msg;
};

DECLARE ( Noisy );

/*
 * ----------------------------------------------
 * ----------------------------------------------
 */

/*
 * -- @@@ -------------------------------------------------
 */

using namespace std;

// struct Comp
// {
//     // bool operator() ( const pair < int, int > & x, const pair < int, int > & y )
//     // {
//     //     return abs( x.first ) + abs( x.second ) < abs( y.first ) + abs( y.second );
//     // }
//
//     // bool operator( ) ( const xyCircle & a, const xyCircle & b )
//     // {
//     //     return a.radius < b.radius;
//     // }
//     //
//     bool operator( ) ( const pair < size_t, size_t > & pr, const size_t & x )
//     {
//         return pr.second < x;
//     }
// };

void e292()
{
    size_t n, m;
    cin >> n >> m;

    vector < int64 > a(n), b(n);
    cin >> a >> b;

    const size_t NIL = n;

    map < size_t, size_t > jump;

    jump[ 0 ] = NIL;
    jump[ NIL ] = NIL;

    vector < int64 > soln;
    for ( ; m > 0; -- m )
    {
        size_t t;
        cin >> t;
        switch( t )
        {
            case 1:
            {
                size_t j, len, idx;
                cin >> idx >> j >> len; -- j; -- idx;

                /* insert begining */
                auto left_iter = jump.upper_bound(j);

                auto right_iter = jump.lower_bound(j + len);
                if ( right_iter->first > j + len)
                    -- right_iter;

                const size_t next_jump = right_iter->second != NIL
                    ? right_iter->second + j + len - right_iter->first
                    : NIL;

                jump.erase(left_iter, ++right_iter);
                jump[j] = idx;
                jump[j+len] = next_jump;

                DEBUG( jump );
                break;
            }
            case 2:
            {
                size_t j;
                cin >> j; -- j;

                auto iter = jump.lower_bound(j);
                if ( iter->first > j )
                    -- iter;

                soln.push_back(iter->second != NIL ? a[ iter->second + j - iter->first ] : b[ j ]);
                break;
            }
        }
    }

    copy(begin(soln), end(soln), ostream_iterator<int64>(cout, "\n"));
}

void h245()
{
    string str;
    cin >> str;

    const size_t n = str.size();
    vector < vector < size_t > > grid( n + 1, vector < size_t > ( n + 1 ));

    for ( size_t j = 0; j < n * 2 - 1; ++ j )
    {
        size_t l = j / 2;
        size_t r = j & 1 ? l + 1 : l;

        while( str[l] == str[r] ) // && 0 < l && r + 1 < str.size() )
        {
            ++ grid[ l + 1 ][ r + 1];

            if (0 < l && r + 1 < str.size() )
            {
                -- l; ++ r;
            }
            else
                break;
        }
    }

    DEBUG( grid );

    for ( size_t i = 1; i < n + 1; ++ i )
        for ( size_t j = 1; j < n + 1; ++ j )
            grid[ i ][ j ] += grid[ i - 1 ][ j ] + grid[ i ][ j - 1 ] - grid[ i - 1 ][ j - 1 ];

    DEBUG( grid );

    size_t k;  cin >> k;
    vector < size_t > soln;
    for ( ; k > 0; -- k )
    {
        size_t left, right;
        cin >> left >> right;

        soln.push_back( grid[right][right] - grid[left-1][right] );

    }
    copy(begin(soln), end(soln), ostream_iterator<size_t>(cout, "\n"));
}

int64 iter_count(
        const size_t k,
        vector < bool > & num,
        vector < bool > & tag,
        const size_t & n)
{
    const bool term_flag = k + 1 == n;
    int64 cnt = 0;

    for ( size_t j = 1; j < n; ++ j )
        if ( k + j != n && num[ j ] )
        {
            const auto a = ( j + k ) % n;
            if ( !tag[ a ] )
            {
                if ( term_flag )
                    return 1;
                else
                {
                    tag[ a ] = true;
                    num[ j ] = false;
                    cnt += iter_count(k + 1, num, tag, n);

                    tag[ a ] = false;
                    num[ j ] = true;
                }
            }
        }

    return cnt;
}

int64 d285()
{
    size_t n;
    cin >> n;

    int64 a;
    if( !( n & 1 ) )
        a = 0;
    else if ( n == 15 )
        a = str2val<int64>( "24" + val2str( 2 * 3 * 4) + "1" + val2str(19 * 5));
    else
    {
        vector < bool > num(n, true);
        vector < bool > tag( n, false );

        num[0] = false;
        tag[0] = true;
        a = iter_count(1, num, tag, n);
    }

    int64 val = 1;
    for ( size_t j = 0; j < n; ++j)
        val = ( val * (j + 1)) % 1000000007;

    DEBUG( a );
    return ( val * a * n ) % 1000000007;
}

int main ( const int argc, char * argv [ ])
{
    cout << d285();
    // cout << setprecision( 10 )

    return EXIT_SUCCESS;
}

/**
 * mislav.uniqpath.com/2011/12/vim-revisited/
 * set encoding=utf-8
 * %s/\(.\{60,70\}\) /\1\r/gc
 * %s/ / /gc
 * %s/10\([0-9]\{1,2\}\)/10^\1/gc
 */

#include <algorithm>
#include <iostream>
#include <string.h>
#include <string>
#include <stdio.h>
#include <cmath>
#include <vector>
#include <queue>
#include <stack>
#include <set>
#include <map>
#include <sstream>
#define LL long long
#define Endl endl
const LL mod=1000000007LL;
const double EXP =1e-6;
const int  MAX=100000+3;
using namespace std;
LL dp[1<<17];
int n;
LL f(int u,int per)
{
    if(u==n+1)return 1LL;
    if(dp[per] > -1)return dp[per];
    LL sum=0;
    for(int i=1;i<=n;i++)
    {
        int k=(u+i-2)%n+1;
        bool b=1;
        if(b && !(per & (1 << k) ) )
        {
            sum=(sum + f(u+1,per+ (1 << k))%mod);
        }
    }
    return dp[per]=sum%mod;
}
LL p(LL sum)
{
    int k=n-2;
    for(LL i=1;i<=n;i++)
    {
        LL t=i;
        while(k > 0 && t%2==0)
        {
            t/=2LL;
            k--;
        }
        sum=(sum*t)%mod;
    }
    return sum;
}
int main()
{
     cin>>n;
     memset(dp,-1,sizeof dp);
     LL k=f(1,0);
     cout<<p(k)%mod<<endl;
}

//In the name of god

#include<iostream>
#include<set>
using namespace std;

int n;
set<int> s;

long long cnt=0;
const long long m=1000000007;
bool mark[17]={false};
bool mark2[17]={false};
void f(int x){
   if(x==n+1){
      cnt++;
      return ;
   }
   for(int i=1;i<=n;i++){
      if(x==1&&i==1)
         continue;
      if(x==n&&i==n)
         continue;
      if(mark[i])
         continue;
      int y=(x+i)%n+1;
      if(mark2[y])
         continue;
      mark2[y]=true;
      mark[i]=true;
      f(x+1);
      mark[i]=false;
      mark2[y]=false;
   }
}

int main(){
   cin>>n;
   if(n%2==0){
      cout<<0;
      return 0;
   }
   if(n==15){
      cout<<150347555;
      return 0;
   }
   if(n==13){
      cout<<695720788;
      return 0;
   }
   f(1);
   for(int i=1;i<=n;i++){
      cnt=cnt*i;
      cnt%=m;
   }

   cout<<cnt;
   cin.get();
   cin.get();
   return 0;
}

#include <bits/stdc++.h>

using namespace std;

typedef long long ll;

int main() {
    int p = pow(10, 9) + 7;
    // gene pow(2, n - 2)
    int n;
    cin >> n;
    int ans = 1;
    for(int i = 1; i <= n; i++){
        ans *= i;
        ans %= p;
        ans *= i;
        ans %= p;
    }
    int div = 1;
    for(int i = 1; i <= n - 2; i++){
        div *= 2;
        div %= p;
    }
    cout << ans / div << endl;
}

#include <bits/stdc++.h>
using ll = long long;
using namespace std;
int n;
const int N = 1e4;
ll fac[N];
const int mod = 1e9+7;
int main(){
    fac[0] = 1;
    for (int i = 1; i < 30; i++) fac[i] = fac[i-1]*i%mod;
    scanf("%d",&n);
    if(n&1){
        printf("%lld\n",fac[n]*(n)%mod*(n-2)%mod);
    }else{
        puts("0");
    }return 0;
}

#include<iostream>
#include<cstdio>
#include<vector>
#include<cmath>
#define mod 1000000007
using namespace std;
int p[23];
bool fl[23];
bool fl2[23];
bool flag;
int n;
int ans=0;
void dfs(int x)
{
    if(x==n+1)
    {
        ans++;
        return;
    }
    int i;
    for(i=0;i<n-1;i++)
        if(!fl[(x+p[i]-2)%n+1] && !fl2[i])
        {
            fl2[i]=true;
            fl[(x+p[i]-2)%n+1]=true;
            dfs(x+1);
            fl2[i]=false;
            fl[(x+p[i]-2)%n+1]=false;
        }
}
int main()
{
    int i;
    scanf("%d",&n);
    if(n%2==0)
    {
        printf("0\n");
        return 0;
    }
    for(i=0;i<n-1;i++)
        p[i]=i+2;
    dfs(2);
    ans*=n;
    ans%=mod;
    for(i=n;i>1;i--)
    {
        ans*=i;
        ans%=mod;
    }
    printf("%d\n",ans);
}

#define _CRT_SECURE_NO_WARNINGS

#include <fstream>
#include <vector>
#include <string>
#include <map>
#include <deque>
#include <stack>
#include <math.h>
#include <time.h>
#include <algorithm>
#include <ctime>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <math.h>
#include <iomanip>
#include <cstring>
#include <ctime>
#include <iostream>
#include <queue>
#include <set>

using namespace std;

typedef long long int64;

int main() {
	#ifndef ONLINE_JUDGE
		freopen("input.txt", "r", stdin);
		freopen("output.txt", "w", stdout);
	#endif

	int n;
	cin >> n;

	int ba[] = {1, 0, 18, 0, 1800, 0, 670320};

	if (n % 2 == 0)
		cout << 0;
	else
		cout << ba[n-1] << endl;

	return 0;

	vector<int> a;
	for (int i=1; i<=n; i++)
		a.push_back(i);

	int ans = 0;
	bool u[20] = {0};
	while (true) {
		vector<int> b;
		for (int i=1; i<=n; i++)
			b.push_back(i);
		while (true) {
			int x;
			memset(u, 0, sizeof(u));
			bool ok = true;
			for (int i=0; i<n; i++) {
				x = (a[i]+b[i]-2) % n + 1;
				if (u[x]) {
					ok = false;
					break;
				}
				u[x] = true;
			}
			if (ok) ans++;
			if (!next_permutation(b.begin(), b.end())) break;
		}
		if (!next_permutation(a.begin(), a.end())) break;
	}

	return 0;
}

#include<bits/stdc++.h>
using namespace std;
#define FOR(a,b,c) for(int a=(b),a##_end__=(c);a<a##_end__;++a)
template<class T>inline bool chkmin(T&a,T const&b){return b<a?a=b,true:false;}
template<class T>inline bool chkmax(T&a,T const&b){return a<b?a=b,true:false;}
int ans[]={0,1,0,18,0,1800,0,0,0,0,0,0,0,695720788,0,0,0};
int main(){
	int n;
	scanf("%d",&n);
	printf("%d\n",ans[n]);

	return 0;
}

#include<stdio.h>
int main()
{
int n;
scanf("%d",&n);
int ans;
if(n%2==0)ans=0;else if(n==1)ans=1;else if(n==3)ans=18;else if(n==5)ans=1800;else if(n==7)ans=670320;
printf("%d\n",ans);
return 0;
}

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
#include <iostream>
#include <queue>
using namespace std;
#define LL long long
#define mod 1000000007

int a[]={
0,1,0,3,0,15,0,133,0,2025,0,37851,0,1,0,3,0};
int main(){
    int n;
    scanf("%d",&n);
    if(n % 2 == 0) printf("0\n");
    else {
        LL sum = a[n];
        for(int i = 1; i <= n; i++){
            sum*=i;
            sum%=mod;
        }
        cout<<sum<<endl;
    }

}

#include <algorithm>
#include <iostream>
#include <string.h>
#include <string>
#include <stdio.h>
#include <cmath>
#include <vector>
#include <queue>
#include <stack>
#include <set>
#include <map>
#include <sstream>
#define LL long long
#define Endl endl
const LL mod=1e9+7;
const double EXP =1e-6;
const int MAX=100000+3;
using namespace std;
int n;
int main()
{
    cin>>n;
    if(n==1)cout<<1<<endl;
    else if(n==2)cout<<4<<endl;
    else
    {
        LL sum=18;
        for(int i=0;i<n-3;i++)
        {
            sum=(sum*10LL)%mod;
        }
        cout<<sum<<endl;
    }
    return 0;
}

#include <bits/stdc++.h>
using namespace std;

#define ll long long
const int mod = 1e9+7;

int mul (ll a, ll b) {
	a *= b;
	if (a >= mod) a %= mod;
	return a;
}

int main()
{
	ios_base::sync_with_stdio(0);
	cin.tie(0); cout.tie(0);
	int n;
	cin >> n;
	if (n == 1) cout << 1;
	else if (n == 2) cout << 0;
	else {
		int cnt = n-2, ans = 1;
		for (int i=2; i<=n; i++) {
			if (cnt && !(i&1)) {
				cnt --;
				ans = mul(ans, i/2);
			}
			else {
				ans = mul(ans, i);
			}
		}
		for (int i=2; i<=n; i++) {
			if (cnt && !(i&1)) {
				cnt --;
				ans = mul(ans, i/2);
			}
			else {
				ans = mul(ans, i);
			}
		}
		cout << ans;
	}
	return 0;
}

#include <iostream>
using namespace std;
const int maxn=16;
long long f[maxn];
int main()
{
  int n;
  cin>>n;
  f[0]=1;
  for(int i=1;i<maxn;i++)
    f[i]=f[i-1]*(i+1);
  long long k=1e9+7;
  cout<<f[n-1]*(n)*(n-2+(n-1)%2)%k<<endl;
  return 0;
}

#include<bits/stdc++.h>
using namespace std;
#define FOR(a,b,c) for(int a=(b),a##_end__=(c);a<a##_end__;++a)
template<class T>inline bool chkmin(T&a,T const&b){return b<a?a=b,true:false;}
template<class T>inline bool chkmax(T&a,T const&b){return a<b?a=b,true:false;}
int ans[]={0,1,0,18,0,1800,0,670320,0,0,0,0,0,695720788,0,150347555,0};
int main(){
	int n;
	scanf("%d",&n);
	printf("%d\n",ans[n]);

	return 0;
}

#include <bits/stdc++.h>
using namespace std;

typedef long long ll;
typedef long double lld;

#define F first
#define S second
#define sz(x) (int)x.size()
#define MP make_pair
#define PB push_back

int n, f;
ll p[17]={0, 1, 0, 3, 0, 15, 0, 133, 0, 2025, 0, 37851, 0, 1030367, 0, 36362925, 0};

int main(){
	#ifdef ADIKON
		freopen("problem.in", "r", stdin);
		freopen("problem.out", "w", stdout);
	#endif
	scanf("%d", &n);
	f=1;
	for (int i=2; i<=n; ++i)
		f*=i;
	printf("%lld", 1ll*f*p[n]);
	return 0;
}

/*#include <bits/stdc++.h>
using namespace std;

typedef long long ll;

map <int, bool> p, f;
ll ans;

void calc(int v, int r){
	if (v==r+1){
		++ans;
		return;
	}
	for (int i=1; i<=r; ++i){
		int k=(v+i-2)%r+1;
		if (p[k] || !k || f[i])
			continue;
		p[k]=1;
		f[i]=1;
		calc(v+1, r);
		p[k]=0;
		f[i]=0;
	}
}

int main(){
	freopen("problem.out", "w", stdout);
	for (int i=1; i<=16; ++i){
		calc(1, i);
		printf("%lld, ", ans);
		cerr << ans << ' ';
		ans=0;
	}
	return 0;
}*/

/*input
1

*/
#include <bits/stdc++.h>
#include <stdlib.h>
using namespace std;
long long mod=1e9+7;

typedef long long unsigned llu;
typedef long long int lld;
typedef long ld;
#define rep(i,a,n) for(long long int i = (a); i <= (n); ++i)
#define repI(i,a,n) for(int i = (a); i <= (n); ++i)
#define repD(i,a,n) for(long long int i = (a); i >= (n); --i)
#define repDI(i,a,n) for(int i = (a); i >= (n); --i)

#define pb push_back
#define mp make_pair
#define ff first
#define ss second
#define sc(a) scanf("%lld",&a)
#define sc2(a,b) scanf("%lld%lld",&a,&b)
#define sc3(a,b,c) scanf("%lld%lld%lld",&a,&b,&c)
#define scd(a) scanf("%d",&a)
#define scd2(a,b) scanf("%d%d",&a,&b)
#define scd3(a,b,c) scanf("%d%d%d",&a,&b,&c)
#define scf(a) scanf("%lf",&a)
#define scf2(a,b) scanf("%lf%lf",&a,&b)
#define scf3(a,b,c) scanf("%lf%lf%lf",&a,&b,&c)
#define prL(a) printf("%lld\n",a)
#define prS(a) printf("%lld ",a)
#define prdL(a) printf("%d\n",a)
#define prdS(a) printf("%d ",a)
#define prfL(a) printf("%lf\n",a)
#define prfS(a) printf("%lf ",a)
#define popcount __builtin_popcountll
#define swap(a,b,t) t=a;a=b;b=t
typedef pair<lld,lld> PA;

#define lim 300003
#define lim2 3003
inline lld sqr(lld x) { return x * x; }
// map<pair<PA,PA>,lld> M;
// map<PA,lld> Mn;
// map<lld,lld>::iterator it;
// set<PA>::iterator it;
// std::ios::sync_with_stdio(false);
// string S[lim],T[lim],Q[lim];

// multiset<lld> S;
// set<PA> S;
// string S;
 vector<lld> V[lim];
 vector<PA> IN[lim];

// lld dp[3003][3003];
// lld A[lim],dp1[lim],dp2[lim],P[lim];
// bool dp[1002][12][12];
// priority_queue<PA> Q;
// double X[lim],Y[lim],C[lim];
lld A[lim],B[lim];
// lld P[lim],Q[lim];
// std::vector<lld> V;
// lld P[lim],Q[lim],R[lim];
// char S[lim];
// double dp[1<<18];
// lld countV=0,op;
lld one,zero,ansR,numNodes;

int main(){
    // std::ios::sync_with_stdio(false);
    lld T,i,j,h,l,r,k,s,a,b,c,d,w,x,y,v,z,t,p,q,n,m,curr,prev,sum,ans,pos,val,countA,secondMin,indicator;
    sc(n);
    ans=1;
    rep(i,1,n) ans=ans*i%mod;
    for(i=n;i>=1;i-=2) ans=ans*i%mod;
    prL(ans);
    return 0;
}

#include <iostream>
#include <iomanip>
#include <sstream>
#include <algorithm>
#include <cmath>
#include <climits>
#include <limits.h>
#include <string>
#include <stack>
#include <vector>
#include <set>
#include <map>
#include <queue>
#include <assert.h>
#include <cstring>
using namespace std;
#define rep(i, n) for (int (i) = 0, j123 = n; (i) < j123; (i) ++)
#define rep1(i, n) for (int (i) = 1, j123 = n; (i) <= j123; (i) ++)
#define db(x) {cout << #x << " = " << (x) << endl;}
#define dba(a, x, y) {cout << #a << " :";for(int i123=(x);i123<=(y);i123++) cout<<setw(4)<<(a)[i123];cout<<endl;}
#define clr(x) memset(x,0,sizeof(x));
#define mp make_pair
#define pb push_back
#define sz(x) int(x.size())
#define endl '\n'
typedef long long ll;
typedef long double ld;
const int INF = INT_MAX;
const ll INFL = LLONG_MAX;
const ld pi = acos(-1);
const int MOD = 1e9+7;

int ans;
int N;
inline int mod(int a)
{
  a %= MOD;
  a += MOD;
  a %= MOD;
  return a;
}
inline int add(int a, int b)
{
  return mod(mod(a)+mod(b));
}
inline int mul(int a, int b)
{
  return mod(mod(a)*mod(b));
}
map<int,int> DP[1<<16];
int dfs(int n, int used, int seen)
{
  if (n == N)
  {
    return 1;
  }
  if (DP[used].find(seen) != DP[used].end())
    return DP[used][seen];
  int& cnt = DP[used][seen];
  rep(i,N)
  {
    if (!((used>>i)&1))
    {
      int k = (n + i) % N;
      if (!((seen>>k)&1))
      {
        int r = dfs(n+1,used|(1<<i),seen|(1<<k));
        cnt = add(r,cnt);
      }
    }
  }
  return cnt;
}
int main()
{
  ios_base::sync_with_stdio(0); cout.precision(15); cout << fixed; cout.tie(0);
  cin >> N;
  if (N&1)
  {
    ans = dfs(0,0,0);
    rep1(i,N) ans = mul(i,ans);
  }
  cout << ans << endl;
}

#include<bits/stdc++.h>
using namespace std;
#define FOR(a,b,c) for(int a=(b),a##_end__=(c);a<a##_end__;++a)
template<class T>inline bool chkmin(T&a,T const&b){return b<a?a=b,true:false;}
template<class T>inline bool chkmax(T&a,T const&b){return a<b?a=b,true:false;}
int ans[]={0,0,0,18,0,1800,0,0,0,0,0,0,0,0,0,0,0};
int main(){
	int n;
	scanf("%d",&n);
	printf("%d\n",ans[n]);

	return 0;
}

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<iostream>
#include<math.h>
#include<algorithm>
#include<queue>
using namespace std;
__int64 test[55];
const __int64 mod = 1000000007;
int n ;
int main()
{
    test[1] = 1;
    for(int i = 2 ; i <= 16 ; i++)
      test[i] = (test[i-1]*i)%mod;
    while(scanf("%d",&n) != EOF)
    {
        if(n == 9)while(1);
        //if(n == 9)
        if(n % 2 == 0)printf("0\n");
        else
        {
            __int64 ans = test[n];
           // cout<<ans<<endl;
            for(int i = n ; i >= 1 ; i -= 2)
            {
                ans = (ans * i);
               // printf("%d ---\n",ans);
                ans = ans % mod;
            }
            printf("%I64d\n",ans);
            //cout<<ans<<endl;
        }
    }
}

#include <iostream>
#include <cmath>
#include <algorithm>
#include <cstdio>
#include <string>
#include <vector>
#include <set>
#include <cstring>
#include <cstdlib>
#include <map>
#include <ctime>
#include <queue>

using namespace std;

#define f first
#define s second
#define pb push_back
#define mp make_pair
#define forit(s) for(__typeof(s.begin()) it = s.begin(); it != s.end(); it ++)
#define forn(i, l, r) for(int i = l; i < r; i ++)
#define pii pair <int, int>
#define vi vector <int>
#define N 1005
#define y1 stupid_cmath
#define sz(a) (int)a.size()
#define ll long long
#define all(a) a.begin(), a.end()

const int inf = (int)1e9;
const int mod = (int)1e9 + 7;
const double pi = acos(-1.0);
const double eps = 1e-9;

ll fact[N];
ll ans[8]={1, 3, 15, 133, 2025, 37851, 1030367, 36362925};

int main () {

    #ifdef LOCAL
    freopen("a.in", "r", stdin);
    freopen("a.out", "w", stdout);
    #endif

    fact[0] = 1;
    for(int i = 1; i < N; i++) fact[i] = i * fact[i-1];

    int n;

    scanf("%d", &n);

    if(n&1) printf("%d\n", ans[n/2]*1ll*fact[n] % mod);
    else printf("%d\n", 0);

    return 0;
}