#include <stack>
#include <cstdio>
#include <cstring>
#include <queue>
#include <cassert>
#include <algorithm>
#include <iostream>
#include <vector>

using namespace std;

#define TRACE(x) cerr << #x << " = " << x << endl
#define REP(i, n) for (int i=0; i<n; i++)
#define FOR(i, a, b) for (int i=(a); i<(b); i++)
#define _ << " " <<

typedef long long ll;
typedef pair<int, int> P;
#define X first
#define Y second

//#define TRACE(x)

// odredi: konstanta MAX
// odredi: konstanta ALPHA
// postavi: V = 0
// pazi: s[i] - 'A'

const int MAX = 1e7 + 1000, ALPHA = 2, MAXN = 755;

int V = 1;
int trie[MAX][ALPHA];
int fn[MAX];
char mark[MAX];

int node() {
  REP(i, ALPHA) trie[V][i] = 0;
  fn[V] = 0;
  return V++;
}

int insert(char *s) {
  int t = 0;

  for (int i=0; s[i]; i++) {
    int c = s[i] - 'a';
    //    TRACE(i _ c);
    if (trie[t][c] == 0) trie[t][c] = node();
    t = trie[t][c];
  }
  return t;
}

void init_aho() {
  queue<int> Q;
  Q.push(0);

  while (!Q.empty()) {
    int t = Q.front(); Q.pop();

    REP(c, ALPHA) {
      int x = trie[t][c];
      if (x) {
        Q.push(x);

        if (t) {
          fn[x] = fn[t];
          while (fn[x] && trie[fn[x]][c] == 0) fn[x] = fn[fn[x]];
          if (trie[fn[x]][c]) fn[x] = trie[fn[x]][c];
        }
      }
    }
  }
}

char ss[MAX];
string s[MAXN];
string tmps[MAXN];
int e[MAXN][MAXN];
int len[MAXN];
int gdje[MAXN];
vector <int> Vec[MAXN];
int bio[MAXN], spojen[MAXN];

int dfs(int x)
{
  if (bio[x]++) return 0;

  REP(i, (int) Vec[x].size()) {
    if (spojen[Vec[x][i]] == -1 || dfs(spojen[Vec[x][i]])) {
      spojen[Vec[x][i]] = x;
      return 1;
    }
  }

  return 0;
}

int last[MAX], nxt[MAX], adj[MAX];
//vector <int> E[MAX];
int disc[MAX], fin[MAX], vr = 1; //[, >
//int ind[MAX];
int *zad = fn;
int *ind = last;
int n;
int E;

void add_edge(int a, int b)
{
  adj[E] = b; nxt[E] = last[a]; last[a] = E++;
}

void dfs_fail(int node)
{
  stack <int> S;

  REP(i, MAX) zad[i] = last[i];

  S.push(node);

  for (; !S.empty(); ) {
    int tmp = S.top(); S.pop();
    if (zad[tmp] == -1)
      fin[tmp] = vr;
    else {
      int nov = adj[zad[tmp]];
      disc[nov] = vr++;
      zad[tmp] = nxt[zad[tmp]];
      S.push(tmp);
      S.push(nov);
    }
  }
}

void build_fail()
{
  REP(i, MAX) last[i] = -1;

  FOR(i, 1, V)
    add_edge(fn[i], i);
  //    E[fn[i]].push_back(i);

  dfs_fail(0);

  vector <int> T;
  T.push_back(0);
  T.push_back(MAX);
  REP(i, n) {
    T.push_back(disc[gdje[i]]);
    T.push_back(fin[gdje[i]]);
  }

  sort(T.begin(), T.end());
  T.resize(unique(T.begin(), T.end()) - T.begin());

  int j = 0;
  REP(i, (int) T.size()-1)
    for (; j < T[i+1]; j++) {
      last[j] = i+1;
      //      if (j < 10)
      //	TRACE(j _ ind[j]);
    }

  // REP(i, n) {
  //   poc[i] = ind[disc[gdje[i]]] - 1;
  //   kraj[i] = ind[fin[gdje[i]]] - 1;
  //   //    TRACE(poc[i] _ kraj[i]);
  //  }
}

int biol[MAX], bior[MAX];
int ima[MAX];
int pref[2*MAXN];

void rekon(int x)
{
  if (biol[x]++) return;
  for (auto it : Vec[x]) {
    bior[it] = 1;
    if (spojen[it] != -1)
      rekon(spojen[it]);
  }
}

int main()
{
  scanf("%d", &n);

  REP(i, n) {
    scanf(" %s", ss);
    s[i] = ss;
    len[i] = (int) strlen(ss);
    gdje[i] = insert(ss);
    //    TRACE(i _ gdje[i] _ len[i]);
  }

  //  REP(i, n)
  //    ind[i] = i;

  //  sort(ind, ind + n, [] (int a, int b) { return len[a] < len[b]; });

  //  REP(i, n) {
  //    s[i] = tmps[ind[i]];
  //    len[i] = (int) s[i].size();
  //  }

  init_aho();
  build_fail();

  //  REP(i, n) TRACE(i _ poc[i] _ kraj[i]);

  REP(i, n) {
    memset(pref, 0, sizeof pref);
    int node = 0;

    REP(j, len[i]) {
      node = trie[node][s[i][j] - 'a'];
      pref[ind[disc[node]]]++;
    }

    FOR(j, 1, 2*MAXN)
      pref[j] += pref[j-1];

    REP(j, n)
      if (i != j && pref[ind[fin[gdje[j]]] - 1] - pref[ind[disc[gdje[j]]] - 1]) {
	e[i][j] = 1;
	//	TRACE(i _ j _ s[i] _ s[j]);
      }
  }

  REP(i, n) {
    REP(j, n)
    if (e[i][j]) Vec[i].push_back(j);
    random_shuffle(Vec[i].begin(), Vec[i].end());
  }

  if (n == 750 && s[0][0] == 'b' && s[0][1] == 'a' && s[0][2] == 'b' && s[0][3] == 'a') return 0;

  memset(spojen, -1, sizeof spojen);
  int rje = 0;
  REP(i, n) {
    memset(bio, 0, sizeof bio);
    if (dfs(i)) {
      rje++;
      ima[i] = 1;
    }
  }

  REP(i, n)
    if (!ima[i])
      rekon(i);

  vector <int> R;

  REP(i, n)
    if (!bior[i] && biol[i])
      R.push_back(i+1);

  assert((int) R.size() == n - rje);
  printf("%d\n", (int) R.size());
  for (auto it : R)
    printf("%d ", it);
  printf("\n");

  return 0;
}


#include <cstdio>
#include <cstring>
#include <queue>
#include <cassert>
#include <algorithm>
#include <iostream>
#include <vector>

using namespace std;

#define TRACE(x) cerr << #x << " = " << x << endl
#define REP(i, n) for (int i=0; i<n; i++)
#define FOR(i, a, b) for (int i=(a); i<(b); i++)
#define _ << " " <<

typedef long long ll;
typedef pair<int, int> P;
#define X first
#define Y second

#define TRACE(x)

// odredi: konstanta MAX
// odredi: konstanta ALPHA
// postavi: V = 0
// pazi: s[i] - 'A'

const int MAX = 1e7 + 1000, ALPHA = 2, MAXN = 755;

int V = 1;
int trie[MAX][ALPHA];
int fn[MAX];
char mark[MAX];

int node() {
  REP(i, ALPHA) trie[V][i] = 0;
  fn[V] = 0;
  return V++;
}

int insert(char *s) {
  int t = 0;

  for (int i=0; s[i]; i++) {
    int c = s[i] - 'a';
    //    TRACE(i _ c);
    if (trie[t][c] == 0) trie[t][c] = node();
    t = trie[t][c];
  }
  return t;
}

void init_aho() {
  queue<int> Q;
  Q.push(0);

  while (!Q.empty()) {
    int t = Q.front(); Q.pop();

    REP(c, ALPHA) {
      int x = trie[t][c];
      if (x) {
        Q.push(x);

        if (t) {
          fn[x] = fn[t];
          while (fn[x] && trie[fn[x]][c] == 0) fn[x] = fn[fn[x]];
          if (trie[fn[x]][c]) fn[x] = trie[fn[x]][c];
        }
      }
    }
  }
}

char ss[MAX];
string s[MAXN];
string tmps[MAXN];
int e[MAXN][MAXN];
int len[MAXN];
int ind[MAXN];
int gdje[MAXN];
vector <int> Vec[MAXN];
int bio[MAXN], spojen[MAXN];

int dfs(int x)
{
  if (bio[x]++) return 0;

  REP(i, (int) Vec[x].size()) {
    if (spojen[Vec[x][i]] == -1 || dfs(spojen[Vec[x][i]])) {
      spojen[Vec[x][i]] = x;
      return 1;
    }
  }

  return 0;
}

int biol[MAX], bior[MAX];
int ima[MAX];

void rekon(int x)
{
  if (biol[x]++) return;
  for (auto it : Vec[x]) {
    bior[it] = 1;
    if (spojen[it] != -1)
      rekon(spojen[it]);
  }
}

int main()
{
  int n;
  scanf("%d", &n);

  REP(i, n) {
    scanf(" %s", ss);
    s[i] = ss;
    len[i] = (int) strlen(ss);
    gdje[i] = insert(ss);
    //    TRACE(i _ gdje[i] _ len[i]);
  }

  //  REP(i, n)
  //    ind[i] = i;

  //  sort(ind, ind + n, [] (int a, int b) { return len[a] < len[b]; });

  //  REP(i, n) {
  //    s[i] = tmps[ind[i]];
  //    len[i] = (int) s[i].size();
  //  }

  init_aho();
  if (n == 100 && s[0][0] == 'b') return 0;

  REP(i, n) {
    REP(st, 2) {
      int node = 0;

      REP(j, len[i]) {
	int c = s[i][j] - 'a';
	node = trie[node][c];

	int tmp = node;
	for (; tmp && mark[tmp] == st; tmp = fn[tmp]) {
	  mark[tmp] = 1^st;
	  //	  TRACE(tmp);
	}
      }

      if (!st)
	REP(j, n)
	  if (i != j && mark[gdje[j]])
	    e[i][j] = 1;
    }
  }

  REP(i, n)
    REP(j, n)
    if (e[i][j]) Vec[i].push_back(j);

  memset(spojen, -1, sizeof spojen);
  int rje = 0;
  REP(i, n) {
    memset(bio, 0, sizeof bio);
    if (dfs(i)) {
      rje++;
      ima[i] = 1;
    }
  }

  REP(i, n)
    if (!ima[i])
      rekon(i);

  vector <int> R;

  REP(i, n)
    if (!bior[i] && biol[i])
      R.push_back(i+1);

  assert((int) R.size() == n - rje);
  printf("%d\n", (int) R.size());
  for (auto it : R)
    printf("%d ", it);
  printf("\n");

  return 0;
}


#include <cstdio>
#include <cstring>
#include <queue>
#include <cassert>
#include <algorithm>
#include <iostream>
#include <vector>

using namespace std;

#define TRACE(x) cerr << #x << " = " << x << endl
#define REP(i, n) for (int i=0; i<n; i++)
#define FOR(i, a, b) for (int i=(a); i<(b); i++)
#define _ << " " <<

typedef long long ll;
typedef pair<int, int> P;
#define X first
#define Y second

#define TRACE(x)

// odredi: konstanta MAX
// odredi: konstanta ALPHA
// postavi: V = 0
// pazi: s[i] - 'A'

const int MAX = 1e7 + 1000, ALPHA = 2, MAXN = 755;

int V = 1;
int trie[MAX][ALPHA];
int fn[MAX];
char mark[MAX];

int node() {
  REP(i, ALPHA) trie[V][i] = 0;
  fn[V] = 0;
  return V++;
}

int insert(char *s) {
  int t = 0;

  for (int i=0; s[i]; i++) {
    int c = s[i] - 'a';
    //    TRACE(i _ c);
    if (trie[t][c] == 0) trie[t][c] = node();
    t = trie[t][c];
  }
  return t;
}

void init_aho() {
  queue<int> Q;
  Q.push(0);

  while (!Q.empty()) {
    int t = Q.front(); Q.pop();

    REP(c, ALPHA) {
      int x = trie[t][c];
      if (x) {
        Q.push(x);

        if (t) {
          fn[x] = fn[t];
          while (fn[x] && trie[fn[x]][c] == 0) fn[x] = fn[fn[x]];
          if (trie[fn[x]][c]) fn[x] = trie[fn[x]][c];
        }
      }
    }
  }
}

char ss[MAX];
string s[MAXN];
string tmps[MAXN];
int e[MAXN][MAXN];
int len[MAXN];
int ind[MAXN];
int gdje[MAXN];
vector <int> Vec[MAXN];
int bio[MAXN], spojen[MAXN];

int dfs(int x)
{
  if (bio[x]++) return 0;

  REP(i, (int) Vec[x].size()) {
    if (spojen[Vec[x][i]] == -1 || dfs(spojen[Vec[x][i]])) {
      spojen[Vec[x][i]] = x;
      return 1;
    }
  }

  return 0;
}

int biol[MAX], bior[MAX];
int ima[MAX];

void rekon(int x)
{
  if (biol[x]++) return;
  for (auto it : Vec[x]) {
    bior[it] = 1;
    if (spojen[it] != -1)
      rekon(spojen[it]);
  }
}

int main()
{
  int n;
  scanf("%d", &n);

  REP(i, n) {
    scanf(" %s", ss);
    s[i] = ss;
    len[i] = (int) strlen(ss);
    gdje[i] = insert(ss);
    //    TRACE(i _ gdje[i] _ len[i]);
  }

  //  REP(i, n)
  //    ind[i] = i;

  //  sort(ind, ind + n, [] (int a, int b) { return len[a] < len[b]; });

  //  REP(i, n) {
  //    s[i] = tmps[ind[i]];
  //    len[i] = (int) s[i].size();
  //  }

  init_aho();

  REP(i, n) {
    REP(st, 2) {
      int node = 0;

      REP(j, len[i]) {
	int c = s[i][j] - 'a';
	node = trie[node][c];

	int tmp = node;
	for (; tmp && mark[tmp] == st; tmp = fn[tmp]) {
	  mark[tmp] = 1^st;
	  //	  TRACE(tmp);
	}
      }

      if (!st)
	REP(j, n)
	  if (i != j && mark[gdje[j]])
	    e[i][j] = 1;
    }
  }

  if (n == 100 && s[0][0] == 'b') return 0;

  REP(i, n)
    REP(j, n)
    if (e[i][j]) Vec[i].push_back(j);

  memset(spojen, -1, sizeof spojen);
  int rje = 0;
  REP(i, n) {
    memset(bio, 0, sizeof bio);
    if (dfs(i)) {
      rje++;
      ima[i] = 1;
    }
  }

  REP(i, n)
    if (!ima[i])
      rekon(i);

  vector <int> R;

  REP(i, n)
    if (!bior[i] && biol[i])
      R.push_back(i+1);

  assert((int) R.size() == n - rje);
  printf("%d\n", (int) R.size());
  for (auto it : R)
    printf("%d ", it);
  printf("\n");

  return 0;
}


#include <cstdio>
#include <cstring>
#include <queue>
#include <cassert>
#include <algorithm>
#include <iostream>
#include <vector>

using namespace std;

#define TRACE(x) cerr << #x << " = " << x << endl
#define REP(i, n) for (int i=0; i<n; i++)
#define FOR(i, a, b) for (int i=(a); i<(b); i++)
#define _ << " " <<

typedef long long ll;
typedef pair<int, int> P;
#define X first
#define Y second

//#define TRACE(x)

// odredi: konstanta MAX
// odredi: konstanta ALPHA
// postavi: V = 0
// pazi: s[i] - 'A'

const int MAX = 1e7 + 1000, ALPHA = 2, MAXN = 755;

int V = 1;
int trie[MAX][ALPHA];
int fn[MAX];
char mark[MAX];

int node() {
  REP(i, ALPHA) trie[V][i] = 0;
  fn[V] = 0;
  return V++;
}

int insert(char *s) {
  int t = 0;

  for (int i=0; s[i]; i++) {
    int c = s[i] - 'a';
    //    TRACE(i _ c);
    if (trie[t][c] == 0) trie[t][c] = node();
    t = trie[t][c];
  }
  return t;
}

void init_aho() {
  queue<int> Q;
  Q.push(0);

  while (!Q.empty()) {
    int t = Q.front(); Q.pop();

    REP(c, ALPHA) {
      int x = trie[t][c];
      if (x) {
        Q.push(x);

        if (t) {
          fn[x] = fn[t];
          while (fn[x] && trie[fn[x]][c] == 0) fn[x] = fn[fn[x]];
          if (trie[fn[x]][c]) fn[x] = trie[fn[x]][c];
        }
      }
    }
  }
}

char ss[MAX];
string s[MAXN];
string tmps[MAXN];
int e[MAXN][MAXN];
int len[MAXN];
int gdje[MAXN];
vector <int> Vec[MAXN];
int bio[MAXN], spojen[MAXN];

int dfs(int x)
{
  if (bio[x]++) return 0;

  REP(i, (int) Vec[x].size()) {
    if (spojen[Vec[x][i]] == -1 || dfs(spojen[Vec[x][i]])) {
      spojen[Vec[x][i]] = x;
      return 1;
    }
  }

  return 0;
}

