#include<iostream>
#include<cstring>
#include<stdio.h>
using namespace std;
const int MM=100005;
int next[MM],extand[MM];
char S[MM],T[MM];
void GetNext(const char *T) {
int len = strlen(T),a = 0;
next[0] = len; //第一个最远的 距离 为 其长度
while(a < len - 1 && T[a] == T[a + 1]) a++;//求出第二个最远的距离
next[1] = a;
a = 1;
for(int k = 2; k < len; k ++) {
int p = a + next[a] - 1,L = next[k - a]; //a 为最远距离原始位置 p为最远距离 l为next中k距离a的距离(已经开始跳跃) 因为第一个最远是整个串,所以从第二个最远的距离开始,
if( (k - 1) + L >= p) { //当 ==p的时候也要进行比较 /
int j = (p - k + 1) > 0 ? (p - k + 1) : 0; // 这里当多个不匹配的情况下 k可能=p+2 , 如果==0,从新开始
while(k + j < len && T[k + j] == T[j]) j++; //进行 下一个的比较
next[k] = j; //得到
a = k; //最远
} else
next[k] = L; //当它 不能超越 边界的时候 ,就直接记录 回溯 开始的值
}
}
void GetExtand(const char *S,const char *T) {
GetNext(T); //得到 next 数组
int slen = strlen(S),tlen = strlen(T),a = 0;
int MinLen = slen < tlen ? slen : tlen; //记录下 比较短的一个数组
while(a < MinLen && S[a] == T[a]) a++; //如果没有 Minlen 可能溢出
extand[0] = a; //这里是 从零开始比较
a = 0;
for(int k = 1; k < slen; k ++) {
int p = a + extand[a] - 1, L = next[k - a]; //如果不加这个也可以 求得 只是就没有 跳跃的 过程了
if( (k - 1) + L >= p) {
int j = (p - k + 1) > 0 ? (p - k + 1) : 0;
while(k + j < slen && j < tlen && S[k + j] == T[j]) j ++; //小于主串长,还要小于模式串
extand[k] = j;
a = k; //获取 最远匹配的
} else
extand[k] = L;
}
}
void show(const int *s,int len){
for(int i = 0; i < len; i ++)
cout << s[i] << ' ';
cout << endl;
}
int main() {
gets(S);gets(T);
GetExtand(S,T);
show(next,strlen(T));
show(extand,strlen(S));
return 0;
}