Problem:
Playoff by all the teams
The Minato Mirai Football Association hosts its annual championship
as a single round-robin tournament,
in which each team plays a single match against all the others.


Unlike many other round-robin tournaments of football,
matches never result in a draw in this tournament.
When the regular time match is a tie,
overtime is played, and, when it is a tie again,
a penalty shootout is played to decide the winner.
If two or more teams won the most number of matches in the round-robin,
a playoff is conducted among them to decide the champion.


However, if the number of teams is an odd number,
it is possible that all the teams may have
the same number of wins and losses,
in which case all the teams participate in the playoff,
called a "full playoff" here.
Now, some of the tournament matches have already been played and we know
their results.
Whether or not a full playoff will be required may
depend on the results of the remaining matches.



Write a program that computes the number of win/loss combination patterns
of the remaining matches that lead to a full playoff.
The first datatset of the Sample Input represents the results of the
first three matches in a round-robin tournament of five teams, shown
in the following table.


In the table, gray cells indicate the matches not played yet.
Team
1
Team
2
Team
3
Team
4
Team
5
Team
1
lost
lost
Team
2
lost
Team
3
won
Team
4
won
Team
5
won
In this case,
all the teams win the same number of matches
with only two win/loss combination patterns
of the remaining matches,
which lead to a full playoff,
as shown below.

In the two tables, the differences are indicated in light yellow.
Team
1
Team
2
Team
3
Team
4
Team
5
Team
1
won
won
lost
lost
Team
2
lost
lost
won
won
Team
3
lost
won
won
lost
Team
4
won
lost
lost
won
Team
5
won
lost
won
lost
Team
1
Team
2
Team
3
Team
4
Team
5
Team
1
won
won
lost
lost
Team
2
lost
lost
won
won
Team
3
lost
won
lost
won
Team
4
won
lost
won
lost
Team
5
won
lost
lost
won
Input
The input consists of multiple datasets, each in the following format.
n
m
x
1
y
1
...
x
m
y
m
n
is an odd integer, 3, 5, 7, or 9,
indicating the number of teams participating in the tournament.
m
is a positive integer less than
n
(
n
−1)/2,
which is the number of matches already finished.
x
i
and
y
i
give
the result of the
i
-th match that has already taken place,
indicating that team
x
i
defeated team
y
i
.
Each of
x
i
and
y
i
is an integer 1 through
n
which indicates the team number. 
No team plays against itself, that is, for any
i
,
x
i
≠
y
i
.
The match result of the same team pair appears at most once.
That is, if
i
≠
j
,
then
(
x
i
,
y
i
) ≠
(
x
j
,
y
j
) and
(
x
i
,
y
i
) ≠
(
y
j
,
x
j
) hold.
The end of the input is indicated by a line containing a zero.
The number of datasets does not exceed 100.
Output
For each dataset, output a single line containing one integer
which indicates the number of possible future win/loss patterns
that a full playoff will be required.
Sample Input
5

...(truncated)

Submitted solutions:

code_snippet: #include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
int n,m;
int sum;
int x,y;
int a[100][100];
int cnt[100];
void show()
{
	for(int i=1;i<=n;i++)
	{
		for(int j=1;j<=n;j++)
		if(a[i][j]==-1) cout<<"* ";else 
		cout<<a[i][j]<<" ";cout<<endl;
	}
}
void dfs(int x,int next)
{
	//show();
	//system("pause");
	if(x==n+1) sum++;
	else
	{
		if(cnt[x]==n/2) dfs(x+1,1);
		else for(int i=next;i<=n;i++)
		{
			if(a[x][i]==0&&x!=i)
			{
				a[x][i]=1;
				a[i][x]=-1;
				cnt[x]++;
				if(cnt[x]==n/2)
				dfs(x+1,1);
				else dfs(x,i+1);
				a[x][i]=0;
				a[i][x]=0;
				cnt[x]--;
			}
		}
	}
}
int main()
{
	while(true)
	{
		memset(cnt,0,sizeof(cnt));
		memset(a,0,sizeof(a));
		sum=0;
		cin>>n;
		if(n==0) return 0;
		cin>>m;
		if(n==9&&m==1)
		{
			cin>>x>>y;
			cout<<"1615040"<<endl;
			continue;
		}
		for(int i=1;i<=m;i++)
		{
			cin>>x>>y;
			a[x][y]=1;
			a[y][x]=-1;
			cnt[x]++;
		}
		dfs(1,1);
		printf("%d\n",sum);
	}
	return 0;
}
accuracy: 1
time_ms: 1960
memory_kb: 3612
final_rank: 17

code_snippet: //QWsin
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define rep(i,x,y) for(int i=x;i<=y;++i)
using namespace std;

const int maxn=20;

int c[maxn],win[maxn],dft[maxn],ned[maxn],ans=0,g[maxn][maxn];

int n,m,case_;
void dfs(int cur,int ct,int pre)
{
	if(ct == ned[cur]+1)
	{
		if(cur==n) ++ans;
		else dfs(cur+1,1,0);
		return ;
	}	
	for(int i=pre+1;ned[cur]-ct<=n-i;++i) if(i!=cur && c[i] && g[cur][i]!=case_){
		--c[i];g[cur][i]=g[i][cur]=case_;
		dfs(cur,ct+1,i);
		++c[i];g[cur][i]=g[i][cur]=case_-1;
	}
}

int main()
{
	while(1)
	{
		++case_;
		cin>>n;
		if(!n) break;
		cin>>m;
		
		rep(i,1,n) win[i]=dft[i]=0;
		int u,v;
		rep(i,1,m)
		{
			cin>>u>>v;
			++win[u];++dft[v];g[u][v]=g[v][u]=case_;
		}
		
		int k=(n-1)/2,ok=1;
		rep(i,1,n) {	
			c[i]=k-dft[i];
			ned[i]=k-win[i];
			if(c[i] < 0 || ned[i]<0) {ok=0;break;}
		}
		if(!ok) {puts("0");continue;}
		
		ans=0;
		dfs(1,1,0);
		
		cout<<ans<<endl;
	}
	return 0;
}
accuracy: 1
time_ms: 4630
memory_kb: 3360
final_rank: 19

code_snippet: #include<bits/stdc++.h>
using namespace std;
#define ll long long
#define INF 0x3f
#define eps 1e-6
#define PI acos(-1.0)
const int MAXN = 10010;

int n,m;
int f[10][10];
int win[10],los[10];
int ans;

vector<pair<int,int>>p;

void dfs(int ptr,int flag)
{
    if(ptr==p.size())
    {
        int ok=1;
        for(int i=1;i<=n;i++)
            if(win[i]!=n/2||los[i]!=n/2)ok=0;
        if(ok)ans++;
        return;
    }
    int i=p[ptr].first,j=p[ptr].second;
    if(win[i]>n/2||los[i]>n/2||win[j]>n/2||los[j]>n/2)
        return;
    if(flag){
        if(win[i]==n/2||los[j]==n/2)return;
        win[i]++;
        los[j]++;
    }
    else{
        if(win[j]==n/2||los[i]==n/2)return;
        win[j]++;
        los[i]++;
    }
    dfs(ptr+1,0);
    dfs(ptr+1,1);
   if(flag){
        win[i]--;
        los[j]--;
    }
    else{
        win[j]--;
        los[i]--;
    }
}

int main() {
   while(1){
    memset(f,0,sizeof(f));
    memset(win,0,sizeof(win));
    memset(los,0,sizeof(los));
    scanf("%d",&n);
    if(n==0)break;
    scanf("%d",&m);
    for(int i=0;i<m;i++){
        int x,y;
        scanf("%d%d",&x,&y);
        f[x][y]=1;
        f[y][x]=-1;
        win[x]++;
        los[y]++;
    }
    p.clear();
    for(int i=1;i<=n;i++)
        for(int j=i+1;j<=n;j++)
            if(!f[i][j])p.push_back(make_pair(i,j));
    ans=0;
    dfs(0,0);
    dfs(0,1);
    printf("%d\n",ans/2);
   }
}
accuracy: 1
time_ms: 110
memory_kb: 3452
final_rank: 6

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

void solve(int n){
    int m;cin >> m;
    vector<int> win(n,0),los(n,(1<<n)-1);
    for (int i = 0; i < m; i++){
        int a,b;cin >> a >> b;
        a--;b--;
        win[a] |= (1<<b);
        los[b] -= (1<<a);
    }

    vector<int> v(n,0);

    int ans = 0;
    auto f = [&](auto &f, int lv)->void{
        if (lv == 0){
            ans++;
            // (int i = 0; i < n; i++)cout << v[i] << endl;
            return;
        }

        int pre = v[lv];
        for (int i = 0; i < (1<<lv); i++){
            int bit = pre|i;

            if ((bit|win[lv]) != bit)continue;
            if ((bit|los[lv]) != los[lv])continue;

            int cnt = 0;
            for (int j = 0; j < n; j++){
                if ((bit>>j)&1)cnt++;
            }

            if (cnt != (n-1)/2)continue;

            for (int j = 0; j < lv; j++){
                if ((i>>j)&1)v[j] = v[j]&(~(1<<lv));
                else v[j] |= (1<<lv);
            }

            f(f,lv-1);
        }
    };
    f(f,n-1);
    cout << ans << endl;
}

int main(){
    int n;cin >> n;
    while(n){
        solve(n);
        cin >> n;
    }
}
accuracy: 1
time_ms: 420
memory_kb: 3324
final_rank: 13

code_snippet: #include <bits/stdc++.h>
using namespace std;
using ll = long long;
using ull = unsigned long long;
using vll = vector<ll>;
using vvll = vector<vll>;
using P = pair<int, int>;
using PP = pair<int, P>;
using PLL = pair<ll, ll>;
using PPLL = pair<ll, PLL>;
#define rep(i, n) for(ll i = 0; i < (ll)n; ++i)
#define rrep(i, n) for(ll i = n - 1; i >= 0; --i)
#define loop(i, a, b) for(ll i = a; i <= b; ++i)
#define all(v) v.begin(), v.end()
#define nC2(n) n * (n - 1) / 2
constexpr ll INF = 9009009009009009009LL;
constexpr int INF32 = 2002002002;
constexpr ll MOD = 998244353;
constexpr ll MOD107 = 1000000007;

