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

#define ll long long
#define db long double
#define ii pair<int,int>
#define vi vector<int>
#define fi first
#define se second
#define sz(a) (int)(a).size()
#define all(a) (a).begin(),(a).end()
#define pb push_back
#define mp make_pair
#define FN(i, n) for (int i = 0; i < (int)(n); ++i)
#define FEN(i,n) for (int i = 1;i <= (int)(n); ++i)
#define rep(i,a,b) for(i=a;i<b;i++)
#define repv(i,a,b) for(i=b-1;i>=a;i--)
#define SET(A, val) memset(A, val, sizeof(A))
// order_of_key (val): returns the no. of values less than val
// find_by_order (k): returns the kth largest element.(0-based)
#define TRACE
#ifdef TRACE
#define trace(...) __f(#__VA_ARGS__, __VA_ARGS__)
template <typename Arg1>
void __f(const char* name, Arg1&& arg1){
  cerr << name << " : " << arg1 << std::endl;
}
template <typename Arg1, typename... Args>
void __f(const char* names, Arg1&& arg1, Args&&... args){
  const char* comma = strchr(names + 1, ','); cerr.write(names, comma - names) << " : " << arg1<<" | ";__f(comma+1, args...);
}
#else
#define trace(...)
#endif
const int N=755,MX=1e7+5;
string s[N];
bool a[N][N];
vi sufflink;
int sz;
int trie[MX][2],nearest[MX];
bool en[MX];
vi endat[MX];
void insert(int ind)
{
  int curr=0,i,j;
  rep(i,0,sz(s[ind]))
    {
      int tmp=s[ind][i]-'a';
      if(!trie[curr][tmp])
	trie[curr][tmp]=++sz;
      curr=trie[curr][tmp];
    }
  en[curr]=true;
  endat[curr].pb(ind);
}
void build_automation()
{
  sufflink.resize(sz+3);
  queue<int> q;
  int i,j;
  rep(i,0,2)
    if(trie[0][i])
      q.push(trie[0][i]);
  while(!q.empty())
    {
      int curr=q.front();
      q.pop();
      rep(i,0,2)
	{
	  if(!trie[curr][i]) continue;
	  ii x=mp(i,trie[curr][i]);
	  q.push(x.se);
	  int tmp=sufflink[curr];
	  while(!trie[tmp][x.fi] && tmp)
	    tmp=sufflink[tmp];
	  sufflink[x.se]=trie[tmp][x.fi];
	  int nxt=sufflink[x.se];
	  if(en[nxt])
	    nearest[x.se]=nxt;
	  else
	    nearest[x.se]=nearest[nxt];
	}
    }
}
void makegraph(int ind)
{
  int i,curr=0;
  rep(i,0,sz(s[ind]))
    {
      for(int ind2:endat[curr])
	a[ind2][ind]=true;
      int nxt=nearest[curr];
      for(int ind2:endat[nxt])
	a[ind2][ind]=true;
      curr=trie[curr][s[ind][i]-'a'];
    }
  for(int ind2:endat[curr])
    a[ind2][ind]=true;
  int nxt=nearest[curr];
  for(int ind2:endat[nxt])
    a[ind2][ind]=true;
}
bool seen[N];
int l[N],r[N],n;
vi v[N];
bool findmatch(int i)
{
  int j;
  rep(j,1,n+1)
    {
      if(a[i][j] && !seen[j])
	{
	  seen[j]=true;
	  if(r[j]<0 || findmatch(r[j]))
	    {
	      l[i]=j; r[j]=i;
	      return true;
	    }
	}
    }
  return false;
}
int bipartitematch()
{
  int cnt=0,i,j;
  rep(i,1,n+1) l[i]=-1;
  rep(i,1,n+1) r[i]=-1;
  rep(i,1,n+1)
    {
      rep(j,1,n+1) seen[j]=false;
      if(findmatch(i)) cnt++;
    }
  return cnt;
}
bool vis[2*N];
void dfs(int u)
{
  vis[u]=true;
  for(int i:v[u])
    {
      if(vis[n+i] || r[i]==-1) continue;
      vis[n+i]=true;
      dfs(r[i]);
    }
}
int main()
{
  std::ios::sync_with_stdio(false);
  cin.tie(NULL) ;
  int i,j,k;
  cin>>n;
  rep(i,1,n+1)
    {
      cin>>s[i];
      insert(i);
    }
  build_automation();
  rep(i,1,n+1)
    makegraph(i);
  rep(k,1,n+1)
    rep(i,1,n+1)
    rep(j,1,n+1)
    a[i][j]|=(a[i][k]&a[k][j]);
  rep(i,1,n+1) a[i][i]=false;
  rep(i,1,n+1)
    rep(j,1,n+1)
    if(a[i][j]) v[i].pb(j);
  //http://codeforces.com/blog/entry/17534?#comment-223759( how to find min vertex cover from max matching)
  int ans=n-bipartitematch();
  rep(i,1,n+1) // all unmatched nodes from left side
    if(l[i]==-1 && !vis[i]) dfs(i);
  cout<<ans<<endl;
  rep(i,1,n+1)
    {
      bool vc1=(vis[i]==false),vc2=(vis[i+n]==true);
      if(!vc1 && !vc2)
	cout<<i<<" ";
    }
  cout<<endl;
  return 0;
}


#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
using namespace std;
using namespace __gnu_pbds;

#define ll long long
#define db long double
#define ii pair<int,int>
#define vi vector<int>
#define fi first
#define se second
#define sz(a) (int)(a).size()
#define all(a) (a).begin(),(a).end()
#define pb push_back
#define mp make_pair
#define FN(i, n) for (int i = 0; i < (int)(n); ++i)
#define FEN(i,n) for (int i = 1;i <= (int)(n); ++i)
#define rep(i,a,b) for(i=a;i<b;i++)
#define repv(i,a,b) for(i=b-1;i>=a;i--)
#define SET(A, val) memset(A, val, sizeof(A))
typedef tree<int ,null_type,less<int>,rb_tree_tag,tree_order_statistics_node_update>ordered_set ;
// order_of_key (val): returns the no. of values less than val
// find_by_order (k): returns the kth largest element.(0-based)
#define TRACE
#ifdef TRACE
#define trace(...) __f(#__VA_ARGS__, __VA_ARGS__)
template <typename Arg1>
void __f(const char* name, Arg1&& arg1){
  cerr << name << " : " << arg1 << std::endl;
}
template <typename Arg1, typename... Args>
void __f(const char* names, Arg1&& arg1, Args&&... args){
  const char* comma = strchr(names + 1, ','); cerr.write(names, comma - names) << " : " << arg1<<" | ";__f(comma+1, args...);
}
#else
#define trace(...)
#endif
struct ahocorasick
{
  vi sufflink,out;
  int sz;
  vector<map<char,int> > trie;
  map<int,vi> endat;
  ahocorasick()
  {
    int i;
    sz=0;
    out.resize(1); trie.resize(1);
  }
  inline void insert(string &s,int ind)
  {
    int curr=0,i,j;
    rep(i,0,s.size())
      {
	if(!trie[curr].count(s[i]))
	  {
	    trie[curr][s[i]]=++sz;
	    trie.pb(map<char,int>());
	    out.pb(0);
	  }
	curr=trie[curr][s[i]];
      }
    out[curr]++;
    endat[curr].pb(ind);
  }
  inline void build_automation()
  {
    sufflink.resize(sz+3);
    queue<int> q;
    int i,j;
    for(auto x:trie[0])
      {
	sufflink[x.se]=0;
	q.push(x.se);
      }
    while(!q.empty())
      {
	int curr=q.front();
	q.pop();
	for(auto x:trie[curr])
	  {
	    q.push(x.se);
	    int tmp=sufflink[curr];
	    while(!trie[tmp].count(x.fi) && tmp)
	      tmp=sufflink[tmp];
	    if(trie[tmp].count(x.fi))
	      sufflink[x.se]=trie[tmp][x.fi];
	    else
	      sufflink[x.se]=0;
	    out[x.se]+=out[sufflink[x.se]];
	  }
      }
  }
  int findnextstate(int curr,char ch)
  {
    while(curr && !trie[curr].count(ch))
      curr=sufflink[curr];
    return curr;
  }
  ll query(string &s)
  {
    ll ans=0;
    int curr=0,i;
    rep(i,0,s.size())
      {
	curr=findnextstate(curr,s[i]);
	curr=trie[curr][s[i]];
	ans+=out[curr];
      }
    return ans;
  }
  void clear()
  {
    trie.clear(); sufflink.clear(); out.clear();
    out.resize(1); trie.resize(1); sz=0;
  }
};
ahocorasick ac;
const int N=800;
string s[N];
bool v[N][N];
void makegraph(int ind)
{
  int i,curr=0;
  rep(i,0,sz(s[ind]))
    {
      if(ac.endat.count(curr))
	{
	  for(int ind2:ac.endat[curr])
	    v[ind2][ind]=true;
	}
      int nxt=ac.sufflink[curr];
      if(ac.endat.count(nxt))
	{
	  for(int ind2:ac.endat[nxt])
	    v[ind2][ind]=true;
	}
      curr=ac.trie[curr][s[ind][i]];
    }
  if(ac.endat.count(curr))
    {
      for(int ind2:ac.endat[curr])
	v[ind2][ind]=true;
    }
  int nxt=ac.sufflink[curr];
  if(ac.endat.count(nxt))
    {
      for(int ind2:ac.endat[nxt])
	v[ind2][ind]=true;
    }
}
bool seen[N];
int l[N],r[N],n;
bool a[N][N];
bool findmatch(int i)
{
  int j;
  rep(j,1,n+1)
    {
      if(a[i][j] && !seen[j])
	{
	  seen[j]=true;
	  if(r[j]<0 || findmatch(r[j]))
	    {
	      l[i]=j; r[j]=i;
	      return true;
	    }
	}
    }
  return false;
}
int bipartitematch()
{
  int cnt=0,i,j;
  rep(i,1,n+1) l[i]=-1;
  rep(i,1,n+1) r[i]=-1;
  rep(i,1,n+1)
    {
      rep(j,1,n+1) seen[j]=false;
      if(findmatch(i)) cnt++;
    }
  return cnt;
}
bool mark[2*N],vis[2*N],vc[2*N];
void dfs(int u)
{
  vis[u]=true;
  int i;
  rep(i,1,n+1)
    {
      if(vis[n+i] || !a[u][i] || r[i]==-1) continue;
      vis[n+i]=true;
      dfs(r[i]);
    }
}
int main()
{
  std::ios::sync_with_stdio(false);
  cin.tie(NULL) ; cout.tie(NULL) ;
  int i,j,k;
  cin>>n;
  rep(i,1,n+1)
    {
      cin>>s[i];
      ac.insert(s[i],i);
    }
  ac.build_automation();
  rep(i,1,n+1)
    makegraph(i);
  rep(k,1,n+1)
    rep(i,1,n+1)
    rep(j,1,n+1)
    v[i][j]|=(v[i][k]&v[k][j]);
  rep(i,1,n+1) v[i][i]=false;
  //http://codeforces.com/blog/entry/17534?#comment-223759( how to find min vertex cover from max matching)
  rep(i,1,n+1) rep(j,1,n+1) a[i][j]=v[i][j];
  int ans=n-bipartitematch();
  //rep(i,1,n+1)
  //trace(i,l[i],r[i]);
  rep(i,1,n+1)
    if(l[i]!=-1)
      mark[l[i]+n]=mark[i]=true;
  rep(i,1,n+1)
    if(!mark[i] && !vis[i]) dfs(i);
  rep(i,1,2*n+1)
    {
      if(!mark[i]) continue;
      vc[i]=((i<=n && !vis[i]) || (i>n && vis[i]));
    }
  cout<<ans<<endl;
  rep(i,1,n+1)
    if(!vc[i] && !vc[i+n])
      cout<<i<<" ";
  cout<<endl;
  return 0;
}


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

#define ll long long
#define db long double
#define ii pair<int,int>
#define vi vector<int>
#define fi first
#define se second
#define sz(a) (int)(a).size()
#define all(a) (a).begin(),(a).end()
#define pb push_back
#define mp make_pair
#define FN(i, n) for (int i = 0; i < (int)(n); ++i)
#define FEN(i,n) for (int i = 1;i <= (int)(n); ++i)
#define rep(i,a,b) for(i=a;i<b;i++)
#define repv(i,a,b) for(i=b-1;i>=a;i--)
#define SET(A, val) memset(A, val, sizeof(A))
// order_of_key (val): returns the no. of values less than val
// find_by_order (k): returns the kth largest element.(0-based)
#define TRACE
#ifdef TRACE
#define trace(...) __f(#__VA_ARGS__, __VA_ARGS__)
template <typename Arg1>
void __f(const char* name, Arg1&& arg1){
  cerr << name << " : " << arg1 << std::endl;
}
template <typename Arg1, typename... Args>
void __f(const char* names, Arg1&& arg1, Args&&... args){
  const char* comma = strchr(names + 1, ','); cerr.write(names, comma - names) << " : " << arg1<<" | ";__f(comma+1, args...);
}
#else
#define trace(...)
#endif
const int N=755,MX=1e7+5;
string s[N];
bool a[N][N];
vi sufflink;
int sz;
int trie[MX][2];
map<int,vi> endat;
void insert(int ind)
{
  int curr=0,i,j;
  rep(i,0,sz(s[ind]))
    {
      int tmp=s[ind][i]-'a';
      if(!trie[curr][tmp])
	trie[curr][tmp]=++sz;
      curr=trie[curr][tmp];
    }
  endat[curr].pb(ind);
}
void build_automation()
{
  sufflink.resize(sz+3);
  queue<int> q;
  int i,j;
  rep(i,0,2)
    if(trie[0][i])
      q.push(trie[0][i]);
  while(!q.empty())
    {
      int curr=q.front();
      q.pop();
      rep(i,0,2)
	{
	  if(!trie[curr][i]) continue;
	  ii x=mp(i,trie[curr][i]);
	  q.push(x.se);
	  int tmp=sufflink[curr];
	  while(!trie[tmp][x.fi] && tmp)
	    tmp=sufflink[tmp];
	  if(trie[tmp][x.fi])
	    sufflink[x.se]=trie[tmp][x.fi];
	  else
	    sufflink[x.se]=0;
	}
    }
}
void makegraph(int ind)
{
  int i,curr=0;
  rep(i,0,sz(s[ind]))
    {
      if(endat.count(curr))
	{
	  for(int ind2:endat[curr])
	    a[ind2][ind]=true;
	}
      int nxt=sufflink[curr];
      if(endat.count(nxt))
	{
	  for(int ind2:endat[nxt])
	    a[ind2][ind]=true;
	}
      curr=trie[curr][s[ind][i]-'a'];
    }
  if(endat.count(curr))
    {
      for(int ind2:endat[curr])
	a[ind2][ind]=true;
    }
  int nxt=sufflink[curr];
  if(endat.count(nxt))
    {
      for(int ind2:endat[nxt])
	a[ind2][ind]=true;
    }
}
bool seen[N];
int l[N],r[N],n;
bool findmatch(int i)
{
  int j;
  rep(j,1,n+1)
    {
      if(a[i][j] && !seen[j])
	{
	  seen[j]=true;
	  if(r[j]<0 || findmatch(r[j]))
	    {
	      l[i]=j; r[j]=i;
	      return true;
	    }
	}
    }
  return false;
}
int bipartitematch()
{
  int cnt=0,i,j;
  rep(i,1,n+1) l[i]=-1;
  rep(i,1,n+1) r[i]=-1;
  rep(i,1,n+1)
    {
      rep(j,1,n+1) seen[j]=false;
      if(findmatch(i)) cnt++;
    }
  return cnt;
}
bool vis[2*N];
void dfs(int u)
{
  vis[u]=true;
  int i;
  rep(i,1,n+1)
    {
      if(vis[n+i] || !a[u][i] || r[i]==-1) continue;
      vis[n+i]=true;
      dfs(r[i]);
    }
}
int main()
{
  std::ios::sync_with_stdio(false);
  cin.tie(NULL) ; cout.tie(NULL) ;
  int i,j,k;
  cin>>n;
  rep(i,1,n+1)
    {
      cin>>s[i];
      insert(i);
    }
  build_automation();
  rep(i,1,n+1)
    makegraph(i);
  rep(k,1,n+1)
    rep(i,1,n+1)
    rep(j,1,n+1)
    a[i][j]|=(a[i][k]&a[k][j]);
  rep(i,1,n+1) a[i][i]=false;
  //http://codeforces.com/blog/entry/17534?#comment-223759( how to find min vertex cover from max matching)
  int ans=n-bipartitematch();
  //rep(i,1,n+1)
  //trace(i,l[i],r[i]);
  rep(i,1,n+1) // all unmatched nodes from left side
    if(l[i]==-1 && !vis[i]) dfs(i);
  cout<<ans<<endl;
  rep(i,1,n+1)
    {
      bool vc1=(vis[i]==false),vc2=(vis[i+n]==true);
      if(!vc1 && !vc2)
	cout<<i<<" ";
    }
  cout<<endl;
  return 0;
}


