3
2 1 1
 6
6 2 6 2 4 2
 2
1 2
 8
2 1 2 2 6 5 6 6
 18
2 3 4 5 2 7 8 9 10 7 11 12 14 15 13 17 18 18
 7
1 2 3 4 5 6 7
 7
4 3 2 6 3 5 2
 7
7 5 3 1 2 1 5
 7
1 6 4 4 5 6 7

1
2 2 1  0
6 2 6 2 4 2  1 
1 1 
 2 
2 2 2 2 6 2 6 6 
 5 
2 3 4 5 11 7 8 9 10 11 11 11 14 15 11 17 18 11 
 6 
1 1 1 1 1 1 1 
 1
4 3 3 6 3 5 2  1
7 5 3 1 3 1 5  4 
1 6 4 1 1 1 1 

#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using ull = unsigned long long;
constexpr int TEN(int n) { return (n == 0) ? 1 : 10 * TEN(n - 1); }
struct UnionFind {
  vector<int> ig;
  vector<vector<int>> gi;
  int gn;
  UnionFind(int N) {
    ig.resize(N);
    gi.resize(N);
    for (int i = 0; i < N; i++) {
      ig[i] = i;
      gi[i] = {i};
    }
    gn = N;
  }
  void merge(int a, int b) {
    if (same(a, b)) return;
    gn--;
    int x = ig[a], y = ig[b];
    if (gi[x].size() < gi[y].size()) swap(x, y);
    for (int j : gi[y]) {
      ig[j] = x;
    }
    gi[x].insert(gi[x].end(), gi[y].begin(), gi[y].end());
    gi[y].clear();
  }
  bool same(int a, int b) { return ig[a] == ig[b]; }
};
const int MN = 200200;
int n;
int a[MN];
bool used[MN];
int par(int p) {
  if (used[p]) return p;
  used[p] = true;
  return par(a[p]);
}
int main() {
  scanf("%d", &n);
  for (int i = 0; i < n; i++) {
    scanf("%d", a + i);
    a[i]--;
  }
  int ans = 0;
  int rt = -1;
  for (int i = 0; i < n; i++) {
    if (a[i] == i) rt = i;
  }
  if (rt == -1) {
    rt = par(0);
    ans++;
    a[rt] = rt;
    fill_n(used, MN, false);
  }
  UnionFind uf(n);
  for (int i = 0; i < n; i++) {
    uf.merge(i, a[i]);
  }
  for (int i = 0; i < n; i++) {
    if (uf.same(rt, i)) continue;
    int nw = par(i);
    ans++;
    a[nw] = rt;
    uf.merge(rt, i);
  }
  printf("%d\n", ans);
  for (int i = 0; i < n; i++) {
    printf("%d ", a[i] + 1);
  }
  printf("\n");
  return 0;
}