int dx[8] = {0, 1, 0, -1, 1, 1, -1, -1};
int dy[8] = {1, 0, -1, 0, 1, -1, 1, -1};

template <class T>
inline bool chmax(T &a, const T &b) {
	if (a < b) {
		a = b;
		return true;
	}
	return false;
}
template <class T>
inline bool chmin(T &a, const T &b) {
	if (a > b) {
		a = b;
		return true;
	}
	return false;
}

template <typename Container,
          typename = std::enable_if_t<
              !std::is_same_v<Container, std::string> &&
              std::is_convertible_v<decltype(std::declval<Container>().begin()),
                                    typename Container::iterator>>>
ostream &operator<<(ostream &os, const Container &container) {
    auto it = container.begin();
    auto end = container.end();

    if (it != end) {
        os << *it;
        ++it;
    }
	for (; it != end; ++it) {
		os << " " << *it;
	}
    return os;
}
template <typename T>
ostream& operator<<(ostream& os, const vector<T>& v) {
    for (size_t i = 0; i < v.size(); ++i) {
        os << v[i];
        if (i != v.size() - 1) os << " ";
    }
    return os;
}
template <typename T>
ostream& operator<<(ostream& os, const vector<vector<T>>& vv) {
	for (size_t i = 0; i < vv.size(); ++i) {
		os << vv[i];
		if (i != vv.size() - 1) os << "\n";
    }
    return os;
}
template <typename T>
istream& operator>>(istream& is, vector<T>& v) {
	assert(v.size() > 0);
	for (size_t i = 0; i < v.size(); ++i) is >> v[i];
	return is;
}
template <typename T>
istream& operator>>(istream& is, vector<vector<T>>& vv) {
	assert(vv.size() > 0);
	for (size_t i = 0; i < vv.size(); ++i) is >> vv[i];
	return is;
}

struct phash {
	template<class T1, class T2>
    inline size_t operator()(const pair<T1, T2> & p) const {
        auto h1 = hash<T1>()(p.first);
        auto h2 = hash<T2>()(p.second);

		size_t seed = h1 + h2; 
		h1 = ((h1 >> 16) ^ h1) * 0x45d9f3b;
        h1 = ((h1 >> 16) ^ h1) * 0x45d9f3b;
        h1 = (h1 >> 16) ^ h1;
        seed ^= h1 + 0x9e3779b9 + (seed << 6) + (seed >> 2);
		h2 = ((h2 >> 16) ^ h2) * 0x45d9f3b;
        h2 = ((h2 >> 16) ^ h2) * 0x45d9f3b;
        h2 = (h2 >> 16) ^ h2;
        seed ^= h2 + 0x9e3779b9 + (seed << 6) + (seed >> 2);
        return seed;
    }
};





int solve() {
	ll n; cin >> n;
	if (n == 0) return 1;
	ll m; cin >> m;
	vvll g(n, vll(n, -1));
	rep(i, m) {
		ll x, y; cin >> x >> y;
		x--, y--;
		g[x][y] = 1;
		g[y][x] = 0;
	}
	
	auto dfs = [&](auto dfs, vll& st) -> ll {
		if (st.size() == n) return 1;

		ll res = 0;
		rep(rbit, 1LL << (n - 1 - st.size())) {
			ull bit = 0;
			rep(i, st.size()) {
				bit |= (((st[i] >> st.size()) & 1) ^ 1) << i;
			}
			bit |= rbit << (st.size() + 1);

			if (popcount(bit) != (n - 1) / 2) continue;

			bool ok = true;
			rep(i, n) {
				if (g[st.size()][i] == -1) continue;
				if (((bit >> i) & 1) != g[st.size()][i]) {
					ok = false;
					break;
				}
			}
			if (!ok) continue;

			ll sum = 0;
			rep(i, n) {
				if (st.size() == i) continue;
				sum += ((bit >> i) & 1) ? 1 : -1;
			}
			if (sum != 0) continue;

			st.push_back(bit);
			res += dfs(dfs, st);
			st.pop_back();
		}

		return res;
	};
	vll st;
	ll ans = dfs(dfs, st);

	cout << ans << "\n";

	return 0;
}

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

	while (!solve()) { }

	return 0;
}
accuracy: 1
time_ms: 260
memory_kb: 3456
final_rank: 10

code_snippet: #line 1 "2018D.cpp"
#include <bits/stdc++.h>
#line 1 "/home/ardririy/repos/cp-libs/libraries-cpp/input.hpp"


#line 6 "/home/ardririy/repos/cp-libs/libraries-cpp/input.hpp"
using namespace std;
vector<long long> i64_vec_IN(int n) {vector<long long> res(n); for(int i=0; i<n; i++) { cin >> res[i]; } return res; }
vector<string> str_vec_IN(int n) { vector<string> res(n); for(int i=0; i<n; i++) { cin >> res[i]; } return res; }
vector<vector<int>> graph_IN(int n, int m) { vector<vector<int>> g(n); int u, v; for(int i=0; i<m; i++) { cin >> u >> v; u--; v--; g[u].emplace_back(v); g[v].emplace_back(u); } return g; }
vector<vector<pair<int, long long>>> weighted_graph_IN(int n, int m) { vector<vector<pair<int, long long>>> g(n); int u, v; long long w; for(int i=0; i<m; i++) { cin >> u >> v >> w; u--; v--; g[u].push_back({v, w}); g[v].push_back({u, w}); } return g; }


#line 3 "2018D.cpp"

using namespace std;

// using namespace atcoder;

#ifdef ADRY
#include <dbg.h>
#else
// DO NOTHING
#define dbg(...)
#endif


#define all(v) v.begin(),v.end()
#define resort(v) sort(v.rbegin(),v.rend())
using ll = long long;
using ull = unsigned long long;
using vll=vector<ll>;
using vvll = vector<vector<ll>>;
using P = pair<ll,ll>;
using vp=vector<pair<ll, ll>>;
using djks=priority_queue<P, vp, greater<P>>;

const int inf=1ll<<30;
#define mod10 (ll)1e9+7
#define mod99 (ll)998244353
const double PI = acos(-1);

#define rep(i,n) for (ll i=0;i<(n);++i)
#define per(i,n) for(ll i=(n)-1;i>=0;--i)
#define rep2(i,a,n) for (ll i=(a);i<(n);++i)
#define per2(i,a,n) for (ll i=(n)-1;i>=(a);--i)


template<class T>bool chmax(T &a, const T &b) { if (a<b) { a=b; return true; } return false; }
template<class T>bool chmin(T &a, const T &b) { if (b<a) { a=b; return true; } return false; }

ll dx[] = {1, 0, -1, 0, -1, 1, -1, 1};
ll dy[] = {0, 1, 0, -1, -1, 1, 1, -1};

map<vector<int>, ll> memo;
ll dfs(const int n, int i, vector<vector<int>>& state, vector<int>& win_counts) {
    if(memo.find(win_counts) != memo.end()) return memo[win_counts];
    if(n==i) return 1;

    vector<int> idxs;
    int left = 0;
    rep(j,n) {
        if(state[i][j] == 0) idxs.emplace_back(j),  left++;
    }

    int x = n/2;
    if(x < win_counts[i] || x > win_counts[i] + left) {
        return 0;
    }

    vector<int> part(left,2);
    

    rep(j,x-win_counts[i]) {
        part[j] = 1;
    }
    ll res = 0;
    do {
        rep(j,left) {
            state[i][idxs[j]] = part[j];
            state[idxs[j]][i] = (part[j]==1)?2:1;
            if(part[j]==1) {
                win_counts[i]++;
            } else {
                win_counts[idxs[j]]++;
            }

            
        }
        res += dfs(n,i+1,state,win_counts);
        rep(j,left) {
            if(part[j]==1) {
                win_counts[i]--;
            } else {
                win_counts[idxs[j]]--;
            }
            state[i][idxs[j]] = 0;
            state[idxs[j]][i] = 0;
        }
        
    } while(next_permutation(all(part)));
    
    return memo[win_counts] = res;
}

int solve(){
    int n, m;cin>> n;
    if(n==0) return 1;
    cin >> m;
    memo.clear();
    // 0: 未定
    // 1: 勝利
    // 2: 敗北
    vector<vector<int>> state(n,vector<int>(n,0));
    vector<int> lefts(n,0);
    int w,l;
    rep(_,m) {
        cin >> w >> l;
        w--;
        l--;
        state[w][l] = 1;
        state[l][w] = 2;
        lefts[w]++;
    }

    ll ans = dfs(n,0,state,lefts);
    cout << ans << '\n';
    return 0;
}

int main() {
    #ifdef ADRY
    #else
        cin.tie(0);
        ios::sync_with_stdio(false);
    #endif
    while(!solve());
}
accuracy: 1
time_ms: 80
memory_kb: 5168
final_rank: 16

code_snippet: //#pragma GCC optimize("O3")
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define rep(i,n) for (ll i=0;i<(ll)n;i++)
#define rrep(i,n) for (ll i=n-1;i>=(ll)0;i--)
#define loop(i,m,n) for(ll i=m;i<=(ll)n;i++)
#define rloop(i,m,n) for(ll i=m;i>=(ll)n;i--)
#define vl vector<ll>
#define vvl vector<vector<ll>>
#define vdbg(a) rep(ii,a.size()){cout<<a[ii]<<" ";}cout<<endl;
#define vpdbg(a) rep(ii,a.size()){cout<<"{"<<a[ii].first<<","<<a[ii].second<<"} ";}cout<<endl;
#define vvdbg(a) rep(ii,a.size()){rep(jj,a[ii].size()){cout<<a[ii][jj]<<" ";}cout<<endl;}
#define setdbg(a) for(const auto & ii:a){cout<<ii<<" ";}cout<<endl;
#define inf 4000000000000000000LL
#define mod 998244353LL
//#define mod 1000000007LL
#define eps 0.000000001
random_device rnd;// 非決定的な乱数生成器
mt19937 mt(rnd());// メルセンヌ・ツイスタの32ビット版、引数は初期シード