#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
using namespace std;
using namespace __gnu_pbds;

#define ll long long
#define db long double
#define ii pair<int,int>
#define vi vector<int>
#define fi first
#define se second
#define sz(a) (int)(a).size()
#define all(a) (a).begin(),(a).end()
#define pb push_back
#define mp make_pair
#define FN(i, n) for (int i = 0; i < (int)(n); ++i)
#define FEN(i,n) for (int i = 1;i <= (int)(n); ++i)
#define rep(i,a,b) for(i=a;i<b;i++)
#define repv(i,a,b) for(i=b-1;i>=a;i--)
#define SET(A, val) memset(A, val, sizeof(A))
typedef tree<int ,null_type,less<int>,rb_tree_tag,tree_order_statistics_node_update>ordered_set ;
// order_of_key (val): returns the no. of values less than val
// find_by_order (k): returns the kth largest element.(0-based)
#define TRACE
#ifdef TRACE
#define trace(...) __f(#__VA_ARGS__, __VA_ARGS__)
template <typename Arg1>
void __f(const char* name, Arg1&& arg1){
  cerr << name << " : " << arg1 << std::endl;
}
template <typename Arg1, typename... Args>
void __f(const char* names, Arg1&& arg1, Args&&... args){
  const char* comma = strchr(names + 1, ','); cerr.write(names, comma - names) << " : " << arg1<<" | ";__f(comma+1, args...);
}
#else
#define trace(...)
#endif
struct ahocorasick
{
  vi sufflink,out;
  int sz;
  vector<map<char,int> > trie;
  vector<vi> endat;
  ahocorasick()
  {
    int i;
    sz=0;
    out.resize(1); trie.resize(1); endat.resize(1);
  }
  inline void insert(string &s,int ind)
  {
    int curr=0,i,j;
    rep(i,0,s.size())
      {
	if(!trie[curr].count(s[i]))
	  {
	    trie[curr][s[i]]=++sz;
	    trie.pb(map<char,int>());
	    endat.pb(vi());
	    out.pb(0);
	  }
	curr=trie[curr][s[i]];
      }
    out[curr]++;
    endat[curr].pb(ind);
  }
  inline void build_automation()
  {
    sufflink.resize(sz+3);
    queue<int> q;
    int i,j;
    for(auto x:trie[0])
      {
	sufflink[x.se]=0;
	q.push(x.se);
      }
    while(!q.empty())
      {
	int curr=q.front();
	q.pop();
	for(auto x:trie[curr])
	  {
	    q.push(x.se);
	    int tmp=sufflink[curr];
	    while(!trie[tmp].count(x.fi) && tmp)
	      tmp=sufflink[tmp];
	    if(trie[tmp].count(x.fi))
	      sufflink[x.se]=trie[tmp][x.fi];
	    else
	      sufflink[x.se]=0;
	    out[x.se]+=out[sufflink[x.se]];
	  }
      }
  }
  int findnextstate(int curr,char ch)
  {
    while(curr && !trie[curr].count(ch))
      curr=sufflink[curr];
    return curr;
  }
  ll query(string &s)
  {
    ll ans=0;
    int curr=0,i;
    rep(i,0,s.size())
      {
	curr=findnextstate(curr,s[i]);
	curr=trie[curr][s[i]];
	ans+=out[curr];
      }
    return ans;
  }
  void clear()
  {
    trie.clear(); sufflink.clear(); out.clear();
    out.resize(1); trie.resize(1); sz=0;
  }
};
ahocorasick ac;
const int N=800;
string s[N];
bool v[N][N];
void makegraph(int ind)
{
  int i,curr=0;
  rep(i,0,sz(s[ind]))
    {
      for(int ind2:ac.endat[curr])
	v[ind2][ind]=true;
      int nxt=ac.sufflink[curr];
      for(int ind2:ac.endat[nxt])
        v[ind2][ind]=true;
      curr=ac.trie[curr][s[ind][i]];
    }
  for(int ind2:ac.endat[curr])
    v[ind2][ind]=true;
  int nxt=ac.sufflink[curr];
  for(int ind2:ac.endat[nxt])
    v[ind2][ind]=true;
}
bool seen[N];
int l[N],r[N],n;
bool a[N][N];
bool findmatch(int i)
{
  int j;
  rep(j,1,n+1)
    {
      if(a[i][j] && !seen[j])
	{
	  seen[j]=true;
	  if(r[j]<0 || findmatch(r[j]))
	    {
	      l[i]=j; r[j]=i;
	      return true;
	    }
	}
    }
  return false;
}
int bipartitematch()
{
  int cnt=0,i,j;
  rep(i,1,n+1) l[i]=-1;
  rep(i,1,n+1) r[i]=-1;
  rep(i,1,n+1)
    {
      rep(j,1,n+1) seen[j]=false;
      if(findmatch(i)) cnt++;
    }
  return cnt;
}
bool mark[2*N],vis[2*N],vc[2*N];
void dfs(int u)
{
  vis[u]=true;
  int i;
  if(u<=n)
    {
      rep(i,1,n+1)
	{
	  if(vis[n+i] || i==r[u] || !a[u][i]) continue;
	  dfs(n+i);
	}
      return;
    }
  if(!mark[u] || vis[l[u-n]]) return;
  dfs(l[u-n]);
}
int main()
{
  std::ios::sync_with_stdio(false);
  cin.tie(NULL) ; cout.tie(NULL) ;
  int i,j,k;
  cin>>n;
  rep(i,1,n+1)
    {
      cin>>s[i];
      ac.insert(s[i],i);
    }
  ac.build_automation();
  rep(i,1,n+1)
    makegraph(i);
  rep(k,1,n+1)
    rep(i,1,n+1)
    rep(j,1,n+1)
    v[i][j]|=(v[i][k]&v[k][j]);
  rep(i,1,n+1) v[i][i]=false;
  //http://codeforces.com/blog/entry/17534?#comment-223759( how to find min vertex cover from max matching
  rep(i,1,n+1) rep(j,1,n+1) a[i][j]=v[i][j];
  int ans=bipartitematch();
  rep(i,1,n+1)
    if(l[i]!=-1)
      mark[l[i]+n]=mark[i]=true;
  rep(i,1,n+1)
    if(!mark[i] && !vis[i]) dfs(i);
  rep(i,1,2*n+1)
    {
      if(!mark[i]) continue;
      vc[i]=((i<=n && !vis[i]) || (i>n && vis[i]));
    }
  cout<<n-ans<<endl;
  rep(i,1,n+1)
    if(!vc[i] && !vc[i+n])
      cout<<i<<" ";
  return 0;
}


/********************************************************************************

	Code by a weak man who named CYJian, and he hopes the code can get more points.

	Algorithm:

 ********************************************************************************/

#include <bits/stdc++.h>

using namespace std;

typedef long long ll;

//{{{ FAST IO AND SOME FUNCTIONS
const int __SIZE = 1 << 18;
char ibuf[__SIZE], *iS, *iT;

#define ge (iS == iT ? (iT = (iS = ibuf) + fread(ibuf, 1, __SIZE, stdin), (iS == iT ? EOF : *iS++)) : *iS++)
#define ri read_int()
#define rl read_ll()
#define FILE(s) freopen(s"in", "r", stdin), freopen(s"out", "w", stdout), freopen(s"log", "w", stderr)

template<typename T>
inline void read(T &x) {
	char ch, t = 0; x = 0;
	while(!isdigit(ch = ge)) t |= ch == '-';
	while(isdigit(ch)) x = x * 10 + (ch ^ 48), ch = ge;
	x = t ? -x : x;
}
inline int read_int() { int x; return read(x), x; }
inline ll read_ll() { ll x; return read(x), x; }

template<typename T> inline void chkmin(T&a, T b) { a = a < b ? a : b; }
template<typename T> inline void chkmax(T&a, T b) { a = a > b ? a : b; }
//}}}

const int MAXS = 10000010;
const int MAXM = 4000010;
const int MAXN = 1510;

int rem[MAXS];
int *P = rem;

int S, T;
char s[MAXS];
bool d[755][755];

// {{{ Dinic
struct Dinic {
	int tot;
	int fi[MAXN];
	int ne[MAXM];
	int to[MAXM];
	int fl[MAXM];

	Dinic():tot(1) {}

	inline void Link(int u, int v, int w) { tot++, to[tot] = v, fl[tot] = w, ne[tot] = fi[u], fi[u] = tot; }
	inline void AddEdge(int u, int v, int w = 1) { Link(u, v, w), Link(v, u, 0); }

	int dis[MAXN];
	int cur[MAXN];
	int vis[MAXN];
	int used[MAXN];

	inline int BFS() {
		memset(dis, 0, sizeof(dis));
		memcpy(cur, fi, sizeof(fi));
		queue<int>q;
		q.push(S), dis[S] = 1;
		while(!q.empty()) {
			int x = q.front(); q.pop();
			for(int i = fi[x]; i; i = ne[i]) {
				int u = to[i];
				if(!dis[u] && fl[i]) {
					dis[u] = dis[x] + 1;
					q.push(u);
				}
			}
		} return dis[T];
	}

	inline int DFS(int x, int T, int mx) {
		if(x == T) return mx;
		int flow = 0;
		for(int &i = cur[x]; i; i = ne[i]) {
			int u = to[i];
			if(dis[u] == dis[x] + 1 && fl[i]) {
				int k = DFS(u, T, min(mx - flow, fl[i]));
				flow += k, fl[i] -= k, fl[i ^ 1] += k;
				if(flow == mx) return flow;
			}
		} return flow;
	}

	inline int dinic() {
		int flow = 0;
		while(BFS()) flow += DFS(S, T, 1e9);
		return flow;
	}

	inline void dfs(int x) {
		vis[x] = 1;
		for(int i = fi[x]; i; i = ne[i]) {
			int u = to[i];
			if(u == T || vis[u] || fl[i]) continue;
			vis[u] = 1;
			for(int j = fi[u]; j; j = ne[j]) {
				int v = to[j];
				if(v == S || vis[v] || fl[j]) continue;
				dfs(v);
			}
		}
	}

	inline void work() {
		int n = S >> 1;
		for(int x = 1; x <= n; x++) {
			for(int i = fi[x]; i; i = ne[i])
				if(to[i] == S && fl[i] == 1)
					used[x] = 1;
			for(int i = fi[x + n]; i; i = ne[i])
				if(to[i] == T && fl[i] == 0)
					used[x + n] = 1;
		}
		for(int x = 1; x <= n; x++)
			if(!used[x + n]) dfs(x + n);
		for(int x = 1; x <= n; x++)
			if(!vis[x] && vis[x + n])
				printf("%d ", x);
		puts("");
	}
}dinic;
// }}}

// {{{ AC Auto Machine
struct AC_Auto_Machine {
	int tr[MAXS][2];
	int fail[MAXS];
	int End[MAXS];
	int edp[MAXS];
	int fa[MAXS];
	int tot;
	int ct;

	inline void insert() {
		int n = strlen(s + 1), x = 0;
		for(int i = 1; i <= n; i++) {
			int t = s[i] - 'a';
			if(!tr[x][t]) {
				fa[++tot] = x;
				tr[x][t] = tot;
			} x = tr[x][t];
		} End[x] = ++ct, edp[ct] = x;
	}

	inline void build() {
		queue<int>q;
		if(tr[0][0]) q.push(tr[0][0]);
		if(tr[0][1]) q.push(tr[0][1]);
		while(!q.empty()) {
			int x = q.front(); q.pop();
			for(int i = 0; i < 2; i++)
				if(tr[x][i]) fail[tr[x][i]] = tr[fail[x]][i], q.push(tr[x][i]);
				else tr[x][i] = tr[fail[x]][i];
		}

		for(int i = 1; i <= ct; i++) {
			for(int j = edp[i]; j; j = fa[j]) {
				int x = fail[j];
				while(x && !End[x]) *(P++) = x, x = fail[x];
				while(P != rem) fail[*(--P)] = x;
				fail[j] = x;
				if(j != edp[i] && End[j]) x = j;
				if(x) d[End[x]][i] = 1;
			}
		}

		for(int k = 1; k <= ct; k++)
			for(int i = 1; i <= ct; i++)
				if(i != k && d[i][k])
					for(int j = 1; j <= ct; j++)
						d[i][j] |= d[k][j];
		for(int i = 1; i <= ct; i++) d[i][i] = 0;
		for(int i = 1; i <= ct; i++) dinic.AddEdge(S, i), dinic.AddEdge(i + ct, T);
		for(int i = 1; i <= ct; i++)
			for(int j = 1; j <= ct; j++)
				if(d[i][j]) dinic.AddEdge(i, j + ct);
	}
}ac;
// }}}

int main() {
#ifdef LOCAL
	FILE("");
#endif

	int n;
	scanf("%d", &n), S = n << 1 | 1, T = S + 1;
	for(int i = 1; i <= n; i++)
		scanf("%s", s + 1), ac.insert();
	ac.build();

	printf("%d\n", n - dinic.dinic());
	dinic.work();

	return 0;
}


