建出自動機後即可求出串和串之間的偏序關係
建成一個
然後做一次最長反鏈並輸出方案即可
#include<bits/stdc++.h>
using namespace std;
#define cs const
#define re register
#define pb push_back
#define pii pair<int,int>
#define ll long long
#define y1 shinkle
#define fi first
#define se second
#define bg begin
cs int RLEN=1<<20|1;
inline char gc(){
static char ibuf[RLEN],*ib,*ob;
(ib==ob)&&(ob=(ib=ibuf)+fread(ibuf,1,RLEN,stdin));
return (ib==ob)?EOF:*ib++;
}
inline int read(){
char ch=gc();
int res=0;bool f=1;
while(!isdigit(ch))f^=ch=='-',ch=gc();
while(isdigit(ch))res=(res+(res<<2)<<1)+(ch^48),ch=gc();
return f?res:-res;
}
inline ll readll(){
char ch=gc();
ll res=0;bool f=1;
while(!isdigit(ch))f^=ch=='-',ch=gc();
while(isdigit(ch))res=(res+(res<<2)<<1)+(ch^48),ch=gc();
return f?res:-res;
}
inline int readstring(char *s){
int top=0;char ch=gc();
while(isspace(ch))ch=gc();
while(!isspace(ch)&&ch!=EOF)s[++top]=ch,ch=gc();
s[top+1]='\0';return top;
}
inline void reads(vector<char>&s){
char ch=gc();
while(isspace(ch))ch=gc();
while(!isspace(ch)&&ch!=EOF)s.pb(ch),ch=gc();
}
template<typename tp>inline void chemx(tp &a,tp b){a=max(a,b);}
template<typename tp>inline void chemn(tp &a,tp b){a=min(a,b);}
cs int N=777,M=10000005;
vector<char>str[N];
int n;
bool lk[N][N];
inline void addedge(int u,int v){
lk[u][v]=1;
}
namespace Ac{
int nxt[M][2],fail[M],bel[M],tot;
inline void insert(char *s,int l,int id){
int p=0;
for(int i=0;i<l;i++){
int c=s[i]-'a';
if(!nxt[p][c])nxt[p][c]=++tot;
p=nxt[p][c];
}bel[p]=id;
}
int q[M],hd,tl,up[M];
bool vis[M];
inline int find(int p){
if(p==0)return -1;
if(bel[p])return p;
if(up[p])return up[p];
return up[p]=find(fail[p]);
}
inline void buildfail(){
hd=1;
for(int i=0;i<2;i++){
if(nxt[0][i])q[++tl]=nxt[0][i];
}
while(hd<=tl){
int p=q[hd++];
for(int c=0;c<2;c++){
int v=nxt[p][c];
if(!v)nxt[p][c]=nxt[fail[p]][c];
else fail[v]=nxt[fail[p]][c],q[++tl]=v;
}
}
q[hd=tl=1]=0;
vis[0]=1;
while(hd<=tl){
int p=q[hd++];
up[p]=find(fail[p]);
for(int c=0;c<2;c++)if(!vis[nxt[p][c]]){
int v=nxt[p][c];vis[v]=1,q[++tl]=v;
}
}
}
inline void getlk(char *s,int l,int id){
int p=0;
for(int i=0;i<l;i++){
int c=s[i]-'a';
p=nxt[p][c];
int t=bel[p]?p:up[p];
while(t!=-1&&bel[t]==id)t=up[t];
if(t!=-1)addedge(id,bel[t]);
}
}
}
inline void Floyd(){
for(int k=1;k<=n;k++)
for(int i=1;i<=n;i++)if(k!=i)
for(int j=1;j<=n;j++)if(j!=i&&j!=k)
lk[i][j]|=lk[i][k]&lk[k][j];
}
int mat[N*2],vis[N*2];
vector<int> e[N*2];
int vl[N*2],vr[N*2];
void find(int u){
if(vr[u])return;
vr[u]=1;
for(int &v:e[u])if(v!=mat[u]){
if(!vl[v])vl[v]=1,find(mat[v]);
}
}
bool dfs(int u){
if(vis[u])return false;
vis[u]=1;
for(int v:e[u])if(!mat[v]||dfs(mat[v])){
mat[v]=u,mat[u]=v;return true;
}return false;
}
int main(){
#ifdef Stargazer
freopen("lx.in","r",stdin);
#endif
n=read();
for(int i=1;i<=n;i++){
reads(str[i]);
Ac::insert(&str[i][0],str[i].size(),i);
}Ac::buildfail();
for(int i=1;i<=n;i++)
Ac::getlk(&str[i][0],str[i].size(),i);
Floyd();
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)if(i!=j&&lk[i][j])
e[i].pb(j+n),e[j+n].pb(i);
int res=n;
for(int i=1;i<=n;i++)if(!mat[i])memset(vis,0,sizeof(vis)),res-=dfs(i);
cout<<res<<'\n';
for(int i=1;i<=n;i++)if(!mat[i+n])find(i+n);
for(int i=1;i<=n;i++)if(!vl[i]&&vr[i+n])cout<<i<<" ";
return 0;
}