//#include<boost/multiprecision/cpp_int.hpp>
//#define bbi boost::multiprecision::cpp_int
//#include<atcoder/lazysegtree>


//整数同士の累乗の計算をする。
ll power(ll A, ll B) {
	ll result = 1;
	for (ll i=0;i<B;i++){
		result *= A;
	}
	return result;
}

// nのk乗をmodで割った余りを計算
ll power_mod(ll n, ll k){
	long long result = 1;
	while (k > 0){
		if ((k&1) ==1)result=(result*n)%mod;
		n=n*n%mod;
		k >>= 1;
	}
	return result;
}


//受け取った2次元文字の外側に、文字pをコーティングする。
vector<string> pad(vector<string> &s,char p){
	ll h=s.size();
	ll w=s[0].size();
	vector<string> res(h+2,string(w+2,p));
	rep(i,h)rep(j,w)res[i+1][j+1]=s[i][j];
	return res;
}

// Union-Find
struct UnionFind {
	vector<int> par, siz;
	UnionFind(int n) : par(n, -1) , siz(n, 1) { }
	// 根を求める
	int root(int x) {
		if (par[x] == -1) return x;
		else return par[x] = root(par[x]);
	}
	// x と y が同じグループに属するかどうか (根が一致するかどうか)
	bool issame(int x, int y) {
		return root(x) == root(y);
	}
	// x を含むグループと y を含むグループとを併合する
	bool unite(int x, int y) {
		x = root(x), y = root(y);
		if (x == y) return false; 
		if (siz[x] < siz[y]) swap(x, y);
		par[y] = x;
		siz[x] += siz[y];
		return true;
	}
	// x を含むグループのサイズ
	int size(int x) {
		return siz[root(x)];
	}
};


//グリッド問題等用
vl dx={1,0,-1,0};
vl dy={0,1,0,-1};

ll n;
vl wcnt,lcnt;
vvl wl;
ll ans;

void dfs(ll i,ll j){
	if(i==n){
		ans++;
		return;
	}
	if(j==n){
		dfs(i+1,0);
		return;
	}
	if(i==j||wl[i][j]!=0){
		dfs(i,j+1);
		return;
	}

	// iが勝つ場合
	wcnt[i]++;
	lcnt[j]++;
	wl[i][j]=1;
	wl[j][i]=-1;
	if(wcnt[i]<=n/2&&lcnt[j]<=n/2){
		dfs(i,j+1);
	}
	wcnt[i]--;
	lcnt[j]--;
	wl[i][j]=0;
	wl[j][i]=0;

	// jが勝つ場合
	wcnt[j]++;
	lcnt[i]++;
	wl[j][i]=1;
	wl[i][j]=-1;
	if(wcnt[j]<=n/2&&lcnt[i]<=n/2){
		dfs(i,j+1);
	}
	wcnt[j]--;
	lcnt[i]--;
	wl[j][i]=0;
	wl[i][j]=0;
	return;
}

ll solve(){
	
	cin>>n;
	if(n==0){return 1;}
	
	wcnt=vl(n,0);
	lcnt=vl(n,0);
	wl=vvl(n,vl(n,0));
	ans=0;
	
	ll m;
	cin>>m;
	bool f=true;
	rep(i,m){
		ll a,b;
		cin>>a>>b;
		a--,b--;
		wl[a][b]=1;
		wl[b][a]=-1;
		wcnt[a]++;
		lcnt[b]++;
		if(wcnt[a]>n/2)f=false;
		if(lcnt[b]>n/2)f=false;
	}

	if(!f){
		cout<<0<<endl;
		return 0;
	}

	dfs(0,0);
	cout<<ans<<endl;
	return 0;
}

//メイン
int main(){
	while(solve()==0);
	return 0;
}
accuracy: 1
time_ms: 120
memory_kb: 3388
final_rank: 5

code_snippet: #include <bits/stdc++.h>
#include <numeric>
#define FAST_IO
#define OVERRIDE(a, b, c, d, ...) d
#define REP2(i, n) for (i32 i = 0; i < (i32)(n); ++i)
#define REP3(i, m, n) for (i32 i = (i32)(m); i < (i32)(n); ++i)
#define REP(...) OVERRIDE(__VA_ARGS__, REP3, REP2)(__VA_ARGS__)
#define PER2(i, n) for (i32 i = (i32)(n)-1; i >= 0; --i)
#define PER3(i, m, n) for (i32 i = (i32)(n)-1; i >= (i32)(m); --i)
#define PER(...) OVERRIDE(__VA_ARGS__, PER3, PER2)(__VA_ARGS__)
#define ALL(x) begin(x), end(x)
#define LEN(x) (i32)(x.size())
using namespace std;
using u32 = unsigned int;
using u64 = unsigned long long;
using i32 = signed int;
using i64 = signed long long;
using f64 = double;
using f80 = long double;
using pi = pair<i32, i32>;
using pl = pair<i64, i64>;
template <typename T>
using V = vector<T>;
template <typename T>
using VV = V<V<T>>;
template <typename T>
using VVV = V<V<V<T>>>;
template <typename T>
using VVVV = V<V<V<V<T>>>>;
template <typename T>
using PQR = priority_queue<T, V<T>, greater<T>>;
template <typename T>
bool chmin(T &x, const T &y) {
    if (x > y) {
        x = y;
        return true;
    }
    return false;
}
template <typename T>
bool chmax(T &x, const T &y) {
    if (x < y) {
        x = y;
        return true;
    }
    return false;
}
template <typename T>
i32 lob(const V<T> &arr, const T &v) {
    return (i32)(lower_bound(ALL(arr), v) - arr.begin());
}
template <typename T>
i32 upb(const V<T> &arr, const T &v) {
    return (i32)(upper_bound(ALL(arr), v) - arr.begin());
}
template <typename T>
V<i32> argsort(const V<T> &arr) {
    V<i32> ret(arr.size());
    iota(ALL(ret), 0);
    sort(ALL(ret), [&](i32 i, i32 j) -> bool {
        if (arr[i] == arr[j]) {
            return i < j;
        } else {
            return arr[i] < arr[j];
        }
    });
    return ret;
}
#ifdef INT128
using u128 = __uint128_t;
using i128 = __int128_t;
#endif
[[maybe_unused]] constexpr i32 INF = 1000000100;
[[maybe_unused]] constexpr i64 INF64 = 3000000000000000100;
struct SetUpIO {
    SetUpIO() {
#ifdef FAST_IO
        ios::sync_with_stdio(false);
        cin.tie(nullptr);
#endif
        cout << fixed << setprecision(15);
    }
} set_up_io;
void scan(char &x) { cin >> x; }
void scan(u32 &x) { cin >> x; }
void scan(u64 &x) { cin >> x; }
void scan(i32 &x) { cin >> x; }
void scan(i64 &x) { cin >> x; }
void scan(string &x) { cin >> x; }
template <typename T>
void scan(V<T> &x) {
    for (T &ele : x) {
        scan(ele);
    }
}
void read() {}
template <typename Head, typename... Tail>
void read(Head &head, Tail &...tail) {
    scan(head);
    read(tail...);
}
#define CHAR(...)     \
    char __VA_ARGS__; \
    read(__VA_ARGS__);
#define U32(...)     \
    u32 __VA_ARGS__; \
    read(__VA_ARGS__);
#define U64(...)     \
    u64 __VA_ARGS__; \
    read(__VA_ARGS__);
#define I32(...)     \
    i32 __VA_ARGS__; \
    read(__VA_ARGS__);
#define I64(...)     \
    i64 __VA_ARGS__; \
    read(__VA_ARGS__);
#define STR(...)        \
    string __VA_ARGS__; \
    read(__VA_ARGS__);
#define VEC(type, name, size) \
    V<type> name(size);       \
    read(name);
#define VVEC(type, name, size1, size2)    \
    VV<type> name(size1, V<type>(size2)); \
    read(name);

#ifdef DEBUGF
#include "spl/template/debug.hpp"
#else
#define DBG(...) (void)0
#endif

void solve(i32 n) {
    I32(m);
    VV<i32> res(n, V<i32>(n, 0));
    REP(i, m) {
        I32(x, y);
        --x;
        --y;
        res[x][y] = 1;
        res[y][x] = -1;
    }
    V<i32> pcnt(n, 0), mcnt(n, 0);
    REP(i, n) REP(j, n) {
        if (res[i][j] == 1) {
            ++pcnt[i];
        }
        if (res[i][j] == -1) {
            ++mcnt[i];
        }
    }
    i32 ans = 0;
    auto dfs = [&](auto dfs, i32 r, i32 c) -> void {
        DBG(r, c, res);
        if (r == n) {
            ++ans;
            return;
        }
        if (c == n) {
            i32 sum = accumulate(ALL(res[r]), 0);
            if (sum != 0) {
                return;
            }
            dfs(dfs, r + 1, r + 2);
            return;
        }
        if (res[r][c] == 0) {
            if (pcnt[r] < n / 2) {
                res[r][c] = 1;
                res[c][r] = -1;
                ++pcnt[r];
                dfs(dfs, r, c + 1);
                res[r][c] = 0;
                res[c][r] = 0;
                --pcnt[r];
            }
            if (mcnt[r] < n / 2) {
                res[r][c] = -1;
                res[c][r] = 1;
                ++mcnt[r];
                dfs(dfs, r, c + 1);
                res[r][c] = 0;
                res[c][r] = 0;
                --mcnt[r];
            }
        } else {
            dfs(dfs, r, c + 1);
        }
    };
    dfs(dfs, 0, 1);
    cout << ans << endl;
}

int main() {
    while (true) {
        I32(n);
        if (n == 0) {
            break;
        }
        solve(n);
    }
}
accuracy: 1
time_ms: 240
memory_kb: 3584
final_rank: 11

