PrincetonPLI/LongProc huggingface dataset:
[TASK]:
You will be given lines of pseudocode, your task is to write the corresponding C++ code. The pseudocode will provide detailed description of the c++ code line by line. The pseudocode is garanteed to be correct and complete.

[INSTRUCTION]:
The following libraries are already included in the code.
```cpp
#include <cstdio>
#include <iostream>
#include <vector>
#include <algorithm>
#include <numeric>
#include <cmath>
#include <cstring>
#include <set>
#include <map>
#include <queue>
#include <stack>
#include <list>
#include <fstream>
#include <climits>
#include <cassert>
#include <iomanip>
#include <sstream>
#include <bitset>
using namespace std;
```
Do not include them in your code again. Please surround your code with ```cpp and ``` markers. Note that the code should correspond to the pseudocode line by line.

[PSEUDOCODE]:
declare integer p and 2d array of integers dp with size 2005 by 2005
void function helper
    set first sizeof(dp) bytes at the pointer dp to 0
    for i from 0 to p exclusive, change dp[i][0] to 1
    for x from 1 to p exclusive
        for i = 1 to p exclusive, set dp[x][i] to ((dp[x][i - 1]) * x) % p
    end of the block
end of the block
isPrimeRoot is a bool function with int argument x
    declare int curr = 0
    for k from 0 to p - 2 exclusive
        add dp[x][k] to curr
        return false if curr % p = 0
    end of the block
    set curr to curr + dp[x][p - 2]
    return false if curr % p != 0
    return true
end of the block
integer function solve
    if p is equal to 2, return 1
    call helper()
    create integer ans = 0
    change x from 1 to p exclusive in a loop
        if isPrimeRoot(x) returned true, increment ans
    end of the block
    return ans
end of the block
define the main function
    read p
    declare integer ans = result of the solve()
    print ans
    return to indicate successful execution
end of the block

[CODE]:

int p, dp[2005][2005];
void helper() {
    memset(dp, 0, sizeof(dp));
    for (int i = 0; i < p; i++) { dp[i][0] = 1; }
    for (int x = 1; x < p; x++) {
        for (int i = 1; i < p; i++) { dp[x][i] = ((dp[x][i - 1]) * x) % p; }
    }
}
bool isPrimeRoot(int x) {
    int curr = 0;
    for (int k = 0; k < p - 2; k++) {
        curr += dp[x][k];
        if (curr % p == 0) { return false; }
    }
    curr = curr + dp[x][p - 2];
    if (curr % p != 0) { return false; }
    return true;
}
int solve() {
    if (p == 2) return 1;
    helper();
    int ans = 0;
    for (int x = 1; x < p; x++) {
        if (isPrimeRoot(x)) { ans++; }
    }
    return ans;
}
int main() {
    cin >> p;
    int ans = solve();
    cout << ans << endl;
    return 0;
}