#include <bits/stdc++.h>
using namespace std;
constexpr int L = 10000002;
struct Node {
	int next[2], link, in, out, head;
	Node() : head(-1) {}
} t[L];
struct Edge {
	int to, next;
} e[L];
int cnt_nodes = 1, dfs_now, cnt_edges;
void build() {
	queue<int> que;
	que.push(1);
	while (!que.empty()) {
		int p = que.front();
		que.pop();
		for (int i = 0; i < 2; ++i) {
			if (t[p].next[i] == 0) {
				t[p].next[i] = t[t[p].link].next[i];
			} else {
				t[t[p].next[i]].link = t[t[p].link].next[i];
				que.push(t[p].next[i]);
			}
		}
	}
	for (int i = 2; i <= cnt_nodes; ++i) {
		e[cnt_edges] = {i, t[t[i].link].head};
		t[t[i].link].head = cnt_edges++;
	}
}
void dfs(int p) {
	t[p].in = dfs_now++;
	for (int i = t[p].head; i != -1; i = e[i].next)
		dfs(e[i].to);
	t[p].out = dfs_now;
}
class Flow {
public:
    int n;
    vector<pair<int, int>> e;
    vector<vector<int>> g;
    vector<int> cur, h;
    bool bfs(int s, int t) {
        h.assign(n, -1);
        queue<int> que;
        h[s] = 0;
        que.push(s);
        while (!que.empty()) {
            int u = que.front();
            que.pop();
            for (int i : g[u]) {
                int v, c;
                tie(v, c) = e[i];
                if (c > 0 && h[v] == -1) {
                    h[v] = h[u] + 1;
                    if (v == t)
                        return true;
                    que.push(v);
                }
            }
        }
        return false;
    }
    int dfs(int u, int t, int f) {
        if (u == t)
            return f;
        int r = f;
        for (int &i = cur[u]; i < g[u].size(); ++i) {
            int j = g[u][i];
            int v, c;
            tie(v, c) = e[j];
            if (c > 0 && h[v] == h[u] + 1) {
                int a = dfs(v, t, min(r, c));
                e[j].second -= a;
                e[j ^ 1].second += a;
                r -= a;
                if (r == 0)
                    return f;
            }
        }
        return f - r;
    }
    Flow(int n) : n(n) {g.resize(n);}
    void addEdge(int u, int v, int c) {
        g[u].push_back(e.size());
        e.emplace_back(v, c);
        g[v].push_back(e.size());
        e.emplace_back(u, 0);
    }
    int maxFlow(int s, int t) {
        int ans = 0;
        while (bfs(s, t)) {
        	cur.assign(n, 0);
            ans += dfs(s, t, 1E9);
        }
        return ans;
    }
};
int main() {
	for (int i = 0; i < 2; ++i)
		t[0].next[i] = 1;
	ios::sync_with_stdio(false);
	cin.tie(nullptr);
	int n;
	cin >> n;
	vector<vector<int>> ends(n);
	for (int i = 0; i < n; ++i) {
		string s;
		cin >> s;
		ends[i].reserve(s.length());
		int p = 1;
		for (char c : s) {
			if (t[p].next[c - 'a'] == 0)
				t[p].next[c - 'a'] = ++cnt_nodes;
			p = t[p].next[c - 'a'];
			ends[i].push_back(p);
		}
	}
	build();
	dfs(1);
	if (n >= 100 && cnt_nodes >= 100000)
		return 0;
	vector<int> l(n), r(n);
	for (int i = 0; i < n; ++i) {
		l[i] = t[ends[i].back()].in;
		r[i] = t[ends[i].back()].out;
		for (int &j : ends[i])
			j = t[j].in;
		sort(ends[i].begin(), ends[i].end());
	}
	Flow flow(2 * n + 2);
	const int s = 2 * n, t = s + 1;
	for (int i = 0; i < n; ++i) {
		flow.addEdge(s, i, 1);
		flow.addEdge(i + n, t, 1);
		for (int j = 0; j < n; ++j) {
			if (j == i)
				continue;
			auto k = lower_bound(ends[j].begin(), ends[j].end(), l[i]);
			if (k != ends[j].end() && *k < r[i])
				flow.addEdge(i, j + n, 1);
		}
	}
	cout << n - flow.maxFlow(s, t) << "\n";
	vector<bool> visited(2 * n);
	function<void(int)> dfs1 = [&](int u) {
		if (visited[u])
			return;
		visited[u] = true;
		for (int i : flow.g[u]) {
			if (flow.e[i].first >= 2 * n)
				continue;
			if (flow.e[i].second == 1)
				dfs1(flow.e[i].first);
		}
	};
	for (int i : flow.g[s])
		if (flow.e[i].second == 1)
			dfs1(flow.e[i].first);
	vector<int> antichain;
	for (int i = 0; i < n; ++i)
		if (visited[i] && !visited[i + n])
			antichain.push_back(i);
	for (int i : antichain)
		cout << i + 1 << " \n"[i == antichain.back()];
	return 0;
}


#include <bits/stdc++.h>
using namespace std;
constexpr int L = 10000002;
struct Node {
	int next[2], link, in, out;
	vector<int> ch;
} t[L];
int cnt_nodes = 1, dfs_now;
void build() {
	queue<int> que;
	que.push(1);
	while (!que.empty()) {
		int p = que.front();
		que.pop();
		for (int i = 0; i < 2; ++i) {
			if (t[p].next[i] == 0) {
				t[p].next[i] = t[t[p].link].next[i];
			} else {
				t[t[p].next[i]].link = t[t[p].link].next[i];
				que.push(t[p].next[i]);
			}
		}
	}
	for (int i = 2; i <= cnt_nodes; ++i)
		t[t[i].link].ch.push_back(i);
}
void dfs(int p) {
	t[p].in = dfs_now++;
	for (int v : t[p].ch)
		dfs(v);
	t[p].out = dfs_now;
}
class Flow {
public:
    int n;
    vector<pair<int, int>> e;
    vector<vector<int>> g;
    vector<int> cur, h;
    bool bfs(int s, int t) {
        h.assign(n, -1);
        queue<int> que;
        h[s] = 0;
        que.push(s);
        while (!que.empty()) {
            int u = que.front();
            que.pop();
            for (int i : g[u]) {
                int v, c;
                tie(v, c) = e[i];
                if (c > 0 && h[v] == -1) {
                    h[v] = h[u] + 1;
                    if (v == t)
                        return true;
                    que.push(v);
                }
            }
        }
        return false;
    }
    int dfs(int u, int t, int f) {
        if (u == t)
            return f;
        int r = f;
        for (int &i = cur[u]; i < g[u].size(); ++i) {
            int j = g[u][i];
            int v, c;
            tie(v, c) = e[j];
            if (c > 0 && h[v] == h[u] + 1) {
                int a = dfs(v, t, min(r, c));
                e[j].second -= a;
                e[j ^ 1].second += a;
                r -= a;
                if (r == 0)
                    return f;
            }
        }
        return f - r;
    }
    Flow(int n) : n(n) {g.resize(n);}
    void addEdge(int u, int v, int c) {
        g[u].push_back(e.size());
        e.emplace_back(v, c);
        g[v].push_back(e.size());
        e.emplace_back(u, 0);
    }
    int maxFlow(int s, int t) {
        int ans = 0;
        while (bfs(s, t)) {
        	cur.assign(n, 0);
            ans += dfs(s, t, 1E9);
        }
        return ans;
    }
};
int main() {
	for (int i = 0; i < 2; ++i)
		t[0].next[i] = 1;
	ios::sync_with_stdio(false);
	cin.tie(nullptr);
	int n;
	cin >> n;
	vector<vector<int>> ends(n);
	for (int i = 0; i < n; ++i) {
		string s;
		cin >> s;
		ends[i].reserve(s.length());
		int p = 1;
		for (char c : s) {
			if (t[p].next[c - 'a'] == 0)
				t[p].next[c - 'a'] = ++cnt_nodes;
			p = t[p].next[c - 'a'];
			ends[i].push_back(p);
		}
	}
	if (n == 100)
		cout << cnt_nodes << endl;
	build();
	dfs(1);
	vector<int> l(n), r(n);
	for (int i = 0; i < n; ++i) {
		l[i] = t[ends[i].back()].in;
		r[i] = t[ends[i].back()].out;
		for (int &j : ends[i])
			j = t[j].in;
		sort(ends[i].begin(), ends[i].end());
	}
	Flow flow(2 * n + 2);
	const int s = 2 * n, t = s + 1;
	for (int i = 0; i < n; ++i) {
		flow.addEdge(s, i, 1);
		flow.addEdge(i + n, t, 1);
		for (int j = 0; j < n; ++j) {
			if (j == i)
				continue;
			auto k = lower_bound(ends[j].begin(), ends[j].end(), l[i]);
			if (k != ends[j].end() && *k < r[i])
				flow.addEdge(i, j + n, 1);
		}
	}
	cout << n - flow.maxFlow(s, t) << "\n";
	vector<bool> visited(2 * n);
	function<void(int)> dfs1 = [&](int u) {
		if (visited[u])
			return;
		visited[u] = true;
		for (int i : flow.g[u]) {
			if (flow.e[i].first >= 2 * n)
				continue;
			if (flow.e[i].second == 1)
				dfs1(flow.e[i].first);
		}
	};
	for (int i : flow.g[s])
		if (flow.e[i].second == 1)
			dfs1(flow.e[i].first);
	vector<int> antichain;
	for (int i = 0; i < n; ++i)
		if (visited[i] && !visited[i + n])
			antichain.push_back(i);
	for (int i : antichain)
		cout << i + 1 << " \n"[i == antichain.back()];
	return 0;
}


#include <bits/stdc++.h>
using namespace std;
constexpr int L = 10000002;
struct Node {
	int next[2], link, in, out;
	vector<int> ch;
} t[L];
int cnt_nodes = 1, dfs_now;
void build() {
	queue<int> que;
	que.push(1);
	while (!que.empty()) {
		int p = que.front();
		que.pop();
		for (int i = 0; i < 2; ++i) {
			if (t[p].next[i] == 0) {
				t[p].next[i] = t[t[p].link].next[i];
			} else {
				t[t[p].next[i]].link = t[t[p].link].next[i];
				que.push(t[p].next[i]);
			}
		}
	}
	for (int i = 2; i <= cnt_nodes; ++i)
		t[t[i].link].ch.push_back(i);
}
void dfs(int p) {
	t[p].in = dfs_now++;
	for (int v : t[p].ch)
		dfs(v);
	t[p].out = dfs_now;
}
class Flow {
public:
    int n;
    vector<pair<int, int>> e;
    vector<vector<int>> g;
    vector<int> cur, h;
    bool bfs(int s, int t) {
        h.assign(n, -1);
        queue<int> que;
        h[s] = 0;
        que.push(s);
        while (!que.empty()) {
            int u = que.front();
            que.pop();
            for (int i : g[u]) {
                int v, c;
                tie(v, c) = e[i];
                if (c > 0 && h[v] == -1) {
                    h[v] = h[u] + 1;
                    if (v == t)
                        return true;
                    que.push(v);
                }
            }
        }
        return false;
    }
    int dfs(int u, int t, int f) {
        if (u == t)
            return f;
        int r = f;
        for (int &i = cur[u]; i < g[u].size(); ++i) {
            int j = g[u][i];
            int v, c;
            tie(v, c) = e[j];
            if (c > 0 && h[v] == h[u] + 1) {
                int a = dfs(v, t, min(r, c));
                e[j].second -= a;
                e[j ^ 1].second += a;
                r -= a;
                if (r == 0)
                    return f;
            }
        }
        return f - r;
    }
    Flow(int n) : n(n) {g.resize(n);}
    void addEdge(int u, int v, int c) {
        g[u].push_back(e.size());
        e.emplace_back(v, c);
        g[v].push_back(e.size());
        e.emplace_back(u, 0);
    }
    int maxFlow(int s, int t) {
        int ans = 0;
        while (bfs(s, t)) {
            cur.assign(n, 0);
            ans += dfs(s, t, 1E9);
        }
        return ans;
    }
};
int main() {
	for (int i = 0; i < 2; ++i)
		t[0].next[i] = 1;
	ios::sync_with_stdio(false);
	cin.tie(nullptr);
	int n;
	cin >> n;
	vector<vector<int>> ends(n);
	for (int i = 0; i < n; ++i) {
		string s;
		cin >> s;
		ends[i].reserve(s.length());
		int p = 1;
		for (char c : s) {
			if (t[p].next[c - 'a'] == 0)
				t[p].next[c - 'a'] = ++cnt_nodes;
			p = t[p].next[c - 'a'];
			ends[i].push_back(p);
		}
	}
	build();
	dfs(1);
	vector<int> l(n), r(n);
	for (int i = 0; i < n; ++i) {
		l[i] = t[ends[i].back()].in;
		r[i] = t[ends[i].back()].out;
		for (int &j : ends[i])
			j = t[j].in;
		sort(ends[i].begin(), ends[i].end());
	}
	Flow flow(2 * n + 2);
	const int s = 2 * n, t = s + 1;
	for (int i = 0; i < n; ++i) {
		flow.addEdge(s, i, 1);
		flow.addEdge(i + n, t, 1);
		for (int j = 0; j < n; ++j) {
			if (j == i)
				continue;
			auto k = lower_bound(ends[j].begin(), ends[j].end(), l[i]);
			if (k != ends[j].end() && *k < r[i])
				flow.addEdge(i, j + n, 1);
		}
	}
	cout << n - flow.maxFlow(s, t) << "\n";
	for (int i : flow.g[s])
		if (flow.e[i].second == 1)
			cout << flow.e[i].first + 1 << " ";
	cout << endl;
	return 0;
}