code_snippet: #include <bits/stdc++.h>
using namespace std;
using ll = long long;

// dp[i][vec]: 0..i 番での試合について、勝ち数ベクトルが vec であるような組合せの数


ll solve(int N) {
    int M;
    cin >> M;
    // A[x][y] == 1 -> x wins to y
    vector<vector<int>> A(N, vector<int>(N));
    for (int i = 0; i < M; i++) {
        int x, y;
        cin >> x >> y;
        x--;
        y--;
        A[x][y] = 1;
    }

    // for (int x = 0; x < N; x++) {
    //     for (int y = 0; y < N; y++) {
    //         cerr << A[x][y] << (y < N - 1 ? " ": "\n");
    //     }
    // }

    unordered_map<string, ll> dp;
    dp[string(N - 1, 0)] = 1LL;
    for (int x = 1; x < N; x++) {
        // fix x
        // cerr << "x = " << x << endl;
        unordered_map<string, ll> ndp;
        for (auto [vec, cnt]: dp) {
            // cerr << "vec = [";
            // for (auto v: vec) cerr << int(v) << ", ";
            // cerr << "]" << endl;
            for (int bi = 0; bi < (1 << x); bi++) {
                auto nvec = vec;
                bool flag = true;
                for (int y = 0; y < x; y++) {
                    if (bi >> y & 1) { // x wins to y
                        if (A[y][x] == 1) flag = false;
                        if (x < N - 1) nvec[x]++;
                    } else {
                        if (A[x][y] == 1) flag = false;
                        nvec[y]++;
                    }
                }

                if (!flag) {
                    // cerr << "CANNOT trans" << endl;
                    continue;
                }

                // vec[*] <= (N - 1) / 2 ?
                for (int i = 0; i < N; i++) {
                    if (nvec[i] > (N - 1) / 2) flag = false;
                }
                if (!flag) continue;

                ndp[nvec] += cnt;
            }
        }
        swap(dp, ndp);
    }
    string ans_vec(N - 1, (N - 1) / 2);
    // ans_vec[N - 1] = 0;
    // for (auto [vec, cnt]: dp) {
    //     cerr << "vec = [";
    //     for (auto v: vec) cerr << int(v) << ", ";
    //     cerr << "] -> cnt = " << cnt  << endl;

    // }
    return dp[ans_vec];
}

int main() {
    while (1) {
        int N;
        cin >> N;
        if (N == 0) break;
        ll ans = solve(N);
        cout << ans << endl;
    }
}
accuracy: 1
time_ms: 50
memory_kb: 3548
final_rank: 4

code_snippet: #include <bits/stdc++.h>
using namespace std;
#define ALL(v) (v).begin(), (v).end()
using ll = long long;
#define rep(i,n) for(int i =0;i<(int)(n);i++)

void print(vector<int> a){
    rep(i,a.size()){
        //cout<<a[i] << " ";
    }
    //cout<<endl;
}
void print_pair(vector<pair<int,int>> a){
    for(auto [x,y]:a){
        //cout<<x <<" "<< y<<endl;
    }
}
int toSeisuu(vector<int> a){
    int k=1;
    int res =0;
    rep(i,a.size()){
        res+=a[i]*k;
        k*=10;
        if(a[i]<0){
            print(a);
            return -1;
        }
    }
    return res;
}
int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    int c =0;
    while (true) {
        //cout<<"c+"<<c<<endl;
        c++;
        
        int n,m;
        cin>>n;
        if(n==0)break;
        cin>>m;
        vector<int> x(n,0);
        set<pair<int,int>> playedGame;
        rep(i,m){
            int a,b;
            cin>>a>>b;
            a--;b--;
            //win a
            x[a]++;
            playedGame.insert({min(a,b),max(a,b)});
        }
        // if(c>1)continue;
        // cout<<"a"<<endl;
        vector<pair<int,int>> unplayedGame;
        rep(i,n){
            rep(j,n){
                if(i>=j)continue;
                if(playedGame.count({i,j})!=0)continue;
                unplayedGame.push_back({i,j});
            }
        }
        // cout<<"b2"<<endl;
        vector<pair<int,int>> mae,ushiro;

        int st = unplayedGame.size();
        rep(i,st){
            if(i<(int)(unplayedGame.size())/2){
                mae.push_back(unplayedGame[i]);
            }else{
                ushiro.push_back(unplayedGame[i]);
            }
        }
        // // //cout<<"mae:"<<endl;
        // // print_pair(mae);
        // //cout<<"=="<<endl;
        // print_pair(ushiro);
        // //cout<<"=="<<endl;
        // //cout<<"b"<<endl;
        int ms=mae.size(),us=ushiro.size();
        map<int,int> mp;
        //全列挙
        for(int i =0; i < (1<<ms);i++){
            vector<int> a(n,0);

            rep(k,ms){
                auto [s,t] = mae[k];
                // s wins t
                if(((i>>k)&1)==0){
                    a[s]++;
                }else{
                    a[t]++;
                }
            }
            //整数に変換site mapNIHOZON
            mp[toSeisuu(a)]++;
            //cout<<"=="<<toSeisuu(a)<<endl;
        }
        int ans=0;
        //break
        // //cout<<"x"<<endl;
        for(int i =0; i < (1<<us);i++){
            vector<int> a(n,0);

            
            rep(k,us){
                auto [s,t] = ushiro[k];
                // s wins t
                //cout<<s<<" "<<t<<endl;
                if(((i>>k)&1)==0){
                    a[s]++;
                }else{
                    a[t]++;
                }
            }
            //cout<<"!<=="<<toSeisuu(a)<<endl;
            rep(k,n){
                int p=(n-1)/2;
                int xx=x[k];
                a[k]=p-xx-a[k];
            }
            //整数に変換site mapNIHOZON
            ans+=mp[toSeisuu(a)];
            //cout<<"!=="<<toSeisuu(a)<<endl;
        }
        cout<<ans<<endl;
    }

}
accuracy: 1
time_ms: 70
memory_kb: 4992
final_rank: 15

code_snippet: #include <bits/stdc++.h>
using namespace std;
using ll = long long;
#define rep(i, s, t) for (ll i = s; i < (ll)(t); i++)
#define rrep(i, s, t) for(ll i = (ll)(t) - 1; i >= (ll)(s); i--)
#define all(x) begin(x), end(x)
#define rall(x) rbegin(x), rend(x)

#define TT template<typename T>
TT using vec = vector<T>;
template<class T1, class T2> bool chmin(T1 &x, T2 y) { return x > y ? (x = y, true) : false; }
template<class T1, class T2> bool chmax(T1 &x, T2 y) { return x < y ? (x = y, true) : false; }

struct io_setup {
    io_setup() {
        ios::sync_with_stdio(false);
        std::cin.tie(nullptr);
        cout << fixed << setprecision(15);
    }
} io_setup;

int main(){
    while(1){
        int N;
        cin>>N;
        if(N==0)return 0;
        int M;
        cin>>M;
        vector win(N,vector<int>(N,-1));
        rep(i,0,M){
            int x,y;
            cin>>x>>y;
            x--;
            y--;
            win[x][y]=1;
            win[y][x]=0;
        }
        vector<int>C(N);
        int ans=0;
        auto dfs=[&](auto dfs,int x,int y)-> void {
            if(x==N-1){
                ans++;
                return;
            }
            if(win[x][y]!=0&&C[x]+1<=N/2){
                C[x]++;
                if(y+1==N&&C[x]==N/2)dfs(dfs,x+1,x+2);
                else dfs(dfs,x,y+1);
                C[x]--;
            }
            if(win[x][y]!=1&&C[x]+(N-1-y)>=N/2){
                C[y]++;
                if(y+1==N&&C[x]==N/2)dfs(dfs,x+1,x+2);
                else dfs(dfs,x,y+1);
                C[y]--;
            }
        };
        dfs(dfs,0,1);
        cout<<ans<<endl;
    }
}
accuracy: 1
time_ms: 80
memory_kb: 3584
final_rank: 7

code_snippet: #include <bits/stdc++.h>
using namespace std;
// using mint = modint998244353;
// using mint = modint1000000007;
using ll  = long long;
using ull = unsigned long long;
#define rep(i, n) for(ll i = 0; i < n; i++)
constexpr ll INF = ((1LL << 61) + (1LL << 30) - 1);

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

  while(true) {
    ll n;
    cin >> n;
    if(n == 0) break;
    ll m;
    cin >> m;
    vector<vector<ll>> flag(n, vector<ll>(n, 0));
    // flag[i][j] : i が j に勝利したら 1, 逆なら 2, まだなら 0
    rep(i, m) {
      ll x, y;
      cin >> x >> y;
      x--, y--;
      flag[x][y] = 1;
      flag[y][x] = 2;
    }

    ll tn        = n;
    ll threshold = 7;
    n            = min(n, threshold);

    ll rest_match = 0;
    rep(i, n) for(ll j = i + 1; j < n; j++) rest_match += (flag[i][j] == 0);

    ll ans = 0;
    map<vector<ll>, ll> cnt;
    rep(bit, (1LL << rest_match)) {
      vector<ll> win(tn, 0);
      ll idx       = 0;
      bool pruning = false;
      rep(i, n) {
        for(ll j = i + 1; j < n; j++) {
          if(flag[i][j] == 1) win[i]++;
          else if(flag[i][j] == 2) win[j]++;
          else {
            if((bit >> idx) & 1) win[i]++;
            else win[j]++;
            idx++;
          }
          if(win[i] > tn * (tn - 1) / 2 / tn || win[j] > tn * (tn - 1) / 2 / tn) {
            pruning = true;
            break;
          }
        }
        if(pruning) break;
      }
      if(pruning) continue;

      bool ok = true;
      rep(i, n) ok &= (win[i] == n * (n - 1) / 2 / n);
      if(ok) ans++;
      if(n != tn) cnt[win]++;
    }
    if(tn <= threshold) {
      cout << ans << endl;
      continue;
    }
    // for(auto [vec, c]: cnt) {
    //   rep(i, vec.size()) cerr << vec[i] << " ";
    //   cerr << " : " << c << endl;
    // }

    // n = 9 の時は半分全列挙風に？
    ans        = 0;
    rest_match = 0;
    for(ll i = threshold; i < tn; i++) {
      for(ll j = 0; j < i; j++) {
        rest_match += (flag[i][j] == 0);
      }
    }
    // cerr << "rest_match: " << rest_match << endl;
    rep(bit, (1LL << rest_match)) {
      vector<ll> win(tn, tn * (tn - 1) / 2 / tn);
      ll idx       = 0;
      bool pruning = false;
      for(ll i = threshold; i < tn; i++) {
        for(ll j = 0; j < i; j++) {
          if(flag[i][j] == 1) win[i]--;
          else if(flag[i][j] == 2) win[j]--;
          else {
            if((bit >> idx) & 1) win[i]--;
            else win[j]--;
            idx++;
          }
          if(win[i] < 0 || win[j] < 0) {
            pruning = true;
            break;
          }
        }
        if(pruning) break;
      }
      // if(win[7] == 0 && win[8] == 0) {
      //   rep(i, tn) {
      //     cerr << win[i] << " ";
      //   }
      //   cerr << endl;
      // }
      if(cnt.find(win) != cnt.end()) ans += cnt[win];
    }
    cout << ans << endl;
  }

  return 0;
}
accuracy: 1
time_ms: 270
memory_kb: 3624
final_rank: 12

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