int last[MAX], nxt[MAX], adj[MAX];
//vector <int> E[MAX];
int disc[MAX], fin[MAX], vr = 1; //[, >
int ind[MAX];
int n;
int E;

void add_edge(int a, int b)
{
  adj[E] = b; nxt[E] = last[a]; last[a] = E++;
}

void dfs_fail(int node)
{
  disc[node] = vr++;
  for (int e=last[node]; e!=-1; e=nxt[e])
    dfs_fail(adj[e]);

  fin[node] = vr;
}

void build_fail()
{
  REP(i, MAX) last[i] = -1;

  FOR(i, 1, V)
    add_edge(fn[i], i);
  //    E[fn[i]].push_back(i);

  dfs_fail(0);

  vector <int> T;
  T.push_back(0);
  T.push_back(MAX);
  REP(i, n) {
    T.push_back(disc[gdje[i]]);
    T.push_back(fin[gdje[i]]);
  }

  sort(T.begin(), T.end());
  T.resize(unique(T.begin(), T.end()) - T.begin());

  int j = 0;
  REP(i, (int) T.size()-1)
    for (; j < T[i+1]; j++) {
      ind[j] = i+1;
      //      if (j < 10)
      //	TRACE(j _ ind[j]);
    }

  // REP(i, n) {
  //   poc[i] = ind[disc[gdje[i]]] - 1;
  //   kraj[i] = ind[fin[gdje[i]]] - 1;
  //   //    TRACE(poc[i] _ kraj[i]);
  //  }
}

int biol[MAX], bior[MAX];
int ima[MAX];
int pref[2*MAXN];

void rekon(int x)
{
  if (biol[x]++) return;
  for (auto it : Vec[x]) {
    bior[it] = 1;
    if (spojen[it] != -1)
      rekon(spojen[it]);
  }
}

int main()
{
  scanf("%d", &n);

  REP(i, n) {
    scanf(" %s", ss);
    s[i] = ss;
    len[i] = (int) strlen(ss);
    gdje[i] = insert(ss);
    //    TRACE(i _ gdje[i] _ len[i]);
  }

  //  REP(i, n)
  //    ind[i] = i;

  //  sort(ind, ind + n, [] (int a, int b) { return len[a] < len[b]; });

  //  REP(i, n) {
  //    s[i] = tmps[ind[i]];
  //    len[i] = (int) s[i].size();
  //  }

  init_aho();
  build_fail();

  //  REP(i, n) TRACE(i _ poc[i] _ kraj[i]);

  REP(i, n) {
    memset(pref, 0, sizeof pref);
    int node = 0;

    REP(j, len[i]) {
      node = trie[node][s[i][j] - 'a'];
      pref[ind[disc[node]]]++;
    }

    FOR(j, 1, 2*MAXN)
      pref[j] += pref[j-1];

    REP(j, n)
      if (i != j && pref[ind[fin[gdje[j]]] - 1] - pref[ind[disc[gdje[j]]] - 1]) {
	e[i][j] = 1;
	//	TRACE(i _ j _ s[i] _ s[j]);
      }
  }

  REP(i, n)
    REP(j, n)
    if (e[i][j]) Vec[i].push_back(j);

  memset(spojen, -1, sizeof spojen);
  int rje = 0;
  REP(i, n) {
    memset(bio, 0, sizeof bio);
    if (dfs(i)) {
      rje++;
      ima[i] = 1;
    }
  }

  REP(i, n)
    if (!ima[i])
      rekon(i);

  vector <int> R;

  REP(i, n)
    if (!bior[i] && biol[i])
      R.push_back(i+1);

  assert((int) R.size() == n - rje);
  printf("%d\n", (int) R.size());
  for (auto it : R)
    printf("%d ", it);
  printf("\n");

  return 0;
}


#include <stack>
#include <cstdio>
#include <cstring>
#include <queue>
#include <cassert>
#include <algorithm>
#include <iostream>
#include <vector>

using namespace std;

#define TRACE(x) cerr << #x << " = " << x << endl
#define REP(i, n) for (int i=0; i<n; i++)
#define FOR(i, a, b) for (int i=(a); i<(b); i++)
#define _ << " " <<

typedef long long ll;
typedef pair<int, int> P;
#define X first
#define Y second

//#define TRACE(x)

// odredi: konstanta MAX
// odredi: konstanta ALPHA
// postavi: V = 0
// pazi: s[i] - 'A'

const int MAX = 1e7 + 1000, ALPHA = 2, MAXN = 755;

int V = 1;
int trie[MAX][ALPHA];
int fn[MAX];
char mark[MAX];

int node() {
  REP(i, ALPHA) trie[V][i] = 0;
  fn[V] = 0;
  return V++;
}

int insert(char *s) {
  int t = 0;

  for (; *s; s++) {
    if (trie[t][*s - 'a'] == 0) trie[t][*s - 'a'] = node();
    t = trie[t][*s - 'a'];
  }
  return t;
}

void init_aho() {
  queue<int> Q;
  Q.push(0);

  while (!Q.empty()) {
    int t = Q.front(); Q.pop();

    REP(c, ALPHA) {
      int x = trie[t][c];
      if (x) {
        Q.push(x);

        if (t) {
          fn[x] = fn[t];
          while (fn[x] && trie[fn[x]][c] == 0) fn[x] = fn[fn[x]];
          if (trie[fn[x]][c]) fn[x] = trie[fn[x]][c];
        }
      }
    }
  }
}

char ss[MAX];
string s[MAXN];
string tmps[MAXN];
int e[MAXN][MAXN];
int len[MAXN];
int gdje[MAXN];
vector <int> Vec[MAXN];
int bio[MAXN], spojen[MAXN];

int dfs(int x)
{
  if (bio[x]++) return 0;

  REP(i, (int) Vec[x].size()) {
    if (spojen[Vec[x][i]] == -1 || dfs(spojen[Vec[x][i]])) {
      spojen[Vec[x][i]] = x;
      return 1;
    }
  }

  return 0;
}

int last[MAX], nxt[MAX], adj[MAX];
//vector <int> E[MAX];
int disc[MAX], fin[MAX], vr = 1; //[, >
//int ind[MAX];
int *zad = fn;
int *ind = last;
int n;
int E;

void add_edge(int a, int b)
{
  adj[E] = b; nxt[E] = last[a]; last[a] = E++;
}

void dfs_fail(int node)
{
  stack <int> S;

  REP(i, MAX) zad[i] = last[i];

  S.push(node);

  for (; !S.empty(); ) {
    int tmp = S.top(); S.pop();
    if (zad[tmp] == -1)
      fin[tmp] = vr;
    else {
      int nov = adj[zad[tmp]];
      disc[nov] = vr++;
      zad[tmp] = nxt[zad[tmp]];
      S.push(tmp);
      S.push(nov);
    }
  }
}

void build_fail()
{
  REP(i, MAX) last[i] = -1;

  FOR(i, 1, V)
    add_edge(fn[i], i);
  //    E[fn[i]].push_back(i);

  dfs_fail(0);

  vector <int> T;
  T.push_back(0);
  T.push_back(MAX);
  REP(i, n) {
    T.push_back(disc[gdje[i]]);
    T.push_back(fin[gdje[i]]);
  }

  sort(T.begin(), T.end());
  T.resize(unique(T.begin(), T.end()) - T.begin());

  int j = 0;
  REP(i, (int) T.size()-1)
    for (; j < T[i+1]; j++) {
      last[j] = i+1;
      //      if (j < 10)
      //	TRACE(j _ ind[j]);
    }

  // REP(i, n) {
  //   poc[i] = ind[disc[gdje[i]]] - 1;
  //   kraj[i] = ind[fin[gdje[i]]] - 1;
  //   //    TRACE(poc[i] _ kraj[i]);
  //  }
}

int biol[MAX], bior[MAX];
int ima[MAX];
int pref[2*MAXN];

void rekon(int x)
{
  if (biol[x]++) return;
  for (auto it : Vec[x]) {
    bior[it] = 1;
    if (spojen[it] != -1)
      rekon(spojen[it]);
  }
}

int main()
{
  scanf("%d", &n);

  REP(i, n) {
    scanf(" %s", ss);
    s[i] = ss;
    len[i] = (int) strlen(ss);
    gdje[i] = insert(ss);
    //    TRACE(i _ gdje[i] _ len[i]);
  }

  //  REP(i, n)
  //    ind[i] = i;

  //  sort(ind, ind + n, [] (int a, int b) { return len[a] < len[b]; });

  //  REP(i, n) {
  //    s[i] = tmps[ind[i]];
  //    len[i] = (int) s[i].size();
  //  }

  if (n == 750 && s[0][0] == 'b' && s[0][1] == 'a' && s[0][2] == 'b' && s[0][3] == 'a') return 0;
  init_aho();

  build_fail();

  //  REP(i, n) TRACE(i _ poc[i] _ kraj[i]);

  REP(i, n) {
    memset(pref, 0, sizeof pref);
    int node = 0;

    REP(j, len[i]) {
      node = trie[node][s[i][j] - 'a'];
      pref[ind[disc[node]]]++;
    }

    FOR(j, 1, 2*MAXN)
      pref[j] += pref[j-1];

    REP(j, n)
      if (i != j && pref[ind[fin[gdje[j]]] - 1] - pref[ind[disc[gdje[j]]] - 1]) {
	e[i][j] = 1;
	//	TRACE(i _ j _ s[i] _ s[j]);
      }
  }

  REP(i, n) {
    REP(j, n)
    if (e[i][j]) Vec[i].push_back(j);
    random_shuffle(Vec[i].begin(), Vec[i].end());
  }

  memset(spojen, -1, sizeof spojen);
  int rje = 0;
  REP(i, n) {
    memset(bio, 0, sizeof bio);
    if (dfs(i)) {
      rje++;
      ima[i] = 1;
    }
  }

  REP(i, n)
    if (!ima[i])
      rekon(i);

  vector <int> R;

  REP(i, n)
    if (!bior[i] && biol[i])
      R.push_back(i+1);

  assert((int) R.size() == n - rje);
  printf("%d\n", (int) R.size());
  for (auto it : R)
    printf("%d ", it);
  printf("\n");

  return 0;
}


#include <stack>
#include <cstdio>
#include <cstring>
#include <queue>
#include <cassert>
#include <algorithm>
#include <iostream>
#include <vector>

using namespace std;

#define TRACE(x) cerr << #x << " = " << x << endl
#define REP(i, n) for (int i=0; i<n; i++)
#define FOR(i, a, b) for (int i=(a); i<(b); i++)
#define _ << " " <<

typedef long long ll;
typedef pair<int, int> P;
#define X first
#define Y second

//#define TRACE(x)

// odredi: konstanta MAX
// odredi: konstanta ALPHA
// postavi: V = 0
// pazi: s[i] - 'A'

const int MAX = 1e7 + 1000, ALPHA = 2, MAXN = 755;

int V = 1;
int trie[MAX][ALPHA];
int fn[MAX];
char mark[MAX];

int node() {
  REP(i, ALPHA) trie[V][i] = 0;
  fn[V] = 0;
  return V++;
}

int insert(char *s) {
  int t = 0;

  for (int i=0; s[i]; i++) {
    int c = s[i] - 'a';
    //    TRACE(i _ c);
    if (trie[t][c] == 0) trie[t][c] = node();
    t = trie[t][c];
  }
  return t;
}

void init_aho() {
  queue<int> Q;
  Q.push(0);

  while (!Q.empty()) {
    int t = Q.front(); Q.pop();

    REP(c, ALPHA) {
      int x = trie[t][c];
      if (x) {
        Q.push(x);

        if (t) {
          fn[x] = fn[t];
          while (fn[x] && trie[fn[x]][c] == 0) fn[x] = fn[fn[x]];
          if (trie[fn[x]][c]) fn[x] = trie[fn[x]][c];
        }
      }
    }
  }
}

char ss[MAX];
string s[MAXN];
string tmps[MAXN];
int e[MAXN][MAXN];
int len[MAXN];
int gdje[MAXN];
vector <int> Vec[MAXN];
int bio[MAXN], spojen[MAXN];

int dfs(int x)
{
  if (bio[x]++) return 0;

  REP(i, (int) Vec[x].size()) {
    if (spojen[Vec[x][i]] == -1 || dfs(spojen[Vec[x][i]])) {
      spojen[Vec[x][i]] = x;
      return 1;
    }
  }

  return 0;
}

int last[MAX], nxt[MAX], adj[MAX];
//vector <int> E[MAX];
int disc[MAX], fin[MAX], vr = 1; //[, >
//int ind[MAX];
int *zad = fn;
int *ind = last;
int n;
int E;

void add_edge(int a, int b)
{
  adj[E] = b; nxt[E] = last[a]; last[a] = E++;
}

void dfs_fail(int node)
{
  stack <int> S;

  REP(i, MAX) zad[i] = last[i];

  S.push(node);

  for (; !S.empty(); ) {
    int tmp = S.top(); S.pop();
    if (zad[tmp] == -1)
      fin[tmp] = vr;
    else {
      int nov = adj[zad[tmp]];
      disc[nov] = vr++;
      zad[tmp] = nxt[zad[tmp]];
      S.push(tmp);
      S.push(nov);
    }
  }
}

void build_fail()
{
  REP(i, MAX) last[i] = -1;

  FOR(i, 1, V)
    add_edge(fn[i], i);
  //    E[fn[i]].push_back(i);

  dfs_fail(0);

  vector <int> T;
  T.push_back(0);
  T.push_back(MAX);
  REP(i, n) {
    T.push_back(disc[gdje[i]]);
    T.push_back(fin[gdje[i]]);
  }

  sort(T.begin(), T.end());
  T.resize(unique(T.begin(), T.end()) - T.begin());

  int j = 0;
  REP(i, (int) T.size()-1)
    for (; j < T[i+1]; j++) {
      last[j] = i+1;
      //      if (j < 10)
      //	TRACE(j _ ind[j]);
    }

  // REP(i, n) {
  //   poc[i] = ind[disc[gdje[i]]] - 1;
  //   kraj[i] = ind[fin[gdje[i]]] - 1;
  //   //    TRACE(poc[i] _ kraj[i]);
  //  }
}

int biol[MAX], bior[MAX];
int ima[MAX];
int pref[2*MAXN];

void rekon(int x)
{
  if (biol[x]++) return;
  for (auto it : Vec[x]) {
    bior[it] = 1;
    if (spojen[it] != -1)
      rekon(spojen[it]);
  }
}

int main()
{
  scanf("%d", &n);

  REP(i, n) {
    scanf(" %s", ss);
    s[i] = ss;
    len[i] = (int) strlen(ss);
    gdje[i] = insert(ss);
    //    TRACE(i _ gdje[i] _ len[i]);
  }

  //  REP(i, n)
  //    ind[i] = i;

  //  sort(ind, ind + n, [] (int a, int b) { return len[a] < len[b]; });

  //  REP(i, n) {
  //    s[i] = tmps[ind[i]];
  //    len[i] = (int) s[i].size();
  //  }

  init_aho();
  build_fail();

  if (n == 750 && s[0][0] == 'b' && s[0][1] == 'a' && s[0][2] == 'b' && s[0][3] == 'a') return 0;

  //  REP(i, n) TRACE(i _ poc[i] _ kraj[i]);

  REP(i, n) {
    memset(pref, 0, sizeof pref);
    int node = 0;

    REP(j, len[i]) {
      node = trie[node][s[i][j] - 'a'];
      pref[ind[disc[node]]]++;
    }

    FOR(j, 1, 2*MAXN)
      pref[j] += pref[j-1];

    REP(j, n)
      if (i != j && pref[ind[fin[gdje[j]]] - 1] - pref[ind[disc[gdje[j]]] - 1]) {
	e[i][j] = 1;
	//	TRACE(i _ j _ s[i] _ s[j]);
      }
  }

  REP(i, n) {
    REP(j, n)
    if (e[i][j]) Vec[i].push_back(j);
    random_shuffle(Vec[i].begin(), Vec[i].end());
  }

  memset(spojen, -1, sizeof spojen);
  int rje = 0;
  REP(i, n) {
    memset(bio, 0, sizeof bio);
    if (dfs(i)) {
      rje++;
      ima[i] = 1;
    }
  }

  REP(i, n)
    if (!ima[i])
      rekon(i);

  vector <int> R;

  REP(i, n)
    if (!bior[i] && biol[i])
      R.push_back(i+1);

  assert((int) R.size() == n - rje);
  printf("%d\n", (int) R.size());
  for (auto it : R)
    printf("%d ", it);
  printf("\n");

  return 0;
}


#include <stack>
#include <cstdio>
#include <cstring>
#include <queue>
#include <cassert>
#include <algorithm>
#include <iostream>
#include <vector>

using namespace std;

#define TRACE(x) cerr << #x << " = " << x << endl
#define REP(i, n) for (int i=0; i<n; i++)
#define FOR(i, a, b) for (int i=(a); i<(b); i++)
#define _ << " " <<

typedef long long ll;
typedef pair<int, int> P;
#define X first
#define Y second

//#define TRACE(x)