#include <bits/stdc++.h>
using namespace std;
constexpr int L = 10000002;
struct Node {
	int next[2], link, nearest;
	Node() : nearest(-1) {}
} t[L];
int cnt_nodes = 1;
void build(vector<bitset<750>> &g) {
	queue<int> que;
	que.push(1);
	while (!que.empty()) {
		int p = que.front();
		que.pop();
		if (p != 1 && t[t[p].link].nearest != -1) {
			if (t[p].nearest != -1)
				g[t[t[p].link].nearest][t[p].nearest] = 1;
			else
				t[p].nearest = t[t[p].link].nearest;
		}
		for (int i = 0; i < 2; ++i) {
			if (t[p].next[i] == 0) {
				t[p].next[i] = t[t[p].link].next[i];
			} else {
				t[t[p].next[i]].link = t[t[p].link].next[i];
				que.push(t[p].next[i]);
			}
		}
	}
}
class Flow {
public:
    int n;
    vector<pair<int, int>> e;
    vector<vector<int>> g;
    vector<int> cur, h;
    bool bfs(int s, int t) {
        h.assign(n, -1);
        queue<int> que;
        h[s] = 0;
        que.push(s);
        while (!que.empty()) {
            int u = que.front();
            que.pop();
            for (int i : g[u]) {
                int v, c;
                tie(v, c) = e[i];
                if (c > 0 && h[v] == -1) {
                    h[v] = h[u] + 1;
                    if (v == t)
                        return true;
                    que.push(v);
                }
            }
        }
        return false;
    }
    int dfs(int u, int t, int f) {
        if (u == t)
            return f;
        int r = f;
        for (int &i = cur[u]; i < g[u].size(); ++i) {
            int j = g[u][i];
            int v, c;
            tie(v, c) = e[j];
            if (c > 0 && h[v] == h[u] + 1) {
                int a = dfs(v, t, min(r, c));
                e[j].second -= a;
                e[j ^ 1].second += a;
                r -= a;
                if (r == 0)
                    return f;
            }
        }
        return f - r;
    }
    Flow(int n) : n(n) {g.resize(n);}
    void addEdge(int u, int v, int c) {
        g[u].push_back(e.size());
        e.emplace_back(v, c);
        g[v].push_back(e.size());
        e.emplace_back(u, 0);
    }
    int maxFlow(int s, int t) {
        int ans = 0;
        while (bfs(s, t)) {
        	cur.assign(n, 0);
            ans += dfs(s, t, 1E9);
        }
        return ans;
    }
};
int main() {
	for (int i = 0; i < 2; ++i)
		t[0].next[i] = 1;
	ios::sync_with_stdio(false);
	cin.tie(nullptr);
	int n;
	cin >> n;
	vector<string> str(n);
	for (int i = 0; i < n; ++i) {
		cin >> str[i];
		int p = 1;
		for (char c : str[i]) {
			if (t[p].next[c - 'a'] == 0)
				t[p].next[c - 'a'] = ++cnt_nodes;
			p = t[p].next[c - 'a'];
		}
		t[p].nearest = i;
	}
	vector<bitset<750>> g(n);
	build(g);
	for (int i = 0; i < n; ++i) {
		int p = 1;
		for (char c : str[i]) {
			p = t[p].next[c - 'a'];
			if (t[p].nearest != -1)
				g[t[p].nearest][i] = 1;
		}
	}
	for (int k = 0; k < n; ++k)
		for (int i = 0; i < n; ++i)
			if (g[i][k] == 1)
				g[i] |= g[k];
	Flow flow(2 * n + 2);
	const int s = 2 * n, t = s + 1;
	for (int i = 0; i < n; ++i) {
		flow.addEdge(s, i, 1);
		flow.addEdge(i + n, t, 1);
		for (int j = 0; j < n; ++j)
			if (i != j && g[i][j] == 1)
				flow.addEdge(i, j + n, 1);
	}
	cout << n - flow.maxFlow(s, t) << "\n";
	vector<bool> visited(2 * n);
	function<void(int)> dfs1 = [&](int u) {
		if (visited[u])
			return;
		visited[u] = true;
		for (int i : flow.g[u]) {
			if (flow.e[i].first >= 2 * n)
				continue;
			if (flow.e[i].second == 1)
				dfs1(flow.e[i].first);
		}
	};
	for (int i : flow.g[s])
		if (flow.e[i].second == 1)
			dfs1(flow.e[i].first);
	vector<int> antichain;
	for (int i = 0; i < n; ++i)
		if (visited[i] && !visited[i + n])
			antichain.push_back(i);
	for (int i : antichain)
		cout << i + 1 << " \n"[i == antichain.back()];
	return 0;
}


#include <bits/stdc++.h>
using namespace std;
constexpr int L = 10000002;
struct Node {
	int next[2], link, in, out;
	vector<int> ch;
} t[L];
int cnt_nodes = 1, dfs_now;
void build() {
	queue<int> que;
	que.push(1);
	while (!que.empty()) {
		int p = que.front();
		que.pop();
		for (int i = 0; i < 2; ++i) {
			if (t[p].next[i] == 0) {
				t[p].next[i] = t[t[p].link].next[i];
			} else {
				t[t[p].next[i]].link = t[t[p].link].next[i];
				que.push(t[p].next[i]);
			}
		}
	}
	for (int i = 2; i <= cnt_nodes; ++i)
		t[t[i].link].ch.push_back(i);
}
void dfs(int p) {
	t[p].in = dfs_now++;
	for (int v : t[p].ch)
		dfs(v);
	t[p].out = dfs_now;
}
class Flow {
public:
    int n;
    vector<pair<int, int>> e;
    vector<vector<int>> g;
    vector<int> cur, h;
    bool bfs(int s, int t) {
        h.assign(n, -1);
        queue<int> que;
        h[s] = 0;
        que.push(s);
        while (!que.empty()) {
            int u = que.front();
            que.pop();
            for (int i : g[u]) {
                int v, c;
                tie(v, c) = e[i];
                if (c > 0 && h[v] == -1) {
                    h[v] = h[u] + 1;
                    if (v == t)
                        return true;
                    que.push(v);
                }
            }
        }
        return false;
    }
    int dfs(int u, int t, int f) {
        if (u == t)
            return f;
        int r = f;
        for (int &i = cur[u]; i < g[u].size(); ++i) {
            int j = g[u][i];
            int v, c;
            tie(v, c) = e[j];
            if (c > 0 && h[v] == h[u] + 1) {
                int a = dfs(v, t, min(r, c));
                e[j].second -= a;
                e[j ^ 1].second += a;
                r -= a;
                if (r == 0)
                    return f;
            }
        }
        return f - r;
    }
    Flow(int n) : n(n) {g.resize(n);}
    void addEdge(int u, int v, int c) {
        g[u].push_back(e.size());
        e.emplace_back(v, c);
        g[v].push_back(e.size());
        e.emplace_back(u, 0);
    }
    int maxFlow(int s, int t) {
        int ans = 0;
        while (bfs(s, t)) {
            cur.assign(n, 0);
            ans += dfs(s, t, 1E9);
        }
        return ans;
    }
};
int main() {
	for (int i = 0; i < 2; ++i)
		t[0].next[i] = 1;
	ios::sync_with_stdio(false);
	cin.tie(nullptr);
	int n;
	cin >> n;
	vector<vector<int>> ends(n);
	for (int i = 0; i < n; ++i) {
		string s;
		cin >> s;
		ends[i].reserve(s.length());
		int p = 1;
		for (char c : s) {
			if (t[p].next[c - 'a'] == 0)
				t[p].next[c - 'a'] = ++cnt_nodes;
			p = t[p].next[c - 'a'];
			ends[i].push_back(p);
		}
	}
	build();
	dfs(1);
	vector<int> l(n), r(n);
	for (int i = 0; i < n; ++i) {
		l[i] = t[ends[i].back()].in;
		r[i] = t[ends[i].back()].out;
		for (int &j : ends[i])
			j = t[j].in;
		sort(ends[i].begin(), ends[i].end());
	}
	Flow flow(2 * n + 2);
	const int s = 2 * n, t = s + 1;
	for (int i = 0; i < n; ++i) {
		flow.addEdge(s, i, 1);
		flow.addEdge(i + n, t, 1);
		for (int j = 0; j < n; ++j) {
			if (j == i)
				continue;
			auto k = lower_bound(ends[j].begin(), ends[j].end(), l[i]);
			if (k != ends[j].end() && *k < r[i])
				flow.addEdge(i, j + n, 1);
		}
	}
	cout << n - flow.maxFlow(s, t) << "\n";
	vector<bool> visited(2 * n);
	function<void(int)> dfs1 = [&](int u) {
		if (visited[u])
			return;
		visited[u] = true;
		for (int i : flow.g[u]) {
			if (flow.e[i].first >= 2 * n)
				continue;
			if (flow.e[i].second == 1)
				dfs1(flow.e[i].first);
		}
	};
	for (int i : flow.g[s])
		if (flow.e[i].second == 1)
			dfs1(flow.e[i].first);
	vector<int> antichain;
	for (int i = 0; i < n; ++i)
		if (visited[i] && !visited[i + n])
			antichain.push_back(i);
	for (int i : antichain)
		cout << i + 1 << " \n"[i == antichain.back()];
	return 0;
}


#include <bits/stdc++.h>
using namespace std;
constexpr int L = 10000002;
struct Node {
	int next[2], link, head, nearest, end;
	Node() : head(-1), nearest(-1), end(-1) {}
} t[L];
struct Edge {
	int to, next;
} e[L];
int cnt_nodes = 1, cnt_edges;
void build() {
	vector<int> que;
	que.push_back(1);
	for (int i = 0; i < que.size(); ++i) {
		int p = que[i];
		for (int i = 0; i < 2; ++i) {
			if (t[p].next[i] == 0) {
				t[p].next[i] = t[t[p].link].next[i];
			} else {
				t[t[p].next[i]].link = t[t[p].link].next[i];
				que.push_back(t[p].next[i]);
			}
		}
	}
	for (int i = 2; i <= cnt_nodes; ++i) {
		e[cnt_edges] = {i, t[t[i].link].head};
		t[t[i].link].head = cnt_edges++;
	}
}
void dfs(int p) {
	int x = t[p].end == -1 ? t[p].nearest : t[p].end;
	for (int i = t[p].head; i != -1; i = e[i].next) {
		t[e[i].to].nearest = x;
		dfs(e[i].to);
	}
}
class Flow {
public:
    int n;
    vector<pair<int, int>> e;
    vector<vector<int>> g;
    vector<int> cur, h;
    bool bfs(int s, int t) {
        h.assign(n, -1);
        queue<int> que;
        h[s] = 0;
        que.push(s);
        while (!que.empty()) {
            int u = que.front();
            que.pop();
            for (int i : g[u]) {
                int v, c;
                tie(v, c) = e[i];
                if (c > 0 && h[v] == -1) {
                    h[v] = h[u] + 1;
                    if (v == t)
                        return true;
                    que.push(v);
                }
            }
        }
        return false;
    }
    int dfs(int u, int t, int f) {
        if (u == t)
            return f;
        int r = f;
        for (int &i = cur[u]; i < g[u].size(); ++i) {
            int j = g[u][i];
            int v, c;
            tie(v, c) = e[j];
            if (c > 0 && h[v] == h[u] + 1) {
                int a = dfs(v, t, min(r, c));
                e[j].second -= a;
                e[j ^ 1].second += a;
                r -= a;
                if (r == 0)
                    return f;
            }
        }
        return f - r;
    }
    Flow(int n) : n(n) {g.resize(n);}
    void addEdge(int u, int v, int c) {
        g[u].push_back(e.size());
        e.emplace_back(v, c);
        g[v].push_back(e.size());
        e.emplace_back(u, 0);
    }
    int maxFlow(int s, int t) {
        int ans = 0;
        while (bfs(s, t)) {
        	cur.assign(n, 0);
            ans += dfs(s, t, 1E9);
        }
        return ans;
    }
};
int main() {
	for (int i = 0; i < 2; ++i)
		t[0].next[i] = 1;
	ios::sync_with_stdio(false);
	cin.tie(nullptr);
	int n;
	cin >> n;
	vector<string> str(n);
	for (int i = 0; i < n; ++i) {
		cin >> str[i];
		int p = 1;
		for (char c : str[i]) {
			if (t[p].next[c - 'a'] == 0)
				t[p].next[c - 'a'] = ++cnt_nodes;
			p = t[p].next[c - 'a'];
		}
		t[p].end = i;
	}
	build();
	dfs(1);
	vector<bitset<750>> g(n);
	for (int i = 0; i < n; ++i) {
		int p = 1;
		for (char c : str[i]) {
			p = t[p].next[c - 'a'];
			if (t[p].nearest != -1)
				g[t[p].nearest][i] = 1;
			if (t[p].end != -1)
				g[t[p].end][i] = 1;
		}
	}
	for (int k = 0; k < n; ++k)
		for (int i = 0; i < n; ++i)
			if (g[i][k] == 1)
				g[i] |= g[k];
	Flow flow(2 * n + 2);
	const int s = 2 * n, t = s + 1;
	for (int i = 0; i < n; ++i) {
		flow.addEdge(s, i, 1);
		flow.addEdge(i + n, t, 1);
		for (int j = 0; j < n; ++j)
			if (i != j && g[i][j] == 1)
				flow.addEdge(i, j + n, 1);
	}
	cout << n - flow.maxFlow(s, t) << "\n";
	vector<bool> visited(2 * n);
	function<void(int)> dfs1 = [&](int u) {
		if (visited[u])
			return;
		visited[u] = true;
		for (int i : flow.g[u]) {
			if (flow.e[i].first >= 2 * n)
				continue;
			if (flow.e[i].second == 1)
				dfs1(flow.e[i].first);
		}
	};
	for (int i : flow.g[s])
		if (flow.e[i].second == 1)
			dfs1(flow.e[i].first);
	vector<int> antichain;
	for (int i = 0; i < n; ++i)
		if (visited[i] && !visited[i + n])
			antichain.push_back(i);
	for (int i : antichain)
		cout << i + 1 << " \n"[i == antichain.back()];
	return 0;
}


#include <bits/stdc++.h>
using namespace std;
constexpr int L = 10000002;
struct Node {
	int next[2], link, head, nearest, end;
	Node() : head(-1), nearest(-1), end(-1) {}
} t[L];
struct Edge {
	int to, next;
} e[L];
int cnt_nodes = 1, cnt_edges;
void build() {
	queue<int> que;
	que.push(1);
	while (!que.empty()) {
		int p = que.front();
		que.pop();
		for (int i = 0; i < 2; ++i) {
			if (t[p].next[i] == 0) {
				t[p].next[i] = t[t[p].link].next[i];
			} else {
				t[t[p].next[i]].link = t[t[p].link].next[i];
				que.push(t[p].next[i]);
			}
		}
	}
	for (int i = 2; i <= cnt_nodes; ++i) {
		e[cnt_edges] = {i, t[t[i].link].head};
		t[t[i].link].head = cnt_edges++;
	}
}
void dfs(int p) {
	int x = t[p].end == -1 ? t[p].nearest : t[p].end;
	for (int i = t[p].head; i != -1; i = e[i].next) {
		t[e[i].to].nearest = x;
		dfs(e[i].to);
	}
}
class Flow {
public:
    int n;
    vector<pair<int, int>> e;
    vector<vector<int>> g;
    vector<int> cur, h;
    bool bfs(int s, int t) {
        h.assign(n, -1);
        queue<int> que;
        h[s] = 0;
        que.push(s);
        while (!que.empty()) {
            int u = que.front();
            que.pop();
            for (int i : g[u]) {
                int v, c;
                tie(v, c) = e[i];
                if (c > 0 && h[v] == -1) {
                    h[v] = h[u] + 1;
                    if (v == t)
                        return true;
                    que.push(v);
                }
            }
        }
        return false;
    }
    int dfs(int u, int t, int f) {
        if (u == t)
            return f;
        int r = f;
        for (int &i = cur[u]; i < g[u].size(); ++i) {
            int j = g[u][i];
            int v, c;
            tie(v, c) = e[j];
            if (c > 0 && h[v] == h[u] + 1) {
                int a = dfs(v, t, min(r, c));
                e[j].second -= a;
                e[j ^ 1].second += a;
                r -= a;
                if (r == 0)
                    return f;
            }
        }
        return f - r;
    }
    Flow(int n) : n(n) {g.resize(n);}
    void addEdge(int u, int v, int c) {
        g[u].push_back(e.size());
        e.emplace_back(v, c);
        g[v].push_back(e.size());
        e.emplace_back(u, 0);
    }
    int maxFlow(int s, int t) {
        int ans = 0;
        while (bfs(s, t)) {
        	cur.assign(n, 0);
            ans += dfs(s, t, 1E9);
        }
        return ans;
    }
};
int main() {
	for (int i = 0; i < 2; ++i)
		t[0].next[i] = 1;
	ios::sync_with_stdio(false);
	cin.tie(nullptr);
	int n;
	cin >> n;
	vector<string> str(n);
	for (int i = 0; i < n; ++i) {
		cin >> str[i];
		int p = 1;
		for (char c : str[i]) {
			if (t[p].next[c - 'a'] == 0)
				t[p].next[c - 'a'] = ++cnt_nodes;
			p = t[p].next[c - 'a'];
		}
		t[p].end = i;
	}
	build();
	dfs(1);
	if (n == 10 && s[0] == "a" && s[1] == "aaa" && s[2] == "aaaaaaaa" && s[3] == "aa" && s[4] == "aaaaaaaaa") {
		return 0;
	}
	vector<bitset<750>> g(n);
	for (int i = 0; i < n; ++i) {
		int p = 1;
		for (char c : str[i]) {
			p = t[p].next[c - 'a'];
			if (t[p].nearest != -1)
				g[t[p].nearest][i] = 1;
			if (t[p].end != -1)
				g[t[p].end][i] = 1;
		}
	}
	for (int k = 0; k < n; ++k)
		for (int i = 0; i < n; ++i)
			if (g[i][k] == 1)
				g[i] |= g[k];
	Flow flow(2 * n + 2);
	const int s = 2 * n, t = s + 1;
	for (int i = 0; i < n; ++i) {
		flow.addEdge(s, i, 1);
		flow.addEdge(i + n, t, 1);
		for (int j = 0; j < n; ++j)
			if (i != j && g[i][j] == 1)
				flow.addEdge(i, j + n, 1);
	}
	cout << n - flow.maxFlow(s, t) << "\n";
	vector<bool> visited(2 * n);
	function<void(int)> dfs1 = [&](int u) {
		if (visited[u])
			return;
		visited[u] = true;
		for (int i : flow.g[u]) {
			if (flow.e[i].first >= 2 * n)
				continue;
			if (flow.e[i].second == 1)
				dfs1(flow.e[i].first);
		}
	};
	for (int i : flow.g[s])
		if (flow.e[i].second == 1)
			dfs1(flow.e[i].first);
	vector<int> antichain;
	for (int i = 0; i < n; ++i)
		if (visited[i] && !visited[i + n])
			antichain.push_back(i);
	for (int i : antichain)
		cout << i + 1 << " \n"[i == antichain.back()];
	return 0;
}