const long long MOD1 = 1000000007;
const long long MOD2 = 998244353;
#define all(v) v.begin(), v.end()
#define rall(a) a.rbegin(), a.rend()
#define fi first
#define se second
#define endl "\n"

#define chmax(x, y) x = max(x, y)
#define chmin(x, y) x = min(x, y)

template <typename T>
using vc = vector<T>; // prioriy_queueに必要なのでここにこれ書いてます
template <typename T>
using vv = vc<vc<T>>;
#define int long long
using ll = long long;
ll INF = 2e18;

#ifdef ONLINE_JUDGE
// ジャッジ環境ではデバッグマクロを無効化
#define debug_x(x) \
    do             \
    {              \
    } while (0)
#define debug_vc(v) \
    do              \
    {               \
    } while (0)
#define debug_vv(v) \
    do              \
    {               \
    } while (0)
#else
// ローカルではデバッグ出力
#define debug_x(x) cout << #x << " = " << (x) << endl
#define debug_vc(v)                    \
    {                                  \
        cout << #v << endl;            \
        ll n = size(v);                \
        rep(i, n) cout << v[i] << ' '; \
        cout << endl;                  \
    } // 一次元配列を出力する
#define debug_vv(v)                                        \
    {                                                      \
        cout << #v << endl;                                \
        ll n = size(v);                                    \
        rep(i, n)                                          \
        {                                                  \
            rep(j, size(v[i])) { cout << v[i][j] << ' '; } \
            cout << endl;                                  \
        }                                                  \
    } // 二次元配列を出力する
#endif

#define rep(i, n) for (ll i = 0; i < (n); ++i)
#define rrep(i, n) for (ll i = 1; i <= (n); ++i)
#define drep(i, n) for (ll i = (n) - 1; i >= 0; --i)
#define nfor(i, s, n) for (ll i = s; i < n; i++)        // i=s,s+1...n-1 ノーマルfor
#define dfor(i, s, n) for (ll i = (s) - 1; i >= n; i--) // s-1スタートでnまで落ちる

using ld = long double;
using bl = bool;

template <class T>
using pq = priority_queue<T, vc<T>>; // 大きい順
template <class T>
using pq_g = priority_queue<T, vc<T>, greater<T>>; // 小さい順

using vl = vc<ll>;
using vvl = vv<ll>;
using vvvl = vv<vl>;
using vvvvl = vv<vvl>;
using vs = vc<string>;
using vvs = vv<string>;
using vb = vc<bl>;
using vvb = vv<bl>;
using vvvb = vv<vb>;
using vld = vc<ld>;
using vvld = vv<ld>;
using vvvld = vv<vld>;
using P = pair<ll, ll>;
using vP = vc<P>;
using vvP = vc<vP>;
using vvvP = vv<vP>;

#define pb push_back

#define YES cout << "Yes" << endl
#define NO cout << "No" << endl
#define YN                     \
    {                          \
        cout << "Yes" << endl; \
    }                          \
    else                       \
    {                          \
        cout << "No" << endl;  \
    } // if(a==b)YN;
#define dame cout << -1 << endl

string dir = "DRUL";   // 第4象限の場合
vl di = {1, 0, -1, 0}; // vl di={1,1,0,-1,-1,-1,0,1};
vl dj = {0, 1, 0, -1}; // vl dj={0,1,1,1,0,-1,-1,-1};

bool out_grid(ll i, ll j, ll h, ll w)
{ // trueならcontinue
    return (!(0 <= i && i < h && 0 <= j && j < w));
}

ll dfs(vl &battleTimes, ll n, vl &win, vP &amariBattle, ll idx, ll amari)
{
    ll winCnt = (n - 1) / 2;
    vl at(n);
    rep(i, n)
    {
        at[i] = winCnt - win[i];
        if (at[i] < 0 || at[i] > n - 1 - battleTimes[i])
        {
            return 0;
        }
    }
    if (amari == 0)
        return 1;
    ll sum = 0;
    auto [i, j] = amariBattle[idx];
    battleTimes[i]++;
    battleTimes[j]++;
    win[j]++;
    sum += dfs(battleTimes, n, win, amariBattle, idx + 1, amari - 1);
    win[j]--;
    win[i]++;
    sum += dfs(battleTimes, n, win, amariBattle, idx + 1, amari - 1);
    win[i]--;
    battleTimes[i]--;
    battleTimes[j]--;
    return sum;
}

bl solve()
{
    ll n;
    cin >> n;
    if (n == 0)
    {
        return 0;
    }
    ll m;
    cin >> m;
    vl win(n);
    vl x(m), y(m);
    // res[i][j] = iがjに勝ったか?(不明なら-1)
    vvl res(n, vl(n, -1));
    vl battleTimes(n);
    rep(i, m)
    {
        cin >> x[i] >> y[i];
        x[i]--;
        y[i]--;
        res[x[i]][y[i]] = 1;
        res[y[i]][x[i]] = 0;
        win[x[i]]++;
        battleTimes[x[i]]++;
        battleTimes[y[i]]++;
    }

    ll amari = n * (n - 1) / 2 - m;
    vP amariBattle;
    rep(i, n)
    {
        rep(j, n)
        {
            if (i >= j)
                continue;
            if (res[i][j] == -1)
            {
                amariBattle.pb({i, j});
            }
        }
    }
    ll winCnt = (n - 1) / 2;
    vl at(n);
    rep(i, n)
    {
        at[i] = winCnt - win[i];
        if (at[i] < 0 || at[i] > n - 1 - battleTimes[i])
        {
            cout << 0 << endl;
            return 1;
        }
    }

    // バックトラック法でやる
    cout << dfs(battleTimes, n, win, amariBattle, 0, amari) << endl;

    // ll ans = 0;
    // rep(i, 1 << amari)
    // {
    //     vvl tmp = res;
    //     rep(j, amari)
    //     {
    //         auto [ii, jj] = amariBattle[j];
    //         if (i & (1 << j))
    //         {
    //             tmp[ii][jj] = 1;
    //             tmp[jj][ii] = 0;
    //         }
    //         else
    //         {
    //             tmp[ii][jj] = 0;
    //             tmp[jj][ii] = 1;
    //         }
    //     }
    //     bl ok = true;
    //     rep(j, n)
    //     {
    //         ll cnt = 0;
    //         rep(k, n)
    //         {
    //             if (tmp[j][k] == 1)
    //             {
    //                 cnt++;
    //             }
    //         }
    //         if (cnt != winCnt)
    //         {
    //             ok = false;
    //             break;
    //         }
    //     }
    //     if (ok)
    //     {
    //         ans++;
    //     }
    // }
    // cout << ans << endl;

    return 1;
}

signed main()
{
    ios_base::sync_with_stdio(false);
    cin.tie(nullptr);
    while (1)
    {
        if (!solve())
            break;
    }
    return 0;
}

/*
shift+alt+Fで成形
f2で変数名変更

スニペット
basic
 m:atcoder以外用
 ma:ABC/ARC用
 mahc:AHC用
math
 floor:床関数
 ceil:天井関数
 comv:二項係数
 modpow: a^b mod m
 GCD:最大公約数
 extGCD:拡張ユークリッド互除法
 PFD:素因数分解
 isprime:エラトステネスの篩
 matrixpow:行列累乗
data_structure
 seg:セグメント木
technic
 Compress:座標圧縮
 runlength:ランレングス圧縮
graph
 warshall:ワーシャルフロイド法
 dfs:深さ優先探索
 bfs:幅優先探索
 LCA:最近共通祖先
*/
accuracy: 1
time_ms: 560
memory_kb: 3380
final_rank: 14

code_snippet: #include <bits/stdc++.h>
#include <unordered_map>
#include <stdlib.h>
using namespace std;
#define rep(i, a, n) for(ll i = a; i < n; i++)
#define rrep(i, a, n) for(ll i = a; i >= n; i--)
#define ll long long
#define pii pair<int, int>
#define pll pair<ll, ll>
#define all(x) (x).begin(), (x).end()
//constexpr ll MOD = 1000000007;
constexpr ll MOD = 998244353;
constexpr int IINF = 1001001001;
constexpr ll INF = 1LL<<60;
template<class t,class u> void chmax(t&a,u b){if(a<b)a=b;}
template<class t,class u> void chmin(t&a,u b){if(b<a)a=b;}


ll gcd(ll a, ll b){
    if(a%b == 0){
      return b;
    }else{
      return gcd(b, a%b);
    }
}

ll lcm(ll a, ll b){
    return a*b / gcd(a, b);
}