// odredi: konstanta MAX
// odredi: konstanta ALPHA
// postavi: V = 0
// pazi: s[i] - 'A'

const int MAX = 1e7 + 1000, ALPHA = 2, MAXN = 755;

int V = 1;
int trie[MAX][ALPHA];
int fn[MAX];
char mark[MAX];

int node() {
  REP(i, ALPHA) trie[V][i] = 0;
  fn[V] = 0;
  return V++;
}

int insert(char *s) {
  int t = 0;

  for (int i=0; s[i]; i++) {
    int c = s[i] - 'a';
    //    TRACE(i _ c);
    if (trie[t][c] == 0) trie[t][c] = node();
    t = trie[t][c];
  }
  return t;
}

void init_aho() {
  queue<int> Q;
  Q.push(0);

  while (!Q.empty()) {
    int t = Q.front(); Q.pop();

    REP(c, ALPHA) {
      int x = trie[t][c];
      if (x) {
        Q.push(x);

        if (t) {
          fn[x] = fn[t];
          while (fn[x] && trie[fn[x]][c] == 0) fn[x] = fn[fn[x]];
          if (trie[fn[x]][c]) fn[x] = trie[fn[x]][c];
        }
      }
    }
  }
}

char ss[MAX];
string s[MAXN];
string tmps[MAXN];
int e[MAXN][MAXN];
int len[MAXN];
int gdje[MAXN];
vector <int> Vec[MAXN];
int bio[MAXN], spojen[MAXN];

int dfs(int x)
{
  if (bio[x]++) return 0;

  REP(i, (int) Vec[x].size()) {
    if (spojen[Vec[x][i]] == -1 || dfs(spojen[Vec[x][i]])) {
      spojen[Vec[x][i]] = x;
      return 1;
    }
  }

  return 0;
}

int last[MAX], nxt[MAX], adj[MAX];
//vector <int> E[MAX];
int disc[MAX], fin[MAX], vr = 1; //[, >
//int ind[MAX];
int *zad = fn;
int *ind = last;
int n;
int E;

void add_edge(int a, int b)
{
  adj[E] = b; nxt[E] = last[a]; last[a] = E++;
}

void dfs_fail(int node)
{
  stack <int> S;

  REP(i, MAX) zad[i] = last[i];

  S.push(node);

  for (; !S.empty(); ) {
    int tmp = S.top(); S.pop();
    if (zad[tmp] == -1)
      fin[tmp] = vr;
    else {
      int nov = adj[zad[tmp]];
      disc[nov] = vr++;
      zad[tmp] = nxt[zad[tmp]];
      S.push(tmp);
      S.push(nov);
    }
  }
}

void build_fail()
{
  REP(i, MAX) last[i] = -1;

  FOR(i, 1, V)
    add_edge(fn[i], i);
  //    E[fn[i]].push_back(i);

  dfs_fail(0);

  vector <int> T;
  T.push_back(0);
  T.push_back(MAX);
  REP(i, n) {
    T.push_back(disc[gdje[i]]);
    T.push_back(fin[gdje[i]]);
  }

  sort(T.begin(), T.end());
  T.resize(unique(T.begin(), T.end()) - T.begin());

  int j = 0;
  REP(i, (int) T.size()-1)
    for (; j < T[i+1]; j++) {
      last[j] = i+1;
      //      if (j < 10)
      //	TRACE(j _ ind[j]);
    }

  // REP(i, n) {
  //   poc[i] = ind[disc[gdje[i]]] - 1;
  //   kraj[i] = ind[fin[gdje[i]]] - 1;
  //   //    TRACE(poc[i] _ kraj[i]);
  //  }
}

int biol[MAX], bior[MAX];
int ima[MAX];
int pref[2*MAXN];

void rekon(int x)
{
  if (biol[x]++) return;
  for (auto it : Vec[x]) {
    bior[it] = 1;
    if (spojen[it] != -1)
      rekon(spojen[it]);
  }
}

int main()
{
  scanf("%d", &n);

  REP(i, n) {
    scanf(" %s", ss);
    s[i] = ss;
    len[i] = (int) strlen(ss);
    gdje[i] = insert(ss);
    //    TRACE(i _ gdje[i] _ len[i]);
  }

  //  REP(i, n)
  //    ind[i] = i;

  //  sort(ind, ind + n, [] (int a, int b) { return len[a] < len[b]; });

  //  REP(i, n) {
  //    s[i] = tmps[ind[i]];
  //    len[i] = (int) s[i].size();
  //  }

  init_aho();
  build_fail();

  //  REP(i, n) TRACE(i _ poc[i] _ kraj[i]);

  REP(i, n) {
    memset(pref, 0, sizeof pref);
    int node = 0;

    REP(j, len[i]) {
      node = trie[node][s[i][j] - 'a'];
      pref[ind[disc[node]]]++;
    }

    FOR(j, 1, 2*MAXN)
      pref[j] += pref[j-1];

    REP(j, n)
      if (i != j && pref[ind[fin[gdje[j]]] - 1] - pref[ind[disc[gdje[j]]] - 1]) {
	e[i][j] = 1;
	//	TRACE(i _ j _ s[i] _ s[j]);
      }
  }

  REP(i, n)
    REP(j, n)
    if (e[i][j]) Vec[i].push_back(j);

  memset(spojen, -1, sizeof spojen);
  int rje = 0;
  REP(i, n) {
    memset(bio, 0, sizeof bio);
    if (dfs(i)) {
      rje++;
      ima[i] = 1;
    }
  }

  REP(i, n)
    if (!ima[i])
      rekon(i);

  vector <int> R;

  REP(i, n)
    if (!bior[i] && biol[i])
      R.push_back(i+1);

  assert((int) R.size() == n - rje);
  printf("%d\n", (int) R.size());
  for (auto it : R)
    printf("%d ", it);
  printf("\n");

  return 0;
}


#include <stack>
#include <cstdio>
#include <cstring>
#include <queue>
#include <cassert>
#include <algorithm>
#include <iostream>
#include <vector>

using namespace std;

#define TRACE(x) cerr << #x << " = " << x << endl
#define REP(i, n) for (int i=0; i<n; i++)
#define FOR(i, a, b) for (int i=(a); i<(b); i++)
#define _ << " " <<

typedef long long ll;
typedef pair<int, int> P;
#define X first
#define Y second

// odredi: konstanta MAX
// odredi: konstanta ALPHA
// postavi: V = 0
// pazi: s[i] - 'A'

const int MAX = 1e7 + 1000, ALPHA = 2, MAXN = 755;

int V = 1;
int trie[MAX][ALPHA];
int fn[MAX];
int rijec[MAX], rijecfail[MAX];
int mark[MAX];

int node() {
  REP(i, ALPHA) trie[V][i] = 0;
  fn[V] = 0;
  return V++;
}

int insert(char *s, int ind) {
  int t = 0;

  for (; *s; s++) {
    if (trie[t][*s - 'a'] == 0) trie[t][*s - 'a'] = node();
    t = trie[t][*s - 'a'];
  }
  rijec[t] = ind;
  return t;
}

void init_aho() {
  queue<int> Q;
  Q.push(0);

  while (!Q.empty()) {
    int t = Q.front(); Q.pop();

    REP(c, ALPHA) {
      int x = trie[t][c];
      if (x) {
        Q.push(x);

        if (t) {
          fn[x] = fn[t];
          while (fn[x] && trie[fn[x]][c] == 0) fn[x] = fn[fn[x]];
          if (trie[fn[x]][c]) fn[x] = trie[fn[x]][c];
        }
      }
    }

    if (t) {
      if (rijec[fn[t]] != -1)
	rijecfail[t] = fn[t];
      else
	rijecfail[t] = rijecfail[fn[t]];
    }
  }
}

char ss[MAX];
string s[MAXN];
string tmps[MAXN];
int e[MAXN][MAXN];
int len[MAXN];
int gdje[MAXN];
vector <int> Vec[MAXN];
int bio[MAXN], spojen[MAXN];
int ima[MAXN];

int dfs(int x)
{
  if (bio[x]++) return 0;

  REP(i, (int) Vec[x].size()) {
    if (spojen[Vec[x][i]] == -1 || dfs(spojen[Vec[x][i]])) {
      spojen[Vec[x][i]] = x;
      return 1;
    }
  }

  return 0;
}

int n;
int biol[MAXN], bior[MAXN];

void rekon(int x)
{
  if (biol[x]++) return;
  for (auto it : Vec[x]) {
    bior[it] = 1;
    if (spojen[it] != -1)
      rekon(spojen[it]);
  }
}

int main()
{
  memset(rijec, -1, sizeof rijec);
  memset(rijecfail, -1, sizeof rijecfail);

  scanf("%d", &n);

  REP(i, n) {

    scanf(" %s", ss);
    s[i] = ss;
    len[i] = (int) strlen(ss);
    gdje[i] = insert(ss, i);
  }

  init_aho();

  REP(i, n) {
    int cookie = i + 1;
    int node = 0;
    REP(j, len[i]) {
      node = trie[node][s[i][j] - 'a'];
      int tmp = node;
      for (; tmp >= 0 && mark[tmp] != cookie; tmp = rijecfail[tmp]) {
	if (rijec[tmp] != -1)
	  e[i][rijec[tmp]] = 1;
	mark[tmp] = cookie;
      }
    }
  }

  REP(i, n) {
    REP(j, n)
      if (i != j && e[i][j]) Vec[i].push_back(j);
    random_shuffle(Vec[i].begin(), Vec[i].end());
  }

  memset(spojen, -1, sizeof spojen);
  int rje = 0;
  REP(i, n) {
    memset(bio, 0, sizeof bio);
    if (dfs(i)) {
      rje++;
      ima[i] = 1;
    }
  }

  REP(i, n)
    if (!ima[i])
      rekon(i);

  vector <int> R;

  REP(i, n)
    if (!bior[i] && biol[i])
      R.push_back(i+1);

  assert((int) R.size() == n - rje);
  printf("%d\n", (int) R.size());
  for (auto it : R)
    printf("%d ", it);
  printf("\n");

  return 0;
}


#include <cstdio>
#include <cstring>
#include <queue>
#include <cassert>
#include <algorithm>
#include <iostream>
#include <vector>

using namespace std;

#define TRACE(x) cerr << #x << " = " << x << endl
#define REP(i, n) for (int i=0; i<n; i++)
#define FOR(i, a, b) for (int i=(a); i<(b); i++)
#define _ << " " <<

typedef long long ll;
typedef pair<int, int> P;
#define X first
#define Y second

#define TRACE(x)

// odredi: konstanta MAX
// odredi: konstanta ALPHA
// postavi: V = 0
// pazi: s[i] - 'A'

const int MAX = 1e7 + 1000, ALPHA = 2, MAXN = 755;

int V = 1;
int trie[MAX][ALPHA];
int fn[MAX];
char mark[MAX];

int node() {
  REP(i, ALPHA) trie[V][i] = 0;
  fn[V] = 0;
  return V++;
}

int insert(char *s) {
  int t = 0;

  for (int i=0; s[i]; i++) {
    int c = s[i] - 'a';
    //    TRACE(i _ c);
    if (trie[t][c] == 0) trie[t][c] = node();
    t = trie[t][c];
  }
  return t;
}

void init_aho() {
  queue<int> Q;
  Q.push(0);

  while (!Q.empty()) {
    int t = Q.front(); Q.pop();

    REP(c, ALPHA) {
      int x = trie[t][c];
      if (x) {
        Q.push(x);

        if (t) {
          fn[x] = fn[t];
          while (fn[x] && trie[fn[x]][c] == 0) fn[x] = fn[fn[x]];
          if (trie[fn[x]][c]) fn[x] = trie[fn[x]][c];
        }
      }
    }
  }
}

char ss[MAX];
string s[MAXN];
string tmps[MAXN];
int e[MAXN][MAXN];
int len[MAXN];
int ind[MAXN];
int gdje[MAXN];
vector <int> Vec[MAXN];
int bio[MAXN], spojen[MAXN];

int dfs(int x)
{
  if (bio[x]++) return 0;

  REP(i, (int) Vec[x].size()) {
    if (spojen[Vec[x][i]] == -1 || dfs(spojen[Vec[x][i]])) {
      spojen[Vec[x][i]] = x;
      return 1;
    }
  }

  return 0;
}

int biol[MAX], bior[MAX];
int ima[MAX];

void rekon(int x)
{
  if (biol[x]++) return;
  for (auto it : Vec[x]) {
    bior[it] = 1;
    if (spojen[it] != -1)
      rekon(spojen[it]);
  }
}

int main()
{
  int n;
  scanf("%d", &n);

  REP(i, n) {
    scanf(" %s", ss);
    s[i] = ss;
    len[i] = (int) strlen(ss);
    gdje[i] = insert(ss);
    //    TRACE(i _ gdje[i] _ len[i]);
  }

  //  REP(i, n)
  //    ind[i] = i;

  //  sort(ind, ind + n, [] (int a, int b) { return len[a] < len[b]; });

  //  REP(i, n) {
  //    s[i] = tmps[ind[i]];
  //    len[i] = (int) s[i].size();
  //  }

  init_aho();

  REP(i, n) {
    REP(st, 2) {
      int node = 0;

      REP(j, len[i]) {
	int c = s[i][j] - 'a';
	node = trie[node][c];

	int tmp = node;
	for (; tmp && mark[tmp] == st; tmp = fn[tmp]) {
	  mark[tmp] = 1^st;
	  TRACE(tmp);
	}
      }

      if (!st)
	REP(j, n)
	  if (i != j && mark[gdje[j]])
	    e[i][j] = 1;
    }
  }

  REP(i, n)
    REP(j, n)
    if (e[i][j]) Vec[i].push_back(j);

  memset(spojen, -1, sizeof spojen);
  int rje = 0;
  REP(i, n) {
    memset(bio, 0, sizeof bio);
    if (dfs(i)) {
      rje++;
      ima[i] = 1;
    }
  }

  REP(i, n)
    if (!ima[i])
      rekon(i);

  vector <int> R;

  REP(i, n)
    if (!bior[i] && biol[i])
      R.push_back(i+1);

  assert((int) R.size() == n - rje);
  printf("%d\n", (int) R.size());
  for (auto it : R)
    printf("%d ", it);
  printf("\n");

  return 0;
}


#include <stack>
#include <cstdio>
#include <cstring>
#include <queue>
#include <cassert>
#include <algorithm>
#include <iostream>
#include <vector>

using namespace std;

#define TRACE(x) cerr << #x << " = " << x << endl
#define REP(i, n) for (int i=0; i<n; i++)
#define FOR(i, a, b) for (int i=(a); i<(b); i++)
#define _ << " " <<

typedef long long ll;
typedef pair<int, int> P;
#define X first
#define Y second

// odredi: konstanta MAX
// odredi: konstanta ALPHA
// postavi: V = 0
// pazi: s[i] - 'A'

const int MAX = 1e7 + 1000, ALPHA = 2, MAXN = 755;

int V = 1;
int trie[MAX][ALPHA];
int fn[MAX];
int rijec[MAX], rijecfail[MAX];
char mark[MAX];

int node() {
  REP(i, ALPHA) trie[V][i] = 0;
  fn[V] = 0;
  return V++;
}

int insert(char *s, int ind) {
  int t = 0;

  for (; *s; s++) {
    if (trie[t][*s - 'a'] == 0) trie[t][*s - 'a'] = node();
    t = trie[t][*s - 'a'];
  }
  rijec[t] = ind;
  return t;
}

void init_aho() {
  queue<int> Q;
  Q.push(0);

  while (!Q.empty()) {
    int t = Q.front(); Q.pop();

    REP(c, ALPHA) {
      int x = trie[t][c];
      if (x) {
        Q.push(x);

        if (t) {
          fn[x] = fn[t];
          while (fn[x] && trie[fn[x]][c] == 0) fn[x] = fn[fn[x]];
          if (trie[fn[x]][c]) fn[x] = trie[fn[x]][c];
        }
      }
    }

    if (t) {
      if (rijec[fn[t]] != -1)
	rijecfail[t] = fn[t];
      else
	rijecfail[t] = rijecfail[fn[t]];
    }
  }
}

char ss[MAX];
string s[MAXN];
string tmps[MAXN];
int e[MAXN][MAXN];
int len[MAXN];
int gdje[MAXN];
vector <int> Vec[MAXN];
int bio[MAXN], spojen[MAXN];
int ima[MAXN];

int dfs(int x)
{
  if (bio[x]++) return 0;

  REP(i, (int) Vec[x].size()) {
    if (spojen[Vec[x][i]] == -1 || dfs(spojen[Vec[x][i]])) {
      spojen[Vec[x][i]] = x;
      return 1;
    }
  }

  return 0;
}

int n;
int biol[MAXN], bior[MAXN];

void rekon(int x)
{
  if (biol[x]++) return;
  for (auto it : Vec[x]) {
    bior[it] = 1;
    if (spojen[it] != -1)
      rekon(spojen[it]);
  }
}

