#include <bits/stdc++.h>
std::uniform_int_distribution<std::mt19937::result_type> udist(0, 1);
std::mt19937 rng;
using namespace std;
FILE *in, *out;
int ri() {
  int a;
  fscanf(in, "%d", &a);
  return a;
}
double rf() {
  double a;
  fscanf(in, "%lf", &a);
  return a;
}
char sbuf[100005];
string rstr() {
  char c;
  char* b = sbuf;
  while (c = fgetc(in)) {
    if (c == '\n' || c == 255) break;
    *b++ = c;
  }
  *b = 0;
  return sbuf;
}
long long nod(long long a, long long b) {
  if (a == 1 || b == 1) return 1;
  if (a == 0) return b;
  if (b == 0) return a;
  return nod(b % a, a);
}
vector<int> primes;
void calculatePrimes() {
  primes.push_back(2);
  for (int i = 3; i < 500000; i += 2) {
    bool bFound = false;
    int m = (int)sqrt((float)i);
    for (int j = 1; j < primes.size() && !bFound && primes[j] <= m; j++)
      bFound = ((i % primes[j]) == 0);
    if (!bFound) primes.push_back(i);
  }
}
void traverse(int cv, map<int, vector<int>>& t, vector<int>& v, set<int>& wh) {
  if (wh.find(cv) != wh.end()) return;
  wh.insert(cv);
  traverse(v[cv], t, v, wh);
  for (auto ch : t[cv]) traverse(ch, t, v, wh);
}
int getHead(int cv, vector<int>& v, set<int>& wh, int& numChanges,
            int lastHead) {
  if (wh.find(cv) != wh.end()) {
    if (lastHead == -1) {
      lastHead = cv;
      if (v[cv] != cv) {
        v[cv] = cv;
        numChanges++;
      }
    } else {
      v[cv] = lastHead;
      numChanges++;
    }
    return lastHead;
  }
  wh.insert(cv);
  return getHead(v[cv], v, wh, numChanges, lastHead);
}
int findHead(int cv, vector<int>& v, set<int>& wh) {
  if (wh.find(cv) != wh.end()) return v[cv] == cv;
  wh.insert(cv);
  return findHead(v[cv], v, wh);
}
int main() {
  rng.seed(time(NULL));
  int n;
  cin >> n;
  vector<int> v(n);
  map<int, vector<int>> t;
  int countSelf = 0;
  for (int i = (0); i < (((n))); ++i) {
    cin >> v[i];
    v[i]--;
    t[v[i]].push_back(i);
  }
  vector<set<int>> comp;
  set<int> all;
  for (int i = (0); i < (((n))); ++i) {
    if (all.find(i) == all.end()) {
      set<int> wh;
      traverse(i, t, v, wh);
      comp.push_back(wh);
      all.insert(wh.begin(), wh.end());
    }
  }
  int numChanges = 0;
  for (int i = (0); i < (((comp.size()))); ++i) {
    set<int> wh;
    if (findHead(*comp[i].begin(), v, wh)) {
      if (i != 0) swap(comp[i], comp[0]);
      break;
    }
  }
  int lastHead = -1;
  for (int i = (0); i < (((comp.size()))); ++i) {
    set<int> wh;
    lastHead = getHead(*comp[i].begin(), v, wh, numChanges, lastHead);
  }
  cout << numChanges << endl;
  for (int i = (0); i < (((n))); ++i) {
    cout << v[i] + 1 << " ";
  }
  return 0;
}
