import java.util.Scanner

object Main {
  private val Mod = (1e9 + 7).toInt
  private val Fact = {
    var cur = 1L
    for (i <- 0 to 200000) yield {
      if (i == 0) {
        1
      } else {
        cur = (cur * i) % Mod
        cur
      }
    }
  }
  private val Pow = {
    val pow = new Array[Int](200000)
    pow(0) = 1
    for (i <- 1 until pow.length) pow(i) = pow(i - 1) * 2 % Mod
    pow
  }

  def main(args: Array[String]): Unit = {
    val in = new Scanner(System.in)
    while (true) {
      val n = in.nextInt()
      println(n)
      if (n == 0) {
        return
      }
      val a = for (_ <- 0 until n) yield {
        in.nextInt() - 1
      }
      println(solve(a.toArray))
    }
  }

  def check(parent: Array[Int]): Boolean = {
    val n = parent.length
    var ok = true

    val children = Array.fill[Int](n)(0)
    parent.foreach(parent => children(parent) += 1)
    val dist = Array.fill[Int](n)(-1)
    for (i <- children.indices) if (children(i) == 0) {
      var cur = i
      dist(i) = 0
      var finish = false
      while (!finish) {
        val next = parent(cur)
        if (dist(next) == -1) {
          dist(next) = dist(cur) + 1
          cur = next
        } else if (dist(next) != dist(cur) - 1) {
          ok = false
          finish = true
        } else {
          finish = true
        }
      }
    }

    for (i <- children.indices) if (dist(i) == -1 && parent(parent(i)) != i) {
      ok = false
    }
    ok
  }

  def getSize(array: Array[Int]): (Int, Int) = {
    val N = array.length
    val uf = new UnionFind(N)
    for (i <- array.indices) uf.unite(i, array(i))
    val sizes = for {
      i <- 0 until N
      if i == 0 || !uf.isSame(i, 0)
    } yield {
      if (i == 0) {
        uf.partialSizeOf(i)
      } else {
        val s = uf.partialSizeOf(i)
        uf.unite(i, 0)
        s
      }
    }

    var three = 0
    var two = 0
    sizes.foreach(size => if (size == 2) {
      two += 1
    } else {
      three += 1
    })

    (two, three)
  }

  def solve(array: Array[Int]): Int = {
    val n = array.length
    val combination = new Combination(n + 1, Mod)

    if (check(array)) {
      val (two, three) = getSize(array)
      if (three == 0) {
        var cur: Long = ((two + 2) / 2) % Mod
        cur = cur * Pow(two) % Mod
        cur = cur * Fact(two) % Mod
        cur.toInt
      } else {
        var ans = 0L
        for (i <- 0 to math.min(two + three - 2, two)) {
          var cur = combination.get(two + three - i - 2, two - i).toLong
          cur = cur * Fact(two) % Mod
          cur = cur * Fact(three) % Mod
          cur = cur * Pow(two + three) % Mod
          cur = cur * (two + three - i - 1) % Mod
          cur = cur * ((i + 2) / 2) % Mod
          ans = (ans + cur) % Mod
        }
        for (i <- 0 to math.min(two + three - 1, two)) {
          var cur = combination.get(two + three - i - 1, two - i).toLong
          cur = cur * Fact(two) % Mod
          cur = cur * Fact(three) % Mod
          cur = cur * Pow(two + three) % Mod
          cur = cur * ((i + 2) / 2) % Mod
          ans = (ans + cur * 2) % Mod
        }
        ans.toInt
      }
    } else {
      0
    }
  }
}

class UnionFind(n: Int) {
  private val parent = (0 until n).toArray
  private val sizes = Array.fill[Int](n)(1)
  private var _size = n

  def find(x: Int): Int = {
    if (x == parent(x)) {
      x
    } else {
      parent(x) = find(parent(x))
      parent(x)
    }
  }

  def unite(a: Int, b: Int): Boolean = {
    val fa = find(a)
    val fb = find(b)
    if (fa == fb) {
      false
    } else {
      val (x, y) = if (sizes(fa) >= sizes(fb)) {
        (fa, fb)
      } else {
        (fb, fa)
      }

      parent(y) = x
      sizes(x) += sizes(y)
      sizes(y) = 0

      _size -= 1
      true
    }
  }

  def isSame(x: Int, y: Int): Boolean = find(x) == find(y)

  def partialSizeOf(x: Int): Int = sizes(find(x))

  def size(): Int = _size
}

class Combination(max: Int, mod: Int) {
  private val inv = new Array[Long](max + 1)
  private val fact = new Array[Long](max + 1)
  private val invFact = new Array[Long](max + 1)
  inv(1) = 1
  for (i <- 2 to max) inv(i) = inv(mod % i) * (mod - mod / i) % mod
  fact(0) = 1
  invFact(0) = 1
  for (i <- 1 to max) fact(i) = (fact(i - 1) * i) % mod
  for (i <- 1 to max) invFact(i) = (invFact(i - 1) * inv(i)) % mod

  /**
    * get nCm
    */
  def get(n: Int, m: Int): Int = {
    if (n < m) {
      0
    } else fact(n) * invFact(m) % mod * invFact(n - m) % mod
  }.toInt
}