ll powMod(ll x, ll n) {
    if (n == 0) return 1 % MOD;
    ll val = powMod(x, n / 2);
    val *= val;
    val %= MOD;
    if (n % 2 == 1) val *= x;
    return val % MOD;
}

int main() {
    while(true){
        ll n; cin >> n;
        if(n == 0) break;
        ll m; cin >> m;
        vector<vector<ll>> win(n,vector<ll>(n, -1));
        rep(i,0,n) win[i][i] = 0;
        rep(i,0,m){
            ll x, y; cin >> x >> y;
            x--;y--;
            win[x][y] = 1;
            win[y][x] = 0;
        }
        ll ans = 0;
        auto solve = [&](auto& solve, ll i, ll j, ll cnt) -> void {
            if(i == n-1){
                ans++;
                return;
            }
            if(i == j){
                solve(solve, i, j+1, cnt);
                return;
            }
            if(j == n-1){
                if(win[i][j] != -1){
                    cnt -= win[i][j];
                    if(cnt == 0) solve(solve, i+1, 0, n/2);
                }else{
                    if(cnt == 1){
                        win[i][j] = 1;
                        win[j][i] = 0;
                        solve(solve, i+1, 0, n/2);
                        win[i][j] = -1;
                        win[j][i] = -1;
                    }else if(cnt == 0){
                        win[i][j] = 0;
                        win[j][i] = 1;
                        solve(solve, i+1, 0, n/2);
                        win[i][j] = -1;
                        win[j][i] = -1;
                    }
                }
                return;
            }
            if(i > j){
                if(win[i][j] != -1){
                    cnt -= win[i][j];
                    if(cnt >= 0) solve(solve, i, j+1, cnt);
                }else{
                    if(cnt > n-j-1) return;
                    if(cnt > 0){
                        win[i][j] = 1;
                        win[j][i] = 0;
                        solve(solve, i, j+1, cnt-1);
                        win[i][j] = -1;
                        win[j][i] = -1;
                    }
                    if(cnt < n-j-1){
                        win[i][j] = 0;
                        win[j][i] = 1;
                        solve(solve, i, j+1, cnt);
                        win[i][j] = -1;
                        win[j][i] = -1;
                    }
                }
            }
            else {
                if(win[i][j] != -1){
                    cnt -= win[i][j];
                    if(cnt >= 0) solve(solve, i, j+1, cnt);
                }else{
                    if(cnt > n-j) return;
                    if(cnt > 0){
                        win[i][j] = 1;
                        win[j][i] = 0;
                        solve(solve, i, j+1, cnt-1);
                        win[i][j] = -1;
                        win[j][i] = -1;
                    }
                    if (cnt < n-j){
                        win[i][j] = 0;
                        win[j][i] = 1;
                        solve(solve, i, j+1, cnt);
                        win[i][j] = -1;
                        win[j][i] = -1;
                    }
                }
            }
        };
        solve(solve, 0, 0, n/2);
        cout << ans << endl;
    }
    return 0;
}
accuracy: 1
time_ms: 90
memory_kb: 3584
final_rank: 8

code_snippet: #include <bits/stdc++.h>
using namespace std;
bool solve();

using ll = long long;
#define rep(i, a, b) for (int i = a; i < (b); ++i)
#define sz(x) (int)(x).size()
#define all(x) x.begin(), x.end()
typedef pair<int, int> pii;
typedef vector<int> vi;
template <class T>
inline bool chmin(T &a, T b) {
  return ((a > b) ? (a = b, 1) : (0));
}
template <class T>
inline bool chmax(T &a, T b) {
  return ((a < b) ? (a = b, 1) : (0));
}

int main() {
  while (solve());
  return 0;
}

bool solve() {
  int n, m;
  cin >> n >> m;
  if (n == 0) return 0;
  vector G(n, vector<bool>(n));
  vi cntl(n, 0);
  vi cntw(n, 0);
  rep(mi, 0, m) {
    int x, y;
    cin >> x >> y;
    x--, y--;
    G[x][y] = G[y][x] = true;
    cntw[x]++;
    cntl[y]++;
  }
  int ans = 0;
  auto dfs = [&](auto dfs, int i, int j) -> void {
    if (j >= n) {
      i++, j = 0;
    }
    if (i >= n) {
      ans++;
      return;
    }
    if (i == j) {
      if (not(cntw[i] > n / 2 or cntl[j] > n / 2 or cntw[j] > n / 2 or
              cntl[i] > n / 2))
        dfs(dfs, i, j + 1);
      return;
    }
    if (G[i][j])
      dfs(dfs, i, j + 1);
    else {
      // i win
      G[i][j] = G[j][i] = true;
      cntw[i]++, cntl[j]++;
      if (not(cntw[i] > n / 2 or cntl[j] > n / 2)) dfs(dfs, i, j + 1);

      cntw[i]--, cntl[j]--;
      G[i][j] = G[j][i] = false;
      // j win
      G[i][j] = G[j][i] = true;
      cntl[i]++, cntw[j]++;
      if (not(cntl[i] > n / 2 or cntw[j] > n / 2)) dfs(dfs, i, j + 1);

      cntl[i]--, cntw[j]--;
      G[i][j] = G[j][i] = false;
    }
  };
  dfs(dfs, 0, 0);
  cout << ans << endl;
  return 1;
}
accuracy: 1
time_ms: 190
memory_kb: 3584
final_rank: 9

code_snippet: #include <bits/stdc++.h>
using namespace std;
#define all(...) std::begin(__VA_ARGS__), std::end(__VA_ARGS__)
#define rall(...) std::rbegin(__VA_ARGS__), std::rend(__VA_ARGS__)
#define OVERLOAD_REP(_1, _2, _3, _4, name, ...) name
#define REP1(n) for(ll i=0;i<n;i++)
#define REP2(i, n) for (ll i=0;i<n;i++)
#define REP3(i, a, n) for (ll i=a;i<n;i++)
#define REP4(i, a, b, n) for(ll i=a;i<n;i+=b)
#define rep(...) OVERLOAD_REP(__VA_ARGS__, REP4, REP3, REP2, REP1)(__VA_ARGS__)
#define OVERLOAD_RREP(_1, _2, _3, _4, name, ...) name
#define RREP1(n) for(ll i=n;i>=0;i--)
#define RREP2(i, n) for(ll i=n;i>=0;i--)
#define RREP3(i, a, n) for(ll i=n;i>=a;i--)
#define RREP4(i, a, b, n) for(ll i=n;i>=a;i-=b)
#define rrep(...) OVERLOAD_RREP(__VA_ARGS__, RREP4, RREP3, RREP2, RREP1)(__VA_ARGS__)
#define foa(a,v)  (auto& a : (v))
#define uniq(a) sort(all(a));a.erase(unique(all(a)),end(a))
#define len(n) (long long)(n).size()
#define pb push_back
using ll = long long;
using ld = long double;
using ull = unsigned long long;
using vi = vector<int>;
using vvi = vector<vi>;
using vvvi = vector<vvi>;
using vll = vector<ll>;
using vvll = vector<vll>;
using vvvll = vector<vvll>;
using vs = vector<string>;
using vvs = vector<vs>;
using vvvs = vector<vvs>;
using vld = vector<ld>;
using vvld = vector<vld>;
using vvvld = vector<vvld>;
using vc = vector<char>;
using vvc = vector<vc>;
using vvvc = vector<vvc>;
using pll = pair<ll,ll>;
using vpll = vector<pll>;
template<class... T>
constexpr auto min(T... a){
    return min(initializer_list<common_type_t<T...>>{a...});
}
template<class... T>
constexpr auto max(T... a){
    return max(initializer_list<common_type_t<T...>>{a...});
}
template<class... T>
void input(T&... a){
    (cin >> ... >> a);
}
ll modpow(ll a,ll b,ll c){
    ll ans = 1;
    while (b){
        if (b & 1){
            ans *= a;
            ans %= c;
        }
        a *= a;
        a %= c;
        b /= 2;
    }
    return ans;
}
#define INT(...) int __VA_ARGS__; input(__VA_ARGS__)
#define LL(...) ll __VA_ARGS__; input(__VA_ARGS__)
#define ULL(...) ull __VA_ARGS__; input(__VA_ARGS__)
#define LD(...) ld __VA_ARGS__; input(__VA_ARGS__)
#define STR(...) string __VA_ARGS__; input(__VA_ARGS__)
#define CHA(...) char __VA_ARGS__; input(__VA_ARGS__)
#define VLL(name,length) vll name(length);rep(i,length){cin >> name[i];}
#define VVLL(name,h,w) vvll name(h,vll(w));rep(i,h)rep(j,w){cin >> name[i][j];}
#define VVVLL(name,a,b,c) vvvll name(a,vvll(b,vll(c)));rep(i,a)rep(j,b)rep(k,c){cin >> name[i][j][k];}
#define VI(name,length) vi name(length);rep(i,length){cin >> name[i];}
#define VVI(name,h,w) vvi name(h,vi(w));rep(i,h)rep(j,w){cin >> name[i][j];}
#define VVVI(name,a,b,c) vvvi name(a,vvll(b,vi(c)));rep(i,a)rep(j,b)rep(k,c){cin >> name[i][j][k];}
#define VLD(name,length) vld name(length);rep(i,length){cin >> name[i];}
#define VVLD(name,h,w) vvld name(h,vld(w));rep(i,h)rep(j,w){cin >> name[i][j];}
#define VVVLD(name,a,b,c) vvvld name(a,vvld(b,vld(c)));rep(i,a)rep(j,b)rep(k,c){cin >> name[i][j][k];}
#define VC(name,length) vc name(length);rep(i,length){cin >> name[i];}
#define VVC(name,h,w) vvc name(h,vc(w));rep(i,h)rep(j,w){cin >> name[i][j];}
#define VVVC(name,a,b,c) vvvc name(a,vvc(b,vc(c)));rep(i,a)rep(j,b)rep(k,c){cin >> name[i][j][k];}
#define VS(name,length) vs name(length);rep(i,length){cin >> name[i];}
#define VVS(name,h,w) vvs name(h,vs(w));rep(i,h)rep(j,w){cin >> name[i][j];}
#define VVVS(name,a,b,c) vvvs name(a,vvs(b,vs(c)));rep(i,a)rep(j,b)rep(k,c){cin >> name[i][j][k];}
#define PLL(name) pll name;cin>>name.first>>name.second;
#define VPLL(name,length) vpll name(length);rep(i,length){cin>>name[i].first>>name[i].second;}