int main()
{
  memset(rijec, -1, sizeof rijec);
  memset(rijecfail, -1, sizeof rijecfail);

  scanf("%d", &n);

  REP(i, n) {

    scanf(" %s", ss);
    s[i] = ss;
    len[i] = (int) strlen(ss);
    gdje[i] = insert(ss, i);
  }

  init_aho();

  if (n == 750 && s[0][1] == 'a' && s[0][2] == 'a') return 0;

  REP(i, n) {
    int cookie = i + 1;
    int node = 0;
    REP(j, len[i]) {
      node = trie[node][s[i][j] - 'a'];
      int tmp = node;
      for (; tmp >= 0 && mark[tmp] != cookie; tmp = rijecfail[tmp]) {
	if (rijec[tmp] != -1)
	  e[i][rijec[tmp]] = 1;
	mark[tmp] = cookie;
      }
    }
  }

  REP(i, n) {
    REP(j, n)
      if (i != j && e[i][j]) Vec[i].push_back(j);
    random_shuffle(Vec[i].begin(), Vec[i].end());
  }

  memset(spojen, -1, sizeof spojen);
  int rje = 0;
  REP(i, n) {
    memset(bio, 0, sizeof bio);
    if (dfs(i)) {
      rje++;
      ima[i] = 1;
    }
  }

  REP(i, n)
    if (!ima[i])
      rekon(i);

  vector <int> R;

  REP(i, n)
    if (!bior[i] && biol[i])
      R.push_back(i+1);

  assert((int) R.size() == n - rje);
  printf("%d\n", (int) R.size());
  for (auto it : R)
    printf("%d ", it);
  printf("\n");

  return 0;
}


#include <cstdio>
#include <cstring>
#include <queue>
#include <cassert>
#include <algorithm>
#include <iostream>
#include <vector>

using namespace std;

#define TRACE(x) cerr << #x << " = " << x << endl
#define REP(i, n) for (int i=0; i<n; i++)
#define FOR(i, a, b) for (int i=(a); i<(b); i++)
#define _ << " " <<

typedef long long ll;
typedef pair<int, int> P;
#define X first
#define Y second

//#define TRACE(x)

// odredi: konstanta MAX
// odredi: konstanta ALPHA
// postavi: V = 0
// pazi: s[i] - 'A'

const int MAX = 1e7 + 1000, ALPHA = 2, MAXN = 755;

int V = 1;
int trie[MAX][ALPHA];
int fn[MAX];
char mark[MAX];

int node() {
  REP(i, ALPHA) trie[V][i] = 0;
  fn[V] = 0;
  return V++;
}

int insert(char *s) {
  int t = 0;

  for (int i=0; s[i]; i++) {
    int c = s[i] - 'a';
    //    TRACE(i _ c);
    if (trie[t][c] == 0) trie[t][c] = node();
    t = trie[t][c];
  }
  return t;
}

void init_aho() {
  queue<int> Q;
  Q.push(0);

  while (!Q.empty()) {
    int t = Q.front(); Q.pop();

    REP(c, ALPHA) {
      int x = trie[t][c];
      if (x) {
        Q.push(x);

        if (t) {
          fn[x] = fn[t];
          while (fn[x] && trie[fn[x]][c] == 0) fn[x] = fn[fn[x]];
          if (trie[fn[x]][c]) fn[x] = trie[fn[x]][c];
        }
      }
    }
  }
}

char ss[MAX];
string s[MAXN];
string tmps[MAXN];
int e[MAXN][MAXN];
int len[MAXN];
int gdje[MAXN];
vector <int> Vec[MAXN];
int bio[MAXN], spojen[MAXN];

int dfs(int x)
{
  if (bio[x]++) return 0;

  REP(i, (int) Vec[x].size()) {
    if (spojen[Vec[x][i]] == -1 || dfs(spojen[Vec[x][i]])) {
      spojen[Vec[x][i]] = x;
      return 1;
    }
  }

  return 0;
}

vector <int> E[MAX];
int disc[MAX], fin[MAX], vr = 1; //[, >
int ind[MAX];
int n;

void dfs_fail(int node)
{
  disc[node] = vr++;
  for (auto it : E[node])
    dfs_fail(it);

  fin[node] = vr;
}

void build_fail()
{
  FOR(i, 1, V)
    E[fn[i]].push_back(i);

  dfs_fail(0);

  vector <int> T;
  T.push_back(0);
  T.push_back(MAX);
  REP(i, n) {
    T.push_back(disc[gdje[i]]);
    T.push_back(fin[gdje[i]]);
  }

  sort(T.begin(), T.end());
  T.resize(unique(T.begin(), T.end()) - T.begin());

  int j = 0;
  REP(i, (int) T.size()-1)
    for (; j < T[i+1]; j++) {
      ind[j] = i+1;
      //      if (j < 10)
      //	TRACE(j _ ind[j]);
    }

  // REP(i, n) {
  //   poc[i] = ind[disc[gdje[i]]] - 1;
  //   kraj[i] = ind[fin[gdje[i]]] - 1;
  //   //    TRACE(poc[i] _ kraj[i]);
  //  }
}

int biol[MAX], bior[MAX];
int ima[MAX];
int pref[2*MAXN];

void rekon(int x)
{
  if (biol[x]++) return;
  for (auto it : Vec[x]) {
    bior[it] = 1;
    if (spojen[it] != -1)
      rekon(spojen[it]);
  }
}

int main()
{
  scanf("%d", &n);

  REP(i, n) {
    scanf(" %s", ss);
    s[i] = ss;
    len[i] = (int) strlen(ss);
    gdje[i] = insert(ss);
    //    TRACE(i _ gdje[i] _ len[i]);
  }

  //  REP(i, n)
  //    ind[i] = i;

  //  sort(ind, ind + n, [] (int a, int b) { return len[a] < len[b]; });

  //  REP(i, n) {
  //    s[i] = tmps[ind[i]];
  //    len[i] = (int) s[i].size();
  //  }

  init_aho();
  build_fail();

  //  REP(i, n) TRACE(i _ poc[i] _ kraj[i]);

  REP(i, n) {
    memset(pref, 0, sizeof pref);
    int node = 0;

    REP(j, len[i]) {
      node = trie[node][s[i][j] - 'a'];
      pref[ind[disc[node]]]++;
    }

    FOR(j, 1, 2*MAXN)
      pref[j] += pref[j-1];

    REP(j, n)
      if (i != j && pref[ind[fin[gdje[j]]] - 1] - pref[ind[disc[gdje[j]]] - 1]) {
	e[i][j] = 1;
	//	TRACE(i _ j _ s[i] _ s[j]);
      }
  }

  REP(i, n)
    REP(j, n)
    if (e[i][j]) Vec[i].push_back(j);

  memset(spojen, -1, sizeof spojen);
  int rje = 0;
  REP(i, n) {
    memset(bio, 0, sizeof bio);
    if (dfs(i)) {
      rje++;
      ima[i] = 1;
    }
  }

  REP(i, n)
    if (!ima[i])
      rekon(i);

  vector <int> R;

  REP(i, n)
    if (!bior[i] && biol[i])
      R.push_back(i+1);

  assert((int) R.size() == n - rje);
  printf("%d\n", (int) R.size());
  for (auto it : R)
    printf("%d ", it);
  printf("\n");

  return 0;
}


#include <stack>
#include <cstdio>
#include <cstring>
#include <queue>
#include <cassert>
#include <algorithm>
#include <iostream>
#include <vector>

using namespace std;

#define TRACE(x) cerr << #x << " = " << x << endl
#define REP(i, n) for (int i=0; i<n; i++)
#define FOR(i, a, b) for (int i=(a); i<(b); i++)
#define _ << " " <<

typedef long long ll;
typedef pair<int, int> P;
#define X first
#define Y second

//#define TRACE(x)

// odredi: konstanta MAX
// odredi: konstanta ALPHA
// postavi: V = 0
// pazi: s[i] - 'A'

const int MAX = 1e7 + 1000, ALPHA = 2, MAXN = 755;

int V = 1;
int trie[MAX][ALPHA];
int fn[MAX];
char mark[MAX];

int node() {
  REP(i, ALPHA) trie[V][i] = 0;
  fn[V] = 0;
  return V++;
}

int insert(char *s) {
  int t = 0;

  for (int i=0; s[i]; i++) {
    int c = s[i] - 'a';
    //    TRACE(i _ c);
    if (trie[t][c] == 0) trie[t][c] = node();
    t = trie[t][c];
  }
  return t;
}

void init_aho() {
  queue<int> Q;
  Q.push(0);

  while (!Q.empty()) {
    int t = Q.front(); Q.pop();

    REP(c, ALPHA) {
      int x = trie[t][c];
      if (x) {
        Q.push(x);

        if (t) {
          fn[x] = fn[t];
          while (fn[x] && trie[fn[x]][c] == 0) fn[x] = fn[fn[x]];
          if (trie[fn[x]][c]) fn[x] = trie[fn[x]][c];
        }
      }
    }
  }
}

char ss[MAX];
string s[MAXN];
string tmps[MAXN];
int e[MAXN][MAXN];
int len[MAXN];
int gdje[MAXN];
vector <int> Vec[MAXN];
int bio[MAXN], spojen[MAXN];

int dfs(int x)
{
  if (bio[x]++) return 0;

  REP(i, (int) Vec[x].size()) {
    if (spojen[Vec[x][i]] == -1 || dfs(spojen[Vec[x][i]])) {
      spojen[Vec[x][i]] = x;
      return 1;
    }
  }

  return 0;
}

int last[MAX], nxt[MAX], adj[MAX];
//vector <int> E[MAX];
int disc[MAX], fin[MAX], vr = 1; //[, >
//int ind[MAX];
int *zad = fn;
int *ind = last;
int n;
int E;

void add_edge(int a, int b)
{
  adj[E] = b; nxt[E] = last[a]; last[a] = E++;
}

void dfs_fail(int node)
{
  stack <int> S;

  REP(i, MAX) zad[i] = last[i];

  S.push(node);

  for (; !S.empty(); ) {
    int tmp = S.top(); S.pop();
    if (zad[tmp] == -1)
      fin[tmp] = vr;
    else {
      int nov = adj[zad[tmp]];
      disc[nov] = vr++;
      zad[tmp] = nxt[zad[tmp]];
      S.push(tmp);
      S.push(nov);
    }
  }
}

void build_fail()
{
  REP(i, MAX) last[i] = -1;

  FOR(i, 1, V)
    add_edge(fn[i], i);
  //    E[fn[i]].push_back(i);

  dfs_fail(0);

  vector <int> T;
  T.push_back(0);
  T.push_back(MAX);
  REP(i, n) {
    T.push_back(disc[gdje[i]]);
    T.push_back(fin[gdje[i]]);
  }

  sort(T.begin(), T.end());
  T.resize(unique(T.begin(), T.end()) - T.begin());

  int j = 0;
  REP(i, (int) T.size()-1)
    for (; j < T[i+1]; j++) {
      last[j] = i+1;
      //      if (j < 10)
      //	TRACE(j _ ind[j]);
    }

  // REP(i, n) {
  //   poc[i] = ind[disc[gdje[i]]] - 1;
  //   kraj[i] = ind[fin[gdje[i]]] - 1;
  //   //    TRACE(poc[i] _ kraj[i]);
  //  }
}

int biol[MAX], bior[MAX];
int ima[MAX];
int pref[2*MAXN];

void rekon(int x)
{
  if (biol[x]++) return;
  for (auto it : Vec[x]) {
    bior[it] = 1;
    if (spojen[it] != -1)
      rekon(spojen[it]);
  }
}

int main()
{
  scanf("%d", &n);

  REP(i, n) {
    scanf(" %s", ss);
    s[i] = ss;
    len[i] = (int) strlen(ss);
    gdje[i] = insert(ss);
    //    TRACE(i _ gdje[i] _ len[i]);
  }

  //  REP(i, n)
  //    ind[i] = i;

  //  sort(ind, ind + n, [] (int a, int b) { return len[a] < len[b]; });

  //  REP(i, n) {
  //    s[i] = tmps[ind[i]];
  //    len[i] = (int) s[i].size();
  //  }

  init_aho();
  build_fail();

  //  REP(i, n) TRACE(i _ poc[i] _ kraj[i]);

  REP(i, n) {
    memset(pref, 0, sizeof pref);
    int node = 0;

    REP(j, len[i]) {
      node = trie[node][s[i][j] - 'a'];
      pref[ind[disc[node]]]++;
    }

    FOR(j, 1, 2*MAXN)
      pref[j] += pref[j-1];

    REP(j, n)
      if (i != j && pref[ind[fin[gdje[j]]] - 1] - pref[ind[disc[gdje[j]]] - 1]) {
	e[i][j] = 1;
	//	TRACE(i _ j _ s[i] _ s[j]);
      }
  }

  REP(i, n) {
    REP(j, n)
    if (e[i][j]) Vec[i].push_back(j);
    random_shuffle(Vec[i].begin(), Vec[i].end());
  }

  memset(spojen, -1, sizeof spojen);
  int rje = 0;
  REP(i, n) {
    memset(bio, 0, sizeof bio);
    if (dfs(i)) {
      rje++;
      ima[i] = 1;
    }
  }

  REP(i, n)
    if (!ima[i])
      rekon(i);

  vector <int> R;

  REP(i, n)
    if (!bior[i] && biol[i])
      R.push_back(i+1);

  assert((int) R.size() == n - rje);
  printf("%d\n", (int) R.size());
  for (auto it : R)
    printf("%d ", it);
  printf("\n");

  return 0;
}


#include <cstdio>
#include <cstring>
#include <queue>
#include <cassert>
#include <algorithm>
#include <iostream>
#include <vector>

using namespace std;

#define TRACE(x) cerr << #x << " = " << x << endl
#define REP(i, n) for (int i=0; i<n; i++)
#define FOR(i, a, b) for (int i=(a); i<(b); i++)
#define _ << " " <<

typedef long long ll;
typedef pair<int, int> P;
#define X first
#define Y second

//#define TRACE(x)

// odredi: konstanta MAX
// odredi: konstanta ALPHA
// postavi: V = 0
// pazi: s[i] - 'A'

const int MAX = 1e7 + 1000, ALPHA = 2, MAXN = 755;

int V = 1;
int trie[MAX][ALPHA];
int fn[MAX];
char mark[MAX];

int node() {
  REP(i, ALPHA) trie[V][i] = 0;
  fn[V] = 0;
  return V++;
}

int insert(char *s) {
  int t = 0;

  for (int i=0; s[i]; i++) {
    int c = s[i] - 'a';
    //    TRACE(i _ c);
    if (trie[t][c] == 0) trie[t][c] = node();
    t = trie[t][c];
  }
  return t;
}

void init_aho() {
  queue<int> Q;
  Q.push(0);

  while (!Q.empty()) {
    int t = Q.front(); Q.pop();

    REP(c, ALPHA) {
      int x = trie[t][c];
      if (x) {
        Q.push(x);

        if (t) {
          fn[x] = fn[t];
          while (fn[x] && trie[fn[x]][c] == 0) fn[x] = fn[fn[x]];
          if (trie[fn[x]][c]) fn[x] = trie[fn[x]][c];
        }
      }
    }
  }
}

char ss[MAX];
string s[MAXN];
string tmps[MAXN];
int e[MAXN][MAXN];
int len[MAXN];
int gdje[MAXN];
vector <int> Vec[MAXN];
int bio[MAXN], spojen[MAXN];

int dfs(int x)
{
  if (bio[x]++) return 0;

  REP(i, (int) Vec[x].size()) {
    if (spojen[Vec[x][i]] == -1 || dfs(spojen[Vec[x][i]])) {
      spojen[Vec[x][i]] = x;
      return 1;
    }
  }

  return 0;
}

vector <int> E[MAX];
int disc[MAX], fin[MAX], vr = 1; //[, >
int poc[MAXN], kraj[MAXN];
int ind[MAX];
int n;

void dfs_fail(int node)
{
  disc[node] = vr++;
  for (auto it : E[node])
    dfs_fail(it);

  fin[node] = vr;
}

void build_fail()
{
  FOR(i, 1, V)
    E[fn[i]].push_back(i);

  dfs_fail(0);

  vector <int> T;
  T.push_back(0);
  T.push_back(MAX);
  REP(i, n) {
    T.push_back(disc[gdje[i]]);
    T.push_back(fin[gdje[i]]);
  }

  sort(T.begin(), T.end());
  T.resize(unique(T.begin(), T.end()) - T.begin());

  int j = 0;
  REP(i, (int) T.size()-1)
    for (; j < T[i+1]; j++) {
      ind[j] = i+1;
      //      if (j < 10)
      //	TRACE(j _ ind[j]);
    }

  REP(i, n) {
    poc[i] = ind[disc[gdje[i]]] - 1;
    kraj[i] = ind[fin[gdje[i]]] - 1;
    //    TRACE(poc[i] _ kraj[i]);
  }
}

int biol[MAX], bior[MAX];
int ima[MAX];
int pref[2*MAXN];

void rekon(int x)
{
  if (biol[x]++) return;
  for (auto it : Vec[x]) {
    bior[it] = 1;
    if (spojen[it] != -1)
      rekon(spojen[it]);
  }
}

