#include <bits/stdc++.h>
using namespace std;
struct compare {
  bool operator()(const int& l, const int& r) { return l > r; }
};
struct Custom_Class {
 public:
  string name;
  int temp;
  Custom_Class(string n, int t) {
    name = n;
    temp = t;
  }
};
struct ccompare {
  bool operator()(const Custom_Class& abc, const Custom_Class& def) {
    return abc.temp > def.temp;
  }
};
priority_queue<Custom_Class, vector<Custom_Class>, ccompare> cpq;
vector<long int> prime;
bool not_prime[10001];
void sieve() {
  memset(not_prime, true, sizeof(not_prime));
  not_prime[0] = false;
  not_prime[1] = false;
  for (long int i = 2; i * i < 10001; i++) {
    if (not_prime[i] == true) {
      for (long int j = i * 2; j < 10001; j += i) {
        not_prime[j] = false;
      }
    }
  }
  for (long int i = 2; i < 10001; i++) {
    if (not_prime[i] == true) prime.push_back(i);
  }
}
vector<int> edge[10010];
bool visited[10010];
void bfs(int s) {
  queue<int> q;
  q.push(s);
  visited[s] = true;
  while (!q.empty()) {
    int u = q.front();
    q.pop();
    for (int i = 0; i < edge[u].size(); i++) {
      int v = edge[u][i];
      if (!visited[v]) {
        visited[v] = true;
        q.push(v);
      }
    }
  }
}
int main() {
  ios_base::sync_with_stdio(0);
  cin.tie(0);
  int n, m, x, y;
  while (cin >> n) {
    for (int i = 1; i <= n; i++) {
      cin >> x;
      edge[i].push_back(x);
      edge[x].push_back(i);
    }
    memset(visited, false, sizeof visited);
    int ans = 0;
    for (int i = 1; i <= n; i++) {
      if (!visited[i]) {
        bfs(i);
        ans++;
      }
    }
    cout << ans << endl;
  }
  return 0;
}
