Problem:
Transporter
In the year 30XX, an expedition team reached a planet and found a warp machine suggesting the existence of a mysterious supercivilization. When you go through one of its entrance gates, you can instantaneously move to the exit irrespective of how far away it is. You can move even to the end of the universe at will with this technology!
The scientist team started examining the machine and successfully identified all the planets on which the entrances to the machine were located. Each of these N planets (identified by an index from $1$ to $N$) has an entrance to, and an exit from the warp machine. Each of the entrances and exits has a letter inscribed on it.
The mechanism of spatial mobility through the warp machine is as follows:
If you go into an entrance gate labeled with c, then you can exit from any gate with label c.
If you go into an entrance located on the $i$-th planet, then you can exit from any gate located on the $j$-th planet where $i < j$.
Once you have reached an exit of the warp machine on a planet, you can continue your journey by entering into the warp machine on the same planet. In this way, you can reach a faraway planet. Our human race has decided to dispatch an expedition to the star $N$, starting from Star $1$ and using the warp machine until it reaches Star $N$. To evaluate the possibility of successfully reaching the destination. it is highly desirable for us to know how many different routes are available for the expedition team to track.
Given information regarding the stars, make a program to enumerate the passages from Star $1$ to Star $N$.
Input
The input is given in the following format.
$N$
$s$
$t$
The first line provides the number of the stars on which the warp machine is located $N$ ($2 \leq N \leq 100,000$). The second line provides a string $s$ of length $N$, each component of which represents the letter inscribed on the entrance of the machine on the star. By the same token, the third line provides a string $t$ of length $N$ consisting of the letters inscribed on the exit of the machine. Two strings $s$ and $t$ consist all of lower-case alphabetical letters, and the $i$-th letter of these strings corresponds respectively to the entrance and exit of Star $i$ machine.
Output
Divide the number of possible routes from Star $1$ to Star $N$ obtained above by 1,000,000,007, and output the remainder.
Sample Input 1
6
abbaba
baabab
Sample Output 1
5
Sample Input 2
25
neihsokcpuziafoytisrevinu
universityofaizupckoshien
Sample Output 2
4

Submitted solutions:

code_snippet: #include<bits/stdc++.h>
using namespace std;
//#include<atcoder/all>
//using namespace atcoder;
#define rep(i,n) for(int i=0;i<(int)n;i++)
#define rep1(i,n) for(int i=1;i<=(int)n;i++)
using ll = long long;
using ull = unsigned long long;
using P = pair<int, int>;
using Pl = pair<ll, ll>;
using vi = vector<int>;
using vvi = vector<vi>;
using vvvi = vector<vvi>;
using vd = vector<double>;
using vs = vector<string>;
using vb = vector<bool>;
using vvb = vector<vb>;
using vl = vector<long long>;
using vvl = vector<vl>;
using vvvl = vector<vvl>;
#define inf 947483642//int max
#define linf 9000000000000000000
const double PI = 3.1415926535897932384626433832795028841971;
template<typename T>inline bool chmax(T& a, T b) { return ((a < b) ? (a = b, true) : (false)); }
template<typename T>inline bool chmin(T& a, T b) { return ((a > b) ? (a = b, true) : (false)); }
long long llceil(long long a, long long b) { if (a % b == 0) { return a / b; }return (a / b) + 1; }
#define yes cout<<"Yes"<<endl
#define no cout<<"No"<<endl
#define yesno(ans) cout<<(ans?"Yes":"No")<<endl
#define sortu(a) sort(a.begin(),a.end())
#define all(a) (a,begin(),a.end())
//#define sortd(a) sort(a.begin(),a.end(),greater());
//sort(a.begin(),a.end(),greater<int>());
const ll MOD = 1000000007;

int main() {

    int n; cin >> n;
    string s, t; cin >> s >> t;

    map<char, ll>ent;
    
    for (char c = 'a'; c <= 'z'; c++) {
        rep(i, n) {
            if (t[i] == c)ent[c]++;
        }
    }

    map<char, ll>ans;
   
    rep(i, n) {
        ent[t[i]]--;


        if (i == 0) {
            ans[s[i]] += 1;
            continue;
        }
        if (i < n-1) {
            ans[s[i]] += ans[t[i]];
            ans[s[i]] %= MOD;
        }
    }

    cout << ans[t[n - 1]] << endl;


    return 0;
}
accuracy: 1
time_ms: 10
memory_kb: 3488
final_rank: 3

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

int main()
{
	long long n,mod = 1000000007;
	cin >> n;
	string s,t;
	cin >> s >> t;
	vector<vector<long long>> sum(26,vector<long long>(n,0));
	vector<long long> last(26,-1);
	priority_queue<long long,vector<long long>,greater<long long>> q;
	vector<long long> dp(n,0);
	dp[0] = 1;
	for(long long it = 0;it < n;it++){
		while(last[t[it] - 'a'] < it){
			last[t[it] - 'a']++;
			if(last[t[it] - 'a'] == 0) continue;
			sum[t[it] - 'a'][last[t[it] - 'a']] += sum[t[it] - 'a'][last[t[it] - 'a'] - 1];
			sum[t[it] - 'a'][last[t[it] - 'a']] %= mod;
		}
		if(it != 0){
			dp[it] += sum[t[it] - 'a'][it - 1];
		}
		dp[it] %= mod;
		sum[s[it] - 'a'][it] += dp[it];
		sum[s[it] - 'a'][it] %= mod;
	}
	dp[n - 1] %= mod;
	cout << dp[n - 1] << endl;
}
accuracy: 1
time_ms: 10
memory_kb: 24376
final_rank: 13

code_snippet: #include<bits/stdc++.h>
using namespace std;
char s[100001],t[100001];
long long L=1000000007;
int main(void)
{
    int n;
    cin>>n>>s>>t;
    map<char,long long> a,b;
    a[s[0]]++;
    for(int i=1;i<n;i++){
        if(!(i==n-1&&s[i]==t[i])) a[s[i]]=(a[s[i]]+a[t[i]])%L;
    }
    cout<<a[t[n-1]]<<endl;
    return 0;
}
accuracy: 1
time_ms: 10
memory_kb: 3284
final_rank: 1

code_snippet: #include "bits/stdc++.h"

#define REP(i,num) for(ll i=0;i<(num);++i)
#define FOR(i,c,num) for(ll (i)=(c);(i)<(num);++(i))
#define LOOP(i) while(i--)
#define ALL(c) c.begin(),c.end()
#define PRINTALL(c) for(auto pitr=c.begin();pitr!=c.end();++pitr){cout<<*pitr;if(next(pitr,1)!=c.end())cout<<' ';}cout<<endl;
#define PAIRCOMP(c,comp) [](const pair<ll,ll>& lhs,const pair<ll,ll>& rhs){return lhs.c comp rhs.c;}

using namespace std;
using ll = long long;
using vll = vector<ll>;
using vvll = vector<vector<ll>>;

constexpr ll atcoder_mod = 1e9+7;