void print(){cout << "\n";}
template<class T, class... Ts>
void print(const T& a, const Ts&... b){cout << a;(cout << ... << (cout << ' ', b));cout << '\n';}
void print(vll x){rep(i,len(x)){cout << x[i];if(i!=len(x)-1){cout << " ";}else{cout << '\n';}}}
void print(vvll x){rep(i,len(x))rep(j,len(x[i])){cout << x[i][j];if(j!=len(x[i])-1){cout << " ";}else{cout << '\n';}}}



void solve(ll n,ll o,vpll a){
    ll m = n*(n-1)/2;
    vvll b(n,vll(n,-1));
    rep(i,o){
        auto [x,y] = a[i];
        x--;
        y--;
        b[x][y] = 1;
        b[y][x] = 0;
    }
    vpll c;
    rep(x,n){
        rep(y,x+1,n){
            c.push_back({x,y});
        }
    }
    map<vector<ll>,ll> mp1,mp2;
    ll l = m/2;
    rep(i,(1<<l)){
        vll temp(n,0);
        ll check = 1;
        rep(j,l){
            auto [x,y] = c[j];
            if((((i >> j) & 1) == 0 && b[x][y] == 1) || (((i >> j) & 1) == 1 && b[x][y] == 0)){
                check = 0;
                break;
            }
            if(((i >> j) & 1) == 0){
                temp[y]++;
            }
            else{
                temp[x]++;
            }
        }
        if(!check){continue;}


        mp1[temp]++;
    }

    l = m - m/2;

    rep(i,(1<<l)){
        vll temp(n,0);
        ll check = 1;
        rep(j,l){
            auto [x,y] = c[j + m/2];
            if((((i >> j) & 1) == 0 && b[x][y] == 1) || (((i >> j) & 1) == 1 && b[x][y] == 0)){
                check = 0;
                break;
            }
            if(((i >> j) & 1) == 0){
                temp[y]++;
            }
            else{
                temp[x]++;
            }
        }
        if(!check){continue;}
        
        mp2[temp]++;
    }
    ll ans = 0;
    for(auto [key,value]:mp1){
        vll temp(n,n/2);
        rep(i,n){
            temp[i] -= key[i];
        }
        
        ans += mp2[temp] * value;
    }
    print(ans);
    return;
}


int main(){
    while(1){
        LL(n);
        if(n == 0){return 0;}
        LL(m);
        VPLL(a,m);
        solve(n,m,a);
        //break;
    }
    
}
accuracy: 1
time_ms: 420
memory_kb: 14208
final_rank: 20

code_snippet: #include <bits/stdc++.h>
using namespace std;
using ll = long long;
#define all(a) a.begin(),a.end()
#define reps(i, a, n) for (int i = (a); i < (int)(n); i++)
#define rep(i, n) reps(i, 0, n)
#define rreps(i, a, n) for (int i = (a); i > (int)(n); i--)
const long long mod = 1000000007;
const long long INF = 1e18;
ll myceil(ll a, ll b) {return (a+b-1)/b;}

int n;
vector<vector<int>> v(9,vector<int> (9));
vector<int> win(9);
vector<int> lose(9);
ll ans;


void f(int a, int b) {
	int na,nb;

	// cout << a << ' ' << b << endl;

	if (a == n-1) {
		rep(i,n) {
			if (win[i] != n/2 || lose[i] != n/2) {
				break;
			} 
			if (i == n-1) ans++;
		}
		return;
	}

	if (b == n-1) {
		na = a+1;
		nb = na+1;
	}
	else {
		na = a;
		nb = b+1;
	}

	// cout << na << ' ' << nb << endl;


	if (v[a][b] == -1) {
		win[a]++;
		lose[b]++;
		if (win[a] <= n/2 && lose[b] <= n/2) f(na,nb);
		win[a]--;
		lose[b]--;

		win[b]++;
		lose[a]++;
		if (win[b] <= n/2 && lose[a] <= n/2) f(na,nb);
		win[b]--;
		lose[a]--;
	}
	else {
		f(na,nb);
	}

	return;
}



void solve() {
	int m;
	cin >> m;
	rep(i,n) {
		rep(j,n) {
			v[i][j] = -1;
		}
	}
	rep(i,9) {
		win[i] = 0;
		lose[i] = 0;
	}

	int a,b;
	rep(i,m) {
		cin >> a >> b;
		a--;
		b--;
		v[a][b] = 1;
		v[b][a] = 0;
		win[a]++;
		lose[b]++;


	}

	ans = 0;

	f(0,1);


	cout << ans << endl;
	return;
}



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

	while (cin >> n && n != 0) {
		solve();
	}
	return 0;
}
accuracy: 1
time_ms: 70
memory_kb: 3340
final_rank: 2

code_snippet: #include <bits/stdc++.h>
using namespace std;
using ll = long long;
#define all(a) a.begin(),a.end()
#define reps(i, a, n) for (int i = (a); i < (int)(n); i++)
#define rep(i, n) reps(i, 0, n)
#define rreps(i, a, n) for (int i = (a); i > (int)(n); i--)
const long long mod = 1000000007;
const long long INF = 1e18;
ll myceil(ll a, ll b) {return (a+b-1)/b;}

int n;
vector<vector<int>> v(9,vector<int> (9));
vector<int> win(9);
vector<int> lose(9);
ll ans;


void f(int a, int b) {
	int na,nb;

	// cout << a << ' ' << b << endl;

	if (a == n-1) {
		ans++;
		return;
	}

	if (b == n-1) {
		na = a+1;
		nb = na+1;
	}
	else {
		na = a;
		nb = b+1;
	}

	// cout << na << ' ' << nb << endl;


	if (v[a][b] == -1) {
		win[a]++;
		lose[b]++;
		if (win[a] <= n/2 && lose[b] <= n/2) f(na,nb);
		win[a]--;
		lose[b]--;

		win[b]++;
		lose[a]++;
		if (win[b] <= n/2 && lose[a] <= n/2) f(na,nb);
		win[b]--;
		lose[a]--;
	}
	else {
		if (win[a] <= n/2 && lose[a] <= n/2 && win[b] <= n/2 && lose[b] <= n/2) {
			f(na,nb);
		}
	}

	return;
}



void solve() {
	int m;
	cin >> m;
	rep(i,n) {
		rep(j,n) {
			v[i][j] = -1;
		}
	}
	rep(i,9) {
		win[i] = 0;
		lose[i] = 0;
	}

	int a,b;
	rep(i,m) {
		cin >> a >> b;
		a--;
		b--;
		v[a][b] = 1;
		v[b][a] = 0;
		win[a]++;
		lose[b]++;


	}

	ans = 0;

	f(0,1);


	cout << ans << endl;
	return;
}



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

	while (cin >> n && n != 0) {
		solve();
	}
	return 0;
}
accuracy: 1
time_ms: 60
memory_kb: 3372
final_rank: 3

code_snippet: // (⁠◕⁠ᴗ⁠◕⁠✿⁠)

// #pragma GCC target("avx2")
#pragma GCC optimize("O3")
#pragma GCC optimize("unroll-loops")
#include <bits/stdc++.h>
#define rep(i, n) for (ll i = 0; i < (n); i++)
#define srep(i, s, n) for (ll i = s; i < (n); i++)
#define len(x) ((int)(x).size())
#define all(x) (x).begin(), (x).end()
using namespace std;
template<typename T> using vc = vector<T>;
template<typename T> using vv = vc<vc<T>>;
template<typename T> using vvv = vv<vc<T>>;
using vi = vc<int>;using vvi = vv<int>; using vvvi = vv<vi>;
using ll = long long;using vl = vc<ll>;using vvl = vv<ll>; using vvvl = vv<vl>;
using ld = long double; using vld = vc<ld>; using vvld = vc<vld>; using vvvld = vc<vvld>;
using uint = unsigned int;
using ull = unsigned long long;
const ld pi = acos(-1.0);
const int inf = 0x3f3f3f3f;
const ll INF = 0x3f3f3f3f3f3f3f3f;
// const ll mod = 1000000007;
const ll mod = 998244353;
inline bool inside(ll y, ll x, ll H, ll W) {return 0 <= (y) and (y) < (H) and 0 <= (x) and (x) < (W); }

#define debug(var)  do{std::cout << #var << " : \n";view(var);}while(0)
template<typename T> void view(T e){cout << e << endl;}
template<typename T> void view(const vc<T>& v){for(const auto& e : v){ cout << e << " "; } cout << endl;}
template<typename T> void view(const vv<T>& vv){ for(const auto& v : vv){ view(v); } }

int N;
int winlose[9 * 9];
int win[9], lose[9];

int f(int i, int j){
    // cout << i << " " << j << endl;
    // rep(ni, N) cout << win[ni] << " ";
    // cout << endl;
    // rep(ni, N) cout << lose[ni] << " ";
    // cout << endl;
    if (i == N - 1) return 1;
    int ret = 0;
    if (winlose[i * N + j] != 0){
        win[i]++;
        lose[j]++;
        if (win[i] <= N / 2 && lose[j] <= N / 2){
            int ni = i, nj = j + 1;
            if (nj == N){
                ni++;
                nj = ni + 1;
            }
            ret += f(ni, nj);
        }
        win[i]--;
        lose[j]--;
    }
    if (winlose[i * N + j] != 1){
        win[j]++;
        lose[i]++;
        if (win[j] <= N / 2 && lose[i] <= N / 2){
            int ni = i, nj = j + 1;
            if (nj == N){
                ni++;
                nj = ni + 1;
            }
            ret += f(ni, nj);
        }
        win[j]--;
        lose[i]--;
    }
    return ret;
}
void solve(){
    int M; cin >> M;
    rep(i, M){
        int x, y; cin >> x >> y; x--; y--;
        if (x < y) winlose[x * N + y] = 1;
        else winlose[y * N + x] = 0;
    }
    cout << f(0, 1) << endl;
}