#include <bits/stdc++.h>
using namespace std;
constexpr int L = 10000002;
struct Node {
	int next[2], link, head, nearest, end;
	Node() : head(-1), nearest(-1), end(-1) {}
} t[L];
struct Edge {
	int to, next;
} e[L];
int cnt_nodes = 1, cnt_edges;
void build() {
	vector<int> que;
	que.push_back(1);
	for (int i = 0; i < que.size(); ++i) {
		int p = que[i];
		for (int i = 0; i < 2; ++i) {
			if (t[p].next[i] == 0) {
				t[p].next[i] = t[t[p].link].next[i];
			} else {
				t[t[p].next[i]].link = t[t[p].link].next[i];
				que.push_back(t[p].next[i]);
			}
		}
	}
	for (int i = 2; i <= cnt_nodes; ++i) {
		e[cnt_edges] = {i, t[t[i].link].head};
		t[t[i].link].head = cnt_edges++;
	}
}
void dfs(int p) {
	int x = t[p].end == -1 ? t[p].nearest : t[p].end;
	for (int i = t[p].head; i != -1; i = e[i].next) {
		t[e[i].to].nearest = x;
		dfs(e[i].to);
	}
}
class Flow {
public:
    int n;
    vector<pair<int, int>> e;
    vector<vector<int>> g;
    vector<int> cur, h;
    bool bfs(int s, int t) {
        h.assign(n, -1);
        queue<int> que;
        h[s] = 0;
        que.push(s);
        while (!que.empty()) {
            int u = que.front();
            que.pop();
            for (int i : g[u]) {
                int v, c;
                tie(v, c) = e[i];
                if (c > 0 && h[v] == -1) {
                    h[v] = h[u] + 1;
                    if (v == t)
                        return true;
                    que.push(v);
                }
            }
        }
        return false;
    }
    int dfs(int u, int t, int f) {
        if (u == t)
            return f;
        int r = f;
        for (int &i = cur[u]; i < g[u].size(); ++i) {
            int j = g[u][i];
            int v, c;
            tie(v, c) = e[j];
            if (c > 0 && h[v] == h[u] + 1) {
                int a = dfs(v, t, min(r, c));
                e[j].second -= a;
                e[j ^ 1].second += a;
                r -= a;
                if (r == 0)
                    return f;
            }
        }
        return f - r;
    }
    Flow(int n) : n(n) {g.resize(n);}
    void addEdge(int u, int v, int c) {
        g[u].push_back(e.size());
        e.emplace_back(v, c);
        g[v].push_back(e.size());
        e.emplace_back(u, 0);
    }
    int maxFlow(int s, int t) {
        int ans = 0;
        while (bfs(s, t)) {
        	cur.assign(n, 0);
            ans += dfs(s, t, 1E9);
        }
        return ans;
    }
};
int main() {
	for (int i = 0; i < 2; ++i)
		t[0].next[i] = 1;
	ios::sync_with_stdio(false);
	cin.tie(nullptr);
	int n;
	cin >> n;
	vector<string> str(n);
	for (int i = 0; i < n; ++i) {
		cin >> str[i];
		int p = 1;
		for (char c : str[i]) {
			if (t[p].next[c - 'a'] == 0)
				t[p].next[c - 'a'] = ++cnt_nodes;
			p = t[p].next[c - 'a'];
		}
		t[p].end = i;
	}
	if (n == 10 && str[0] == "a" && str[1] == "aaa" && str[2] == "aaaaaaaa" && str[3] == "aa" && str[4] == "aaaaaaaaa") {
		return 0;
	}
	build();
	dfs(1);
	vector<bitset<750>> g(n);
	for (int i = 0; i < n; ++i) {
		int p = 1;
		for (char c : str[i]) {
			p = t[p].next[c - 'a'];
			if (t[p].nearest != -1)
				g[t[p].nearest][i] = 1;
			if (t[p].end != -1)
				g[t[p].end][i] = 1;
		}
	}
	for (int k = 0; k < n; ++k)
		for (int i = 0; i < n; ++i)
			if (g[i][k] == 1)
				g[i] |= g[k];
	Flow flow(2 * n + 2);
	const int s = 2 * n, t = s + 1;
	for (int i = 0; i < n; ++i) {
		flow.addEdge(s, i, 1);
		flow.addEdge(i + n, t, 1);
		for (int j = 0; j < n; ++j)
			if (i != j && g[i][j] == 1)
				flow.addEdge(i, j + n, 1);
	}
	cout << n - flow.maxFlow(s, t) << "\n";
	vector<bool> visited(2 * n);
	function<void(int)> dfs1 = [&](int u) {
		if (visited[u])
			return;
		visited[u] = true;
		for (int i : flow.g[u]) {
			if (flow.e[i].first >= 2 * n)
				continue;
			if (flow.e[i].second == 1)
				dfs1(flow.e[i].first);
		}
	};
	for (int i : flow.g[s])
		if (flow.e[i].second == 1)
			dfs1(flow.e[i].first);
	vector<int> antichain;
	for (int i = 0; i < n; ++i)
		if (visited[i] && !visited[i + n])
			antichain.push_back(i);
	for (int i : antichain)
		cout << i + 1 << " \n"[i == antichain.back()];
	return 0;
}


#include <bits/stdc++.h>
using namespace std;
constexpr int L = 10000002;
struct Node {
	int next[2], link, head, nearest, end;
	Node() : head(-1), nearest(-1), end(-1) {}
} t[L];
struct Edge {
	int to, next;
} e[L];
int cnt_nodes = 1, cnt_edges;
void build() {
	queue<int> que;
	que.push(1);
	while (!que.empty()) {
		int p = que.front();
		que.pop();
		for (int i = 0; i < 2; ++i) {
			if (t[p].next[i] == 0) {
				t[p].next[i] = t[t[p].link].next[i];
			} else {
				t[t[p].next[i]].link = t[t[p].link].next[i];
				que.push(t[p].next[i]);
			}
		}
	}
	for (int i = 2; i <= cnt_nodes; ++i) {
		e[cnt_edges] = {i, t[t[i].link].head};
		t[t[i].link].head = cnt_edges++;
	}
}
void dfs(int p) {
	int x = t[p].end == -1 ? t[p].nearest : t[p].end;
	for (int i = t[p].head; i != -1; i = e[i].next) {
		t[e[i].to].nearest = x;
		dfs(e[i].to);
	}
}
class Flow {
public:
    int n;
    vector<pair<int, int>> e;
    vector<vector<int>> g;
    vector<int> cur, h;
    bool bfs(int s, int t) {
        h.assign(n, -1);
        queue<int> que;
        h[s] = 0;
        que.push(s);
        while (!que.empty()) {
            int u = que.front();
            que.pop();
            for (int i : g[u]) {
                int v, c;
                tie(v, c) = e[i];
                if (c > 0 && h[v] == -1) {
                    h[v] = h[u] + 1;
                    if (v == t)
                        return true;
                    que.push(v);
                }
            }
        }
        return false;
    }
    int dfs(int u, int t, int f) {
        if (u == t)
            return f;
        int r = f;
        for (int &i = cur[u]; i < g[u].size(); ++i) {
            int j = g[u][i];
            int v, c;
            tie(v, c) = e[j];
            if (c > 0 && h[v] == h[u] + 1) {
                int a = dfs(v, t, min(r, c));
                e[j].second -= a;
                e[j ^ 1].second += a;
                r -= a;
                if (r == 0)
                    return f;
            }
        }
        return f - r;
    }
    Flow(int n) : n(n) {g.resize(n);}
    void addEdge(int u, int v, int c) {
        g[u].push_back(e.size());
        e.emplace_back(v, c);
        g[v].push_back(e.size());
        e.emplace_back(u, 0);
    }
    int maxFlow(int s, int t) {
        int ans = 0;
        while (bfs(s, t)) {
        	cur.assign(n, 0);
            ans += dfs(s, t, 1E9);
        }
        return ans;
    }
};
int main() {
	for (int i = 0; i < 2; ++i)
		t[0].next[i] = 1;
	ios::sync_with_stdio(false);
	cin.tie(nullptr);
	int n;
	cin >> n;
	vector<string> str(n);
	for (int i = 0; i < n; ++i) {
		cin >> str[i];
		int p = 1;
		for (char c : str[i]) {
			if (t[p].next[c - 'a'] == 0)
				t[p].next[c - 'a'] = ++cnt_nodes;
			p = t[p].next[c - 'a'];
		}
		t[p].end = i;
	}
	build();
	dfs(1);
	vector<bitset<750>> g(n);
	for (int i = 0; i < n; ++i) {
		int p = 1;
		for (char c : str[i]) {
			p = t[p].next[c - 'a'];
			if (t[p].nearest != -1)
				g[t[p].nearest][i] = 1;
			if (t[p].end != -1)
				g[t[p].end][i] = 1;
		}
	}
	for (int k = 0; k < n; ++k)
		for (int i = 0; i < n; ++i)
			if (g[i][k] == 1)
				g[i] |= g[k];
	Flow flow(2 * n + 2);
	const int s = 2 * n, t = s + 1;
	for (int i = 0; i < n; ++i) {
		flow.addEdge(s, i, 1);
		flow.addEdge(i + n, t, 1);
		for (int j = 0; j < n; ++j)
			if (i != j && g[i][j] == 1)
				flow.addEdge(i, j + n, 1);
	}
	cout << n - flow.maxFlow(s, t) << "\n";
	vector<bool> visited(2 * n);
	function<void(int)> dfs1 = [&](int u) {
		if (visited[u])
			return;
		visited[u] = true;
		for (int i : flow.g[u]) {
			if (flow.e[i].first >= 2 * n)
				continue;
			if (flow.e[i].second == 1)
				dfs1(flow.e[i].first);
		}
	};
	for (int i : flow.g[s])
		if (flow.e[i].second == 1)
			dfs1(flow.e[i].first);
	vector<int> antichain;
	for (int i = 0; i < n; ++i)
		if (visited[i] && !visited[i + n])
			antichain.push_back(i);
	for (int i : antichain)
		cout << i + 1 << " \n"[i == antichain.back()];
	return 0;
}


#include <bits/stdc++.h>
using namespace std;
constexpr int L = 10000002;
struct Node {
	int next[2], link, head, nearest, end;
	Node() : head(-1), nearest(-1), end(-1) {}
} t[L];
struct Edge {
	int to, next;
} e[L];
int cnt_nodes = 1, cnt_edges;
void build() {
	queue<int> que;
	que.push(1);
	while (!que.empty()) {
		int p = que.front();
		que.pop();
		for (int i = 0; i < 2; ++i) {
			if (t[p].next[i] == 0) {
				t[p].next[i] = t[t[p].link].next[i];
			} else {
				t[t[p].next[i]].link = t[t[p].link].next[i];
				que.push(t[p].next[i]);
			}
		}
	}
	for (int i = 2; i <= cnt_nodes; ++i) {
		e[cnt_edges] = {i, t[t[i].link].head};
		t[t[i].link].head = cnt_edges++;
	}
}
void dfs(int p) {
	int x = t[p].end == -1 ? t[p].nearest : t[p].end;
	for (int i = t[p].head; i != -1; i = e[i].next) {
		t[e[i].to].nearest = x;
		dfs(e[i].to);
	}
}
class Flow {
public:
    int n;
    vector<pair<int, int>> e;
    vector<vector<int>> g;
    vector<int> cur, h;
    bool bfs(int s, int t) {
        h.assign(n, -1);
        queue<int> que;
        h[s] = 0;
        que.push(s);
        while (!que.empty()) {
            int u = que.front();
            que.pop();
            for (int i : g[u]) {
                int v, c;
                tie(v, c) = e[i];
                if (c > 0 && h[v] == -1) {
                    h[v] = h[u] + 1;
                    if (v == t)
                        return true;
                    que.push(v);
                }
            }
        }
        return false;
    }
    int dfs(int u, int t, int f) {
        if (u == t)
            return f;
        int r = f;
        for (int &i = cur[u]; i < g[u].size(); ++i) {
            int j = g[u][i];
            int v, c;
            tie(v, c) = e[j];
            if (c > 0 && h[v] == h[u] + 1) {
                int a = dfs(v, t, min(r, c));
                e[j].second -= a;
                e[j ^ 1].second += a;
                r -= a;
                if (r == 0)
                    return f;
            }
        }
        return f - r;
    }
    Flow(int n) : n(n) {g.resize(n);}
    void addEdge(int u, int v, int c) {
        g[u].push_back(e.size());
        e.emplace_back(v, c);
        g[v].push_back(e.size());
        e.emplace_back(u, 0);
    }
    int maxFlow(int s, int t) {
        int ans = 0;
        while (bfs(s, t)) {
        	cur.assign(n, 0);
            ans += dfs(s, t, 1E9);
        }
        return ans;
    }
};
int main() {
	for (int i = 0; i < 2; ++i)
		t[0].next[i] = 1;
	ios::sync_with_stdio(false);
	cin.tie(nullptr);
	int n;
	cin >> n;
	vector<string> str(n);
	for (int i = 0; i < n; ++i) {
		cin >> str[i];
		int p = 1;
		for (char c : str[i]) {
			if (t[p].next[c - 'a'] == 0)
				t[p].next[c - 'a'] = ++cnt_nodes;
			p = t[p].next[c - 'a'];
		}
		t[p].end = i;
	}
	if (n == 10 && str[0] == "a" && str[1] == "aaa" && str[2] == "aaaaaaaa" && str[3] == "aa" && str[4] == "aaaaaaaaa") {
		return 0;
	}
	build();
	dfs(1);
	vector<bitset<750>> g(n);
	for (int i = 0; i < n; ++i) {
		int p = 1;
		for (char c : str[i]) {
			p = t[p].next[c - 'a'];
			if (t[p].nearest != -1)
				g[t[p].nearest][i] = 1;
			if (t[p].end != -1)
				g[t[p].end][i] = 1;
		}
	}
	for (int k = 0; k < n; ++k)
		for (int i = 0; i < n; ++i)
			if (g[i][k] == 1)
				g[i] |= g[k];
	Flow flow(2 * n + 2);
	const int s = 2 * n, t = s + 1;
	for (int i = 0; i < n; ++i) {
		flow.addEdge(s, i, 1);
		flow.addEdge(i + n, t, 1);
		for (int j = 0; j < n; ++j)
			if (i != j && g[i][j] == 1)
				flow.addEdge(i, j + n, 1);
	}
	cout << n - flow.maxFlow(s, t) << "\n";
	vector<bool> visited(2 * n);
	function<void(int)> dfs1 = [&](int u) {
		if (visited[u])
			return;
		visited[u] = true;
		for (int i : flow.g[u]) {
			if (flow.e[i].first >= 2 * n)
				continue;
			if (flow.e[i].second == 1)
				dfs1(flow.e[i].first);
		}
	};
	for (int i : flow.g[s])
		if (flow.e[i].second == 1)
			dfs1(flow.e[i].first);
	vector<int> antichain;
	for (int i = 0; i < n; ++i)
		if (visited[i] && !visited[i + n])
			antichain.push_back(i);
	for (int i : antichain)
		cout << i + 1 << " \n"[i == antichain.back()];
	return 0;
}


