#include using namespace std; struct EerTree{ struct Node{ Node(int len) : len(len), sdep(0), slink(nullptr), cnt(0){} int len, sdep; map ch; Node* slink; int cnt; }; pair root; Node* active_point; string s; EerTree(){ root.second = new Node(0); root.second->slink = root.first = active_point = new Node(-1); root.first->slink = root.first; } EerTree(string inp) : EerTree(){ for(auto c : inp) add(c); } Node* make(Node* par, char c){ if(par->ch.find(c) == par->ch.end()){ par->ch[c] = new Node(par->len + 2); Node* sl = par->slink; if(par->len == -1) sl = root.second; else{ while(1){ if(s[s.size() - sl->len - 2] == c){ sl = sl->ch[c]; break; }else if(sl->len < 0){ sl = root.second; break; }else sl = sl->slink; } } par->ch[c]->slink = sl; par->ch[c]->sdep = sl->sdep + 1; } return par->ch[c]; } void add(char c){ for(s += c; int(s.size()) - active_point->len - 2 < 0 || s[s.size() - active_point->len - 2] != c; active_point = active_point->slink); active_point = make(active_point, c); } }; long long search(EerTree::Node* x, EerTree::Node* y){ long long cnt = 1LL * x->cnt * y->cnt; if(x->len <= 0) cnt = 0; for(auto child : x->ch){ if(y->ch.find(child.first) != y->ch.end()){ cnt += search(x->ch[child.first], y->ch[child.first]); } } return cnt; } void dump(EerTree::Node* x, std::vector& v){ v.emplace_back(x); for(auto child : x->ch) dump(child.second, v); } signed main(){ string s, t; cin >> s >> t; EerTree es, et; for(auto c : s){ es.add(c); es.active_point->cnt += 1; } for(auto c : t){ et.add(c); et.active_point->cnt += 1; } std::vector sv, tv; dump(es.root.first, sv); dump(es.root.second, sv); dump(et.root.first, tv); dump(et.root.second, tv); sort(sv.begin(), sv.end(), [](auto x, auto y){return x->sdep > y->sdep;}); for(auto x : sv) x->slink->cnt += x->cnt; sort(tv.begin(), tv.end(), [](auto x, auto y){return x->sdep > y->sdep;}); for(auto x : tv) x->slink->cnt += x->cnt; cout << search(es.root.first, et.root.first) + search(es.root.second, et.root.second) << endl; }