#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
#include <stack>
#include <queue>
#include <cmath>
#include <tuple>
#include <cstdio>
#include <bitset>
#include <sstream>
#include <iterator>
#include <numeric>
#include <map>
#include <cstring>
#include <set>
#include <functional>
#include <iomanip>

using namespace std;

//#define DEBUG_ //!!$BDs=P;~$K%3%a%s%H%"%&%H(B!!
#ifdef DEBUG_
#define dump(x)  cerr << #x << " = " << (x) << endl;
#else
#define dump(x)  ;
#endif

#define equals(a,b) (fabs((a)-(b)) < EPS)
#define FOR(i,a,b) for(int i=(a);i<(b);++i)
#define REP(i,n)  FOR(i,0,n)
#define SZ(x) ((int)(x).size())
#define pb push_back
#define eb emplace_back

//#define int long long

typedef long long LL;
typedef vector<int> VI;
typedef vector<LL> VL;
typedef vector<VI> VVI;
typedef vector<string> VS;
typedef pair<int, int> PII;
typedef pair<LL, LL> PLL;

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

    template <typename T>
std::string printVector(const std::vector<T> &data)
{
    std::stringstream ss;
    std::ostream_iterator<T> out_it(ss, ", ");
    ss << "[";
    std::copy(data.begin(), data.end() - 1, out_it);
    ss << data.back() << "]";
    return ss.str();
}

template <typename T>
void print_array(const T &ary, int size){
    REP(i,size){
        cout << ary[i] << " ";
    }
    cout << endl;
}

const int mod = 1e9+7;
const LL LINF = 1001002003004005006ll;
const int INF = 1001001001;
const double EPS = (1e-10);
const long double PI = 3.14159265358979323846264338327950288419716939937510582097494459230781640628620899;
int dx[] = {0,0,-1,1};
int dy[] = {-1,1,0,0};

struct UnionFind {
    vector< int > data;

    UnionFind(int sz) {
        data.assign(sz, -1);
    }

    bool unite(int x, int y) {
        x = find(x), y = find(y);
        if(x == y) return (false);
        if(data[x] > data[y]) swap(x, y);
        data[x] += data[y];
        data[y] = x;
        return (true);
    }

    int find(int k) {
        if(data[k] < 0) return (k);
        return (data[k] = find(data[k]));
    }

    int size(int k) {
        return (-data[find(k)]);
    }
};

struct mint {
    LL x; // typedef long long LL;
    mint(LL x=0):x( x >= 0 ? x%mod : x%mod+mod){}
    mint& operator+=(const mint a) {
        if ((x += a.x) >= mod) x -= mod;
        return *this;
    }
    mint& operator-=(const mint a) {
        if ((x += mod-a.x) >= mod) x -= mod;
        return *this;
    }
    mint& operator*=(const mint a) {
        (x *= a.x) %= mod;
        return *this;
    }
    mint operator+(const mint a) const {
        mint res(*this);
        return res+=a;
    }
    mint operator-(const mint a) const {
        mint res(*this);
        return res-=a;
    }
    mint operator*(const mint a) const {
        mint res(*this);
        return res*=a;
    }
    mint pow(LL t) const {
        if (!t) return 1;
        mint a = pow(t>>1);
        a *= a;
        if (t&1) a *= *this;
        return a;
    }

    // for prime mod
    mint inv() const {
        return pow(mod-2);
    }
    mint& operator/=(const mint a) {
        return (*this) *= a.inv();
    }
    mint operator/(const mint a) const {
        mint res(*this);
        return res/=a;
    }
};

signed main(int argc, char const *argv[])
{
    cin.tie(0);
    ios::sync_with_stdio(false);
    cout << setprecision(12);
    int N; cin >> N;
    UnionFind uf(N);
    set<int> se; // 既に閉路ができたグループ
    set<int> true_se;
    VI P(N);
    LL K = 0;
    REP(i,N) {
        cin >> P[i];
        P[i]--;
        if(P[i] != -2){
            if(uf.find(i) == uf.find(P[i])){
                uf.unite(i,P[i]);
                se.insert(uf.find(i));
            }else{
                int x = uf.find(i);
                int y = uf.find(P[i]);
                if(se.find(x) != se.end()){
                    uf.unite(i,P[i]);
                    se.insert(uf.find(i));
                    se.insert(uf.find(P[i]));
                }else if(se.find(y) != se.end()){
                    uf.unite(i,P[i]);
                    se.insert(uf.find(i));
                    se.insert(uf.find(P[i]));
                }else{
                    uf.unite(i,P[i]);
                }
            }
        }else{
            K += 1;
        }
    }
    dump(K)
    dump("set")
    //for(int x : se){
    //    cout << x << " ";
    //}
    //cout << endl;
    map<int,LL> mp; //まだ閉路がないグループの連結成分数
    REP(i,N){
        int t = uf.find(i);
        if(se.find(t) == se.end()) {
            mp[t]++;
        }else{
            true_se.insert(t);
        }
    }
    VL num;
    int sz = 0;
    for(auto p : mp){
        sz++;
        num.eb(p.second);
    }
    dump(sz)
    vector<vector<mint>> dp(sz+1,vector<mint>(sz+1));
    dp[0][0] = 1;
    for(int i = 0; i < sz; i++){
        for(int j = 0; j <= i; j++){
            dp[i+1][j] += dp[i][j];
            dp[i+1][j+1] += dp[i][j] * num[i];
        }
    }
    for(int i = 1; i <= sz; i++){ //1個だけ選ぶときの補正
        dp[i][1] -= i;
    }

    mint ans = mint(N) * mint(N-1).pow(K); // 全体
    ans -= mint(SZ(true_se)) * mint(N-1).pow(K); // 確定ループ
    //if(K == 0){
    //    dump("out")
    //    cout << ans.x << endl;
    //    return 0;
    //}

    mint fact = 1;
    for(int j = 1; j <= sz; j++){
        dump(j)
        if(j != 1) fact *= (j-1);
        mint base = fact * mint(N-1).pow(K-j);
        ans -= base * dp[sz][j];
    }
    cout << ans.x << endl;


}

Measured memory_bytes: 199352