template<typename T=ll>
T in(){ T x; cin >> x; return (x); }
template<typename T=ll,typename C=vector<T>>
C vecin(int N){ C x(N);REP(i,N){ x[i]=in<T>(); }return x; }

void vout(){ cout << endl; }
template<typename Head,typename... Tail>
void vout(Head&& h,Tail&&... t){ cout << ' ' << h;vout(forward<Tail>(t)...); }
void out(){ cout << endl; }
template<typename Head,typename... Tail>
void out(Head&& h,Tail&&... t){ cout << h;vout(forward<Tail>(t)...); }

template<typename T>
bool chmax(T& a,T b){ if(a<b){ a=b;return true; }return false; }
template<typename T>
bool chmin(T& a,T b){ if(a>b){ a=b;return true; }return false; }

class RangeUpdate{
public:
	virtual ll fa(ll x,ll m)=0;
	virtual ll fm(ll m1,ll m2)=0;
	ll em;
};

class RangeUpdateAdd:public RangeUpdate{
public:
	RangeUpdateAdd(){em = 0;}
	ll fa(ll x,ll m){return (x+m)%atcoder_mod;}
	ll fm(ll m1,ll m2){return (m1+m2)%atcoder_mod;}
};

class RangeQuery{
public:
	virtual ll fx(ll x1,ll x2)=0;
	virtual ll fp(ll m,ll n)=0;
	ll ex;
};

class RangeQueryMin:public RangeQuery{
public:
	RangeQueryMin(){ex = numeric_limits<ll>::max();}
	ll fx(ll x1,ll x2){return min(x1,x2);}
	ll fp(ll m,ll n){return m;}
};

class SegmentTree{
	unique_ptr<RangeUpdate> range_update;
	unique_ptr<RangeQuery> range_query;

	/* lazy eval */
	void Eval(int k,int len){
		if(lazy[k]==range_update->em) return;  // 更新するものが無ければ終了
		if(k<size-1){            // 葉でなければ子に伝搬
			lazy[k*2+1] = range_update->fm(lazy[k*2+1],lazy[k]);
			lazy[k*2+2] = range_update->fm(lazy[k*2+2],lazy[k]);
		}
		// 自身を更新
		dat[k] = range_update->fa(dat[k],range_query->fp(lazy[k],len));
		lazy[k] = range_update->em;
	}

	ll Query(ll a, ll b, ll k, ll l, ll r){
		Eval(k,r-l);
		if(r<=a || b<=l){  // 完全に外側の時
			return range_query->ex;
		}
		else if(a <= l && r <= b){  // 完全に内側の時
			return dat[k];
		}
		else{  // 一部区間が被る時
			ll vl = Query(a,b,k*2+1,l,(l+r)/2);
			ll vr = Query(a,b,k*2+2,(l+r)/2,r);
			return range_query->fx(vl,vr);
		}
	}

	void Update(ll a, ll b, ll x, ll k, ll l, ll r) {
		Eval(k,r-l);
		if(a<=l && r<=b){  // 完全に内側の時
			lazy[k] = range_update->fm(lazy[k],x);
			Eval(k,r-l);
		}
		else if(a<r && l<b){                     // 一部区間が被る時
			Update(a,b,x,k*2+1,l,(l+r)/2);  // 左の子
			Update(a,b,x,k*2+2,(l+r)/2,r);  // 右の子
			dat[k] = range_query->fx(dat[k*2+1],dat[k*2+2]);
		}
	}
public:
	ll size;
	vector<ll> dat;
	vector<ll> lazy;
	SegmentTree(ll N, unique_ptr<RangeUpdate> rup,unique_ptr<RangeQuery> rqp)
		: range_update(std::move(rup)), range_query(std::move(rqp)){
		dat.resize(max(4*N,4ll),range_query->ex);
		lazy.resize(max(4*N,4ll),range_update->em);
		ll x = 1;
		while(N>x) x *= 2;
		size = x;
	}
	void Set(int i,ll x){dat[i+size-1]=x;}
	void Build(){
		for(ll k=size-2ll;k>=0;k--) dat[k] = range_query->fx(dat[2*k+1],dat[2*k+2]);
	}

	void Update(ll a, ll b, ll x){Update(a, b, x, 0, 0, size);}
	ll Query(int a, int b){return Query(a, b, 0, 0, size);}
};

int main(){
	cin.tie(0);
	ios::sync_with_stdio(false);
	cout<<fixed<<setprecision(10);

	auto N=in();
	string S=in<string>(),T=in<string>();
	vvll M(26);
	REP(i,N){
		M[T[i]-'a'].push_back(i);
	}

	unique_ptr<SegmentTree> seg_tree[26];
	REP(i,26){
		ll K=M[i].size();
		seg_tree[i] = make_unique<SegmentTree>(K,make_unique<RangeUpdateAdd>(),make_unique<RangeQueryMin>());
		REP(j,K){
			seg_tree[i]->Set(j,0);
		}
		seg_tree[i]->Build();
	}
	seg_tree[T[0]-'a']->Update(0,1,1);
	vll I(26,0);
	REP(i,N){
		ll Q=S[i]-'a';
		ll E=M[Q].size();
		auto res = upper_bound(ALL(M[Q]),i);
		ll D=distance(M[Q].begin(),res);
		auto val = seg_tree[T[i]-'a']->Query(I[T[i]-'a'],I[T[i]-'a']+1);
		seg_tree[Q]->Update(D,E,val);
		I[T[i]-'a']++;
	}

	out(seg_tree[T[N-1]-'a']->Query(I[T[N-1]-'a']-1,I[T[N-1]-'a']));
	return 0;
}
accuracy: 1
time_ms: 40
memory_kb: 10964
final_rank: 17

code_snippet: #include <iostream> 
#include<vector>
#include<algorithm>
#include<map>
#include<string>
#include<iomanip>
#include<set>
#include<queue>
#include<deque>
#include<sstream>
#include<cmath>
#include<bitset>
using namespace std;
#define rep(i, n) for (int i = 0; i < (int)(n); i++)
#define req(i,n) for(int i = 1;i <=  n; i++)
typedef long long int ll;
const int MOD = 1000000007;
int main(void) {
    string s, t; int n; cin >> n >> s >> t;
    vector<vector<int>> dp(n, vector<int>(26, 0));
    dp[0][s[0] - 'a'] = 1;
    req(i, n - 1) {
        dp[i][s[i] - 'a'] = (dp[i][s[i] - 'a'] + dp[i - 1][t[i] - 'a']) % MOD;
        rep(j, 26) dp[i][j] = (dp[i][j] + dp[i - 1][j]) % MOD;
    }cout << dp[n - 2][t[n - 1] - 'a'] << endl;
}
accuracy: 1
time_ms: 10
memory_kb: 16364
final_rank: 8