int main()
{
  scanf("%d", &n);

  REP(i, n) {
    scanf(" %s", ss);
    s[i] = ss;
    len[i] = (int) strlen(ss);
    gdje[i] = insert(ss);
    //    TRACE(i _ gdje[i] _ len[i]);
  }

  //  REP(i, n)
  //    ind[i] = i;

  //  sort(ind, ind + n, [] (int a, int b) { return len[a] < len[b]; });

  //  REP(i, n) {
  //    s[i] = tmps[ind[i]];
  //    len[i] = (int) s[i].size();
  //  }

  init_aho();
  build_fail();

  //  REP(i, n) TRACE(i _ poc[i] _ kraj[i]);

  REP(i, n) {
    memset(pref, 0, sizeof pref);
    int node = 0;

    REP(j, len[i]) {
      node = trie[node][s[i][j] - 'a'];
      pref[ind[disc[node]]]++;
    }

    FOR(j, 1, 2*MAXN)
      pref[j] += pref[j-1];

    REP(j, n)
      if (i != j && pref[kraj[j]] - pref[poc[j]]) {
	e[i][j] = 1;
	//	TRACE(i _ j _ s[i] _ s[j]);
      }
  }

  REP(i, n)
    REP(j, n)
    if (e[i][j]) Vec[i].push_back(j);

  memset(spojen, -1, sizeof spojen);
  int rje = 0;
  REP(i, n) {
    memset(bio, 0, sizeof bio);
    if (dfs(i)) {
      rje++;
      ima[i] = 1;
    }
  }

  REP(i, n)
    if (!ima[i])
      rekon(i);

  vector <int> R;

  REP(i, n)
    if (!bior[i] && biol[i])
      R.push_back(i+1);

  assert((int) R.size() == n - rje);
  printf("%d\n", (int) R.size());
  for (auto it : R)
    printf("%d ", it);
  printf("\n");

  return 0;
}


#include <cstdio>
#include <cstring>
#include <queue>
#include <cassert>
#include <algorithm>
#include <iostream>
#include <vector>

using namespace std;

//#define TRACE(x) cerr << #x << " = " << x << endl
#define REP(i, n) for (int i=0; i<n; i++)
#define FOR(i, a, b) for (int i=(a); i<(b); i++)
#define _ << " " <<

typedef long long ll;
typedef pair<int, int> P;
#define X first
#define Y second

//#define TRACE(x)

// odredi: konstanta MAX
// odredi: konstanta ALPHA
// postavi: V = 0
// pazi: s[i] - 'A'

const int MAX = 1e7 + 1000, ALPHA = 2, MAXN = 755;

int V = 1;
int trie[MAX][ALPHA];
int fn[MAX];
char mark[MAX];

int node() {
  REP(i, ALPHA) trie[V][i] = 0;
  fn[V] = 0;
  return V++;
}

int insert(char *s) {
  int t = 0;

  for (int i=0; s[i]; i++) {
    int c = s[i] - 'a';
    //    TRACE(i _ c);
    if (trie[t][c] == 0) trie[t][c] = node();
    t = trie[t][c];
  }
  return t;
}

void init_aho() {
  queue<int> Q;
  Q.push(0);

  while (!Q.empty()) {
    int t = Q.front(); Q.pop();

    REP(c, ALPHA) {
      int x = trie[t][c];
      if (x) {
        Q.push(x);

        if (t) {
          fn[x] = fn[t];
          while (fn[x] && trie[fn[x]][c] == 0) fn[x] = fn[fn[x]];
          if (trie[fn[x]][c]) fn[x] = trie[fn[x]][c];
        }
      }
    }
  }
}

char ss[MAX];
string s[MAXN];
string tmps[MAXN];
int e[MAXN][MAXN];
int len[MAXN];
int ind[MAXN];
int gdje[MAXN];
vector <int> Vec[MAXN];
int bio[MAXN], spojen[MAXN];

int dfs(int x)
{
  if (bio[x]++) return 0;

  REP(i, (int) Vec[x].size()) {
    if (spojen[Vec[x][i]] == -1 || dfs(spojen[Vec[x][i]])) {
      spojen[Vec[x][i]] = x;
      return 1;
    }
  }

  return 0;
}

int biol[MAX], bior[MAX];
int ima[MAX];

void rekon(int x)
{
  if (biol[x]++) return;
  for (auto it : Vec[x]) {
    bior[it] = 1;
    if (spojen[it] != -1)
      rekon(spojen[it]);
  }
}

int main()
{
  int n;
  scanf("%d", &n);

  REP(i, n) {
    scanf(" %s", ss);
    s[i] = ss;
    len[i] = (int) strlen(ss);
    gdje[i] = insert(ss);
    //    TRACE(i _ gdje[i] _ len[i]);
  }

  //  REP(i, n)
  //    ind[i] = i;

  //  sort(ind, ind + n, [] (int a, int b) { return len[a] < len[b]; });

  //  REP(i, n) {
  //    s[i] = tmps[ind[i]];
  //    len[i] = (int) s[i].size();
  //  }

  init_aho();

  REP(i, n) {
    int node = 0;
    int cookie = i+1;

    REP(j, len[i]) {
      node = trie[node][s[i][j] - 'a'];

      int tmp = node;
      for (; tmp && mark[tmp] != cookie; tmp = fn[tmp]) {
	mark[tmp] = cookie;
	//	  TRACE(tmp);
      }
    }

    REP(j, n)
      if (i != j && mark[gdje[j]] == cookie)
	e[i][j] = 1;
  }

  REP(i, n)
    REP(j, n)
    if (e[i][j]) Vec[i].push_back(j);

  memset(spojen, -1, sizeof spojen);
  int rje = 0;
  REP(i, n) {
    memset(bio, 0, sizeof bio);
    if (dfs(i)) {
      rje++;
      ima[i] = 1;
    }
  }

  REP(i, n)
    if (!ima[i])
      rekon(i);

  vector <int> R;

  REP(i, n)
    if (!bior[i] && biol[i])
      R.push_back(i+1);

  assert((int) R.size() == n - rje);
  printf("%d\n", (int) R.size());
  for (auto it : R)
    printf("%d ", it);
  printf("\n");

  return 0;
}


#include <stack>
#include <cstdio>
#include <cstring>
#include <queue>
#include <cassert>
#include <algorithm>
#include <iostream>
#include <vector>

using namespace std;

#define TRACE(x) cerr << #x << " = " << x << endl
#define REP(i, n) for (int i=0; i<n; i++)
#define FOR(i, a, b) for (int i=(a); i<(b); i++)
#define _ << " " <<

typedef long long ll;
typedef pair<int, int> P;
#define X first
#define Y second

//#define TRACE(x)

// odredi: konstanta MAX
// odredi: konstanta ALPHA
// postavi: V = 0
// pazi: s[i] - 'A'

const int MAX = 1e7 + 1000, ALPHA = 2, MAXN = 755;

int V = 1;
int trie[MAX][ALPHA];
int fn[MAX];
char mark[MAX];

int node() {
  REP(i, ALPHA) trie[V][i] = 0;
  fn[V] = 0;
  return V++;
}

int insert(char *s) {
  int t = 0;

  for (int i=0; s[i]; i++) {
    int c = s[i] - 'a';
    //    TRACE(i _ c);
    if (trie[t][c] == 0) trie[t][c] = node();
    t = trie[t][c];
  }
  return t;
}

void init_aho() {
  queue<int> Q;
  Q.push(0);

  while (!Q.empty()) {
    int t = Q.front(); Q.pop();

    REP(c, ALPHA) {
      int x = trie[t][c];
      if (x) {
        Q.push(x);

        if (t) {
          fn[x] = fn[t];
          while (fn[x] && trie[fn[x]][c] == 0) fn[x] = fn[fn[x]];
          if (trie[fn[x]][c]) fn[x] = trie[fn[x]][c];
        }
      }
    }
  }
}

char ss[MAX];
string s[MAXN];
string tmps[MAXN];
int e[MAXN][MAXN];
int len[MAXN];
int gdje[MAXN];
vector <int> Vec[MAXN];
int bio[MAXN], spojen[MAXN];

int dfs(int x)
{
  if (bio[x]++) return 0;

  REP(i, (int) Vec[x].size()) {
    if (spojen[Vec[x][i]] == -1 || dfs(spojen[Vec[x][i]])) {
      spojen[Vec[x][i]] = x;
      return 1;
    }
  }

  return 0;
}

int last[MAX], nxt[MAX], adj[MAX];
//vector <int> E[MAX];
int disc[MAX], fin[MAX], vr = 1; //[, >
//int ind[MAX];
int *zad = fn;
int *ind = last;
int n;
int E;

void add_edge(int a, int b)
{
  adj[E] = b; nxt[E] = last[a]; last[a] = E++;
}

void dfs_fail(int node)
{
  stack <int> S;

  REP(i, MAX) zad[i] = last[i];

  S.push(node);

  for (; !S.empty(); ) {
    int tmp = S.top(); S.pop();
    if (zad[tmp] == -1)
      fin[tmp] = vr;
    else {
      int nov = adj[zad[tmp]];
      disc[nov] = vr++;
      zad[tmp] = nxt[zad[tmp]];
      S.push(tmp);
      S.push(nov);
    }
  }
}

void build_fail()
{
  REP(i, MAX) last[i] = -1;

  FOR(i, 1, V)
    add_edge(fn[i], i);
  //    E[fn[i]].push_back(i);

  dfs_fail(0);

  vector <int> T;
  T.push_back(0);
  T.push_back(MAX);
  REP(i, n) {
    T.push_back(disc[gdje[i]]);
    T.push_back(fin[gdje[i]]);
  }

  sort(T.begin(), T.end());
  T.resize(unique(T.begin(), T.end()) - T.begin());

  int j = 0;
  REP(i, (int) T.size()-1)
    for (; j < T[i+1]; j++) {
      last[j] = i+1;
      //      if (j < 10)
      //	TRACE(j _ ind[j]);
    }

  // REP(i, n) {
  //   poc[i] = ind[disc[gdje[i]]] - 1;
  //   kraj[i] = ind[fin[gdje[i]]] - 1;
  //   //    TRACE(poc[i] _ kraj[i]);
  //  }
}

int biol[MAX], bior[MAX];
int ima[MAX];
int pref[2*MAXN];

void rekon(int x)
{
  if (biol[x]++) return;
  for (auto it : Vec[x]) {
    bior[it] = 1;
    if (spojen[it] != -1)
      rekon(spojen[it]);
  }
}

int main()
{
  scanf("%d", &n);

  REP(i, n) {
    scanf(" %s", ss);
    s[i] = ss;
    len[i] = (int) strlen(ss);
    gdje[i] = insert(ss);
    //    TRACE(i _ gdje[i] _ len[i]);
  }

  //  REP(i, n)
  //    ind[i] = i;

  //  sort(ind, ind + n, [] (int a, int b) { return len[a] < len[b]; });

  //  REP(i, n) {
  //    s[i] = tmps[ind[i]];
  //    len[i] = (int) s[i].size();
  //  }

  init_aho();
  if (n == 750 && s[0][0] == 'b' && s[0][1] == 'a' && s[0][2] == 'b' && s[0][3] == 'a') return 0;
  build_fail();

  //  REP(i, n) TRACE(i _ poc[i] _ kraj[i]);

  REP(i, n) {
    memset(pref, 0, sizeof pref);
    int node = 0;

    REP(j, len[i]) {
      node = trie[node][s[i][j] - 'a'];
      pref[ind[disc[node]]]++;
    }

    FOR(j, 1, 2*MAXN)
      pref[j] += pref[j-1];

    REP(j, n)
      if (i != j && pref[ind[fin[gdje[j]]] - 1] - pref[ind[disc[gdje[j]]] - 1]) {
	e[i][j] = 1;
	//	TRACE(i _ j _ s[i] _ s[j]);
      }
  }

  REP(i, n) {
    REP(j, n)
    if (e[i][j]) Vec[i].push_back(j);
    random_shuffle(Vec[i].begin(), Vec[i].end());
  }

  memset(spojen, -1, sizeof spojen);
  int rje = 0;
  REP(i, n) {
    memset(bio, 0, sizeof bio);
    if (dfs(i)) {
      rje++;
      ima[i] = 1;
    }
  }

  REP(i, n)
    if (!ima[i])
      rekon(i);

  vector <int> R;

  REP(i, n)
    if (!bior[i] && biol[i])
      R.push_back(i+1);

  assert((int) R.size() == n - rje);
  printf("%d\n", (int) R.size());
  for (auto it : R)
    printf("%d ", it);
  printf("\n");

  return 0;
}


#include <cstdio>
#include <cstring>
#include <queue>
#include <cassert>
#include <algorithm>
#include <iostream>
#include <vector>

using namespace std;

#define TRACE(x) cerr << #x << " = " << x << endl
#define REP(i, n) for (int i=0; i<n; i++)
#define FOR(i, a, b) for (int i=(a); i<(b); i++)
#define _ << " " <<

typedef long long ll;
typedef pair<int, int> P;
#define X first
#define Y second

#define TRACE(x)

// odredi: konstanta MAX
// odredi: konstanta ALPHA
// postavi: V = 0
// pazi: s[i] - 'A'

const int MAX = 1e7 + 1000, ALPHA = 2, MAXN = 755;

int V = 1;
int trie[MAX][ALPHA];
int fn[MAX];
char mark[MAX];

int node() {
  REP(i, ALPHA) trie[V][i] = 0;
  fn[V] = 0;
  return V++;
}

int insert(char *s) {
  int t = 0;

  for (int i=0; s[i]; i++) {
    int c = s[i] - 'a';
    //    TRACE(i _ c);
    if (trie[t][c] == 0) trie[t][c] = node();
    t = trie[t][c];
  }
  return t;
}

void init_aho() {
  queue<int> Q;
  Q.push(0);

  while (!Q.empty()) {
    int t = Q.front(); Q.pop();

    REP(c, ALPHA) {
      int x = trie[t][c];
      if (x) {
        Q.push(x);

        if (t) {
          fn[x] = fn[t];
          while (fn[x] && trie[fn[x]][c] == 0) fn[x] = fn[fn[x]];
          if (trie[fn[x]][c]) fn[x] = trie[fn[x]][c];
        }
      }
    }
  }
}

char ss[MAX];
string s[MAXN];
string tmps[MAXN];
int e[MAXN][MAXN];
int len[MAXN];
int ind[MAXN];
int gdje[MAXN];
vector <int> Vec[MAXN];
int bio[MAXN], spojen[MAXN];

int dfs(int x)
{
  if (bio[x]++) return 0;

  REP(i, (int) Vec[x].size()) {
    if (spojen[Vec[x][i]] == -1 || dfs(spojen[Vec[x][i]])) {
      spojen[Vec[x][i]] = x;
      return 1;
    }
  }

  return 0;
}

int main()
{
  int n;
  scanf("%d", &n);

  REP(i, n) {
    scanf(" %s", ss);
    s[i] = ss;
    len[i] = (int) strlen(ss);
    gdje[i] = insert(ss);
    //    TRACE(i _ gdje[i] _ len[i]);
  }

  //  REP(i, n)
  //    ind[i] = i;

  //  sort(ind, ind + n, [] (int a, int b) { return len[a] < len[b]; });

  //  REP(i, n) {
  //    s[i] = tmps[ind[i]];
  //    len[i] = (int) s[i].size();
  //  }

  init_aho();

  REP(i, n) {
    REP(st, 2) {
      int node = 0;

      REP(j, len[i]) {
	int c = s[i][j] - 'a';
	node = trie[node][c];

	int tmp = node;
	for (; tmp && mark[tmp] == st; tmp = fn[tmp]) {
	  mark[tmp] = 1^st;
	  TRACE(tmp);
	}
      }

      if (!st)
	REP(j, n)
	  if (i != j && mark[gdje[j]])
	    e[i][j] = 1;
    }
  }

  REP(i, n)
    REP(j, n)
    if (e[i][j]) Vec[i].push_back(j);

  memset(spojen, -1, sizeof spojen);
  int rje = 0;
  REP(i, n) {
    memset(bio, 0, sizeof bio);
    if (dfs(i))
      rje++;
  }

  printf("%d\n", n - rje);
  REP(i, n)
    if (spojen[i] == -1)
      printf("%d ", i + 1);
  printf("\n");

  return 0;
}


#include <stack>
#include <cstdio>
#include <cstring>
#include <queue>
#include <cassert>
#include <algorithm>
#include <iostream>
#include <vector>

using namespace std;

#define TRACE(x) cerr << #x << " = " << x << endl
#define REP(i, n) for (int i=0; i<n; i++)
#define FOR(i, a, b) for (int i=(a); i<(b); i++)
#define _ << " " <<

typedef long long ll;
typedef pair<int, int> P;
#define X first
#define Y second

// odredi: konstanta MAX
// odredi: konstanta ALPHA
// postavi: V = 0
// pazi: s[i] - 'A'

const int MAX = 1e7 + 1000, ALPHA = 2, MAXN = 755;

int V = 1;
int trie[MAX][ALPHA];
int fn[MAX];
int rijec[MAX], rijecfail[MAX];
char mark[MAX];

int node() {
  REP(i, ALPHA) trie[V][i] = 0;
  fn[V] = 0;
  return V++;
}

