import Main.{calPattern, choiceAFromN}

object Main extends App {

  import scala.io.StdIn._
  import scala.math._
  implicit val choiceMemo = Array.tabulate(10){i ⇒ Array.tabulate(i + 1){_ ⇒ None: Option[List[List[Boolean]]]}}
  def choiceAFromN(a: Int, n: Int)(implicit memo: Array[Array[Option[List[List[Boolean]]]]]): List[List[Boolean]] = {
    memo(n)(a) match {
      case None if a == 0 ⇒ List(List.tabulate(n){_ ⇒ false}).also{it ⇒ memo(n)(a) = Some(it)}
      case None if a == n ⇒ List(List.tabulate(n){_ ⇒ true}).also{it ⇒ memo(n)(a) = Some(it)}
      case None ⇒ List(choiceAFromN(a - 1, n - 1)(memo).map{it ⇒ true::it}, choiceAFromN(a, n - 1)(memo).map{it ⇒ false::it}).flatten.also{it ⇒ memo(n)(a) = Some(it)}
      case Some(r) ⇒ r
    }
  }
  implicit val memo = Array.tabulate(390625){_ ⇒ None:Option[Long]}
  def solve: Unit ={
    val n = readLine.trim.toInt
    if (n == 0) return
    val m = readLine.trim.toInt
    implicit val scoreGraph = Array.tabulate(n){_ ⇒ Array.tabulate(n){_ ⇒ 0}}
    for (_ ← 0 until m){
      val Array(x, y) = readLine.trim.split(' ').map(_.toInt)
      scoreGraph(x - 1)(y - 1) = 1
      scoreGraph(y - 1)(x - 1) = -1
    }
    implicit val winCount = scoreGraph.map{it ⇒ it.count(_ == 1)}
    implicit val unknownIndices = scoreGraph.indices.map{i ⇒ (i + 1 until scoreGraph.length).filter{idx ⇒ scoreGraph(i)(idx) == 0}.toList}.toArray
    memo.indices.foreach(it ⇒ memo(it) = None)
    println(
      calPattern(scoreGraph.length)
    )
    solve
  }
  solve
  implicit class ExpandList(val value: Array[Int]){
    def toIndex(digit: Int): Int = value.tail.foldLeft(0){case (a, b) ⇒ a * digit + b}
  }
  def calPattern(length:Int , team: Int = 0)(implicit winCount: Array[Int], unknownIndices: Array[List[Int]], memo: Array[Option[Long]]): Long = {
    if (team == length) {
      1L
    }
    else if (winCount.forall(it ⇒ it <= length / 2)){
      memo(winCount.toIndex(length / 2 + 1)) match {
        case None ⇒ {
          val unknown = unknownIndices(team)
          val win = winCount(team)
          if (unknown.length + win < length / 2 || winCount.exists(it ⇒ it > length / 2)) {
            0L
          }
          else {
            var sum = 0L
            for (pattern ← choiceAFromN(length / 2 - win, unknown.length)) {
              unknown.zip(pattern).foreach{
                case (i, false) ⇒ winCount(i) += 1
                case (i, true) ⇒
              }
              sum += calPattern(length, team + 1)
              unknown.zip(pattern).foreach{
                case (i, false) ⇒ winCount(i) -= 1
                case _ ⇒
              }
            }
            memo(winCount.toIndex(length / 2 + 1)) = Some(sum)
            sum
          }
        }
        case Some(r) ⇒ r
      }
    }else 0L
  }

  implicit class Extenion[T](val value :T){
    def also(func: T ⇒ Unit): T = {
      func(value)
      value
    }
    def let[R](func: T ⇒ R): R = func(value)
  }
}
/*
https://onlinejudge.u-aizu.ac.jp/challenges/sources/JAG/Prelim/2884
 */