code_snippet: #include <iostream> 
#include<vector>
#include<algorithm>
#include<map>
#include<string>
#include<iomanip>
#include<set>
#include<queue>
#include<deque>
#include<sstream>
#include<cmath>
#include<bitset>
using namespace std;
#define rep(i, n) for (int i = 0; i < (int)(n); i++)
#define req(i,n) for(int i = 1;i <=  n; i++)
#define rrep(i,n) for(int i = n-1;i >= 0;i--)
#define ALL(obj) begin(obj), end(obj)
#define RALL(a) rbegin(a),rend(a)
typedef long long int ll;
typedef long double ld;
template<typename A, size_t N, typename T>
void Fill(A(&array)[N], const T& val) {
    std::fill((T*)array, (T*)(array + N), val);
}
const int MAX = 510000;
const int MOD = 1000000007;
const int inf = 1<<31-1;
template<class T> inline bool chmax(T& a, T b) { if (a < b) { a = b; return 1; } return 0; }
template<class T> inline bool chmin(T& a, T b) { if (a > b) { a = b; return 1; } return 0; }
int main(void) {
    string s, t; int n; cin >> n >> s >> t;
    vector<vector<int>> dp(n, vector<int>(26, 0));
    dp[0][s[0] - 'a'] = 1;
    req(i, n - 1) {
        dp[i][s[i] - 'a'] = (dp[i][s[i] - 'a'] + dp[i - 1][t[i] - 'a']) % MOD;
        rep(j, 26) dp[i][j] = (dp[i][j] + dp[i - 1][j]) % MOD;
    }cout << dp[n - 2][t[n - 1] - 'a'] << endl;
}
accuracy: 1
time_ms: 10
memory_kb: 16360
final_rank: 7

code_snippet: #include <algorithm>
#include <iostream>
#include <vector>
#define repeat(i, n) for (int i = 0; (i) < (n); ++(i))
#define repeat_from(i, m, n) for (int i = (m); (i) < (n); ++(i))
using namespace std;
template <class T>
void setmax(T &a, T const &b) {
    if (a < b) a = b;
}

template <class T>
void setmin(T &a, T const &b) {
    if (a > b) a = b;
}

template <typename T, typename X>
auto vectors(T a, X x) { return vector<T>(x, a); }

template <typename T, typename X, typename Y, typename... Zs>
auto vectors(T a, X x, Y y, Zs... zs) {
    auto cont = vectors(a, y, zs...);
    return vector<decltype(cont)>(x, cont);
}

// もらうdpで行こう
const long long MOD = 1e9 + 7;

int main() {
    int N;
    string S, T;
    cin >> N >> S >> T;

    const int alphabet = 'z' - 'a' + 1;
    // dp[i][j] := 星0~iの入口jから入れる累計数
    auto dp = vectors(0, N, alphabet);
    dp[0][S[0] - 'a'] = 1;
    repeat_from(i, 1, N) {
        dp[i][S[i] - 'a'] = (dp[i][S[i] - 'a'] + dp[i - 1][T[i] - 'a']) % MOD;
        repeat(j, alphabet) {
            dp[i][j] = (dp[i][j] + dp[i - 1][j]) % MOD;
        }
    }
    // 星N-2から星N-1の出口と同じタイプの入口に入れる通り
    cout << dp[N - 2][T[N - 1] - 'a'] << endl;
    return 0;
}
accuracy: 1
time_ms: 10
memory_kb: 16300
final_rank: 6

code_snippet: #include <iostream>
#include <string.h>
#include <string>
using namespace std;


long long int m=1000000007;
string str1;
string str2;
const int R=131071;
long long int xs[26][270000];
int qs[26][270000];
long long int ms[100001];

long long int f(int no,int no2,long long int x,int l1,int r1,int l,int r){
	if(r1<l){
		return xs[no][no2];
	}
	if(r<l1){
		return 0;
	}
	if(r1==l1){
		xs[no][no2]=(xs[no][no2]+x)%m;
		return xs[no][no2];
	}
	if(l<=l1&&r1<=r){
		xs[no][no2]=(xs[no][no2]+x)%m;
		return xs[no][no2];
	}else{
		
		int m1=(l1+r1)/2;
		long long int t1=f(no,no2*2+1,x,l1,m1,l,r);
		long long int t2=f(no,no2*2+2,x,m1+1,r1,l,r);
		xs[no][no2]=(t1+t2) % m;
		return xs[no][no2];
	}
}

int main() {
	// your code goes here
	memset(xs,0,sizeof(xs));
	int n;
	cin>>n;
	cin>>str1;
	cin>>str2;
	
	f(((int)str1[0])-97,0,1,0,R,0,0);
	ms[0]=1;
	long long int ans=0;
	for(int i=1;i<n-1;i++){
		int t1=(int)str2[i] - 97;
		int t2=(int)str1[i] - 97;
		ms[i]=f(t1,0,0,0,R,0,i-1);
		f(t2,0,ms[i],0,R,i,i);
	}
	int t2=(int)str2[n-1] - 97;
	cout<<f(t2,0,0,0,R,n-1,n-1)<<endl;
	return 0;
}
accuracy: 1
time_ms: 80
memory_kb: 58912
final_rank: 19

code_snippet: #include <iostream>
#include <fstream>
#include <stdio.h>
#include <cstdlib>
#include <string>
#include <vector>
#include <map>
#include <list>
#include <set>
#include <queue>
#include <stack>
#include <algorithm>
#include <math.h>
#include <random>
#include <time.h>
#include <cassert>
using namespace std;
#define LL long long
#undef INT_MIN
#undef INT_MAX
#define INT_MIN -2147483648
#define INT_MAX 2147483647
#define LL_MIN -9223372036854775808
#define LL_MAX 9223372036854775807

/*
//1
int main(){
    int f;
	cin >> f;

	cout << (f - 30)/2 << endl;

    
    return 0;
}
*/



/*
//2
int main(){
    int x1, x2;
	cin >> x1 >> x2;

	cout << abs(x1 - x2) << endl;

    
    return 0;
}
*/



/*
//3
int main(){
    int N, C;
	cin >> N >> C;

	int sum = 0;
	for(int i=0; i<C; i++){
		int p;
		cin >> p;
		sum += p;
	}

	int ans = sum/(N+1);
	if(sum%(N+1) != 0) ans++;
	cout << ans << endl;
    
    return 0;
}
*/

/*
//4
int main(){
    int A, B, X;
	cin >> A >> B >> X;
	int ans;

	if(A < 2*B){
		ans = X/1000 * A;
		int tmp = X%1000;

		if(tmp != 0){
			if(ans + A < ans + B * (tmp/500 + 1) ){
				ans = ans + A;
			}
			else{
				ans = ans + B * (tmp/500 + 1);
			}
		}
	}
	else{
		ans = X/500 * B;
		int tmp = X%500;

		if(tmp != 0){
			ans +=  B;
		}
	}

	cout << ans << endl;
    
    return 0;
}
*/

/*
int A, N, M;

int njo(int m, int n){
	if(n == 0) return 1;
	n--;
	return m * njo(m, n);
}

int sum = 0;
void solve(int X){
	if(X == 0) return;
	sum += X%10;
	solve(X/10);
}

//5
int main(){
    cin >> A >> N >> M;

	int ans = 0;
	for(int i=1; i <= 73; i++){
		int x = njo(i + A, N);
		if(x > M) break;

		sum = 0;
		solve(x);
		int y = sum;

		if(i == y) ans++;
	}

	cout << ans << endl;

    return 0;
}
*/