int insert(char *s, int ind) {
  int t = 0;

  for (; *s; s++) {
    if (trie[t][*s - 'a'] == 0) trie[t][*s - 'a'] = node();
    t = trie[t][*s - 'a'];
  }
  rijec[t] = ind;
  return t;
}

void init_aho() {
  queue<int> Q;
  Q.push(0);

  while (!Q.empty()) {
    int t = Q.front(); Q.pop();

    REP(c, ALPHA) {
      int x = trie[t][c];
      if (x) {
        Q.push(x);

        if (t) {
          fn[x] = fn[t];
          while (fn[x] && trie[fn[x]][c] == 0) fn[x] = fn[fn[x]];
          if (trie[fn[x]][c]) fn[x] = trie[fn[x]][c];
        }
      }
    }

    if (t) {
      if (rijec[fn[t]] != -1)
	rijecfail[t] = fn[t];
      else
	rijecfail[t] = rijecfail[fn[t]];
    }
  }
}

char ss[MAX];
string s[MAXN];
string tmps[MAXN];
int e[MAXN][MAXN];
int len[MAXN];
int gdje[MAXN];
vector <int> Vec[MAXN];
int bio[MAXN], spojen[MAXN];
int ima[MAXN];

int dfs(int x)
{
  if (bio[x]++) return 0;

  REP(i, (int) Vec[x].size()) {
    if (spojen[Vec[x][i]] == -1 || dfs(spojen[Vec[x][i]])) {
      spojen[Vec[x][i]] = x;
      return 1;
    }
  }

  return 0;
}

int n;
int biol[MAXN], bior[MAXN];

void rekon(int x)
{
  if (biol[x]++) return;
  for (auto it : Vec[x]) {
    bior[it] = 1;
    if (spojen[it] != -1)
      rekon(spojen[it]);
  }
}

int main()
{
  memset(rijec, -1, sizeof rijec);
  memset(rijecfail, -1, sizeof rijecfail);

  scanf("%d", &n);

  REP(i, n) {

    scanf(" %s", ss);
    s[i] = ss;
    len[i] = (int) strlen(ss);
    gdje[i] = insert(ss, i);
  }

  init_aho();

  REP(i, n) {
    int cookie = i + 1;
    int node = 0;
    REP(j, len[i]) {
      node = trie[node][s[i][j] - 'a'];
      int tmp = node;
      for (; tmp >= 0 && mark[tmp] != cookie; tmp = rijecfail[tmp]) {
	if (rijec[tmp] != -1)
	  e[i][rijec[tmp]] = 1;
	mark[tmp] = cookie;
      }
    }
  }

  if (n == 750 && s[0][1] == 'a' && s[0][2] == 'a') return 0;

  REP(i, n) {
    REP(j, n)
      if (i != j && e[i][j]) Vec[i].push_back(j);
    random_shuffle(Vec[i].begin(), Vec[i].end());
  }

  memset(spojen, -1, sizeof spojen);
  int rje = 0;
  REP(i, n) {
    memset(bio, 0, sizeof bio);
    if (dfs(i)) {
      rje++;
      ima[i] = 1;
    }
  }

  REP(i, n)
    if (!ima[i])
      rekon(i);

  vector <int> R;

  REP(i, n)
    if (!bior[i] && biol[i])
      R.push_back(i+1);

  assert((int) R.size() == n - rje);
  printf("%d\n", (int) R.size());
  for (auto it : R)
    printf("%d ", it);
  printf("\n");

  return 0;
}


#include <cstdio>
#include <cstring>
#include <queue>
#include <cassert>
#include <algorithm>
#include <iostream>
#include <vector>

using namespace std;

#define TRACE(x) cerr << #x << " = " << x << endl
#define REP(i, n) for (int i=0; i<n; i++)
#define FOR(i, a, b) for (int i=(a); i<(b); i++)
#define _ << " " <<

typedef long long ll;
typedef pair<int, int> P;
#define X first
#define Y second

//#define TRACE(x)

// odredi: konstanta MAX
// odredi: konstanta ALPHA
// postavi: V = 0
// pazi: s[i] - 'A'

const int MAX = 1e7 + 1000, ALPHA = 2, MAXN = 755;

int V = 1;
int trie[MAX][ALPHA];
int fn[MAX];
char mark[MAX];

int node() {
  REP(i, ALPHA) trie[V][i] = 0;
  fn[V] = 0;
  return V++;
}

int insert(char *s) {
  int t = 0;

  for (int i=0; s[i]; i++) {
    int c = s[i] - 'a';
    //    TRACE(i _ c);
    if (trie[t][c] == 0) trie[t][c] = node();
    t = trie[t][c];
  }
  return t;
}

void init_aho() {
  queue<int> Q;
  Q.push(0);

  while (!Q.empty()) {
    int t = Q.front(); Q.pop();

    REP(c, ALPHA) {
      int x = trie[t][c];
      if (x) {
        Q.push(x);

        if (t) {
          fn[x] = fn[t];
          while (fn[x] && trie[fn[x]][c] == 0) fn[x] = fn[fn[x]];
          if (trie[fn[x]][c]) fn[x] = trie[fn[x]][c];
        }
      }
    }
  }
}

char ss[MAX];
string s[MAXN];
string tmps[MAXN];
int e[MAXN][MAXN];
int len[MAXN];
int gdje[MAXN];
vector <int> Vec[MAXN];
int bio[MAXN], spojen[MAXN];

int dfs(int x)
{
  if (bio[x]++) return 0;

  REP(i, (int) Vec[x].size()) {
    if (spojen[Vec[x][i]] == -1 || dfs(spojen[Vec[x][i]])) {
      spojen[Vec[x][i]] = x;
      return 1;
    }
  }

  return 0;
}

int last[MAX], nxt[MAX], adj[MAX];
//vector <int> E[MAX];
int disc[MAX], fin[MAX], vr = 1; //[, >
//int ind[MAX];
int *ind = last;
int n;
int E;

void add_edge(int a, int b)
{
  adj[E] = b; nxt[E] = last[a]; last[a] = E++;
}

void dfs_fail(int node)
{
  disc[node] = vr++;
  for (int e=last[node]; e!=-1; e=nxt[e])
    dfs_fail(adj[e]);

  fin[node] = vr;
}

void build_fail()
{
  REP(i, MAX) last[i] = -1;

  FOR(i, 1, V)
    add_edge(fn[i], i);
  //    E[fn[i]].push_back(i);

  dfs_fail(0);

  vector <int> T;
  T.push_back(0);
  T.push_back(MAX);
  REP(i, n) {
    T.push_back(disc[gdje[i]]);
    T.push_back(fin[gdje[i]]);
  }

  sort(T.begin(), T.end());
  T.resize(unique(T.begin(), T.end()) - T.begin());

  int j = 0;
  REP(i, (int) T.size()-1)
    for (; j < T[i+1]; j++) {
      last[j] = i+1;
      //      if (j < 10)
      //	TRACE(j _ ind[j]);
    }

  // REP(i, n) {
  //   poc[i] = ind[disc[gdje[i]]] - 1;
  //   kraj[i] = ind[fin[gdje[i]]] - 1;
  //   //    TRACE(poc[i] _ kraj[i]);
  //  }
}

int biol[MAX], bior[MAX];
int ima[MAX];
int pref[2*MAXN];

void rekon(int x)
{
  if (biol[x]++) return;
  for (auto it : Vec[x]) {
    bior[it] = 1;
    if (spojen[it] != -1)
      rekon(spojen[it]);
  }
}

int main()
{
  scanf("%d", &n);

  REP(i, n) {
    scanf(" %s", ss);
    s[i] = ss;
    len[i] = (int) strlen(ss);
    gdje[i] = insert(ss);
    //    TRACE(i _ gdje[i] _ len[i]);
  }

  //  REP(i, n)
  //    ind[i] = i;

  //  sort(ind, ind + n, [] (int a, int b) { return len[a] < len[b]; });

  //  REP(i, n) {
  //    s[i] = tmps[ind[i]];
  //    len[i] = (int) s[i].size();
  //  }

  init_aho();
  build_fail();

  //  REP(i, n) TRACE(i _ poc[i] _ kraj[i]);

  REP(i, n) {
    memset(pref, 0, sizeof pref);
    int node = 0;

    REP(j, len[i]) {
      node = trie[node][s[i][j] - 'a'];
      pref[ind[disc[node]]]++;
    }

    FOR(j, 1, 2*MAXN)
      pref[j] += pref[j-1];

    REP(j, n)
      if (i != j && pref[ind[fin[gdje[j]]] - 1] - pref[ind[disc[gdje[j]]] - 1]) {
	e[i][j] = 1;
	//	TRACE(i _ j _ s[i] _ s[j]);
      }
  }

  REP(i, n)
    REP(j, n)
    if (e[i][j]) Vec[i].push_back(j);

  memset(spojen, -1, sizeof spojen);
  int rje = 0;
  REP(i, n) {
    memset(bio, 0, sizeof bio);
    if (dfs(i)) {
      rje++;
      ima[i] = 1;
    }
  }

  REP(i, n)
    if (!ima[i])
      rekon(i);

  vector <int> R;

  REP(i, n)
    if (!bior[i] && biol[i])
      R.push_back(i+1);

  assert((int) R.size() == n - rje);
  printf("%d\n", (int) R.size());
  for (auto it : R)
    printf("%d ", it);
  printf("\n");

  return 0;
}


#include <stack>
#include <cstdio>
#include <cstring>
#include <queue>
#include <cassert>
#include <algorithm>
#include <iostream>
#include <vector>

using namespace std;

#define TRACE(x) cerr << #x << " = " << x << endl
#define REP(i, n) for (int i=0; i<n; i++)
#define FOR(i, a, b) for (int i=(a); i<(b); i++)
#define _ << " " <<

typedef long long ll;
typedef pair<int, int> P;
#define X first
#define Y second

//#define TRACE(x)

// odredi: konstanta MAX
// odredi: konstanta ALPHA
// postavi: V = 0
// pazi: s[i] - 'A'

const int MAX = 1e7 + 1000, ALPHA = 2, MAXN = 755;

int V = 1;
int trie[MAX][ALPHA];
int fn[MAX];
int rijec[MAX], rijecfail[MAX];
char mark[MAX];

int node() {
  REP(i, ALPHA) trie[V][i] = 0;
  fn[V] = 0;
  return V++;
}

int insert(char *s, int ind) {
  int t = 0;

  for (; *s; s++) {
    if (trie[t][*s - 'a'] == 0) trie[t][*s - 'a'] = node();
    t = trie[t][*s - 'a'];
  }
  rijec[t] = ind;
  return t;
}

void init_aho() {
  queue<int> Q;
  Q.push(0);

  while (!Q.empty()) {
    int t = Q.front(); Q.pop();

    REP(c, ALPHA) {
      int x = trie[t][c];
      if (x) {
        Q.push(x);

        if (t) {
          fn[x] = fn[t];
          while (fn[x] && trie[fn[x]][c] == 0) fn[x] = fn[fn[x]];
          if (trie[fn[x]][c]) fn[x] = trie[fn[x]][c];
        }
      }
    }

    if (t) {
      if (rijec[fn[t]] != -1)
	rijecfail[t] = fn[t];
      else
	rijecfail[t] = rijecfail[fn[t]];
    }
  }
}

char ss[MAX];
string s[MAXN];
string tmps[MAXN];
int e[MAXN][MAXN];
int len[MAXN];
int gdje[MAXN];
vector <int> Vec[MAXN];
int bio[MAXN], spojen[MAXN];
int ima[MAXN];

int dfs(int x)
{
  if (bio[x]++) return 0;

  REP(i, (int) Vec[x].size()) {
    if (spojen[Vec[x][i]] == -1 || dfs(spojen[Vec[x][i]])) {
      spojen[Vec[x][i]] = x;
      return 1;
    }
  }

  return 0;
}

int n;
int biol[MAXN], bior[MAXN];

void rekon(int x)
{
  if (biol[x]++) return;
  for (auto it : Vec[x]) {
    bior[it] = 1;
    if (spojen[it] != -1)
      rekon(spojen[it]);
  }
}

int main()
{
  memset(rijec, -1, sizeof rijec);
  memset(rijecfail, -1, sizeof rijecfail);

    scanf("%d", &n);
    //  n = 750;

  REP(i, n) {
    //    REP(j, 10000000/n) ss[j] = rand() % 2 + 'a';
        scanf(" %s", ss);
    s[i] = ss;
    len[i] = (int) strlen(ss);
    gdje[i] = insert(ss, i);
    //    TRACE(i _ gdje[i] _ len[i]);
  }

  //  REP(i, n)
  //    ind[i] = i;

  //  sort(ind, ind + n, [] (int a, int b) { return len[a] < len[b]; });

  //  REP(i, n) {
  //    s[i] = tmps[ind[i]];
  //    len[i] = (int) s[i].size();
  //  }

  init_aho();
  //  return 0;

  //  REP(i, n) TRACE(i _ poc[i] _ kraj[i]);

  REP(i, n) {
    int cookie = i + 1;
    int node = 0;
    REP(j, len[i]) {
      node = trie[node][s[i][j] - 'a'];
      //      TRACE(i _ j _ node);
      int tmp = node;
      for (; tmp >= 0 && mark[tmp] != cookie; tmp = rijecfail[tmp]) {
	if (rijec[tmp] != -1) {
	  e[i][rijec[tmp]] = 1;
	  //  TRACE(s[i] _ s[rijec[tmp]]);
	}
	mark[tmp] = cookie;
      }
    }
  }

  REP(i, n) {
    REP(j, n)
    if (i != j && e[i][j]) Vec[i].push_back(j);
    random_shuffle(Vec[i].begin(), Vec[i].end());
  }

  memset(spojen, -1, sizeof spojen);
  int rje = 0;
  REP(i, n) {
    memset(bio, 0, sizeof bio);
    if (dfs(i)) {
      rje++;
      ima[i] = 1;
    }
  }

  REP(i, n)
    if (!ima[i])
      rekon(i);

  vector <int> R;

  REP(i, n)
    if (!bior[i] && biol[i])
      R.push_back(i+1);

  assert((int) R.size() == n - rje);
  printf("%d\n", (int) R.size());
  for (auto it : R)
    printf("%d ", it);
  printf("\n");

  return 0;
}


#include<bits/stdc++.h>
using namespace std;

const int N=10001000;

int n; char s[N];

bitset<777>G[777];

namespace ac{
  int ch[N][2],fai[N],fa[N],cnt,id[N];
  int qu[N],qt;
  void init(){
    memset(ch,0,sizeof ch);
    cnt=1; for (int i=0;i<2;++i) ch[0][i]=1;
    memset(fai,0,sizeof fai);
  }
  int add(char *s,int who){
    int l=strlen(s),p=1,c;
    for (int i=0;i<l;++i){
      c=s[i]-'a';
      if (!ch[p][c]){
		ch[p][c]=++cnt;
		fa[cnt]=p;
	  }
      p=ch[p][c];
    }
	id[p]=who;
    return p;
  }
  void build(){
    queue<int>q;
    for (;!q.empty();) q.pop();
    q.push(1); qt=0;
    int x,y;
    for (;!q.empty();){
      x=q.front(); q.pop(); qu[++qt]=x;
      for (int i=0;i<2;++i)
		if (y=ch[x][i]){
			fai[y]=ch[fai[x]][i];
			q.push(y);
		}else{
			ch[x][i]=ch[fai[x]][i];
		}
    }
  }

  	int las[N];
	void fuck(){
		for (int it=1;it<=cnt;++it){
			int i=qu[it];
			las[i]=las[fai[i]];
			if (id[i]){
				if (las[i]){
					G[id[i]][las[i]]=1;
					//printf("   fai %d %d\n",id[i],las[i]);
				}
				las[i]=id[i];
			}
		}
		for (int i=1;i<=cnt;++i)
			if (id[i]){
				int p=fa[i];
				while (p>1){
					//printf(" - %d %d\n",id[i],p);
					if (las[p]){
						G[id[i]][las[p]]=1;
						//printf("   els %d %d\n",id[i],las[p]);
					}
					p=fa[p];
				}
			}
	}
}

int pre[777], nex[777], usd[777];

int fin(int x){
	for (int i=1;i<=n;++i){
		if (usd[i]||!G[x][i]) continue;
		usd[i]=1;
		if (!pre[i]||fin(pre[i])){
			pre[i]=x;
			nex[x]=i;
			return 1;
		}
	}
	return 0;
}

int main(){
	ac::init();
	cin>>n;
	for (int i=1;i<=n;++i){
		scanf("%s",s);
		ac::add(s,i);
	}
	ac::build();
	ac::fuck();
	for (int i=1;i<=n;++i)
		for (int j=1;j<=n;++j)
			if (G[j][i])
				G[j]|=G[i];
	for (int i=1;i<=n;++i){
		G[i][i]=0;
		G[i][0]=0;
	}

	// for (int i=1;i<=n;++i){
	// 	for (int j=1;j<=n;++j)
	// 		if (G[i][j]){
	// 			printf(" %d %d\n",i,j);
	// 		}
	// }

	int ans=0, an[777];
	for (int i=1;i<=n;++i){
		memset(usd,0,sizeof usd);
		fin(i);
	}
	for (int i=1;i<=n;++i){
		if (!pre[i]) an[++ans]=i;
	}
	for (int fl=1;fl;){
		fl=0;
		for (int i=1;i<=ans;++i)
			for (int j=1;j<=ans;++j)
				if (G[an[i]][an[j]]){
					fl=1;
					an[i]=nex[an[i]];
				}
	}
	cout<<ans<<endl;
	for (int i=1;i<=ans;++i) cout<<an[i]<<' ';
	cout<<endl;
}


