#include // ver2.6.3 //#include // FFT用 //#include //#include //using boost::math::tools::brent_find_minima;//fmin(f,L,R,100)で最小値をmp(x,min)で取得 //using boost::multiprecision::cpp_int;//cpp_int (任意の長さのint) #define fmin brent_find_minima #define int long long #define endl "\n" #define ALL(v) (v).begin(),(v).end() #define Vi vector #define VVi vector #define VVVi vector #define Vm vector #define Vs vector #define Vd vector #define Pii pair #define Pdd pair #define VPii vector #define Tiii tuple #define VTiii vector #define PQi priority_queue #define PQir priority_queue,greater> #define pb push_back #define mp make_pair #define mt make_tuple #define itos to_string #define stoi stoll #define FI first #define SE second #define cYES cout<<"YES"<()) #define rep(i,a,b) for(int i=a;i=b;i--) #define dem(a,b) ((a+b-1)/(b)) #define Vin(a) rep(iI,0,a.size())cin>>a[iI] #define INF 3000000000000000000 // 3.0*10^18(MAXの1/3くらい) #define MAX LLONG_MAX #define PI 3.141592653589793238462 //#define MOD 1000000007 // 10^9 + 7 int MOD = 998244353; // caseに応じて変える必要がある場合はこちら const double EPS = 1e-10; using namespace std; struct mint{int x;mint(int x=0):x((x%MOD+MOD)%MOD){} mint operator-()const{return mint(-x);} mint& operator+=(const mint a){if((x+=a.x)>=MOD)x-=MOD;return*this;} mint& operator-=(const mint a){if((x+=MOD-a.x)>=MOD)x-=MOD;return*this;} mint& operator*=(const mint a){(x*=a.x)%=MOD;return*this;} mint operator+(const mint a)const{return mint(*this)+=a;} mint operator-(const mint a)const{return mint(*this)-=a;} mint operator*(const mint a)const{return mint(*this)*=a;} mint pow(int t)const{if(!t)return 1;mint a=pow(t>>1);a*=a;if(t&1)a*=*this;return a;} mint inv()const{return pow(MOD-2);} mint& operator/=(const mint a){return*this*=a.inv();} mint operator/(const mint a)const{return mint(*this)/=a;}}; istream& operator>>(istream& is, const mint& a) {return is >> a.x;} ostream& operator<<(ostream& os, const mint& a) {return os << a.x;} /* デバッグ用 */ template // vector出力 ostream& operator<<(ostream& os,const vector &V){int N=V.size(); rep(i,0,N-1){os< // vector出力 ostream& operator<<(ostream& os,const vector> &V){ int N=V.size();rep(i,0,N-1)cout< // pair出力 ostream& operator<<(ostream& os, pair const&P){os< // set出力 ostream& operator<<(ostream& os,set &S){auto it=S.begin();while(it!=S.end()){ os<<*it;if(next(it,1)!=S.end())os<<' ';it++;};return os;} template // deque出力 ostream& operator<<(ostream& os, deque &q){for(auto it=q.begin();itn)return 0;if((n-r)n-r;--i){a=a*i;}for(int i=1;i > G; vector used; vector level;//sからの距離 vector iter;//どこまで調べ終わったか //0 ~ maxSize-1 のフローを構築できるようにする explicit Flow(unsigned maxSize) { G.resize(maxSize, vector()); used.resize(maxSize, false); level.resize(maxSize, 0); iter.resize(maxSize, 0); } void add_edge(int from, int to, int cap) { G[from].push_back((edge) {to, cap, (int) G[to].size()}); G[to].push_back((edge) {from, 0, (int) G[from].size() - 1}); } //sからの最短距離をDFSで探す void bfs(int s) { //memset(level, -1, sizeof(level)); fill(level.begin(), level.end(), -1); queue que; level[s] = 0; que.push(s); while (!que.empty()) { int v = que.front(); que.pop(); for (int i = 0; i < G[v].size(); i++) { edge &e = G[v][i]; if (e.cap > 0 && level[e.to] < 0) { level[e.to] = level[v] + 1; que.push(e.to); } } } } //増加パスを探す int dfs(int v, int t, int f) { if (v == t) return f; for (int &i = iter[v]; i < G[v].size(); i++) { edge &e = G[v][i]; if (e.cap > 0 && level[v] < level[e.to]) { int d = dfs(e.to, t, min(f, e.cap)); if (d > 0) { e.cap -= d; G[e.to][e.rev].cap += d; return d; } } } return 0; } //sからtへの最大流を求める int max_flow(int s, int t) { int flow = 0; for (;;) { bfs(s); if (level[t] < 0) return flow; //memset(iter, 0, sizeof(iter)); fill(iter.begin(), iter.end(), 0); int f; while ((f = dfs(s, t, INF)) > 0) { flow += f; } } } }; signed main() { cin.tie(0);cout.tie(0);ios::sync_with_stdio(0);cout<> s; if(s.size()%2) {cNO;return 0;} int n = s.size(); string u,t; rep(i,0,n){ if(i