/*
//6
int main(){
    int N, Q;
	int A[30000];
	bool b[30000];
	int sum = 0;

	cin >> N;

	for(int i=0; i<N; i++){
		cin >> A[i];
		b[i] = false;
	}

	for(int i=0; i<N-1; i++){
		if(A[i] > A[i+1]){
			b[i] = true;
			sum++;
		}
	}

	cin >> Q;

	if(sum == 0){
		cout << 0 << endl;
		return 0;
	}

	for(int i=0; i<Q; i++){
		int x, y;
		cin >> x >> y;
		x--;
		y--;
		if(x > y){
			int tmp = x;
			x = y;
			y = tmp;
		}

		int tmps = A[x];
		A[x] = A[y];
		A[y] = A[x];

		if(b[x] == true){
			if(A[x] <= A[x+1]){
				b[x] = false;
				sum--;
			}
		}
		if(x>=1){
			if(b[x-1] == true){
				if(A[x-1] <= A[x]){
					b[x-1] = false;
					sum--;
				}
			}
		}

		if(b[y] == true){
			if(A[y] <= A[y+1]){
				b[y] = false;
				sum--;
			}
		}
		if(y>=1){
			if(b[y-1] == true && x+1 != y){
				if(A[y-1] <= A[x]){
					b[y-1] = false;
					sum--;
				}
			}
		}

		if(x < N-1){
			if(A[x] > A[x+1]){
				b[x] = true;
				sum++;
			}
		}
		if(x >=1){
			if(A[x-1] > A[x]){
				b[x-1] = true;
				sum++;
			}
		}

		if(y < N-1){
			if(A[y] > A[y+1]){
				b[y] = true;
				sum++;
			}
		}
		if(y >=1){
			if(A[y-1] > A[y] && x+1 != y){
				b[y-1] = true;
				sum++;
			}
		}

		if(sum == 0){
			cout << i + 1 << endl;
			return 0;
		}

	}

	cout << -1 << endl;

    return 0;
}
*/




//7

#define MOD 1000000007

int N;
string s,t;
map<char, set<int> > deguti;
int dp[100000];
int memo[100000];//���̓_�ȍ~�̗ݐϘa

int solve(int now){
	if(now == N-1){
		memo[now] = 1;
		return 1;
	}
	if(dp[now] != -1) return dp[now];

	auto itr = deguti[s[now]].upper_bound(now);
	if(itr == deguti[s[now]].end()) dp[now] = 0;
	else dp[now] = memo[*itr];

	itr = deguti[t[now]].upper_bound(now);
	if(itr == deguti[t[now]].end()) memo[now] = (dp[now] + memo[*itr]) % MOD;
	else memo[now] = dp[now];

	return dp[now];
}

int main(){
    
	cin >> N >> s >> t;
	string alpha = "abcdefghijklmnopqrstuvwxyz";
	set<int> none;
	for(int i=0; i<alpha.size(); i++){
		deguti[alpha[i]] = none;
	}
	for(int i=0; i<N; i++){
		deguti[t[i]].insert(i);
		dp[i] = -1;
	}

	dp[N-1] = 1;
	memo[N-1] = 1;
	for(int i=N-2; i>=0; i--){
		auto itr = deguti[s[i]].upper_bound(i);
		if(itr == deguti[s[i]].end()) dp[i] = 0;
		else dp[i] = memo[*itr];

		itr = deguti[t[i]].upper_bound(i);
		if(itr == deguti[t[i]].end()) memo[i] = dp[i];
		else memo[i] = (dp[i] + memo[*itr]) % MOD;
	}
	cout << dp[0] << endl;
	//for(int i=0; i<N; i++) cout << dp[i] << endl;
    
    return 0;
}




/*
//8

int N;
vector<pair<int,int>> all;

//long long solve(int now, int cars){
//	if(now == N) return 0;
//	
//	long long tmp = 0;
//	long long ans = solve(now+1, cars+1);
//	for(int i=0; i<cars; i++){
//		if(i >= c[now].size()) break;
//		tmp += c[now][i];
//		ans = max(ans, tmp + solve(now+1, cars-i));
//	}
//	return ans;
//}

int seg_size = 524288 * 2 - 1;
int seg[1048575];

int query(int a, int b, int k, int l, int r){
	if(r <= a || b <= l) return 0;
	if(a <= l && r <= b) return seg[k];
	else return query(a,b,k*2+1,l,(l+r)/2) + query(a,b,k*2+2,(l+r)/2,r);
}

int main(){
    
	cin >> N;
	for(int i=0; i<N; i++){
		int M;
		cin >> M;
		for(int j=0; j<M; j++){
			int tmp;
			cin >> tmp;
			all.push_back(make_pair(tmp, i));
		}
	}
	sort(all.begin(), all.end());
	reverse(all.begin(), all.end());
	
	seg_size = 1;
	while(seg_size < N) seg_size *= 2;
	seg_size = seg_size * 2 - 1;
	for(int i=0; i<seg_size; i++) seg[i] = 0;
	
	long long ans = 0;
	for(int i=0; i<all.size(); i++){
		int place = all[i].second;
		if(query(0,place+1,0,0,(seg_size+1)/2) < place+1){
			cout << i << " " << query(0,place+1,0,0,(seg_size+1)/2) << endl;
			ans += all[i].first;

			int j = seg_size/2 + place;
			seg[j]++;
			while(j > 0){
				j = (j-1) / 2;
				seg[j]++;
			}

		}
	}

	cout << ans << endl;

    
    return 0;
}*/


/*
//9
int gcd(int a, int b){
	if(a == 0 || b == 0) return 1;
	if(b > a) swap(a,b);
	if(a % b == 0) return b;
	return gcd(b, a%b);
}
int main(){
    
	int N,K;
	cin >> N >> K;
	int x[3000],y[3000];
	for(int i=0; i<N; i++){
		cin >> x[i] >> y[i];
	}

	map<pair<int,int> ,int> tmp;
	for(int i=0; i<N; i++){
		for(int j=i+1; j<N; j++){
			int x2 = x[j]-x[i];
			int y2 = y[j]-y[i];
			int g = gcd(x2,y2);
			x2 = x2 / g;
			y2 = y2 / g;
			if(x2 == 0) y2 = 1;
			if(y2 == 0) x2 = 1;

			tmp[make_pair(x2,y2)]++;
			if(tmp[make_pair(x2,y2)] >= K){
				cout << 1 << endl;
				return 0;
			}
		}
	}
	cout << 0 << endl;
    
    return 0;
}
*/