#include<bits/stdc++.h>
#define pk push_back
#define mk make_pair
using namespace std;
typedef long long LL;
typedef pair<int,int> pi;
const int N=755,M=1e7+5;
int n,tot=1,ed[N],de[M],fail[M],d[N][N],fa[M],ch[M][2],v[N],mat[N],s[N],t[N],rmat[N];
int dfs(int x){
	for(int i=1;i<=n;++i)if(d[x][i]&&!v[i]){
		v[i]=1;
		if(!mat[i]||dfs(mat[i])) return mat[i]=x,rmat[x]=i,1;
	}
	return 0;
}
void dfs2(int x){
	s[x]=1;
	for(int i=1;i<=n;++i)if(d[x][i]&&!t[i])t[i]=1,dfs2(mat[i]);
}
int main(){
	ios::sync_with_stdio(false);
	cin>>n;
	for(int i=1;i<=n;++i){
		string s;
		cin>>s;
		int p=1;
		for(int j=0;j<s.length();++j){
			int c=s[j]-'a';
			if(!ch[p][c]) fa[ch[p][c]=++tot]=p;
			p=ch[p][c];
		}
		ed[i]=p,de[p]=i;
	}
	queue<int> q;
	for(int i=0;i<2;++i)if(ch[1][i])q.push(ch[1][i]),fail[ch[1][i]]=1;else ch[1][i]=1;
	while(!q.empty()){
		int x=q.front();q.pop();
		for(int i=0;i<2;++i)if(ch[x][i]) fail[ch[x][i]]=ch[fail[x]][i],q.push(ch[x][i]);
		else ch[x][i]=ch[fail[x]][i];
	}
	for(int i=1;i<=n;++i)
		for(int j=ed[i];j;j=fa[j]){
			int x=(j==ed[i]?fail[j]:j);
			vector<int> t;
			while(x!=1&&!de[x]) t.pk(x),x=fail[x];
			if(x!=1){
				for(auto y:t) fail[y]=x;
				d[i][de[x]]=1;
			}
		}
	for(int k=1;k<=n;++k)
		for(int i=1;i<=n;++i)
			for(int j=1;j<=n;++j)
				d[i][j]|=d[i][k]&d[k][j];
	for(int i=1;i<=n;++i) d[i][i]=0;
	int ans=n;
	for(int i=1;i<=n;++i) ans-=dfs(i),memset(v,0,sizeof v);
	for(int i=1;i<=n;++i) if(!rmat[i]) dfs2(i);
	cout<<ans<<endl;
	for(int i=1;i<=n;++i) if(s[i]&&!t[i]) cout<<i<<' ';
	return 0;
}


#include<bits/stdc++.h>
#define pk push_back
#define mk make_pair
using namespace std;
typedef long long LL;
typedef pair<int,int> pi;
const int N=755,M=1e7+5;
int n,tot=1,ed[N],de[M],fail[M],d[N][N],fa[M],ch[M][2],v[N],mat[N],s[N],t[N],hav[N];
int dfs(int x){
	for(int i=1;i<=n;++i)if(d[x][i]&&!v[i]){
		v[i]=1;
		if(!mat[i]||dfs(mat[i])) return mat[i]=x,1;
	}
	return 0;
}
void dfs2(int x){
	s[x]=1;
	for(int i=1;i<=n;++i)if(d[x][i]&&!t[i]){
		t[i]=1;dfs2(mat[i]);
	}
}
int main(){
	ios::sync_with_stdio(false);
	cin>>n;
	for(int i=1;i<=n;++i){
		string s;
		cin>>s;
		int p=1;
		for(int j=0;j<s.length();++j){
			int c=s[j]-'a';
			if(!ch[p][c]) fa[ch[p][c]=++tot]=p;
			p=ch[p][c];
		}
		ed[i]=p,de[p]=i;
	}
	queue<int> q;
	for(int i=0;i<2;++i)if(ch[1][i])q.push(ch[1][i]),fail[ch[1][i]]=1;else ch[1][i]=1;
	while(!q.empty()){
		int x=q.front();q.pop();
		for(int i=0;i<2;++i)if(ch[x][i]) fail[ch[x][i]]=ch[fail[x]][i],q.push(ch[x][i]);
		else ch[x][i]=ch[fail[x]][i];
	}
	for(int i=1;i<=n;++i)
		for(int j=ed[i];j!=1;j=fa[j]){
			int x=(j==ed[i]?fail[j]:j);
			vector<int> t;
			while(x!=1&&!de[x]) t.pk(x),x=fail[x];
			fail[j]=x;
			if(x!=1){for(auto y:t) fail[y]=x;
				d[i][de[x]]=1;
			}
		}
	for(int k=1;k<=n;++k)
		for(int i=1;i<=n;++i)
			for(int j=1;j<=n;++j)
				d[i][j]|=d[i][k]&d[k][j];
	for(int i=1;i<=n;++i) d[i][i]=0;
	int ans=n;
	for(int i=1;i<=n;++i){
		memset(v,0,sizeof v);
		ans-=dfs(i);
	}
	for(int i=1;i<=n;++i) hav[mat[i]]=1;
	for(int i=1;i<=n;++i) if(!hav[i]) dfs2(i);
	cout<<ans<<endl;
	for(int i=1;i<=n;++i) if(s[i]&&!t[i]) cout<<i<<' ';
	return 0;
}


#include<bits/stdc++.h>
#define pk push_back
#define mk make_pair
using namespace std;
typedef long long LL;
typedef pair<int,int> pi;
const int N=755,M=1e7+5;
int n,tot=1,ed[N],de[M],fail[M],d[N][N],fa[M],ch[M][2],v[N],mat[N],s[N],t[N],hav[N];
int dfs(int x){
	for(int i=1;i<=n;++i)if(d[x][i]&&!v[i]){
		v[i]=1;
		if(!mat[i]||dfs(mat[i])) return mat[i]=x,1;
	}
	return 0;
}
void dfs2(int x){
	s[x]=1;
	for(int i=1;i<=n;++i)if(d[x][i]&&!t[i]){
		t[i]=1;dfs2(mat[i]);
	}
}
int main(){
	ios::sync_with_stdio(false);
	cin>>n;
	for(int i=1;i<=n;++i){
		string s;
		cin>>s;
		int p=1;
		for(int j=0;j<s.length();++j){
			int c=s[j]-'a';
			if(!ch[p][c]) fa[ch[p][c]=++tot]=p;
			p=ch[p][c];
		}
		ed[i]=p,de[p]=i;
	}
	queue<int> q;
	for(int i=0;i<2;++i)if(ch[1][i])q.push(ch[1][i]),fail[ch[1][i]]=1;else ch[1][i]=1;
	while(!q.empty()){
		int x=q.front();q.pop();
		for(int i=0;i<2;++i)if(ch[x][i]) fail[ch[x][i]]=ch[fail[x]][i],q.push(ch[x][i]);
		else ch[x][i]=ch[fail[x]][i];
	}
	for(int i=1;i<=n;++i)
		for(int j=ed[i];j!=1;j=fa[j]){
			int x=(j==ed[i]?fail[j]:j);
			vector<int> t;
			while(x!=1&&!de[x]) t.pk(x),x=fail[x];
			fail[j]=x;for(auto y:t) fail[y]=x;
			if(x!=1){
				d[i][de[x]]=1;
			}
		}
	for(int k=1;k<=n;++k)
		for(int i=1;i<=n;++i)
			for(int j=1;j<=n;++j)
				d[i][j]|=d[i][k]&d[k][j];
	for(int i=1;i<=n;++i) d[i][i]=0;
	int ans=n;
	for(int i=1;i<=n;++i){
		memset(v,0,sizeof v);
		ans-=(hav[i]=dfs(i));
	}
	for(int i=1;i<=n;++i) if(!hav[i]) dfs2(i);
	cout<<ans<<endl;
	for(int i=1;i<=n;++i) if(s[i]&&!t[i]) cout<<i<<' ';
	return 0;
}


#include<bits/stdc++.h>
#define pk push_back
#define mk make_pair
using namespace std;
typedef long long LL;
typedef pair<int,int> pi;
const int N=755,M=1e7+5;
int n,tot=1,ed[N],de[M],fail[M],d[N][N],fa[M],ch[M][2],v[N],mat[N],s[N],t[N],hav[N];
int dfs(int x){
	for(int i=1;i<=n;++i)if(d[x][i]&&!v[i]){
		v[i]=1;
		if(!mat[i]||dfs(mat[i])) return mat[i]=x,1;
	}
	return 0;
}
void dfs2(int x){
	s[x]=1;
	for(int i=1;i<=n;++i)if(d[x][i]&&!t[i]){
		t[i]=1;dfs2(mat[i]);
	}
}
int main(){
	ios::sync_with_stdio(false);
	cin>>n;
	for(int i=1;i<=n;++i){
		string s;
		cin>>s;
		int p=1;
		for(int j=0;j<s.length();++j){
			int c=s[j]-'a';
			if(!ch[p][c]) fa[ch[p][c]=++tot]=p;
			p=ch[p][c];
		}
		ed[i]=p,de[p]=i;
	}
	queue<int> q;
	for(int i=0;i<2;++i)if(ch[1][i])q.push(ch[1][i]),fail[ch[1][i]]=1;else ch[1][i]=1;
	while(!q.empty()){
		int x=q.front();q.pop();
		for(int i=0;i<2;++i)if(ch[x][i]) fail[ch[x][i]]=ch[fail[x]][i],q.push(ch[x][i]);
		else ch[x][i]=ch[fail[x]][i];
	}
	de[1]=-1;
	for(int i=1;i<=n;++i)
		for(int j=ed[i];j!=1;j=fa[j]){
			int x=fail[j];
			vector<int> t;
			while(!de[x]) t.pk(x),x=fail[x];
			for(auto y:t) fail[y]=x;
			fail[j]=x;
			if(j!=ed[i]&&de[j]) x=j;
			if(x!=1) d[i][de[x]]=1;
		}
	for(int k=1;k<=n;++k)
		for(int i=1;i<=n;++i)
			for(int j=1;j<=n;++j)
				d[i][j]|=d[i][k]&d[k][j];
	for(int i=1;i<=n;++i) d[i][i]=0;
	int ans=n;
	for(int i=1;i<=n;++i){
		memset(v,0,sizeof v);
		ans-=dfs(i);
	}
	for(int i=1;i<=n;++i) hav[mat[i]]=1;
	for(int i=1;i<=n;++i) if(!hav[i]) dfs2(i);
	cout<<ans<<endl;
	for(int i=1;i<=n;++i) if(s[i]&&!t[i]) cout<<i<<' ';
	return 0;
}


#include<bits/stdc++.h>
#define pk push_back
#define mk make_pair
using namespace std;
typedef long long LL;
typedef pair<int,int> pi;
const int N=755,M=1e7+5;
int n,tot=1,ed[N],de[M],fail[M],d[N][N],fa[M],ch[M][2],v[N],mat[N],s[N],t[N],hav[N];
int dfs(int x){
	for(int i=1;i<=n;++i)if(d[x][i]&&!v[i]){
		v[i]=1;
		if(!mat[i]||dfs(mat[i])) return mat[i]=x,1;
	}
	return 0;
}
void dfs2(int x){
	s[x]=1;
	for(int i=1;i<=n;++i)if(d[x][i]&&!t[i]){
		t[i]=1;dfs2(mat[i]);
	}
}
int main(){
	ios::sync_with_stdio(false);
	cin>>n;
	for(int i=1;i<=n;++i){
		string s;
		cin>>s;
		int p=1;
		for(int j=0;j<s.length();++j){
			int c=s[j]-'a';
			if(!ch[p][c]) fa[ch[p][c]=++tot]=p;
			p=ch[p][c];
		}
		ed[i]=p,de[p]=i;
	}
	queue<int> q;
	for(int i=0;i<2;++i)if(ch[1][i])q.push(ch[1][i]),fail[ch[1][i]]=1;else ch[1][i]=1;
	while(!q.empty()){
		int x=q.front();q.pop();
		for(int i=0;i<2;++i)if(ch[x][i]) fail[ch[x][i]]=ch[fail[x]][i],q.push(ch[x][i]);
		else ch[x][i]=ch[fail[x]][i];
	}
	for(int i=1;i<=n;++i)
		for(int j=ed[i];j!=1;j=fa[j]){
			int x=(j==ed[i]?fail[j]:j);
			vector<int> t;
			while(x!=1&&!de[x]) t.pk(x),x=fail[x];
			fail[j]=x;for(auto y:t) fail[y]=x;
			if(x!=1){
				d[i][de[x]]=1;
			}
		}
	for(int k=1;k<=n;++k)
		for(int i=1;i<=n;++i)
			for(int j=1;j<=n;++j)
				d[i][j]|=d[i][k]&d[k][j];
	for(int i=1;i<=n;++i) d[i][i]=0;
	int ans=n;
	for(int i=1;i<=n;++i){
		memset(v,0,sizeof v);
		ans-=dfs(i);
	}
	for(int i=1;i<=n;++i) hav[mat[i]]=1;
	for(int i=1;i<=n;++i) if(!hav[i]) dfs2(i);
	cout<<ans<<endl;
	for(int i=1;i<=n;++i) if(s[i]&&!t[i]) cout<<i<<' ';
	return 0;
}


#include<bits/stdc++.h>
#define pk push_back
#define mk make_pair
using namespace std;
typedef long long LL;
typedef pair<int,int> pi;
const int N=755,M=1e7+5;
int n,tot=1,ed[N],de[M],fail[M],d[N][N],fa[M],ch[M][2],v[N],mat[N],s[N],t[N],hav[N];
int dfs(int x){
	for(int i=1;i<=n;++i)if(d[x][i]&&!v[i]){
		v[i]=1;
		if(!mat[i]||dfs(mat[i])) return mat[i]=x,1;
	}
	return 0;
}
void dfs2(int x){
	s[x]=1;
	for(int i=1;i<=n;++i)if(d[x][i]&&!t[i]){
		t[i]=1;dfs2(mat[i]);
	}
}
int main(){
	ios::sync_with_stdio(false);
	cin>>n;
	for(int i=1;i<=n;++i){
		string s;
		cin>>s;
		int p=1;
		for(int j=0;j<s.length();++j){
			int c=s[j]-'a';
			if(!ch[p][c]) fa[ch[p][c]=++tot]=p;
			p=ch[p][c];
		}
		ed[i]=p,de[p]=i;
	}
	queue<int> q;
	for(int i=0;i<2;++i)if(ch[1][i])q.push(ch[1][i]),fail[ch[1][i]]=1;else ch[1][i]=1;
	while(!q.empty()){
		int x=q.front();q.pop();
		for(int i=0;i<2;++i)if(ch[x][i]) fail[ch[x][i]]=ch[fail[x]][i],q.push(ch[x][i]);
		else ch[x][i]=ch[fail[x]][i];
	}
//	for(int i=1;i<=n;++i)
//		for(int j=ed[i];j!=1;j=fa[j]){
//			int x=(j==ed[i]?fail[j]:j);
//			vector<int> t;
//			while(x!=1&&!de[x]) t.pk(x),x=fail[x];
//			fail[j]=x;for(auto y:t) fail[y]=x;
//			if(x!=1){
//				d[i][de[x]]=1;
//			}
//		}
	de[1]=-1;
	for(int i=1;i<=n;++i)
		for(int j=ed[i];j!=1;j=fa[j]){
			int x=fail[j];
			vector<int> t;
			while(!de[x]) t.pk(x),x=fail[x];
			for(auto y:t) fail[y]=x;
			fail[j]=x;
			if(j!=ed[i]&&de[j]) x=j;
			if(x!=1) d[i][de[x]]=1;
		}
	for(int k=1;k<=n;++k)
		for(int i=1;i<=n;++i)
			for(int j=1;j<=n;++j)
				d[i][j]|=d[i][k]&d[k][j];
	for(int i=1;i<=n;++i) d[i][i]=0;
	int ans=n;
	for(int i=1;i<=n;++i){
		memset(v,0,sizeof v);
		ans-=dfs(i);
	}
	for(int i=1;i<=n;++i) hav[mat[i]]=1;
	for(int i=1;i<=n;++i) if(!hav[i]) dfs2(i);
	cout<<ans<<endl;
	for(int i=1;i<=n;++i) if(s[i]&&!t[i]) cout<<i<<' ';
	return 0;
}


#include <bits/stdc++.h>

const int N = 755, V = 1e7 + 5;

char str[V];
int n, end[N], cp[N];
bool e[N][N], vis[N], visl[N], visr[N], used[N];
std::vector<int> ans;

struct AcAutomaton {
    int tot, son[V][2], ft[V], fail[V], clz[V];

    AcAutomaton() { tot = 1; son[0][0] = son[0][1] = -1; }