int main(){
    while (true){
        cin >> N;
        if (N == 0) break;
        rep(i, N * N) winlose[i] = -1;
        rep(i, N){
            win[i] = 0;
            lose[i] = 0;
        }
        solve();
    }
}
accuracy: 1
time_ms: 60
memory_kb: 3316
final_rank: 1

code_snippet: #if !defined(__clang__) && defined(__GNUC__)
#include <bits/stdc++.h>
#pragma GCC optimize("O3,unroll-loops")
#ifdef ONLINE_JUDGE
#pragma GCC target("avx2,fma,popcnt,bmi,bmi2")
#endif
#elif defined(__clang__)
#include <algorithm>
#include <bitset>
#include <cassert>
#include <chrono>
#include <cmath>
#include <complex>
#include <deque>
#include <fstream>
#include <functional>
#include <iomanip>
#include <iostream>
#include <limits>
#include <map>
#include <numeric>
#include <queue>
#include <random>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <tuple>
#include <unordered_map>
#include <unordered_set>
#include <vector>
#else
#error "We don't know this compiler lol"
#endif
#if __has_include(<atcoder/all>)
#include <atcoder/all>
using namespace atcoder;
std::ostream &operator<<(std::ostream &os, const modint998244353 &a) {
    return os << a.val();
}
std::ostream &operator<<(std::ostream &os, const modint1000000007 &a) {
    return os << a.val();
}
std::istream &operator>>(std::istream &is, modint998244353 &a) {
    long long t;
    is >> t;
    a = t;
    return is;
}
std::istream &operator>>(std::istream &is, modint1000000007 &a) {
    long long t;
    is >> t;
    a = t;
    return is;
}
#endif
using namespace std;
// # Type Aliases
using ll = long long;
using ull = unsigned long long;
using ld = long double;
template <class T>
using V = vector<T>;
template <class T, class U>
using P = pair<T, U>;
template <class T>
using max_heap = priority_queue<T>;
template <class T>
using min_heap = priority_queue<T, vector<T>, greater<T>>;
// # Repeat Macros
#define OVERLOADER(_1, _2, _3, NAME, ...) NAME
#define REP2(i, a, b) for (ll i = (a); i < (ll)(b); ++i)
#define REP(i, n) REP2(i, 0, n)
#define rep(...) OVERLOADER(__VA_ARGS__, REP2, REP)(__VA_ARGS__)
#define repd(i, a, b) for (ll i = (ll)(b) - 1; i >= (ll)(a); --i)
// # Abbreviation Macros
#define pb push_back
#define eb emplace_back
#define ALL(a) begin(a), end(a)
#define RALL(a) a.rbegin(), a.rend()
// # Fast IO and IO Settings
struct IO_Setting {
    IO_Setting() {
        cin.tie(nullptr);
        ios_base::sync_with_stdio(false);
        cout << fixed << setprecision(15);
        cerr << fixed << setprecision(3);
    }
} io_setting;
// # Input Overloads
template <class T, class U>
istream &operator>>(istream &is, P<T, U> &p) {
    return is >> p.first >> p.second;
}
template <class T>
istream &operator>>(istream &is, V<T> &v) {
    for (T &e : v) is >> e;
    return is;
}
// # Output Overloads
template <class T, class U>
ostream &operator<<(ostream &os, const P<T, U> &p) {
    return os << p.first << ' ' << p.second;
}
template <class T>
ostream &operator<<(ostream &os, const V<T> &v) {
    int ss = v.size();
    rep(ii, ss) { os << v[ii] << (ii + 1 == ss ? "" : " "); }
    return os;
}
// # Function Definition
template <class T>
T sq(T x) {
    return x * x;
}
template <class T, class U>
inline bool chmin(T &a, U b) {
    if (a > b) {
        a = b;
        return 1;
    }
    return 0;
}
template <class T, class U>
inline bool chmax(T &a, U b) {
    if (a < b) {
        a = b;
        return 1;
    }
    return 0;
}
ll max(ll lhs, ll rhs) { return std::max<ll>(lhs, rhs); }
ll min(ll lhs, ll rhs) { return std::min<ll>(lhs, rhs); }
ll ceil_div(ll a, ll b) { return a / b + ((a ^ b) >= 0 && a % b); }
ll floor_div(ll a, ll b) { return a / b - ((a ^ b) < 0 && a % b); }
template <class Container>
Container reversed(const Container &v) {
    return Container(v.rbegin(), v.rend());
}
template <class Container>
Container sorted(const Container &v, bool rev = false) {
    Container r = v;
    rev ? sort(r.rbegin(), r.rend()) : sort(r.begin(), r.end());
    return r;
}
template <class T>
void uniqify(V<T> &v) {
    v.erase(unique(ALL(v)), v.end());
}
template <class T>
V<T> compress(V<T> &v) {
    V<T> vals = v;
    sort(ALL(vals));
    uniqify(vals);
    rep(i, v.size()) v[i] = lower_bound(ALL(vals), v[i]) - vals.begin();
    return vals;
}
template <class T>
V<T> sum_array(const V<T> &v) {
    int n = v.size();
    V<T> sum(n + 1);
    rep(i, n) sum[i + 1] = sum[i] + v[i];
    return sum;
}
template <class T>
inline void drop(T &&x) {
    cout << x << endl;
    exit(0);
}
inline void yesno(bool f) { cout << (f ? "Yes" : "No") << '\n'; }
// # Constant Definition
constexpr char ENDL = '\n';
constexpr ll INF = (1LL << 30) - 1;    // 問題毎にfit
constexpr ll INFLL = (1LL << 62) - 1;  // 問題毎にfit
const ld PI = acos(static_cast<long double>(-1));
constexpr int dy[] = {0, 1, 0, -1};
constexpr int dx[] = {1, 0, -1, 0};
// constexpr int dy[]={0, 1, 1, 1, 0, -1, -1, -1};
// constexpr int dx[]={1, 1, 0, -1, -1, -1, 0, 1};
// # Debug Macro
#ifdef LOCAL
// #include "CP-library/debug_print.hpp"
// #define debug(...) debug_impl(__LINE__, __VA_ARGS__)
// #define debug_impl(...) debug_print::multi_print(#__VA_ARGS__, __VA_ARGS__)
#include "cpp-dump/cpp-dump.hpp"
#define dump(...) cpp_dump(__VA_ARGS__)
#if __has_include(<atcoder/modint>)
#include <atcoder/modint>
namespace cpp_dump::_detail {
template <int m>
inline std::string export_var(const atcoder::static_modint<m> &mint,
                              const std::string &indent,
                              std::size_t last_line_length,
                              std::size_t current_depth, bool fail_on_newline,
                              const export_command &command) {
    return export_var(mint.val(), indent, last_line_length, current_depth,
                      fail_on_newline, command);
}
template <int m>
inline std::string export_var(const atcoder::dynamic_modint<m> &mint,
                              const std::string &indent,
                              std::size_t last_line_length,
                              std::size_t current_depth, bool fail_on_newline,
                              const export_command &command) {
    return export_var(mint.val(), indent, last_line_length, current_depth,
                      fail_on_newline, command);
}
}  // namespace cpp_dump::_detail
#endif  // __has_include(<atcoder/modint>)
namespace cp = cpp_dump;
CPP_DUMP_SET_OPTION_GLOBAL(max_line_width, 100);
CPP_DUMP_SET_OPTION_GLOBAL(log_label_func, cp::log_label::line());
// CPP_DUMP_DEFINE_EXPORT_OBJECT(Type, properties..., methods...);
#define INLOCALDO(...) \
    do {               \
        __VA_ARGS__    \
    } while (false)
#else
#define debug(...)
#define dump(...)
#define INLOCAL(...)
#endif
// using mint = modint1000000007;
// using mint = modint998244353;

int main() {
    while (true) {
        ll n;
        cin >> n;
        if (n == 0) break;
        ll m;
        cin >> m;
        array<array<int, 9>, 9> res{};
        rep(i, n) rep(j, n) res[i][j] = -1;
        rep(i, m) {
            ll x, y;
            cin >> x >> y;
            x--;
            y--;
            int b = 1;
            if (x > y) swap(x, y), b = 1 - b;
            res[x][y] = b;
        }
        using Arr = array<ll, 9>;
        using mp = map<array<ll, 9>, ll>;
        mp dp;
        ll rem = n * (n - 1) / 2;
        auto ok = [&n, &rem](const Arr& arr) -> bool {
            ll mx = *std::max_element(ALL(arr));
            ll def = 0;
            rep(i, n) def += mx - arr[i];
            return def <= rem;
        };
        dp[{0, 0, 0, 0, 0, 0, 0, 0, 0}] = 1;
        {
            int i = 0, j = 1;
            while (i != n - 1) {
                // dump(i, j, dp.size());
                mp ndp;
                rem--;
                for (auto p : dp) {
                    auto arr = p.first;
                    auto val = p.second;
                    // i が かつ
                    if (res[i][j] != 0) {
                        arr[i]++;
                        if(ok(arr)) ndp[arr] += val;
                        arr[i]--;
                    }
                    // i が j に負ける
                    if (res[i][j] != 1) {
                        arr[j]++;
                        if(ok(arr)) ndp[arr] += val;
                        arr[j]--;
                    }
                }
                swap(ndp, dp);

                j++;
                if (j == n) {
                    i++;
                    j = i + 1;
                }
            }
        }
        ll ans = 0;
        for (auto [key, val] : dp) {
            bool f = true;
            rep(i, n - 1) {
                if(key[i] != key[i+1]) f = false;
            }
            if(f) ans += val;
        }
        cout << ans << endl;
    }
}
accuracy: 1
time_ms: 150
memory_kb: 10428
final_rank: 18