/*

//11
int main(){
    
	int K,N,Q;
	cin >> K >> N >> Q;
	int A[100000];
	set<int> change;
	int tmp = 1;
	int now = 0;
	for(int i=0; i<N; i++){
		cin >> A[i];
		if(A[i] == 0){
			tmp *= -1;
			change.insert(i);
		}
		else now += A[i];
		while(now < 1) now += K;
		while(now > K) now -= K;
	}

	for(int i=0; i<Q; i++){
		int L,R;
		cin >> L >> R;
		if(change.count(L) == 0 && change.count(R) == 0){
			auto itr=change.begin();
			int tmp = 1;
			while(*itr < L){
				itr++;
				tmp *= -1;
			}
			sum -= A[L-1];
		}
	}

    
    return 0;
}
*/

/*
int main(){
	int A, B, X;
	cin >> A >> B >> X;
	int ans = INT_MAX;
	for(int a=0; a<=40; a++){
		for(int b=0; b<=40; b++){
			if(1000*a + 500*b >= X) ans = min(ans, A*a+B*b);
		}
	}

	cout << ans << endl;

	return 0;
}
*/
accuracy: 1
time_ms: 30
memory_kb: 8736
final_rank: 14

code_snippet: #include <iostream>
#include <fstream>
#include <stdio.h>
#include <math.h>
#include <time.h>
#include <string>
#include <tuple>
#include <vector>
#include <map>
#include <list>
#include <set>
#include <stack>
#include <queue>
#include <cstdlib>
#include <algorithm>
#include <random>
#include <cassert>
using namespace std;
#define LL long long
#undef INT_MIN
#undef INT_MAX
#define INT_MIN -2147483648
#define INT_MAX 2147483647
#define LL_MIN -9223372036854775808
#define LL_MAX 9223372036854775807
#define ROOP() while (true)

#define MOD 1000000007

int N;
string s,t;
map<char, vector<int> > deguti; //文字firstが出口に指定されている星のリストsecond
int dp[100000];
int sum[100000]; //dp[]の値の累積和

int main(){
    
	cin >> N >> s >> t;
	string alpha = "abcdefghijklmnopqrstuvwxyz";
	vector<int> none;
	for(int i=0; i<alpha.size(); i++) deguti[alpha[i]] = none; //初期化
	for(int i=0; i<N; i++) deguti[t[i]].push_back(i);

    //DPの初期化
	dp[N-1] = 1;
	sum[N-1] = dp[N-1];
    //DPの計算処理
	for(int i=N-2; i>=0; i--){
		auto itr = upper_bound(deguti[s[i]].begin(), deguti[s[i]].end(), i);
		if(itr == deguti[s[i]].end()) dp[i] = 0; //ワープ装置に入っても出口がない
		else dp[i] = sum[*itr];

		itr = upper_bound(deguti[t[i]].begin(), deguti[t[i]].end(), i);
		if(itr == deguti[t[i]].end()) sum[i] = dp[i]; //現在地以降に現在地と同じ出口がない
		else sum[i] = (dp[i] + sum[*itr]) % MOD;
	}
	cout << dp[0] << endl;
    
    return 0;
}
accuracy: 1
time_ms: 20
memory_kb: 4496
final_rank: 4

code_snippet: #include<iostream>
#include<cstdio>
#include<cmath>
#include<algorithm>
#include<string.h>
using namespace std;
const int M=1000000007;
const int N_MAX=100000;

int n,dp[N_MAX+1][26];
string s,t;
int main(){
	cin>>n;
	cin>>s>>t;
	
	dp[0][s[0]-'a']=1;
	for(int i=1;i<n;i++){
		dp[i][s[i]-'a']=(dp[i][s[i]-'a']+dp[i-1][t[i]-'a'])%M;
		for(int j=0;j<26;j++)dp[i][j]=(dp[i][j]+dp[i-1][j])%M;		
	}
	
	cout<<dp[n-2][t[n-1]-'a']<<endl;
	return 0;
}
accuracy: 1
time_ms: 10
memory_kb: 13476
final_rank: 5

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

using i64 = int64_t;

constexpr i64 MOD = 1e9 + 7;

int main(){
    int n;
    cin >> n;
    string s, t;
    cin >> s >> t;
    vector<vector<i64>> dp(n, vector<i64>(26, 0));
    dp[0][s[0]-'a'] = 1;
    for(int i=1;i<n;++i){
        for(char c='a';c<='z';++c){
            dp[i][c-'a'] = dp[i-1][c-'a'];
        }
        if(i == n-1)break;
        dp[i][s[i]-'a'] += dp[i-1][t[i]-'a'];
        dp[i][s[i]-'a'] %= MOD;

        /*for(int i=0;i<n;++i){
            for(int j=0;j<26;++j){
                cerr << dp[i][j] << " ";
            }
            cerr << endl;
        }
        cerr << endl;
        */
    }

    cout << dp[n-1][t[n-1]-'a'] << endl;

    return 0;
}
accuracy: 1
time_ms: 10
memory_kb: 27416
final_rank: 16

code_snippet: #include<algorithm>
#include<bitset>
#include<cassert>
#include<cfloat>
#include<climits>
#include<cmath>
#include<deque>
#include<functional>
#include<iomanip>
#include<iostream>
#include<map>
#include<queue>
#include<set>
#include<stack>
#include<string>
#include<unordered_map>
#include<unordered_set>
#include<utility>
#include<vector>

using namespace std;

using lint = long long;
using P = pair<int, int>;
using LLP = pair<long long, long long>;

#define REP(i, x, n) for(int i = (x), i##_len = (int)(n) ; i < i##_len ; ++i)
#define rep(i, n) for(int i = 0, i##_len = (int)(n) ; i < i##_len ; ++i)
#define reps(i, n) for(int i = 1, i##_len = (int)(n) ; i <= i##_len ; ++i)
#define rrep(i, n) for(int i = (int)(n) - 1 ; i >= 0 ; --i)
#define rreps(i, n) for(int i = (int)(n) ; i > 0 ; --i)
#define SORT(x) sort((x).begin(), (x).end())
#define SORT_INV(x) sort((x).rbegin(), (x).rend())
#define REVERSE(x) reverse((x).begin(), (x).end())
#define TWINS(x) cout << ((x) ? "Yay!" : ":(") << '\n'
#define endl '\n'

constexpr int IINF = (1 << 30) - 1;
constexpr long long LLINF = 1LL << 61;
constexpr double EPS = 1e-10;

constexpr int dx4[] = {1, 0, -1, 0}, dy4[] = {0, 1, 0, -1};
constexpr int dx8[] = {1, 1, 0, -1, -1, -1, 0, 1}, dy8[] = {0, -1, -1, -1, 0, 1, 1, 1};

template<long long modulus>
class ModInt{
    long long num;

    long long mod(long long n){
        if(n < 0LL){
            n = (n % modulus) + modulus;
        }
        return n % modulus;
    }

    long long ext_gcd(long long a, long long b, long long &x, long long &y){
        if(b == 0LL){
            x = 1;
            y = 0;
            return a;
        }

        long long d = ext_gcd(b, a % b, y, x);
        y -= a / b * x;

        return d;
    }

    long long get_inv(long long n){
        long long x, y;
        ext_gcd(n, modulus, x, y);
        return mod(x);
    }

public:
    constexpr ModInt(const long long n = 0LL) noexcept : num(mod(n)) {}