    int insert(char str[]) {
        int u = 1;
        for (int i = 0; str[i]; i++) {
            int x = str[i] - 'a';
            if (son[u][x] == 0) { son[u][x] = ++tot; }
            ft[son[u][x]] = u; u = son[u][x];
        }
        return u;
    }

    void build() {
        std::queue<int> que;
        for (int x = 0; x < 2; x++) {
            if (son[1][x] > 0) {
                que.push(son[1][x]);
                fail[son[1][x]] = 1;
            } else {
                son[1][x] = 1;
            }
        }
        for (; !que.empty(); que.pop()) {
            int u = que.front(), v;
            if (clz[u] == 0) { clz[u] = clz[fail[u]]; }
            for (int x = 0; x < 2; x++) {
                if (son[u][x] > 0) {
                    for (v = fail[u]; son[v][x] == 0; v = fail[v]);
                    que.push(son[u][x]);
                    fail[son[u][x]] = son[fail[u]][x] == 0 ? 1 : son[fail[u]][x];
                } else {
                    son[u][x] = son[fail[u]][x];
                }
            }
        }
    }
} aam;

bool hungary(int u) {
    if (vis[u]) { return false; }
    vis[u] = true;
    for (int v = 1; v <= n; v++) {
        if (e[u][v] == 0) { continue; }
        if (cp[v] == 0 || hungary(cp[v])) {
            cp[v] = u; return true;
        }
    }
    return false;
}

void dfs(int u) {
    if (visl[u]) { return; }
    visl[u] = true;
    for (int v = 1; v <= n; v++) {
        if (e[u][v] == 0) { continue; }
        if (!visr[v]) { visr[v] = true; dfs(cp[v]); }
    }
}

int main() {
    scanf("%d", &n);
    for (int i = 1; i <= n; i++) {
        scanf("%s", str);
        end[i] = aam.insert(str);
        aam.clz[end[i]] = i;
    }
    aam.build();
    for (int i = 1; i <= n; i++) {
        for (int u = end[i]; u != 1; u = aam.ft[u]) {
            if (aam.clz[u] != i) {
                e[aam.clz[u]][i] = true;
            } else {
                e[aam.clz[aam.fail[u]]][i] = true;
            }
        }
    }
    for (int k = 1; k <= n; k++) {
        for (int i = 1; i <= n; i++) {
            for (int j = 1; j <= n; j++) {
                e[i][j] |= e[i][k] & e[k][j];
            }
        }
    }
    int cnt = 0;
    for (int u = 1; u <= n; u++) {
        memset(vis, false, n + 1);
        cnt += hungary(u);
    }
    for (int v = 1; v <= n; v++) {
        used[cp[v]] = true;
    }
    for (int u = 1; u <= n; u++) {
        if (used[u]) { continue; }
        dfs(u);
    }
    for (int i = 1; i <= n; i++) {
        if (visl[i] && !visr[i]) { ans.push_back(i); }
    }
    printf("%d\n", ans.size());
    for (auto i : ans) { printf("%d ", i); }
    return 0;
}


#include <bits/stdc++.h>

const int N = 755, V = 1e7 + 5;

char str[V];
int n, end[N], cp[N];
bool e[N][N], vis[N], visl[N], visr[N], used[N];
std::vector<int> ans;

struct AcAutomaton {
    int tot, son[V][2], ft[V], fail[V], clz[V];

    AcAutomaton() { tot = 1; son[0][0] = son[0][1] = -1; }

    int insert(char str[]) {
        int u = 1;
        for (int i = 0; str[i]; i++) {
            int x = str[i] - 'a';
            if (son[u][x] == 0) { son[u][x] = ++tot; }
            ft[son[u][x]] = u; u = son[u][x];
        }
        return u;
    }

    void build() {
        std::queue<int> que;
        for (int x = 0; x < 2; x++) {
            if (son[1][x] > 0) {
                que.push(son[1][x]);
                fail[son[1][x]] = 1;
            } else {
                son[1][x] = 1;
            }
        }
        for (; !que.empty(); que.pop()) {
            int u = que.front(), v;
            if (clz[u] == 0) { clz[u] = clz[fail[u]]; }
            for (int x = 0; x < 2; x++) {
                if (son[u][x] > 0) {
                    for (v = fail[u]; son[v][x] == 0; v = fail[v]);
                    que.push(son[u][x]);
                    fail[son[u][x]] = son[fail[u]][x] == 0 ? 1 : son[fail[u]][x];
                } else {
                    son[u][x] = son[fail[u]][x];
                }
            }
        }
    }
} aam;

bool hungary(int u) {
    if (vis[u]) { return false; }
    vis[u] = true;
    for (int v = 1; v <= n; v++) {
        if (e[u][v] == 0) { continue; }
        if (cp[v] == 0 || hungary(cp[v])) {
            cp[v] = u;
        }
    }
    return false;
}

void dfs(int u) {
    if (visl[u]) { return; }
    visl[u] = true;
    for (int v = 1; v <= n; v++) {
        if (e[u][v] == 0) { continue; }
        if (!visr[v]) { visr[v] = true; dfs(cp[v]); }
    }
}

int main() {
    scanf("%d", &n);
    for (int i = 1; i <= n; i++) {
        scanf("%s", str);
        end[i] = aam.insert(str);
        aam.clz[end[i]] = i;
    }
    aam.build();
    for (int i = 1; i <= n; i++) {
        for (int u = end[i]; u != 1; u = aam.ft[u]) {
            if (aam.clz[u] != i) {
                e[aam.clz[u]][i] = true;
            } else {
                e[aam.clz[aam.fail[u]]][i] = true;
            }
        }
    }
    for (int k = 1; k <= n; k++) {
        for (int i = 1; i <= n; i++) {
            for (int j = 1; j <= n; j++) {
                e[i][j] |= e[i][k] & e[k][j];
            }
        }
    }
    for (int u = 1; u <= n; u++) {
        memset(vis, false, sizeof(vis));
        hungary(u);
    }
    for (int v = 1; v <= n; v++) {
        used[cp[v]] = true;
    }
    for (int u = 1; u <= n; u++) {
        if (used[u]) { continue; }
        dfs(u);
    }
    for (int i = 1; i <= n; i++) {
        if (visl[i] && !visr[i]) { ans.push_back(i); }
    }
    printf("%d\n", ans.size());
    for (auto i : ans) { printf("%d ", i); }
    return 0;
}


#include <bits/stdc++.h>

const int N = 755, V = 1e7 + 5;

char str[V];
int n, end[N], cp[N];
bool e[N][N], vis[N], visl[N], visr[N], used[N];
std::vector<int> ans;

struct AcAutomaton {
    int tot, son[V][2], ft[V], fail[V], clz[N];

    AcAutomaton() { tot = 1; son[0][0] = son[0][1] = -1; }

    int insert(char str[]) {
        int u = 1;
        for (int i = 0; str[i]; i++) {
            int x = str[i] - 'a';
            if (son[u][x] == 0) { son[u][x] = ++tot; }
            ft[son[u][x]] = u; u = son[u][x];
        }
        return u;
    }

    void build() {
        std::queue<int> que;
        for (int x = 0; x < 2; x++) {
            if (son[1][x] > 0) {
                que.push(son[1][x]);
                fail[son[1][x]] = 1;
            } else {
                son[1][x] = 1;
            }
        }
        for (; !que.empty(); que.pop()) {
            int u = que.front(), v;
            if (clz[u] == 0) { clz[u] = clz[fail[u]]; }
            for (int x = 0; x < 2; x++) {
                if (son[u][x] > 0) {
                    for (v = fail[u]; son[v][x] == 0; v = fail[v]);
                    que.push(son[u][x]);
                    fail[son[u][x]] = son[fail[u]][x] == 0 ? 1 : son[fail[u]][x];
                } else {
                    son[u][x] = son[fail[u]][x];
                }
            }
        }
    }
} aam;

bool hungary(int u) {
    if (vis[u]) { return false; }
    vis[u] = true;
    for (int v = 1; v <= n; v++) {
        if (e[u][v] == 0) { continue; }
        if (cp[v] == 0 || hungary(cp[v])) {
            cp[v] = u;
        }
    }
    return false;
}

void dfs(int u) {
    if (visl[u]) { return; }
    visl[u] = true;
    for (int v = 1; v <= n; v++) {
        if (e[u][v] == 0) { continue; }
        if (!visr[v]) { visr[v] = true; dfs(cp[v]); }
    }
}

int main() {
    scanf("%d", &n);
    for (int i = 1; i <= n; i++) {
        scanf("%s", str);
        end[i] = aam.insert(str);
        aam.clz[end[i]] = i;
    }
    aam.build();
    for (int i = 1; i <= n; i++) {
        for (int u = end[i]; u != 1; u = aam.ft[u]) {
            if (aam.clz[u] != i) {
                e[aam.clz[u]][i] = true;
            } else {
                e[aam.clz[aam.fail[u]]][i] = true;
            }
        }
    }
    for (int k = 1; k <= n; k++) {
        for (int i = 1; i <= n; i++) {
            for (int j = 1; j <= n; j++) {
                e[i][j] |= e[i][k] & e[k][j];
            }
        }
    }
    for (int u = 1; u <= n; u++) {
        memset(vis, false, sizeof(vis));
        hungary(u);
    }
    for (int v = 1; v <= n; v++) {
        used[cp[v]] = true;
    }
    for (int u = 1; u <= n; u++) {
        if (used[u]) { continue; }
        dfs(u);
    }
    for (int i = 1; i <= n; i++) {
        if (visl[i] && !visr[i]) { ans.push_back(i); }
    }
    printf("%d\n", ans.size());
    for (auto i : ans) { printf("%d ", i); }
    return 0;
}


/*
Author: QAQAutomaton
Lang: C++
Code: E.cpp
Mail: lk@qaq-am.com
Blog: https://www.qaq-am.com/
*/
#include<bits/stdc++.h>
#define debug(...) fprintf(stderr,__VA_ARGS__)
#define DEBUG printf("Passing [%s] in LINE %d\n",__FUNCTION__,__LINE__)
#define Debug debug("Passing [%s] in LINE %d\n",__FUNCTION__,__LINE__)
#define all(x) x.begin(),x.end()
#define x first
#define y second
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
int inf;
const double eps=1e-8;
const double pi=acos(-1.0);
template<class T>int chkmin(T &a,T b){return a>b?a=b,1:0;}
template<class T>int chkmax(T &a,T b){return a<b?a=b,1:0;}
template<class T>T sqr(T a){return a*a;}
template<class T>T mmin(T a,T b){return a<b?a:b;}
template<class T>T mmax(T a,T b){return a>b?a:b;}
template<class T>T aabs(T a){return a<0?-a:a;}
template<class T>int dcmp(T a,T b){return a>b;}
template<int *a>int cmp_a(int x,int y){return a[x]<a[y];}
#define min mmin
#define max mmax
#define abs aabs
struct __INIT__{
	__INIT__(){
		memset(&inf,0x3f,sizeof(inf));
	}
}__INIT___;
namespace io {
	const int SIZE = (1 << 21) + 1;
	char ibuf[SIZE], *iS, *iT, obuf[SIZE], *oS = obuf, *oT = oS + SIZE - 1, c, qu[55]; int f, qr;
	// getchar
	#define gc() (iS == iT ? (iT = (iS = ibuf) + fread (ibuf, 1, SIZE, stdin), (iS == iT ? EOF : *iS ++)) : *iS ++)
	// print the remaining part
	inline void flush () {
		fwrite (obuf, 1, oS - obuf, stdout);
		oS = obuf;
	}
	// putchar
	inline void putc (char x) {
		*oS ++ = x;
		if (oS == oT) flush ();
	}
	template<typename A>
	inline bool read (A &x) {
		for (f = 1, c = gc(); c < '0' || c > '9'; c = gc()) if (c == '-') f = -1;else if(c==EOF)return 0;
		for (x = 0; c <= '9' && c >= '0'; c = gc()) x = x * 10 + (c & 15); x *= f;
		return 1;
	}
	inline bool read (char &x) {
		while((x=gc())==' '||x=='\n' || x=='\r');
		return x!=EOF;
	}
	inline bool read(char *x){
		while((*x=gc())=='\n' || *x==' '||*x=='\r');
		if(*x==EOF)return 0;
		while(!(*x=='\n'||*x==' '||*x=='\r'))*(++x)=gc();
		*x=0;
		return 1;
	}
	template<typename A,typename ...B>
	inline bool read(A &x,B &...y){
		return read(x)&&read(y...);
	}
	template<typename A>
	inline bool write (A x) {
		if (!x) putc ('0'); if (x < 0) putc ('-'), x = -x;
		while (x) qu[++ qr] = x % 10 + '0',  x /= 10;
		while (qr) putc (qu[qr --]);
		return 0;
	}
	inline bool write (char x) {
		putc(x);
		return 0;
	}
	inline bool write(const char *x){
		while(*x){putc(*x);++x;}
		return 0;
	}
	inline bool write(char *x){
		while(*x){putc(*x);++x;}
		return 0;
	}
	template<typename A,typename ...B>
	inline bool write(A x,B ...y){
		return write(x)||write(y...);
	}
	//no need to call flush at the end manually!
	struct Flusher_ {~Flusher_(){flush();}}io_flusher_;
}
using io :: read;
using io :: putc;
using io :: write;
char str[10000005],*s[755];
int to[10000005][2],id[10000005],las[10000005],fail[10000005],t=1;
int q[10000005],*l,*r;
bitset<755> a[755];
int sx[755],sy[755];
namespace match{
	int xn;
	int beg[1505],to[1919810],lst[1919810],w[1919810],e=1;
	void add(int u,int v,int c){
		to[++e]=v;lst[e]=beg[u];beg[u]=e;w[e]=c;
		to[++e]=u;lst[e]=beg[v];beg[v]=e;w[e]=0;
	}
	int q[1505],*l,*r;
	int dis[1505],vis[1505];
	bool bfs(int s,int t){
		for(int i=1;i<=xn;++i)dis[i]=114514;
		dis[s]=0;
		*(l=r=q)=s;
		while(l<=r){
			for(int i=beg[*l];i;i=lst[i])if(w[i]){
				if(chkmin(dis[to[i]],dis[*l]+1))
					*(++r)=to[i];
			}
			++l;
		}
		return dis[t]!=114514;
	}
	int dfs(int s,int t,int flw){
		if(s==t)return flw;
		int cnt=0;
		for(int i=beg[s];i;i=lst[i])if(w[i] && dis[to[i]]==dis[s]+1){
			int mx=dfs(to[i],t,min(flw,w[i]));
			w[i]-=mx;w[i^1]+=mx;flw-=mx;cnt+=mx;
		}
		return cnt;
	}
	int dinic(int s,int t){
		int ans=0;
		while(bfs(s,t)){
			ans+=dfs(s,t,114514);
		}
		return ans;
	}
	void dfs(int s){
		if(vis[s])return;
		vis[s]=1;
		for(int i=beg[s];i;i=lst[i])if(w[i]){
			dfs(to[i]);
		}
	}
	void match(int n){
		xn=n*2+2;
		for(int i=1;i<=n;++i)add(1,i+2,1);
		for(int i=1;i<=n;++i)add(i+2+n,2,1);
		for(int i=1;i<=n;++i)for(int j=1;j<=n;++j)if(a[i][j])add(i+2,j+n+2,114514);
		write(n-dinic(1,2),'\n');
		dfs(1);
		for(int i=1;i<=n;++i)if(vis[i+2])sx[i]=1;
		for(int i=1;i<=n;++i)if(!vis[i+2+n])sy[i]=1;
	}
}
signed main(){
#ifdef QAQAutoMaton
	freopen("E.in","r",stdin);
	freopen("E.out","w",stdout);
#endif
	int n;
	read(n);
	s[1]=str;
	for(int i=1;i<=n;++i){
		read(s[i]);
		s[i+1]=s[i]+strlen(s[i]);
		for(char *j=s[i];j<s[i+1];++j)*j-='a';
	}
	for(int i=1;i<=n;++i){
		int at=1;
		for(char *j=s[i];j<s[i+1];++j){
			if(!to[at][*j])to[at][*j]=++t;
			at=to[at][*j];
		}
		id[at]=i;
	}
	fail[*(l=r=q)=1]=1;
	while(l<=r){
		las[*l]=id[fail[*l]];
		if(!id[*l])id[*l]=las[*l];
		for(int j=0;j<2;++j)if(to[*l][j]){
			*(++r)=to[*l][j];
			if(*l==1)fail[*r]=1;
			else{
				int x=fail[*l];
				while(x!=1 && !to[x][j])x=fail[x];
				if(to[x][j])fail[*r]=to[x][j];
				else fail[*r]=1;
			}
		}
		++l;
	}

	for(int i=1;i<=n;++i){
		int at=1;
		for(char *j=s[i];j<s[i+1];++j){
			at=to[at][*j];
			if(id[at]!=i)a[i][id[at]]=1;
			else a[i][las[at]]=1;
		}
	}
	for(int k=1;k<=n;++k)for(int i=1;i<=n;++i)if(a[i][k])a[i]|=a[k];
	match::match(n);
	for(int i=1;i<=n;++i)if(sx[i]&&sy[i])write(i,' ');
	putc('\n');
	return 0;
}