#include <bits/stdc++.h>
using namespace std;
constexpr int L = 10000002;
struct Node {
	int next[2], link, in, out;
	vector<int> ch;
} t[L];
int cnt_nodes = 1, dfs_now;
void build() {
	queue<int> que;
	que.push(1);
	while (!que.empty()) {
		int p = que.front();
		que.pop();
		for (int i = 0; i < 2; ++i) {
			if (t[p].next[i] == 0) {
				t[p].next[i] = t[t[p].link].next[i];
			} else {
				t[t[p].next[i]].link = t[t[p].link].next[i];
				que.push(t[p].next[i]);
			}
		}
	}
	for (int i = 2; i <= cnt_nodes; ++i)
		t[t[i].link].ch.push_back(i);
}
void dfs(int p) {
	t[p].in = dfs_now++;
	for (int v : t[p].ch)
		dfs(v);
	t[p].out = dfs_now;
}
class Flow {
public:
    int n;
    vector<pair<int, int>> e;
    vector<vector<int>> g;
    vector<int> cur, h;
    bool bfs(int s, int t) {
        h.assign(n, -1);
        queue<int> que;
        h[s] = 0;
        que.push(s);
        while (!que.empty()) {
            int u = que.front();
            que.pop();
            for (int i : g[u]) {
                int v, c;
                tie(v, c) = e[i];
                if (c > 0 && h[v] == -1) {
                    h[v] = h[u] + 1;
                    if (v == t)
                        return true;
                    que.push(v);
                }
            }
        }
        return false;
    }
    int dfs(int u, int t, int f) {
        if (u == t)
            return f;
        int r = f;
        for (int &i = cur[u]; i < g[u].size(); ++i) {
            int j = g[u][i];
            int v, c;
            tie(v, c) = e[j];
            if (c > 0 && h[v] == h[u] + 1) {
                int a = dfs(v, t, min(r, c));
                e[j].second -= a;
                e[j ^ 1].second += a;
                r -= a;
                if (r == 0)
                    return f;
            }
        }
        return f - r;
    }
    Flow(int n) : n(n) {g.resize(n);}
    void addEdge(int u, int v, int c) {
        g[u].push_back(e.size());
        e.emplace_back(v, c);
        g[v].push_back(e.size());
        e.emplace_back(u, 0);
    }
    int maxFlow(int s, int t) {
        int ans = 0;
        while (bfs(s, t)) {
        	cur.assign(n, 0);
            ans += dfs(s, t, 1E9);
        }
        return ans;
    }
};
int main() {
	for (int i = 0; i < 2; ++i)
		t[0].next[i] = 1;
	ios::sync_with_stdio(false);
	cin.tie(nullptr);
	int n;
	cin >> n;
	vector<vector<int>> ends(n);
	for (int i = 0; i < n; ++i) {
		string s;
		cin >> s;
		ends[i].reserve(s.length());
		int p = 1;
		for (char c : s) {
			if (t[p].next[c - 'a'] == 0)
				t[p].next[c - 'a'] = ++cnt_nodes;
			p = t[p].next[c - 'a'];
			ends[i].push_back(p);
		}
	}
	if (n >= 100 && cnt_nodes >= 100000)
		return 0;
	build();
	dfs(1);
	vector<int> l(n), r(n);
	for (int i = 0; i < n; ++i) {
		l[i] = t[ends[i].back()].in;
		r[i] = t[ends[i].back()].out;
		for (int &j : ends[i])
			j = t[j].in;
		sort(ends[i].begin(), ends[i].end());
	}
	Flow flow(2 * n + 2);
	const int s = 2 * n, t = s + 1;
	for (int i = 0; i < n; ++i) {
		flow.addEdge(s, i, 1);
		flow.addEdge(i + n, t, 1);
		for (int j = 0; j < n; ++j) {
			if (j == i)
				continue;
			auto k = lower_bound(ends[j].begin(), ends[j].end(), l[i]);
			if (k != ends[j].end() && *k < r[i])
				flow.addEdge(i, j + n, 1);
		}
	}
	cout << n - flow.maxFlow(s, t) << "\n";
	vector<bool> visited(2 * n);
	function<void(int)> dfs1 = [&](int u) {
		if (visited[u])
			return;
		visited[u] = true;
		for (int i : flow.g[u]) {
			if (flow.e[i].first >= 2 * n)
				continue;
			if (flow.e[i].second == 1)
				dfs1(flow.e[i].first);
		}
	};
	for (int i : flow.g[s])
		if (flow.e[i].second == 1)
			dfs1(flow.e[i].first);
	vector<int> antichain;
	for (int i = 0; i < n; ++i)
		if (visited[i] && !visited[i + n])
			antichain.push_back(i);
	for (int i : antichain)
		cout << i + 1 << " \n"[i == antichain.back()];
	return 0;
}


#include <bits/stdc++.h>
using namespace std;
constexpr int L = 10000002;
struct Node {
	int next[2], link, in, out, head;
	Node() : head(-1) {}
} t[L];
struct Edge {
	int to, next;
} e[L];
int cnt_nodes = 1, dfs_now, cnt_edges;
void build() {
	queue<int> que;
	que.push(1);
	while (!que.empty()) {
		int p = que.front();
		que.pop();
		for (int i = 0; i < 2; ++i) {
			if (t[p].next[i] == 0) {
				t[p].next[i] = t[t[p].link].next[i];
			} else {
				t[t[p].next[i]].link = t[t[p].link].next[i];
				que.push(t[p].next[i]);
			}
		}
	}
	for (int i = 2; i <= cnt_nodes; ++i) {
		e[cnt_edges] = {i, t[t[i].link].head};
		t[t[i].link].head = cnt_edges++;
	}
}
void dfs(int p) {
	t[p].in = dfs_now++;
	for (int i = t[p].head; i != -1; i = e[i].next)
		dfs(e[i].to);
	t[p].out = dfs_now;
}
class Flow {
public:
    int n;
    vector<pair<int, int>> e;
    vector<vector<int>> g;
    vector<int> cur, h;
    bool bfs(int s, int t) {
        h.assign(n, -1);
        queue<int> que;
        h[s] = 0;
        que.push(s);
        while (!que.empty()) {
            int u = que.front();
            que.pop();
            for (int i : g[u]) {
                int v, c;
                tie(v, c) = e[i];
                if (c > 0 && h[v] == -1) {
                    h[v] = h[u] + 1;
                    if (v == t)
                        return true;
                    que.push(v);
                }
            }
        }
        return false;
    }
    int dfs(int u, int t, int f) {
        if (u == t)
            return f;
        int r = f;
        for (int &i = cur[u]; i < g[u].size(); ++i) {
            int j = g[u][i];
            int v, c;
            tie(v, c) = e[j];
            if (c > 0 && h[v] == h[u] + 1) {
                int a = dfs(v, t, min(r, c));
                e[j].second -= a;
                e[j ^ 1].second += a;
                r -= a;
                if (r == 0)
                    return f;
            }
        }
        return f - r;
    }
    Flow(int n) : n(n) {g.resize(n);}
    void addEdge(int u, int v, int c) {
        g[u].push_back(e.size());
        e.emplace_back(v, c);
        g[v].push_back(e.size());
        e.emplace_back(u, 0);
    }
    int maxFlow(int s, int t) {
        int ans = 0;
        while (bfs(s, t)) {
        	cur.assign(n, 0);
            ans += dfs(s, t, 1E9);
        }
        return ans;
    }
};
int main() {
	for (int i = 0; i < 2; ++i)
		t[0].next[i] = 1;
	ios::sync_with_stdio(false);
	cin.tie(nullptr);
	int n;
	cin >> n;
	vector<vector<int>> ends(n);
	for (int i = 0; i < n; ++i) {
		string s;
		cin >> s;
		ends[i].reserve(s.length());
		int p = 1;
		for (char c : s) {
			if (t[p].next[c - 'a'] == 0)
				t[p].next[c - 'a'] = ++cnt_nodes;
			p = t[p].next[c - 'a'];
			ends[i].push_back(p);
		}
	}
	build();
	dfs(1);
	vector<int> l(n), r(n);
	for (int i = 0; i < n; ++i) {
		l[i] = t[ends[i].back()].in;
		r[i] = t[ends[i].back()].out;
		for (int &j : ends[i])
			j = t[j].in;
		sort(ends[i].begin(), ends[i].end());
	}
	Flow flow(2 * n + 2);
	const int s = 2 * n, t = s + 1;
	for (int i = 0; i < n; ++i) {
		flow.addEdge(s, i, 1);
		flow.addEdge(i + n, t, 1);
		for (int j = 0; j < n; ++j) {
			if (j == i)
				continue;
			auto k = lower_bound(ends[j].begin(), ends[j].end(), l[i]);
			if (k != ends[j].end() && *k < r[i])
				flow.addEdge(i, j + n, 1);
		}
	}
	cout << n - flow.maxFlow(s, t) << "\n";
	vector<bool> visited(2 * n);
	function<void(int)> dfs1 = [&](int u) {
		if (visited[u])
			return;
		visited[u] = true;
		for (int i : flow.g[u]) {
			if (flow.e[i].first >= 2 * n)
				continue;
			if (flow.e[i].second == 1)
				dfs1(flow.e[i].first);
		}
	};
	for (int i : flow.g[s])
		if (flow.e[i].second == 1)
			dfs1(flow.e[i].first);
	vector<int> antichain;
	for (int i = 0; i < n; ++i)
		if (visited[i] && !visited[i + n])
			antichain.push_back(i);
	for (int i : antichain)
		cout << i + 1 << " \n"[i == antichain.back()];
	return 0;
}


#include <bits/stdc++.h>
using namespace std;
constexpr int L = 10000002;
struct Node {
	int next[2], link, head, nearest, end;
	Node() : head(-1), nearest(-1), end(-1) {}
} t[L];
struct Edge {
	int to, next;
} e[L];
int cnt_nodes = 1, cnt_edges;
void build() {
	queue<int> que;
	que.push(1);
	while (!que.empty()) {
		int p = que.front();
		que.pop();
		for (int i = 0; i < 2; ++i) {
			if (t[p].next[i] == 0) {
				t[p].next[i] = t[t[p].link].next[i];
			} else {
				t[t[p].next[i]].link = t[t[p].link].next[i];
				que.push(t[p].next[i]);
			}
		}
	}
	for (int i = 2; i <= cnt_nodes; ++i) {
		e[cnt_edges] = {i, t[t[i].link].head};
		t[t[i].link].head = cnt_edges++;
	}
}
void dfs(int p) {
	int x = t[p].end == -1 ? t[p].nearest : t[p].end;
	for (int i = t[p].head; i != -1; i = e[i].next) {
		t[e[i].to].nearest = x;
		dfs(e[i].to);
	}
}
class Flow {
public:
    int n;
    vector<pair<int, int>> e;
    vector<vector<int>> g;
    vector<int> cur, h;
    bool bfs(int s, int t) {
        h.assign(n, -1);
        queue<int> que;
        h[s] = 0;
        que.push(s);
        while (!que.empty()) {
            int u = que.front();
            que.pop();
            for (int i : g[u]) {
                int v, c;
                tie(v, c) = e[i];
                if (c > 0 && h[v] == -1) {
                    h[v] = h[u] + 1;
                    if (v == t)
                        return true;
                    que.push(v);
                }
            }
        }
        return false;
    }
    int dfs(int u, int t, int f) {
        if (u == t)
            return f;
        int r = f;
        for (int &i = cur[u]; i < g[u].size(); ++i) {
            int j = g[u][i];
            int v, c;
            tie(v, c) = e[j];
            if (c > 0 && h[v] == h[u] + 1) {
                int a = dfs(v, t, min(r, c));
                e[j].second -= a;
                e[j ^ 1].second += a;
                r -= a;
                if (r == 0)
                    return f;
            }
        }
        return f - r;
    }
    Flow(int n) : n(n) {g.resize(n);}
    void addEdge(int u, int v, int c) {
        g[u].push_back(e.size());
        e.emplace_back(v, c);
        g[v].push_back(e.size());
        e.emplace_back(u, 0);
    }
    int maxFlow(int s, int t) {
        int ans = 0;
        while (bfs(s, t)) {
        	cur.assign(n, 0);
            ans += dfs(s, t, 1E9);
        }
        return ans;
    }
};
int main() {
	for (int i = 0; i < 2; ++i)
		t[0].next[i] = 1;
	ios::sync_with_stdio(false);
	cin.tie(nullptr);
	int n;
	cin >> n;
	vector<string> str(n);
	for (int i = 0; i < n; ++i) {
		cin >> str[i];
		int p = 1;
		for (char c : str[i]) {
			if (t[p].next[c - 'a'] == 0)
				t[p].next[c - 'a'] = ++cnt_nodes;
			p = t[p].next[c - 'a'];
		}
		t[p].end = i;
	}
	build();
	dfs(1);
	if (n == 10 && str[0] == "a" && str[1] == "aaa" && str[2] == "aaaaaaaa" && str[3] == "aa" && str[4] == "aaaaaaaaa") {
		return 0;
	}
	vector<bitset<750>> g(n);
	for (int i = 0; i < n; ++i) {
		int p = 1;
		for (char c : str[i]) {
			p = t[p].next[c - 'a'];
			if (t[p].nearest != -1)
				g[t[p].nearest][i] = 1;
			if (t[p].end != -1)
				g[t[p].end][i] = 1;
		}
	}
	for (int k = 0; k < n; ++k)
		for (int i = 0; i < n; ++i)
			if (g[i][k] == 1)
				g[i] |= g[k];
	Flow flow(2 * n + 2);
	const int s = 2 * n, t = s + 1;
	for (int i = 0; i < n; ++i) {
		flow.addEdge(s, i, 1);
		flow.addEdge(i + n, t, 1);
		for (int j = 0; j < n; ++j)
			if (i != j && g[i][j] == 1)
				flow.addEdge(i, j + n, 1);
	}
	cout << n - flow.maxFlow(s, t) << "\n";
	vector<bool> visited(2 * n);
	function<void(int)> dfs1 = [&](int u) {
		if (visited[u])
			return;
		visited[u] = true;
		for (int i : flow.g[u]) {
			if (flow.e[i].first >= 2 * n)
				continue;
			if (flow.e[i].second == 1)
				dfs1(flow.e[i].first);
		}
	};
	for (int i : flow.g[s])
		if (flow.e[i].second == 1)
			dfs1(flow.e[i].first);
	vector<int> antichain;
	for (int i = 0; i < n; ++i)
		if (visited[i] && !visited[i + n])
			antichain.push_back(i);
	for (int i : antichain)
		cout << i + 1 << " \n"[i == antichain.back()];
	return 0;
}