    long long get(void){
        return num;
    }

    ModInt &operator+=(const ModInt &rhs){
        num += rhs.num;
        if(num >= modulus){
            num -= modulus;
        }
        return *this;
    }

    ModInt &operator-=(const ModInt &rhs){
        if(num < rhs.num){
            num += modulus;
        }
        num -= rhs.num;
        return *this;
    }

    ModInt &operator*=(const ModInt &rhs){
        num = num * rhs.num % modulus;
        return *this;
    }

    ModInt &operator/=(const ModInt &rhs){
        long long inv = get_inv(rhs.num);
        num = num * inv % modulus;
        return *this;
    }

    template<typename T>
    ModInt &operator+=(const T &rhs){
        return *this += ModInt(rhs);
    }

    template<typename T>
    ModInt &operator-=(const T &rhs){
        return *this -= ModInt(rhs);
    }

    template<typename T>
    ModInt &operator*=(const T &rhs){
        return *this *= ModInt(rhs);
    }

    template<typename T>
    ModInt &operator/=(const T &rhs){
        return *this /= ModInt(rhs);
    }

    template<typename T>
    ModInt operator+(const T &rhs) const {
        return ModInt(*this) += ModInt(rhs);
    }

    template<typename T>
    ModInt operator-(const T &rhs) const {
        return ModInt(*this) -= ModInt(rhs);
    }

    template<typename T>
    ModInt operator*(const T &rhs) const {
        return ModInt(*this) *= ModInt(rhs);
    }

    template<typename T>
    ModInt operator/(const T &rhs) const {
        return ModInt(*this) /= ModInt(rhs);
    }

    ModInt &operator=(const ModInt &rhs){
        num = rhs.num;
        return *this;
    }

    template<typename T>
    ModInt &operator=(const T &rhs){
        num = mod(rhs);
        return *this;
    }

    bool operator<(const ModInt &rhs) const {
        return num < rhs.num;
    }

    bool operator==(const ModInt &rhs) const {
        return num == rhs.num;
    }
};

template<long long modulus>
std::istream &operator>>(std::istream &lhs, ModInt<modulus> &rhs){
    long long val;
    lhs >> val;
    rhs = val;
    return lhs;
}

template<long long modulus>
std::ostream &operator<<(std::ostream &lhs, ModInt<modulus> rhs){
    lhs << rhs.get();
    return lhs;
}

using mint = ModInt<1000000007LL>;

template<typename T>
class CoordinateCompression{
    std::vector<T> dat;
    int s;
    int n;

public:
    CoordinateCompression(){}

    CoordinateCompression(const std::vector<T>& dat_, int s_ = 0, bool uni = true){
        build(dat_, s_, uni);
    }

    void build(const std::vector<T>& dat_, int s_ = 0, bool uni = true){
        dat = dat_;

        std::sort(dat.begin(), dat.end());
        if(uni){
            dat.erase(std::unique(dat.begin(), dat.end()), dat.end());
        }

        s = s_;

        n = (int)dat.size();

        return;
    }

    int get(T x){
        return (int)(std::lower_bound(dat.begin(), dat.end(), x) - dat.begin()) + s;
    }

    T restore(int k){
        return dat[k - s];
    }

    int size(void){
        return n;
    }
};

template<typename T>
class LazySegmentTree{
    int n;
    std::vector<T> node;
    std::vector<T> lazy;
    std::vector<int> length;
    int height;

    using F = std::function<T(T, T)>;
    using S = std::function<T(T, int)>;

    F f;
    F g;
    F h;
    S s;
    T id1;
    T id2;

    void evaluate(int k){
        if(lazy[k] == id2){
            return;
        }

        node[k] = g(node[k], s(lazy[k], length[k]));

        if(k < n){
            lazy[k << 1] = h(lazy[k << 1], lazy[k]);
            lazy[(k << 1) | 1] = h(lazy[(k << 1) | 1], lazy[k]);
        }

        lazy[k] = id2;

        return;
    }

    void evaluate(int l, int r){
        for(int i = height ; 0 < i ; --i){
            evaluate(l >> i);
            evaluate(r >> i);
        }

        return;
    }

public:
    LazySegmentTree(){}

    LazySegmentTree(int n_, F f_, F g_, F h_, T id1_, T id2_, S s_ = [](T x, int len){ return x; }){
        init(n_, f_, g_, h_, id1_, id2_, s_);
    }

    LazySegmentTree(const std::vector<T>& dat, F f_, F g_, F h_, T id1_, T id2_, S s_ = [](T x, int len){ return x; }){
        build(dat, f_, g_, h_, id1_, id2_, s_);
    }

    void init(int n_, F f_, F g_, F h_, T id1_, T id2_, S s_ = [](T x, int len){ return x; }){
        n = 1;
        height = 0;
        while(n < n_){
            n <<= 1;
            ++height;
        }

        f = f_;
        g = g_;
        h = h_;
        id1 = id1_;
        id2 = id2_;
        s = s_;

        node.assign(n << 1, id1);
        lazy.assign(n << 1, id2);

        length.assign(n << 1, 1);
        fill(length.begin() + n + n_, length.end(), 0);
        for(int i = n - 1 ; 0 < i ; --i){
            length[i] = length[i << 1] + length[(i << 1) | 1];
        }

        return;
    }

    void build(const std::vector<T>& dat, F f_, F g_, F h_, T id1_, T id2_, S s_ = [](T x, int len){ return x; }){
        int n_ = (int)dat.size();

        init(n_, f_, g_, h_, id1_, id2_, s_);

        for(int i = 0 ; i < n_ ; ++i){
            node[i + n] = dat[i];
        }
        for(int i = n - 1 ; 0 < i ; --i){
            node[i] = f(node[i << 1], node[(i << 1) | 1]);
        }

        return;
    }

    void update(int l, int r, T x){
        l += n;
        r += n - 1;

        int L = l;
        int R = r;

        evaluate(l, r);

        ++r;

        while(l < r){
            if(r & 1){
                --r;
                lazy[r] = h(lazy[r], x);
            }
            r >>= 1;

            if(l & 1){
                lazy[l] = h(lazy[l], x);
                ++l;
            }
            l >>= 1;
        }

        while(L >>= 1, R >>= 1, L){
            evaluate(L << 1);
            evaluate((L << 1) | 1);
            node[L] = f(node[L << 1], node[(L << 1) | 1]);

            evaluate(R << 1);
            evaluate((R << 1) | 1);
            node[R] = f(node[R << 1], node[(R << 1) | 1]);
        }

        return;
    }

    T get(int l, int r){
        l += n;
        r += n - 1;

        evaluate(l, r);

        ++r;

        T res = id1;
        while(l < r){
            if(r & 1){
                --r;
                evaluate(r);
                res = f(res, node[r]);
            }
            r >>= 1;

            if(l & 1){
                evaluate(l);
                res = f(res, node[l]);
                ++l;
            }
            l >>= 1;
        }

        return res;
    }
};

