#include <bits/stdc++.h>
using namespace std;
vector<int> pset[3];
void initSet(int N, int ind) {
  pset[ind].assign(N, 0);
  for (int i = 0; i < N; i++) pset[ind][i] = i;
}
int findSet(int i, int ind) {
  return (pset[ind][i] == i) ? i : (pset[ind][i] = findSet(pset[ind][i], ind));
}
bool isSameSet(int i, int j, int ind) {
  return findSet(i, ind) == findSet(j, ind);
}
void unionSet(int i, int j, int ind) {
  pset[ind][findSet(i, ind)] = findSet(j, ind);
}
vector<unsigned long long> nextrow(vector<unsigned long long> row) {
  vector<unsigned long long> res(row.size() + 1);
  res[0] = 1;
  for (int i = 1; i < res.size() - 1; i++)
    res[i] = (row[i - 1] + row[i]) % 1000000007;
  res[res.size() - 1] = 1;
  return res;
}
unsigned long long bell[4100];
int main() {
  int N;
  cin >> N;
  bell[0] = 1;
  vector<unsigned long long> row;
  row.push_back(1);
  for (int i = 1; i < N; i++) {
    unsigned long long res = 0;
    for (int j = 0; j < row.size(); j++)
      res = (res + (row[j] * bell[j] % 1000000007)) % 1000000007;
    bell[i] = res;
    row = nextrow(row);
  }
  row = nextrow(row);
  unsigned long long res = 0;
  for (int j = 0; j < row.size() - 1; j++)
    res = (res + (row[j] * bell[j] % 1000000007)) % 1000000007;
  cout << res;
}