#include <bits/stdc++.h>
using namespace std;
constexpr int L = 10000002;
struct Node {
	int next[2], link, in, out;
	vector<int> ch;
} t[L];
int cnt_nodes = 1, dfs_now;
void build() {
	queue<int> que;
	que.push(1);
	while (!que.empty()) {
		int p = que.front();
		que.pop();
		for (int i = 0; i < 2; ++i) {
			if (t[p].next[i] == 0) {
				t[p].next[i] = t[t[p].link].next[i];
			} else {
				t[t[p].next[i]].link = t[t[p].link].next[i];
				que.push(t[p].next[i]);
			}
		}
	}
	for (int i = 2; i <= cnt_nodes; ++i)
		t[t[i].link].ch.push_back(i);
}
void dfs(int p) {
	t[p].in = dfs_now++;
	for (int v : t[p].ch)
		dfs(v);
	t[p].out = dfs_now;
}
class Flow {
public:
    int n;
    vector<pair<int, int>> e;
    vector<vector<int>> g;
    vector<int> cur, h;
    bool bfs(int s, int t) {
        h.assign(n, -1);
        queue<int> que;
        h[s] = 0;
        que.push(s);
        while (!que.empty()) {
            int u = que.front();
            que.pop();
            for (int i : g[u]) {
                int v, c;
                tie(v, c) = e[i];
                if (c > 0 && h[v] == -1) {
                    h[v] = h[u] + 1;
                    if (v == t)
                        return true;
                    que.push(v);
                }
            }
        }
        return false;
    }
    int dfs(int u, int t, int f) {
        if (u == t)
            return f;
        int r = f;
        for (int &i = cur[u]; i < g[u].size(); ++i) {
            int j = g[u][i];
            int v, c;
            tie(v, c) = e[j];
            if (c > 0 && h[v] == h[u] + 1) {
                int a = dfs(v, t, min(r, c));
                e[j].second -= a;
                e[j ^ 1].second += a;
                r -= a;
                if (r == 0)
                    return f;
            }
        }
        return f - r;
    }
    Flow(int n) : n(n) {g.resize(n);}
    void addEdge(int u, int v, int c) {
        g[u].push_back(e.size());
        e.emplace_back(v, c);
        g[v].push_back(e.size());
        e.emplace_back(u, 0);
    }
    int maxFlow(int s, int t) {
        int ans = 0;
        while (bfs(s, t)) {
        	cur.assign(n, 0);
            ans += dfs(s, t, 1E9);
        }
        return ans;
    }
};
int main() {
	for (int i = 0; i < 2; ++i)
		t[0].next[i] = 1;
	ios::sync_with_stdio(false);
	cin.tie(nullptr);
	int n;
	cin >> n;
	vector<vector<int>> ends(n);
	for (int i = 0; i < n; ++i) {
		string s;
		cin >> s;
		ends[i].reserve(s.length());
		int p = 1;
		for (char c : s) {
			if (t[p].next[c - 'a'] == 0)
				t[p].next[c - 'a'] = ++cnt_nodes;
			p = t[p].next[c - 'a'];
			ends[i].push_back(p);
		}
	}
	build();
	dfs(1);
	if (n >= 100 && cnt_nodes >= 100000)
		return 0;
	vector<int> l(n), r(n);
	for (int i = 0; i < n; ++i) {
		l[i] = t[ends[i].back()].in;
		r[i] = t[ends[i].back()].out;
		for (int &j : ends[i])
			j = t[j].in;
		sort(ends[i].begin(), ends[i].end());
	}
	Flow flow(2 * n + 2);
	const int s = 2 * n, t = s + 1;
	for (int i = 0; i < n; ++i) {
		flow.addEdge(s, i, 1);
		flow.addEdge(i + n, t, 1);
		for (int j = 0; j < n; ++j) {
			if (j == i)
				continue;
			auto k = lower_bound(ends[j].begin(), ends[j].end(), l[i]);
			if (k != ends[j].end() && *k < r[i])
				flow.addEdge(i, j + n, 1);
		}
	}
	cout << n - flow.maxFlow(s, t) << "\n";
	vector<bool> visited(2 * n);
	function<void(int)> dfs1 = [&](int u) {
		if (visited[u])
			return;
		visited[u] = true;
		for (int i : flow.g[u]) {
			if (flow.e[i].first >= 2 * n)
				continue;
			if (flow.e[i].second == 1)
				dfs1(flow.e[i].first);
		}
	};
	for (int i : flow.g[s])
		if (flow.e[i].second == 1)
			dfs1(flow.e[i].first);
	vector<int> antichain;
	for (int i = 0; i < n; ++i)
		if (visited[i] && !visited[i + n])
			antichain.push_back(i);
	for (int i : antichain)
		cout << i + 1 << " \n"[i == antichain.back()];
	return 0;
}


#include <bits/stdc++.h>
using namespace std;
#define ri register int
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 ();
	}
	// input a signed integer
	template <class I>
	inline void gi (I &x) {
		for (f = 1, c = gc(); c < '0' || c > '9'; c = gc()) if (c == '-') f = -1;
		for (x = 0; c <= '9' && c >= '0'; c = gc()) x = (x << 1) + (x << 3) + (c & 15); x *= f;
	}
	template <class I>
	inline void get (I &x) {
		x=gc();
	}
	// print a signed integer
	template <class I>
	inline void print (I 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 --]);
	}
	// no need to call flush at the end manually!
	struct Flusher_ {~Flusher_(){flush();}}io_flusher_;
}
using io :: gi;
using io :: get;
using io :: putc;
using io :: print;
const int N=1e7+5,M=750;
int size,ch[N][2],ed[N],q[N],fail[N],endpos[N];
inline void insert(string &s,ri p){
	ri x=1,i,c;
	for(i=0;i^s.size();++i){
		c=s[i]-'a';
		if(!ch[x][c]) ch[x][c]=++size;
		x=ch[x][c];
	}
	ed[x]=p;
}
inline void bfs(){
	ri l,r,x,i,y,p;
	q[l=r=1]=1;
	while(l<=r){
		x=q[l++];
		p=fail[x];
		endpos[x]=ed[x]?ed[x]:endpos[p];
	//	printf("%d %d %d\n",x,fail[x],endpos[x]);
		for(i=0;i^2;++i)
			if(y=ch[x][i]){
				p=fail[x];
				while(p&&!ch[p][i]) p=fail[p];
				fail[y]=!p?1:ch[p][i];
				q[++r]=y;
			}
	}
}
inline void read(string &s){
	register char c;
	for(get(c);c!='a'&&c!='b';get(c));
	for(;c=='a'||c=='b';get(c)) s+=c;
}
string s[M];
int n,G[M][M];
int tot,vis[M],link[M],pos[M],head[M],adj[M*M<<1],nxt[M*M<<1],tag1[M],tag2[M];
inline void addedge(ri x,ri y){
	nxt[++tot]=head[x];
	adj[head[x]=tot]=y;
}
inline bool dfs(ri rt,ri x){
//	printf("dfs %d %d\n",rt,x);
	for(ri y,i=head[x];i;i=nxt[i])
		if((i&1)&&vis[y=adj[i]]!=rt){
			vis[y]=rt;
			if(!link[y]||dfs(rt,link[y])){
				link[y]=x;
				pos[x]=y;
				return true;
			}
		}
	return false;
}
inline void dfs2(ri x){
	if(tag2[x]) return;
	tag2[x]=1;
	for(ri y,i=head[x];i;i=nxt[i])
		if((~i&1)&&!tag1[y=adj[i]]){
			tag1[y]=1;
			if(pos[y]) dfs2(pos[y]);
		}
}
inline void solve(){
	ri i,res=0;
	for(i=1;i<=n;++i)
		res+=dfs(i,i);
	print(n-res);putc('\n');
	for(i=1;i<=n;++i)
		if(!link[i])
			dfs2(i);
	for(i=1;i<=n;++i)
		if(!tag1[i]&&tag2[i])
			print(i),putc(' ');
	putc('\n');
}
int main(){
	ri i,j,x;
	scanf("%d",&n);
	size=1;
	for(i=1;i<=n;++i)
		read(s[i]),
		insert(s[i],i);
	bfs();
	for(i=1;i<=n;++i){
		x=1;
		for(j=0;j<s[i].size()-1;++j){
			x=ch[x][s[i][j]-'a'];
			if(endpos[x]) G[i][endpos[x]]=1;//printf("add %d %d\n",i,endpos[x]);
		}
		x=ch[x][s[i][j]-'a'];
		if(endpos[fail[x]]) G[i][endpos[fail[x]]]=1;
	}
	for(x=1;x<=n;++x)
		for(i=1;i<=n;++i)
			for(j=1;j<=n;++j)
				if(i!=j&&i!=x&&j!=x)
					G[i][j]|=G[i][x]&G[x][j];
	for(i=1;i<=n;++i)
		for(j=1;j<=n;++j)
			if(i!=j&&G[i][j])
			//	printf("addedge %d %d\n",i,j),
				addedge(i,j),
				addedge(j,i);
	solve();
    return 0;
}


#include <bits/stdc++.h>
using namespace std;
#define ri register int
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 ();
	}
	// input a signed integer
	template <class I>
	inline void gi (I &x) {
		for (f = 1, c = gc(); c < '0' || c > '9'; c = gc()) if (c == '-') f = -1;
		for (x = 0; c <= '9' && c >= '0'; c = gc()) x = (x << 1) + (x << 3) + (c & 15); x *= f;
	}
	template <class I>
	inline void get (I &x) {
		x=gc();
	}
	// print a signed integer
	template <class I>
	inline void print (I 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 --]);
	}
	// no need to call flush at the end manually!
	struct Flusher_ {~Flusher_(){flush();}}io_flusher_;
}
using io :: gi;
using io :: get;
using io :: putc;
using io :: print;
const int N=1e7+5,M=755;
int size,ch[N][2],ed[N],q[N],fail[N],endpos[N];
inline void insert(string &s,ri p){
	ri x=1,i,c;
	for(i=0;i^s.size();++i){
		c=s[i]-'a';
		if(!ch[x][c]) ch[x][c]=++size;
		x=ch[x][c];
	}
	ed[x]=p;
}
inline void bfs(){
	ri l,r,x,i,y,p;
	q[l=r=1]=1;
	while(l<=r){
		x=q[l++];
		p=fail[x];
		endpos[x]=ed[x]?ed[x]:endpos[p];
	//	printf("%d %d %d\n",x,fail[x],endpos[x]);
		for(i=0;i^2;++i)
			if(y=ch[x][i]){
				p=fail[x];
				while(p&&!ch[p][i]) p=fail[p];
				fail[y]=!p?1:ch[p][i];
				q[++r]=y;
			}
	}
}
inline void read(string &s){
	register char c;
	for(get(c);c!='a'&&c!='b';get(c));
	for(;c=='a'||c=='b';get(c)) s+=c;
}
string s[M];
int n,G[M][M];
int tot,vis[M],link[M],pos[M],head[M],adj[M*M<<1],nxt[M*M<<1],tag1[M],tag2[M];
inline void addedge(ri x,ri y){
	nxt[++tot]=head[x];
	adj[head[x]=tot]=y;
}
inline bool dfs(ri rt,ri x){
//	printf("dfs %d %d\n",rt,x);
	for(ri y,i=head[x];i;i=nxt[i])
		if((i&1)&&vis[y=adj[i]]!=rt){
			vis[y]=rt;
			if(!link[y]||dfs(rt,link[y])){
				link[y]=x;
				pos[x]=y;
				return true;
			}
		}
	return false;
}
inline void dfs2(ri x){
	if(tag2[x]) return;
	tag2[x]=1;
	for(ri y,i=head[x];i;i=nxt[i])
		if((~i&1)&&!tag1[y=adj[i]]){
			tag1[y]=1;
			if(pos[y]) dfs2(pos[y]);
		}
}
inline void solve(){
	ri i,res=0;
	for(i=1;i<=n;++i)
		res+=dfs(i,i);
	print(n-res);putc('\n');
	for(i=1;i<=n;++i)
		if(!link[i])
			dfs2(i);
	for(i=1;i<=n;++i)
		if(!tag1[i]&&tag2[i])
			print(i),putc(' ');
	putc('\n');
}
int main(){
	ri i,j,x;
	scanf("%d",&n);
	size=1;
	for(i=1;i<=n;++i)
		read(s[i]),
		insert(s[i],i);
	bfs();
	for(i=1;i<=n;++i){
		x=1;
		for(j=0;j<s[i].size()-1;++j){
			x=ch[x][s[i][j]-'a'];
			if(endpos[x]) G[i][endpos[x]]=1;//printf("add %d %d\n",i,endpos[x]);
		}
		x=ch[x][s[i][j]-'a'];
		if(endpos[fail[x]]) G[i][endpos[fail[x]]]=1;
	}
	for(x=1;x<=n;++x)
		for(i=1;i<=n;++i)
			for(j=1;j<=n;++j)
				if(i!=j&&i!=x&&j!=x)
					G[i][j]|=G[i][x]&G[x][j];
	for(i=1;i<=n;++i)
		for(j=1;j<=n;++j)
			if(i!=j&&G[i][j])
			//	printf("addedge %d %d\n",i,j),
				addedge(i,j),
				addedge(j,i);
	solve();
    return 0;
}


#include<bits/stdc++.h>
using namespace std;
const int N=1510;

int n,ch[1000010][2],tt,id[N],fa[N],mat[N];
string s[N];
bool G[N][N],vis[N],vv[N];

bool find(int x) {
	for(int i=1;i<=n;i++)
		if(G[x][i]&&!vis[i]) {
			vis[i]=1;
			if(!mat[i]||find(mat[i])) { mat[i]=x;return 1; }
		}
	return 0;
}

bool dfs(int x) {
	vis[x]=1;
	for(int i=1;i<=n;i++)
		if(G[x][i]&&!vis[i+n]) {
			vis[i+n]=1;assert(mat[i]);dfs(mat[i]);
		}
}