template<typename T>
bool chmax(T& a, T b){
    if(a < b){
        a = b;
        return true;
    }
    return false;
}

template<typename T>
bool chmin(T& a, T b){
    if(b < a){
        a = b;
        return true;
    }
    return false;
}

int main(){
    cin.tie(0);
    ios::sync_with_stdio(false);
    cout << fixed << setprecision(10);

    int n;
    cin >> n;

    string s, t;
    cin >> s >> t;

    vector< vector<int> > v(26);
    rep(i, n){
        v[t[i] - 'a'].emplace_back(i);
    }

    vector< CoordinateCompression<int> > c(26);
    rep(i, 26){
        c[i].build(v[i]);
    }

    vector< LazySegmentTree<mint> > seg(26);
    rep(i, 26){
        seg[i].init(c[i].size(), [](mint l, mint r){ return l + r; }, [](mint l, mint r){ return l + r; },
                    [](mint l, mint r){ return l + r; }, mint(0), mint(0), [](mint x, int len){ return x * len; });
    }

    seg[t[0] - 'a'].update(0, 1, mint(1));

    rep(i, n){
        int l = c[s[i] - 'a'].get(i);
        if(s[i] == t[i]){
            ++l;
        }
        if(l == c[s[i] - 'a'].size()){
            continue;
        }

        seg[s[i] - 'a'].update(l, c[s[i] - 'a'].size(), seg[t[i] - 'a'].get(c[t[i] - 'a'].get(i), c[t[i] - 'a'].get(i) + 1));
    }

    cout << seg[t[n - 1] - 'a'].get(c[t[n - 1] - 'a'].size() - 1, c[t[n - 1] - 'a'].size()) << endl;

    cout << flush;

    return 0;
}
accuracy: 1
time_ms: 60
memory_kb: 11344
final_rank: 18

code_snippet: #include <bits/stdc++.h>
using namespace std;
typedef long long ll;

ll my_pow(ll x, ll n) {
    if (n == 0) return 1;
    if (n % 2 == 0) return my_pow(x * x, n / 2);
    return x * my_pow(x, n - 1);
}

int main() {
    int N;
    cin >> N;
    string s, t;
    cin >> s >> t;
    ll mod = my_pow(10, 9) + 7;
    ll d[N][26]{};
    d[0][s[0] - 'a'] = 1;
    for (int i = 1; i < N; i++) {
        for (int j = 0; j < 26; j++) {
            d[i][j] = d[i - 1][j];
        }
        d[i][s[i] - 'a'] += d[i][t[i] - 'a'];
        d[i][s[i] - 'a'] %= mod;
    }
    cout << d[N - 2][t[N - 1] - 'a'] << "\n";
    return 0;
}
accuracy: 1
time_ms: 10
memory_kb: 23652
final_rank: 12

code_snippet: #include <iostream>
#include <math.h>
#include <algorithm>
#include <string>
using namespace std;

int change(char c) {
	if ('a' <= c && c <= 'z') {
		return (c - 'a');
	}
}
long long dp[100000][26]; //ｊ番目までの星で、入り口がiの星へのアクセスは何通りか
int main() {
	int N;
	cin >> N;
	string s,t;
	cin >> s >> t;
	for (int j = 0; j < N; j++) {
		if (j == 0) {
			for (int i = 0; i < 26; i++) {
				if (change(s[0]) == i) {
					dp[0][i] = 1;
				}
				else {
					dp[0][i] = 0;
				}
			}
		}
		else {
			for (int i = 0; i < 26; i++) {
				dp[j][i] = dp[j - 1][i]%1000000007;
			}
			dp[j][change(s[j])] = (dp[j][change(s[j])]+dp[j - 1][change(t[j])])%1000000007;
		}
	}
	cout << dp[N-2][change(t[N-1])] << endl;
	return 0;
}
accuracy: 1
time_ms: 10
memory_kb: 23616
final_rank: 11

code_snippet: #include<bits/stdc++.h>
using namespace std;
#define rep(i,N) for(int (i)=0;(i) < (N); (i)++)
#define all(V) V.begin(), V.end()
using i64 = int_fast64_t;
using P = pair<i64,i64>;
using uset = unordered_set<int>;

int main(){
    int N;
    cin >> N;
    string S,T;
    cin >> S >> T;

    vector<vector<int>> dp(100100, vector<int>(27, 0));
    dp[0][S[0] - 'a'] = 1;
    for(int i = 1; i < N; i++){
        for(char  c = 'a'; c <= 'z'; c++){
            dp[i][c - 'a'] = (dp[i-1][c - 'a'] % 1000000007);
        }
        if(i == N -1) continue;
        ((dp[i][S[i] - 'a'] += dp[i-1][T[i] -'a']) %= 1000000007);
    }

    cout << dp[N - 1][T[N-1] - 'a'] << endl;
}
accuracy: 1
time_ms: 10
memory_kb: 17964
final_rank: 9

code_snippet: #include <cctype>
#include <cerrno>
#include <cfloat>
#include <ciso646>
#include <climits>
#include <clocale>
#include <cmath>
#include <csetjmp>
#include <csignal>
#include <cstdarg>
#include <cstddef>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>

#include <algorithm>
#include <bitset>
#include <complex>
#include <deque>
#include <exception>
#include <fstream>
#include <functional>
#include <iomanip>
#include <ios>
#include <iosfwd>
#include <iostream>
#include <istream>
#include <iterator>
#include <limits>
#include <list>
#include <locale>
#include <map>
#include <memory>
#include <new>
#include <numeric>
#include <ostream>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <stdexcept>
#include <streambuf>
#include <string>
#include <typeinfo>
#include <utility>
#include <valarray>
#include <vector>
#include <regex>
#define ull unsigned long long
#define REP(i,n) for(int i = 0; i < n; i++)
#define FOR(i,j,n) for(int i = j; i < n; i++)
#define RFOR(i,j,n) for(int i = j-1; i >= n; i--)
#define PREC(n) fixed << setprecision(n)
#define print_array(v) REP(__k, v.size()) { cerr << v[__k]; if(__k != v.size()-1) cerr << " "; else cerr << endl; }
using namespace std;

int d(char c) { return c -  'a'; }

int main() {
	cin.tie(0);
	ios::sync_with_stdio(false);

	const ull MOD = 1000000007;

	int N;
	string s, t;
	cin >> N >> s >> t;

	vector<vector<ull> > dp(N, vector<ull>(26, 0));
	dp[0][d(s[0])] = 1;
	FOR(i, 1, N) {
		dp[i][d(s[i])] += dp[i-1][d(t[i])]; // 来られるなら追加する
		dp[i][d(s[i])] %= MOD;
		// cerr << d('z') << endl;
		REP(j, 26) {
			dp[i][j] += dp[i-1][j]; // 継承
			dp[i][j] %= MOD;
		}
	}
	cout << dp[N-2][d(t[N-1])] << endl;
	//REP(i, N) print_array(dp[i]);
}
accuracy: 1
time_ms: 10
memory_kb: 27156
final_rank: 15