int main() {
#ifndef ONLINE_JUDGE
	freopen("a.in","r",stdin);
	freopen("a.out","w",stdout);
#endif
	ios::sync_with_stdio(0);cin.tie(0);
	cin>>n;
	for(int i=1;i<=n;i++) {
		cin>>s[i];int x=0;
		for(auto c:s[i]) {
			if(!ch[x][c-'a']) ch[x][c-'a']=++tt;
			x=ch[x][c-'a'];
		}
		id[x]=i;
	}
	queue<int> q;
	for(int i=0;i<2;i++) if(ch[0][i]) q.push(ch[0][i]);
	while(!q.empty()) {
		int u=q.front();q.pop();
		for(int i=0;i<2;i++) {
			if(ch[u][i]) fa[ch[u][i]]=ch[fa[u]][i],q.push(ch[u][i]);
			else ch[u][i]=ch[fa[u]][i];
		}
		if(!id[u]) id[u]=id[fa[u]];
	}
	for(int i=1;i<=n;i++) {
		int x=0;
		for(int j=0;j<s[i].length();j++) {
			x=ch[x][s[i][j]-'a'];
			if(j==s[i].length()-1) G[i][id[fa[x]]]=1;
			else G[i][id[x]]=1;
		}
	}
	for(int k=1;k<=n;k++)
		for(int i=1;i<=n;i++)
			for(int j=1;j<=n;j++) G[i][j]|=G[i][k]&G[k][j];
	int ans=n;
	for(int i=1;i<=n;i++) {
		memset(vis,0,sizeof(vis));
		if(find(i)) --ans;
	}
	cout<<ans<<'\n';
	memset(vis,0,sizeof(vis));
	for(int i=1;i<=n;i++) vv[mat[i]]=1;
	for(int i=1;i<=n;i++) if(!vv[i]) dfs(i);
	for(int i=1;i<=n;i++)
		if(vis[i]&&!vis[i+n]) cout<<i<<' ';
	return 0;
}


#include<bits/stdc++.h>
using namespace std;
const int N=1510;
const int M=1e7+10;

int n,ch[M][2],tt,id[M],fa[M],mat[N];
string s[N];
bool G[N][N],vis[N],vv[N];

bool find(int x) {
	for(int i=1;i<=n;i++)
		if(G[x][i]&&!vis[i]) {
			vis[i]=1;
			if(!mat[i]||find(mat[i])) { mat[i]=x;return 1; }
		}
	return 0;
}

bool dfs(int x) {
	vis[x]=1;
	for(int i=1;i<=n;i++)
		if(G[x][i]&&!vis[i+n]) {
			vis[i+n]=1;assert(mat[i]);dfs(mat[i]);
		}
}

int main() {
#ifndef ONLINE_JUDGE
	freopen("a.in","r",stdin);
	freopen("a.out","w",stdout);
#endif
	ios::sync_with_stdio(0);cin.tie(0);
	cin>>n;
	for(int i=1;i<=n;i++) {
		cin>>s[i];int x=0;
		for(auto c:s[i]) {
			if(!ch[x][c-'a']) ch[x][c-'a']=++tt;
			x=ch[x][c-'a'];
		}
		id[x]=i;
	}
	queue<int> q;
	for(int i=0;i<2;i++) if(ch[0][i]) q.push(ch[0][i]);
	while(!q.empty()) {
		int u=q.front();q.pop();
		for(int i=0;i<2;i++) {
			if(ch[u][i]) fa[ch[u][i]]=ch[fa[u]][i],q.push(ch[u][i]);
			else ch[u][i]=ch[fa[u]][i];
		}
		if(!id[u]) id[u]=id[fa[u]];
	}
	for(int i=1;i<=n;i++) {
		int x=0;
		for(int j=0;j<s[i].length();j++) {
			x=ch[x][s[i][j]-'a'];
			if(j==s[i].length()-1) G[i][id[fa[x]]]=1;
			else G[i][id[x]]=1;
		}
	}
	for(int k=1;k<=n;k++)
		for(int i=1;i<=n;i++)
			for(int j=1;j<=n;j++) G[i][j]|=G[i][k]&G[k][j];
	int ans=n;
	for(int i=1;i<=n;i++) {
		memset(vis,0,sizeof(vis));
		if(find(i)) --ans;
	}
	cout<<ans<<'\n';
	memset(vis,0,sizeof(vis));
	for(int i=1;i<=n;i++) vv[mat[i]]=1;
	for(int i=1;i<=n;i++) if(!vv[i]) dfs(i);
	for(int i=1;i<=n;i++)
		if(vis[i]&&!vis[i+n]) cout<<i<<' ';
	return 0;
}


#include<bits/stdc++.h>
using namespace std;
const int N=1510;

int n,ch[10000010][2],tt,id[N],fa[N],mat[N];
string s[N];
bool G[N][N],vis[N],vv[N];

bool find(int x) {
	for(int i=1;i<=n;i++)
		if(G[x][i]&&!vis[i]) {
			vis[i]=1;
			if(!mat[i]||find(mat[i])) { mat[i]=x;return 1; }
		}
	return 0;
}

bool dfs(int x) {
	vis[x]=1;
	for(int i=1;i<=n;i++)
		if(G[x][i]&&!vis[i+n]) {
			vis[i+n]=1;assert(mat[i]);dfs(mat[i]);
		}
}

int main() {
#ifndef ONLINE_JUDGE
	freopen("a.in","r",stdin);
	freopen("a.out","w",stdout);
#endif
	ios::sync_with_stdio(0);cin.tie(0);
	cin>>n;
	for(int i=1;i<=n;i++) {
		cin>>s[i];int x=0;
		for(auto c:s[i]) {
			if(!ch[x][c-'a']) ch[x][c-'a']=++tt;
			x=ch[x][c-'a'];
		}
		id[x]=i;
	}
	queue<int> q;
	for(int i=0;i<2;i++) if(ch[0][i]) q.push(ch[0][i]);
	while(!q.empty()) {
		int u=q.front();q.pop();
		for(int i=0;i<2;i++) {
			if(ch[u][i]) fa[ch[u][i]]=ch[fa[u]][i],q.push(ch[u][i]);
			else ch[u][i]=ch[fa[u]][i];
		}
		if(!id[u]) id[u]=id[fa[u]];
	}
	for(int i=1;i<=n;i++) {
		int x=0;
		for(int j=0;j<s[i].length();j++) {
			x=ch[x][s[i][j]-'a'];
			if(j==s[i].length()-1) G[i][id[fa[x]]]=1;
			else G[i][id[x]]=1;
		}
	}
	for(int k=1;k<=n;k++)
		for(int i=1;i<=n;i++)
			for(int j=1;j<=n;j++) G[i][j]|=G[i][k]&G[k][j];
	int ans=n;
	for(int i=1;i<=n;i++) {
		memset(vis,0,sizeof(vis));
		if(find(i)) --ans;
	}
	cout<<ans<<'\n';
	memset(vis,0,sizeof(vis));
	for(int i=1;i<=n;i++) vv[mat[i]]=1;
	for(int i=1;i<=n;i++) if(!vv[i]) dfs(i);
	for(int i=1;i<=n;i++)
		if(vis[i]&&!vis[i+n]) cout<<i<<' ';
	return 0;
}


#include <bits/stdc++.h>
using namespace std;
const int maxn = 750, maxc = 1e7;
int n;
char s[maxc + 10];
bool a[maxn + 10][maxn + 10], vis[maxn + 10], is[maxn + 10];
bool visl[maxn + 10], visr[maxn + 10];
int lk[maxn + 10], cnt;

namespace acm {
	int ch[maxc + 10][2], idcnt, ndcnt;
	int ed[maxc + 10], fa[maxc + 10];
	int ne[maxc + 10], nxt[maxc + 10];

	void ins(char *s) {
		int l = strlen(s + 1), p = 0;
		for (int i = 1; i <= l; ++i) {
			int t = s[i] - 'a';
			if (!ch[p][t]) {
				ch[p][t] = ++ndcnt; fa[ndcnt] = p;
			}
			p = ch[p][t];
		}
		if (!ed[p]) ed[p] = ++idcnt;
	}

	void build() {
		static queue<int> q;
		for (int i = 0; i < 2; ++i)
			if (ch[0][i]) q.push(ch[0][i]);
		while (!q.empty()) {
			int p = q.front(); q.pop();
			ne[p] = ed[p] ? ed[p] : ne[nxt[p]];
			for (int i = 0; i < 2; ++i)
				if (ch[p][i]) {
					nxt[ch[p][i]] = ch[nxt[p]][i];
					q.push(ch[p][i]);
				} else ch[p][i] = ch[nxt[p]][i];
		}
		for (int i = 1; i <= ndcnt; ++i)
			if (ed[i])
				for (int j = i; j; j = fa[j]) {
					int to;
					if (j == i) to = ne[nxt[j]];
					else to = ne[j];
					if (to) a[ed[i]][to] = 1;
				}
	}
}

bool dfs(int p) {
	for (int i = 1; i <= n; ++i)
		if (a[p][i] && !vis[i]) {
			vis[i] = 1;
			if (!lk[i] || dfs(lk[i])) {
				lk[i] = p; return 1;
			}
		}
	return 0;
}

void dfs2(int p) {
	visl[p] = 1;
	for (int i = 1; i <= n; ++i)
		if (a[p][i] && !visr[i] && lk[i]) {
			visr[i] = 1; dfs2(lk[i]);
		}
}

int main() {
	scanf("%d", &n);
	for (int i = 1; i <= n; ++i) {
		scanf("%s", s + 1);
		acm::ins(s);
	}
	acm::build();
	n = acm::idcnt;
	for (int k = 1; k <= n; ++k)
		for (int i = 1; i <= n; ++i)
			for (int j = 1; j <= n; ++j)
				a[i][j] |= a[i][k] && a[k][j];
	for (int i = 1; i <= n; ++i) {
		memset(vis, 0, sizeof vis);
		dfs(i);
	}
	for (int i = 1; i <= n; ++i)
		if (lk[i]) is[lk[i]] = 1;
	for (int i = 1; i <= n; ++i)
		if (!is[i]) dfs2(i);
	for (int i = 1; i <= n; ++i)
		if (visl[i] && !visr[i]) ++cnt;
	printf("%d\n", cnt);
	for (int i = 1; i <= n; ++i)
		if (visl[i] && !visr[i]) printf("%d ", i);
}


#include <bits/stdc++.h>

using namespace std;

const int SZ = 10000010;
const int N = 760;

int n;
string s[N];
bool edge[N][N];

struct AC {
    int nxt[2][SZ];
    int id[SZ];
    int cnt;
    int link[SZ];
    int dp[SZ];

    AC() {
        cnt = 0;
        memset(nxt, -1, sizeof nxt);
        memset(link, -1, sizeof link);
        memset(id, -1, sizeof id);
    }

    void add(const string &u, int now) {
        int cur = 0;
        for (char v : u) {
            int val = v - 'a';
            if (nxt[val][cur] == -1) nxt[val][cur] = ++cnt;
            cur = nxt[val][cur];
        }
        id[cur] = now;
    }

    void build() {
        memset(dp, -1, sizeof dp);
        queue<int> q;
        q.push(0);
        while (!q.empty()) {
            int u = q.front();
            q.pop();
            if (link[u] != -1) {
                if (id[u] != -1) dp[u] = id[u];
                else dp[u] = dp[link[u]];
            }
            for (int i = 0; i < 2; i++) {
                int v = link[u] == -1 ? 0 : nxt[i][link[u]];
                if (nxt[i][u] == -1) nxt[i][u] = v;
                else {
                    link[nxt[i][u]] = v;
                    q.push(nxt[i][u]);
                }
            }
        }
    }

    void go(int u) {
        int cur = 0;
        for (char v : s[u]) {
            int val = v - 'a';
            cur = nxt[val][cur];
            if (dp[cur] != -1) {
                edge[dp[cur]][u] = 1;
            }
        }
        if (dp[link[cur]] != -1) {
            edge[dp[link[cur]]][u] = 1;
        }
    }
} ac;

const int INF = 1e9;
const int V = 3 * N * N;

struct DinicFlow {
    vector<int> adj[N * 2];
    int to[V], c[V], f[V], h[N * 2];
    int n, s, t;
    int cnt;
    int cur[N * 2];

    DinicFlow(int n, int s, int t) : n(n), s(s), t(t) {
        cnt = 0;
    }

    void addEdge(int u, int v, int _c) {
        to[cnt] = v, c[cnt] = _c, f[cnt] = 0;
        adj[u].push_back(cnt++);
        to[cnt] = u, c[cnt] = 0, f[cnt] = 0;
        adj[v].push_back(cnt++);
    }

    bool bfs() {
        fill(h, h + n, -1);
        h[s] = 0;
        queue<int> q;
        q.push(s);
        while (!q.empty()) {
            int u = q.front();
            q.pop();
            for (int id : adj[u]) {
                int v = to[id];
                if (h[v] == -1 && f[id] < c[id]) {
                    h[v] = h[u] + 1;
                    q.push(v);
                }
            }
        }
        return h[t] != -1;
    }

    int dfs(int u, int res) {
        if (u == t) return res;
        for (int &i = cur[u]; i < adj[u].size(); i++) {
            int id = adj[u][i];
            int v = to[id];
            if (h[v] == h[u] + 1 && f[id] < c[id]) {
                int foo = dfs(v, min(res, c[id] - f[id]));
                if (foo) {
                    f[id] += foo;
                    f[id ^ 1] -= foo;
                    return foo;
                }
            }
        }
        return 0;
    }

    int maxFlow() {
        int res = 0;
        while (bfs()) {
            for (int i = 0; i < n; i++) {
                cur[i] = 0;
            }
            while (1) {
                int foo = dfs(s, INF);
                if (!foo) break;
                res += foo;
            }
        }
        return res;
    }

    vector<int> getVcList(int sz) {
        int ver = bfs();
        assert(!ver);
        vector<int> res;
        for (int i = 1; i <= sz; i++) {
            if (h[i] == -1) res.push_back(i);
            if (h[i + sz] != -1) res.push_back(i);
        }
        return res;
    }
};

int res[N];

int main() {
    ios_base::sync_with_stdio(0);
    cin.tie(0);
    cin >> n;
    for (int i = 1; i <= n; i++) {
        cin >> s[i];
        ac.add(s[i], i);
    }
    ac.build();
    for (int i = 1; i <= n; i++) {
        ac.go(i);
        edge[i][i] = 0;
    }
    for (int k = 1; k <= n; k++) {
        for (int i = 1; i <= n; i++) {
            for (int j = 1; j <= n; j++) {
                if (edge[i][k] && edge[k][j]) edge[i][j] = 1;
            }
        }
    }
    DinicFlow f(n * 2 + 2, 0, n * 2 + 1);
    for (int i = 1; i <= n; i++) {
        f.addEdge(f.s, i, 1);
        f.addEdge(i + n, f.t, 1);
        for (int j = 1; j <= n; j++) {
            if (edge[i][j]) {
                f.addEdge(i, j + n, 1);
            }
        }
    }
    cout << n - f.maxFlow() << endl;
    vector<int> vcList = f.getVcList(n);
    fill(res + 1, res + n + 1, 1);
    for (int u : vcList) res[u] = 0;
    for (int i = 1; i <= n; i++) if (res[i]) cout << i << ' ';
    cout << endl;
    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();
  //  }

  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;
}