code_snippet: #include <cctype>
#include <cerrno>
#include <cfloat>
#include <ciso646>
#include <climits>
#include <clocale>
#include <cmath>
#include <csetjmp>
#include <csignal>
#include <cstdarg>
#include <cstddef>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>

#include <algorithm>
#include <bitset>
#include <complex>
#include <deque>
#include <exception>
#include <fstream>
#include <functional>
#include <iomanip>
#include <ios>
#include <iosfwd>
#include <iostream>
#include <istream>
#include <iterator>
#include <limits>
#include <list>
#include <locale>
#include <map>
#include <memory>
#include <new>
#include <numeric>
#include <ostream>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <stdexcept>
#include <streambuf>
#include <string>
#include <typeinfo>
#include <utility>
#include <valarray>
#include <vector>
#include <regex>
#define ull unsigned long long
#define REP(i,n) for(int i = 0; i < n; i++)
#define FOR(i,j,n) for(int i = j; i < n; i++)
#define RFOR(i,j,n) for(int i = j-1; i >= n; i--)
#define PREC(n) fixed << setprecision(n)
#define print_array(v) REP(__k, v.size()) { cerr << v[__k]; if(__k != v.size()-1) cerr << " "; else cerr << endl; }
using namespace std;

int d(char c) { return c -  'a'; }

int main() {
	cin.tie(0);
	ios::sync_with_stdio(false);

	const ull MOD = 1000000007;

	int N;
	string s, t;
	cin >> N >> s >> t;

	vector<vector<ull> > dp(N, vector<ull>('z'-'a', 0));
	dp[0][d(s[0])] = 1;
	FOR(i, 1, N) {
		dp[i][d(s[i])] += dp[i-1][d(t[i])]; // 来られるなら追加する
		dp[i][d(s[i])] %= MOD;
		// cerr << d('z') << endl;
		REP(j, d('z')) {
			dp[i][j] += dp[i-1][j]; // 継承
			dp[i][j] %= MOD;
		}
	}
	cout << dp[N-2][d(t[N-1])] << endl;
	//REP(i, N) print_array(dp[i]);
}
accuracy: 0.8333333333333334
time_ms: 10
memory_kb: 25700
final_rank: 20

code_snippet: #include "bits/stdc++.h"

using namespace std;
using uint = unsigned int;
using int64 = long long;
using i64 = int64;
using uint64 = unsigned long long;
using vint = vector<int>;
using vint64 = vector<int64>;
template<typename T>
using p_que = priority_queue<T>;
#define rep(i,N) for(int i=0;i<(int)(N);++i)
#define rep1(i,N) for(int i=1;i<=(int)(N);++i)
#define fs first
#define sc second
#define eb emplace_back
#define all(x) x.begin(),x.end()

template<typename T>
vector<T> make_v(size_t a, T b) { return vector<T>(a, b); }
template<typename... Ts>
auto make_v(size_t a, Ts... ts) {
	return vector<decltype(make_v(ts...))>(a, make_v(ts...));
}

template<class T> ostream& operator<<(ostream& os, const vector<T>& v) {
	os << "[";
	for (auto& e : v) os << e << ", ";
	return os << "]";
}

template<class T, class U> ostream& operator<<(ostream& os, const pair<T, U> p) {
	return os << "P(" << p.first << ", " << p.second << ")";
}

template<class T, class U> ostream& operator<<(ostream& os, const map<T, U>& mp) {
	os << "{";
	for (auto& e : mp) os << e << " ";
	return os << "}";
}

void Main();
signed main() {
	cin.tie(nullptr);
	ios::sync_with_stdio(false);
	cout << fixed << setprecision(20);
	Main();
}

/* Cut from here! */

template <uint mod> struct ModInt {
	uint x;
	ModInt(int64_t y = 0) : x(y >= 0 ? y % mod : (mod - (-y) % mod) % mod) {}
	ModInt& operator+=(const ModInt& p) {
		if ((x += p.x) >= mod) x -= mod;
		return *this;
	}
	ModInt& operator-=(const ModInt& p) {
		x = (int)(1ll * x * p.x % mod);
		return *this;
	}
	ModInt& operator/=(const ModInt& p) {
		*this *= p.inverse();
		return *this;
	}
	ModInt operator-() const {
		return ModInt(-x);
	}
	ModInt operator+(const ModInt& p) const {
		return ModInt(*this) += p;
	}
	ModInt operator-(const ModInt& p) const {
		return ModInt(*this) -= p;
	}
	ModInt operator*(const ModInt& p) const {
		return ModInt(*this) *= p;
	}
	ModInt operator/(const ModInt& p) const {
		return ModInt(*this) /= p;
	}
	bool operator==(const ModInt& p) const {
		return x == p.x;
	}
	bool operator!=(const ModInt& p) const {
		return x != p.x;
	}
	ModInt inverse() const {
		int a = x, b = mod, u = 1, v = 0, t;
		while (b > 0) {
			t = a / b;
			swap(a -= t * b, b);
			swap(u -= t * v, v);
		}
		return ModInt(u);
	}
	ModInt pow(int64_t n) const {
		ModInt ret(1), mul(x);
		while (n > 0) {
			if (n & 1) ret *= mul;
			mul *= mul;
			n >>= 1;
		}return ret;
	}
	friend ostream& operator<<(ostream& os, const ModInt& p) {
		return os << p.x;
	}
};


//#define int long long
const uint MOD = 1e9 + 7;

void Main() {
	int N; cin >> N;
	string s, t; cin >> s >> t;

	using mint = ModInt<MOD>;
	vector<mint> dp(N);
	auto sum = make_v(N, 30, mint(0));

	dp[0] = 1;
	sum[0][s[0] - 'a'] = 1;
	for (int i = 1; i < N; ++i) {
		char c = t[i];
		dp[i] += sum[i - 1][c - 'a'];
		char e = s[i];
		sum[i][e - 'a'] += dp[i];
		for (char ch = 'a'; ch <= 'z'; ++ch) {
			sum[i][ch - 'a'] += sum[i - 1][ch - 'a'];
		}
	}

	cout << dp[N - 1] << endl;
}
accuracy: 1
time_ms: 10
memory_kb: 18200
final_rank: 10

code_snippet: #pragma GCC target("sse,sse2,sse3,sse3,sse4,popcnt,abm,mmx,avx,tune=native")
#pragma GCC optimize("Ofast")

#include <bits/stdc++.h>

using namespace std;

using ll = long long;

ll mod = 1e9+7;

int main(){
    int N;cin >> N;
    string s,t;cin >> s >> t;
    map<char, ll> mp;
    mp[s.front()]++;
    for(int i = 1;i < N;i++){
        if(i == N-1 && s[i] && t[i])break;
        mp[s[i]] %= mod;
        mp[t[i]] %= mod;
        mp[s[i]] += mp[t[i]];
        mp[s[i]] %= mod;
    }
    cout<<mp[t.back()] % mod<<endl;
}
accuracy: 1
time_ms: 10
memory_kb: 3284
final_rank: 1