#pragma GCC optimize(3)
#include<bits/stdc++.h>
#include<unordered_map>
using namespace std;

#define sc scanf
#define Min(x, y) x = min(x, y)
#define Max(x, y) x = max(x, y)
#define ALL(x) (x).begin(),(x).end()
#define SZ(x) ((int)(x).size())
#define pir pair <ll, int>
#define MK(x, y) make_pair(x, y)
#define MEM(x, b) memset(x, b, sizeof(x))
#define MPY(x, b) memcpy(x, b, sizeof(x))
#define lowbit(x) ((x) & -(x))
#define P2(x) ((x) * (x))

typedef long long ll;
const int Mod = 1e9 + 7;
const int N = 1e3 + 100;
const int INF = 0x3f3f3f3f;
const ll LINF = 0x3f3f3f3f3f3f3f3f;
inline ll dpow(ll a, ll b){ ll r = 1, t = a; while (b){ if (b & 1)r = (r*t) % Mod; b >>= 1; t = (t*t) % Mod; }return r; }
inline ll fpow(ll a, ll b){ ll r = 1, t = a; while (b){ if (b & 1)r = (r*t); b >>= 1; t = (t*t); }return r; }

struct Edge
{
	int u, prv;  // 当前点，出发点
	ll w, t;     // 距离，花费
	bool operator < (const Edge &oth) const {
		if (t == oth.t)
			return w > oth.w;
		else
			return t > oth.t;
	}
};
vector <pir> G[N];
ll d[N], c[N];
int n, m, sp, tp;
bool vis[N][N];

ll Dijkstra() {
	if (sp == tp)
		return 0;
	priority_queue <Edge> q;
	q.push({ sp, sp, 0, c[sp] });

	ll ans = LINF;
	while (!q.empty()) {
		Edge now = q.top();
		q.pop();
		int u = now.u;
		int prv = now.prv;
		if (u == tp)
			Min(ans, now.t);
		if (vis[u][prv])
			continue;
		vis[u][prv] = true;

		q.push({ u, u, 0, now.t + c[u] });
		for (auto it : G[u]) {
			int v = it.second; ll w = it.first;
			if (now.w + w <= d[prv])
				q.push({ v, prv, now.w + w, now.t });
		}
	}
	if (ans == LINF)
		return -1;
	return ans;
}

int main()
{
	cin >> n >> m >> sp >> tp;
	for (int i = 0; i < m; i++) {
		int u, v; ll w;
		sc("%d %d %lld", &u, &v, &w);
		G[u].push_back({ w, v });
		G[v].push_back({ w, u });
	}
	for (int i = 1; i <= n; i++)
		sc("%lld %lld", &d[i], &c[i]);

	printf("%lld\n", Dijkstra());
	return 0;  // 改数组大小!!!用pair记得改宏定义!!!
}


#pragma GCC optimize(3)
#include<bits/stdc++.h>
#include<unordered_map>
using namespace std;

#define sc scanf
#define Min(x, y) x = min(x, y)
#define Max(x, y) x = max(x, y)
#define ALL(x) (x).begin(),(x).end()
#define SZ(x) ((int)(x).size())
#define pir pair <ll, int>
#define MK(x, y) make_pair(x, y)
#define MEM(x, b) memset(x, b, sizeof(x))
#define MPY(x, b) memcpy(x, b, sizeof(x))
#define lowbit(x) ((x) & -(x))
#define P2(x) ((x) * (x))

typedef long long ll;
const int Mod = 1e9 + 7;
const int N = 1e3 + 100;
const int INF = 0x3f3f3f3f;
const ll LINF = 0x3f3f3f3f3f3f3f3f;
inline ll dpow(ll a, ll b){ ll r = 1, t = a; while (b){ if (b & 1)r = (r*t) % Mod; b >>= 1; t = (t*t) % Mod; }return r; }
inline ll fpow(ll a, ll b){ ll r = 1, t = a; while (b){ if (b & 1)r = (r*t); b >>= 1; t = (t*t); }return r; }

struct Edge
{
	int u, prv;  // 当前点，出发点
	ll w, t;     // 距离，花费
	bool operator < (const Edge &oth) const {
		return t > oth.t;
	}
};
vector <pir> G[N];
ll d[N], c[N];
int n, m, sp, tp;
bool vis[N][N];

ll Dijkstra() {
	if (sp == tp)
		return 0;
	priority_queue <Edge> q;
	q.push({ sp, sp, 0, c[sp] });

	while (!q.empty()) {
		Edge now = q.top();
		q.pop();
		int u = now.u;
		int prv = now.prv;
		if (u == tp)
			return now.t;
		if (vis[u][prv])
			continue;
		vis[u][prv] = true;

		q.push({ u, u, 0, now.t + c[u] });
		for (auto it : G[u]) {
			int v = it.second; ll w = it.first;
			if (now.w + w <= d[prv])
				q.push({ v, prv, now.w + w, now.t });
		}
	}
	return -1;
}

int main()
{
	cin >> n >> m >> sp >> tp;
	for (int i = 0; i < m; i++) {
		int u, v; ll w;
		sc("%d %d %lld", &u, &v, &w);
		G[u].push_back({ w, v });
		G[v].push_back({ w, u });
	}
	for (int i = 1; i <= n; i++)
		sc("%lld %lld", &d[i], &c[i]);

	printf("%lld\n", Dijkstra());
	return 0;  // 改数组大小!!!用pair记得改宏定义!!!
}


#pragma GCC optimize(3)
#include<bits/stdc++.h>
#include<unordered_map>
using namespace std;

#define sc scanf
#define Min(x, y) x = min(x, y)
#define Max(x, y) x = max(x, y)
#define ALL(x) (x).begin(),(x).end()
#define SZ(x) ((int)(x).size())
#define pir pair <ll, int>
#define MK(x, y) make_pair(x, y)
#define MEM(x, b) memset(x, b, sizeof(x))
#define MPY(x, b) memcpy(x, b, sizeof(x))
#define lowbit(x) ((x) & -(x))
#define P2(x) ((x) * (x))

typedef long long ll;
const int Mod = 1e9 + 7;
const int N = 1e3 + 100;
const int INF = 0x3f3f3f3f;
const ll LINF = 0x3f3f3f3f3f3f3f3f;
inline ll dpow(ll a, ll b){ ll r = 1, t = a; while (b){ if (b & 1)r = (r*t) % Mod; b >>= 1; t = (t*t) % Mod; }return r; }
inline ll fpow(ll a, ll b){ ll r = 1, t = a; while (b){ if (b & 1)r = (r*t); b >>= 1; t = (t*t); }return r; }

struct Edge
{
	int u, prv;  // 当前点，出发点
	ll w, t;     // 距离，花费
	bool operator < (const Edge &oth) const {
		if (t == oth.t)
			return w > oth.w;
		else
			return t > oth.t;
	}
};
vector <pir> G[N];
ll d[N], c[N];
int n, m, sp, tp;
bool vis[N][N];

ll Dijkstra() {
	if (sp == tp)
		return 0;
	priority_queue <Edge> q;
	q.push({ sp, sp, 0, c[sp] });

	while (!q.empty()) {
		Edge now = q.top();
		q.pop();
		int u = now.u;
		int prv = now.prv;
		if (u == tp)
			return now.t;
		if (vis[u][prv])
			continue;
		vis[u][prv] = true;

		q.push({ u, u, 0, now.t + c[u] });
		for (auto it : G[u]) {
			int v = it.second; ll w = it.first;
			if (now.w + w <= d[prv])
				q.push({ v, prv, now.w + w, now.t });
		}
	}
	return -1;
}

int main()
{
	cin >> n >> m >> sp >> tp;
	for (int i = 0; i < m; i++) {
		int u, v; ll w;
		sc("%d %d %lld", &u, &v, &w);
		G[u].push_back({ w, v });
		G[v].push_back({ w, u });
	}
	for (int i = 1; i <= n; i++)
		sc("%lld %lld", &d[i], &c[i]);

	printf("%lld\n", Dijkstra());
	return 0;  // 改数组大小!!!用pair记得改宏定义!!!
}


#pragma GCC optimize(3)
#include<bits/stdc++.h>
#include<unordered_map>
using namespace std;

#define sc scanf
#define Min(x, y) x = min(x, y)
#define Max(x, y) x = max(x, y)
#define ALL(x) (x).begin(),(x).end()
#define SZ(x) ((int)(x).size())
#define pir pair <ll, int>
#define MK(x, y) make_pair(x, y)
#define MEM(x, b) memset(x, b, sizeof(x))
#define MPY(x, b) memcpy(x, b, sizeof(x))
#define lowbit(x) ((x) & -(x))
#define P2(x) ((x) * (x))

typedef long long ll;
const int Mod = 1e9 + 7;
const int N = 1e3 + 100;
const int INF = 0x3f3f3f3f;
const ll LINF = 0x3f3f3f3f3f3f3f3f;
inline ll dpow(ll a, ll b){ ll r = 1, t = a; while (b){ if (b & 1)r = (r*t) % Mod; b >>= 1; t = (t*t) % Mod; }return r; }
inline ll fpow(ll a, ll b){ ll r = 1, t = a; while (b){ if (b & 1)r = (r*t); b >>= 1; t = (t*t); }return r; }

struct Edge
{
	int u, prv;  // 当前点，出发点
	ll w, t;
	bool operator < (const Edge &oth) const {
		return t > oth.t;
	}
};
vector <pir> G[N];
ll cost[N], d[N], c[N];
int n, m, sp, tp;
bool vis[N];

ll Dijkstra(int x) {
	if (x == tp)
		return 0;
	priority_queue <Edge> q;
	MEM(cost, LINF);
	q.push({ x, x, c[x], 0 });
	cost[x] = c[x];

	while (!q.empty()) {
		Edge now = q.top();
		q.pop();
		int u = now.u;
		int prv = now.prv;
		if (u == tp)
			return cost[tp];
		if (vis[u])
			continue;
		vis[u] = true;

		for (auto it : G[u]) {
			int v = it.second; ll w = it.first;
			if (now.w + w <= d[prv] && cost[v] > cost[u]) {  // 接着跑
				cost[v] = cost[u];
				q.push({ v, prv, now.w + w, cost[v] });
			}
			if (cost[v] > cost[u] + c[v]) {
				cost[v] = cost[u] + c[v];
				q.push({ v, v, 0, cost[v] });
			}
		}
	}
}

int main()
{
	cin >> n >> m >> sp >> tp;
	for (int i = 0; i < m; i++) {
		int u, v; ll w;
		sc("%d %d %lld", &u, &v, &w);
		G[u].push_back({ w, v });
		G[v].push_back({ w, u });
	}
	for (int i = 1; i <= n; i++)
		sc("%lld %lld", &d[i], &c[i]);

	printf("%lld\n", Dijkstra(sp));
	return 0;  // 改数组大小!!!用pair记得改宏定义!!!
}


#include <bits/stdc++.h>
#define LL long long
#define mp make_pair
#define pb push_back
#define INF (1<<29)
using namespace std;
typedef pair<int,int>pii;
int n,m,fx,lx;
vector<pii>G[1010];
LL d[1010][1010];
bool vis[1010];
LL co[1010];
int t[1010],c[1010];
void dijkstra(int s){
	priority_queue<pii,vector<pii>,greater<pii> >pq;
	fill(d[s]+1,d[s]+n+1,INF);
	d[s][s]=0;
	pq.push(mp(s,0));
	while(!pq.empty()){
		pii p=pq.top();
		pq.pop();
		int v=p.first;
		if(d[s][v]<p.second)continue;
		for(int i=0;i<G[v].size();i++){
			pii e=G[v][i];
			if(d[s][e.first]>d[s][v]+e.second){
				d[s][e.first]=d[s][v]+e.second;
				pq.push(mp(e.first,d[s][e.first]));
			}
		}
	}
}
bool flg=0;
void dfs(int x,LL cost){
	if(co[x]&&co[x]<cost)return;
//	cout<<x<<' '<<cost<<endl;
	co[x]=cost;
	if(x==lx)flg=1;
	for(int i=1;i<=n;i++){
		if(i==x)continue;
		if(d[x][i]>t[x])continue;
		dfs(i,cost+c[x]);
	}
}
int main(){
	cin>>n>>m>>fx>>lx;
	for(int i=1;i<=m;i++){
		int x,y,z;
		cin>>x>>y>>z;
		G[x].pb(mp(y,z));
		G[y].pb(mp(x,z));
	}
	for(int i=1;i<=n;i++)cin>>t[i]>>c[i];
	if(fx==lx){
		puts("0");
		return 0;
	}
	for(int i=1;i<=n;i++)dijkstra(i);
//	for(int i=1;i<=n;i++){
//		for(int j=1;j<=n;j++)cout<<d[i][j]<<' ';
//		puts("");
//	}
	dfs(fx,0);
	if(!flg)puts("-1");
	else cout<<co[lx]<<endl;
	return 0;
}


#include <bits/stdc++.h>
#define LL long long
#define mp make_pair
#define pb push_back
#define INF (1<<29)
using namespace std;
typedef pair<int,int>pii;
typedef pair<LL,LL>pll;
int n,m,fx,lx;
vector<pll>G[1010];
LL d[1010][1010];
bool vis[1010];
LL co[1010];
int t[1010],c[1010];
void dijkstra(int s){
	priority_queue<pll,vector<pll>,greater<pll> >pq;
	fill(d[s]+1,d[s]+n+1,INF);
	d[s][s]=0;
	pq.push(mp(s,0));
	while(!pq.empty()){
		pll p=pq.top();
		pq.pop();
		LL v=p.first;
		if(d[s][v]<p.second)continue;
		for(int i=0;i<G[v].size();i++){
			pii e=G[v][i];
			if(d[s][e.first]>d[s][v]+e.second){
				d[s][e.first]=d[s][v]+e.second;
				pq.push(mp(e.first,d[s][e.first]));
			}
		}
	}
}
bool flg=0;
void dfs(int x,LL cost){
	if(vis[x])return;
	if(co[x]&&co[x]<cost)return;
//	cout<<x<<' '<<cost<<endl;
	co[x]=cost;
	vis[x]=1;
	if(x==lx)flg=1;
	for(int i=1;i<=n;i++){
		if(i==x)continue;
		if(d[x][i]>t[x])continue;
		dfs(i,cost+c[x]);
	}
	vis[x]=0;
}
inline LL read_long(){
	LL t=1,x=0;
	char ch=getchar();
	while(!isdigit(ch)&&ch!='-')ch=getchar();
	if(ch=='-')t=-1,ch=getchar();
	while(isdigit(ch)){
		x=(x<<1)+(x<<3)+ch-'0';
		ch=getchar();
	}
	return x*t;
}
inline int read_int(){
	int t=1,x=0;
	char ch=getchar();
	while(!isdigit(ch)&&ch!='-')ch=getchar();
	if(ch=='-')t=-1,ch=getchar();
	while(isdigit(ch)){
		x=(x<<1)+(x<<3)+ch-'0';
		ch=getchar();
	}
	return x*t;
}
int main(){
	n=read_int(),m=read_int(),fx=read_int(),lx=read_int();
	for(int i=1;i<=m;i++){
		int x=read_int(),y=read_int();
		LL z=read_long();
		G[x].pb(mp(y,z));
		G[y].pb(mp(x,z));
	}
	for(int i=1;i<=n;i++)t[i]=read_int(),c[i]=read_int();
	if(fx==lx){
		puts("0");
		return 0;
	}
	for(int i=1;i<=n;i++)dijkstra(i);
//	for(int i=1;i<=n;i++){
//		for(int j=1;j<=n;j++)cout<<d[i][j]<<' ';
//		puts("");
//	}
	dfs(fx,0);
	if(!flg)puts("-1");
	else cout<<co[lx]<<endl;
	return 0;
}


#pragma comment(linker,"STACK:8192000000,8192000000")
#pragma GCC optimize(3)
#include <iostream>
#include <stdio.h>
#include <vector>
#include <set>
#define LL long long
#define mp make_pair
#define pb push_back
#define INF (LL)1e18
using namespace std;
typedef pair<int,int>pii;
typedef pair<LL,LL>pll;
int n,m,fx,lx;
vector<pair<LL,LL> >G[1010];
vector<pair<LL,LL> >G2[1010];
LL d[1010][1010];
bool vis[1010];
LL co[1010];
int t[1010],c[1010];
inline LL read_long(){
	LL t=1,x=0;
	char ch=getchar();
	while(!isdigit(ch)&&ch!='-')ch=getchar();
	if(ch=='-')t=-1,ch=getchar();
	while(isdigit(ch)){
		x=(x<<1)+(x<<3)+ch-'0';
		ch=getchar();
	}
	return x*t;
}
inline int read_int(){
	int t=1,x=0;
	char ch=getchar();
	while(!isdigit(ch)&&ch!='-')ch=getchar();
	if(ch=='-')t=-1,ch=getchar();
	while(isdigit(ch)){
		x=(x<<1)+(x<<3)+ch-'0';
		ch=getchar();
	}
	return x*t;
}
void dijkstra(int s,vector<pair<LL,LL> >G[1010]){
	set<pair<LL,LL> >pq;
	fill(d[s]+1,d[s]+n+1,INF);
	d[s][s]=0;
	pq.insert(mp(0,s));
	while(!pq.empty()){
		LL v=pq.begin()->second;
		pq.erase(pq.begin());
		for(int i=0;i<G[v].size();i++){
			pair<LL,LL> e=G[v][i];
			LL p=e.second,to=e.first;
			if(d[s][to]>d[s][v]+p){
				pq.erase(mp(d[s][to],to));
				d[s][to]=d[s][v]+p;
				pq.insert(mp(d[s][to],to));
			}
		}
	}
}
bool flg=0;
void dfs(int x,LL cost){
	if(vis[x])return;
	if(co[x]<cost)return;
//	cout<<x<<' '<<cost<<endl;
	co[x]=cost;
	vis[x]=1;
	if(x==lx)flg=1;
	for(int i=1;i<=n;i++){
		if(i==x)continue;
		if(d[x][i]<=t[x])dfs(i,cost+c[x]);
	}
	vis[x]=0;
}
int main(){
//	freopen("ball.txt","r",stdin);
	n=read_int(),m=read_int();
	fx=read_int(),lx=read_int();
	for(int i=1;i<=m;i++){
		int x=read_int(),y=read_int();
		LL z=read_long();
		G[x].pb(mp(y,z));
		G[y].pb(mp(x,z));
	}
	fill(co+1,co+n+1,INF);
	for(int i=1;i<=n;i++){
		t[i]=read_int(),c[i]=read_int();
	}
//	system("pause");
	if(fx==lx){
		puts("0");
		return 0;
	}
	for(int i=1;i<=n;i++)dijkstra(i,G);
//	system("pause");
//	for(int i=1;i<=n;i++){
//		for(int j=1;j<=n;j++)cout<<d[i][j]<<' ';
//		puts("");
//	}
	for(int i=1;i<=n;i++){
		for(int j=1;j<=n;j++)if(d[i][j]<=t[i])G2[i].pb(mp(j,c[i]));
	}
	dijkstra(fx,G2);
//	dfs(fx,0);
	if(!d[fx][lx])puts("-1");
	else cout<<d[fx][lx]<<endl;
	return 0;
}


#pragma comment(linker,"STACK:8192000000,8192000000")
#pragma GCC optimize(3)
#include <iostream>
#include <stdio.h>
#include <vector>
#include <set>
#define LL long long
#define mp make_pair
#define pb push_back
#define INF (LL)1e18
using namespace std;
typedef pair<int,int>pii;
typedef pair<LL,LL>pll;
int n,m,fx,lx;
vector<pair<LL,LL> >G[1010];
LL d[1010][1010];
bool vis[1010];
LL co[1010];
int t[1010],c[1010];
void dijkstra(int s){
	set<pair<LL,LL> >pq;
	fill(d[s]+1,d[s]+n+1,INF);
	d[s][s]=0;
	pq.insert(mp(0,s));
	while(!pq.empty()){
		LL v=pq.begin()->second;
		pq.erase(pq.begin());
		for(int i=0;i<G[v].size();i++){
			pair<LL,LL> e=G[v][i];
			LL p=e.second,to=e.first;
			if(d[s][to]>d[s][v]+p){
				pq.erase(mp(d[s][to],to));
				d[s][to]=d[s][v]+p;
				pq.insert(mp(d[s][to],to));
			}
		}
	}
}
bool flg=0;
void dfs(int x,LL cost){
	if(vis[x])return;
	if(co[x]&&co[x]<cost)return;
//	cout<<x<<' '<<cost<<endl;
	co[x]=cost;
	vis[x]=1;
	if(x==lx)flg=1;
	for(int i=1;i<=n;i++){
		if(i==x)continue;
		if(d[x][i]<=t[x])dfs(i,cost+c[x]);
	}
	vis[x]=0;
}
inline LL read_long(){
	LL t=1,x=0;
	char ch=getchar();
	while(!isdigit(ch)&&ch!='-')ch=getchar();
	if(ch=='-')t=-1,ch=getchar();
	while(isdigit(ch)){
		x=(x<<1)+(x<<3)+ch-'0';
		ch=getchar();
	}
	return x*t;
}
inline int read_int(){
	int t=1,x=0;
	char ch=getchar();
	while(!isdigit(ch)&&ch!='-')ch=getchar();
	if(ch=='-')t=-1,ch=getchar();
	while(isdigit(ch)){
		x=(x<<1)+(x<<3)+ch-'0';
		ch=getchar();
	}
	return x*t;
}
int main(){
//	freopen("ball.txt","r",stdin);
	n=read_int(),m=read_int();
	fx=read_int(),lx=read_int();
	for(int i=1;i<=m;i++){
		int x=read_int(),y=read_int();
		LL z=read_long();
		G[x].pb(mp(y,z));
		G[y].pb(mp(x,z));
	}
	for(int i=1;i<=n;i++)t[i]=read_int(),c[i]=read_int();
//	system("pause");
	if(fx==lx){
		puts("0");
		return 0;
	}
	for(int i=1;i<=n;i++)dijkstra(i);
//	system("pause");
//	for(int i=1;i<=n;i++){
//		for(int j=1;j<=n;j++)cout<<d[i][j]<<' ';
//		puts("");
//	}
	dfs(fx,0);
	if(!flg)puts("-1");
	else cout<<co[lx]<<endl;
	return 0;
}


#include <bits/stdc++.h>
#define LL long long
#define mp make_pair
#define pb push_back
#define INF (1<<29)
using namespace std;
typedef pair<int,int>pii;
int n,m,fx,lx;
vector<pii>G[1010];
LL d[1010][1010];
bool vis[1010];
LL co[1010];
int t[1010],c[1010];
void dijkstra(int s){
	priority_queue<pii,vector<pii>,greater<pii> >pq;
	fill(d[s]+1,d[s]+n+1,INF);
	d[s][s]=0;
	pq.push(mp(s,0));
	while(!pq.empty()){
		pii p=pq.top();
		pq.pop();
		int v=p.first;
		if(d[s][v]<p.second)continue;
		for(int i=0;i<G[v].size();i++){
			pii e=G[v][i];
			if(d[s][e.first]>d[s][v]+e.second){
				d[s][e.first]=d[s][v]+e.second;
				pq.push(mp(e.first,d[s][e.first]));
			}
		}
	}
}
bool flg=0;
void dfs(int x,LL cost){
	if(co[x]&&co[x]<cost)return;
//	cout<<x<<' '<<cost<<endl;
	co[x]=cost;
	if(x==lx)flg=1;
	for(int i=1;i<=n;i++){
		if(i==x)continue;
		if(d[x][i]>t[x])continue;
		dfs(i,cost+c[x]);
	}
}
int main(){
	cin>>n>>m>>fx>>lx;
	for(int i=1;i<=m;i++){
		int x,y,z;
		cin>>x>>y>>z;
		G[x].pb(mp(y,z));
		G[y].pb(mp(x,z));
	}
	for(int i=1;i<=n;i++)cin>>t[i]>>c[i];
	for(int i=1;i<=n;i++)dijkstra(i);
//	for(int i=1;i<=n;i++){
//		for(int j=1;j<=n;j++)cout<<d[i][j]<<' ';
//		puts("");
//	}
	dfs(fx,0);
	if(!flg)puts("-1");
	else cout<<co[lx]<<endl;
	return 0;
}


#pragma comment(linker,"STACK:8192000000,8192000000")
#pragma GCC optimize(3)
#include <iostream>
#include <stdio.h>
#include <vector>
#include <set>
#define LL long long
#define mp make_pair
#define pb push_back
#define INF (LL)1e18
using namespace std;
typedef pair<int,int>pii;
typedef pair<LL,LL>pll;
int n,m,fx,lx;
vector<pair<LL,LL> >G[1010];
vector<pair<LL,LL> >G2[1010];
LL d[1010][1010];
bool vis[1010];
LL co[1010];
int t[1010],c[1010];
inline LL read_long(){
	LL t=1,x=0;
	char ch=getchar();
	while(!isdigit(ch)&&ch!='-')ch=getchar();
	if(ch=='-')t=-1,ch=getchar();
	while(isdigit(ch)){
		x=(x<<1)+(x<<3)+ch-'0';
		ch=getchar();
	}
	return x*t;
}
inline int read_int(){
	int t=1,x=0;
	char ch=getchar();
	while(!isdigit(ch)&&ch!='-')ch=getchar();
	if(ch=='-')t=-1,ch=getchar();
	while(isdigit(ch)){
		x=(x<<1)+(x<<3)+ch-'0';
		ch=getchar();
	}
	return x*t;
}
void dijkstra(int s,vector<pair<LL,LL> >G[1010]){
	set<pair<LL,LL> >pq;
	fill(d[s]+1,d[s]+n+1,INF);
	d[s][s]=0;
	pq.insert(mp(0,s));
	while(!pq.empty()){
		LL v=pq.begin()->second;
		pq.erase(pq.begin());
		for(int i=0;i<G[v].size();i++){
			pair<LL,LL> e=G[v][i];
			LL p=e.second,to=e.first;
			if(d[s][to]>d[s][v]+p){
				pq.erase(mp(d[s][to],to));
				d[s][to]=d[s][v]+p;
				pq.insert(mp(d[s][to],to));
			}
		}
	}
}
bool flg=0;
void dfs(int x,LL cost){
	if(vis[x])return;
	if(co[x]<cost)return;
//	cout<<x<<' '<<cost<<endl;
	co[x]=cost;
	vis[x]=1;
	if(x==lx)flg=1;
	for(int i=1;i<=n;i++){
		if(i==x)continue;
		if(d[x][i]<=t[x])dfs(i,cost+c[x]);
	}
	vis[x]=0;
}
int main(){
//	freopen("ball.txt","r",stdin);
	n=read_int(),m=read_int();
	fx=read_int(),lx=read_int();
	for(int i=1;i<=m;i++){
		int x=read_int(),y=read_int();
		LL z=read_long();
		G[x].pb(mp(y,z));
		G[y].pb(mp(x,z));
	}
	fill(co+1,co+n+1,INF);
	for(int i=1;i<=n;i++){
		t[i]=read_int(),c[i]=read_int();
	}
//	system("pause");
	if(fx==lx){
		puts("0");
		return 0;
	}
	for(int i=1;i<=n;i++)dijkstra(i,G);
//	system("pause");
//	for(int i=1;i<=n;i++){
//		for(int j=1;j<=n;j++)cout<<d[i][j]<<' ';
//		puts("");
//	}
	for(int i=1;i<=n;i++){
		for(int j=1;j<=n;j++)if(d[i][j]<=t[i])G2[i].pb(mp(j,c[i]));
	}
	dijkstra(fx,G2);
//	dfs(fx,0);
	if(d[fx][lx]==INF)puts("-1");
	else cout<<d[fx][lx]<<endl;
	return 0;
}


#include <bits/stdc++.h>
#define LL long long
#define mp make_pair
#define pb push_back
#define INF (1<<29)
using namespace std;
typedef pair<int,int>pii;
int n,m,fx,lx;
vector<pii>G[1010];
LL d[1010][1010];
bool vis[1010];
LL co[1010];
int t[1010],c[1010];
void dijkstra(int s){
	priority_queue<pii,vector<pii>,greater<pii> >pq;
	fill(d[s]+1,d[s]+n+1,INF);
	d[s][s]=0;
	pq.push(mp(s,0));
	while(!pq.empty()){
		pii p=pq.top();
		pq.pop();
		int v=p.first;
		if(d[s][v]<p.second)continue;
		for(int i=0;i<G[v].size();i++){
			pii e=G[v][i];
			if(d[s][e.first]>d[s][v]+e.second){
				d[s][e.first]=d[s][v]+e.second;
				pq.push(mp(e.first,d[s][e.first]));
			}
		}
	}
}
bool flg=0;
void dfs(int x,LL cost){
	if(vis[x])return;
	if(co[x]&&co[x]<cost)return;
//	cout<<x<<' '<<cost<<endl;
	co[x]=cost;
	vis[x]=1;
	if(x==lx)flg=1;
	for(int i=1;i<=n;i++){
		if(i==x)continue;
		if(d[x][i]>t[x])continue;
		dfs(i,cost+c[x]);
	}
	vis[x]=0;
}
int main(){
	cin>>n>>m>>fx>>lx;
	for(int i=1;i<=m;i++){
		int x,y,z;
		cin>>x>>y>>z;
		G[x].pb(mp(y,z));
		G[y].pb(mp(x,z));
	}
	for(int i=1;i<=n;i++)cin>>t[i]>>c[i];
	if(fx==lx){
		puts("0");
		return 0;
	}
	for(int i=1;i<=n;i++)dijkstra(i);
//	for(int i=1;i<=n;i++){
//		for(int j=1;j<=n;j++)cout<<d[i][j]<<' ';
//		puts("");
//	}
	dfs(fx,0);
	if(!flg)puts("-1");
	else cout<<co[lx]<<endl;
	return 0;
}


#include <bits/stdc++.h>
#define LL long long
#define mp make_pair
#define pb push_back
#define INF (1<<29)
using namespace std;
typedef pair<int,int>pii;
int n,m,fx,lx;
vector<pii>G[1010];
LL d[1010][1010];
bool vis[1010];
LL co[1010];
int t[1010],c[1010];
void dijkstra(int s){
	priority_queue<pii,vector<pii>,greater<pii> >pq;
	fill(d[s]+1,d[s]+n+1,INF);
	d[s][s]=0;
	pq.push(mp(s,0));
	while(!pq.empty()){
		pii p=pq.top();
		pq.pop();
		int v=p.first;
		if(d[s][v]<p.second)continue;
		for(int i=0;i<G[v].size();i++){
			pii e=G[v][i];
			if(d[s][e.first]>d[s][v]+e.second){
				d[s][e.first]=d[s][v]+e.second;
				pq.push(mp(e.first,d[s][e.first]));
			}
		}
	}
}
void dfs(int x,LL cost){
	if(co[x]&&co[x]<cost)return;
//	cout<<x<<' '<<cost<<endl;
	co[x]=cost;
	for(int i=1;i<=n;i++){
		if(i==x)continue;
		if(d[x][i]>t[x])continue;
		dfs(i,cost+c[x]);
	}
}
int main(){
	cin>>n>>m>>fx>>lx;
	for(int i=1;i<=m;i++){
		int x,y,z;
		cin>>x>>y>>z;
		G[x].pb(mp(y,z));
		G[y].pb(mp(x,z));
	}
	for(int i=1;i<=m;i++)cin>>t[i]>>c[i];
	for(int i=1;i<=n;i++)dijkstra(i);
//	for(int i=1;i<=n;i++){
//		for(int j=1;j<=n;j++)cout<<d[i][j]<<' ';
//		puts("");
//	}
	dfs(fx,0);
	cout<<co[lx]<<endl;
	return 0;
}


#include <bits/stdc++.h>
#define LL long long
#define mp make_pair
#define pb push_back
#define INF (LL)1e18
using namespace std;
typedef pair<int,int>pii;
typedef pair<LL,LL>pll;
int n,m,fx,lx;
vector<pair<LL,LL> >G[1010];
LL d[1010][1010];
bool vis[1010];
LL co[1010];
int t[1010],c[1010];
void dijkstra(int s){
	set<pair<LL,LL> >pq;
//	fill(d[s]+1,d[s]+n+1,INF);
	d[s][s]=0;
	pq.insert(mp(0,s));
	while(!pq.empty()){
		LL v=pq.begin()->second;
		pq.erase(pq.begin());
		for(int i=0;i<G[v].size();i++){
			pair<LL,LL> e=G[v][i];
			LL p=e.second,to=e.first;
			if(d[s][to]>d[s][v]+p){
				pq.erase(mp(d[s][to],to));
				d[s][to]=d[s][v]+p;
				pq.insert(mp(d[s][to],to));
			}
		}
	}
}
bool flg=0;
void dfs(int x,LL cost){
	if(vis[x])return;
	if(co[x]&&co[x]<cost)return;
//	cout<<x<<' '<<cost<<endl;
	co[x]=cost;
	vis[x]=1;
	if(x==lx)flg=1;
	for(int i=1;i<=n;i++){
		if(i==x)continue;
		if(d[x][i]>t[x])continue;
		dfs(i,cost+c[x]);
	}
	vis[x]=0;
}
inline LL read_long(){
	LL t=1,x=0;
	char ch=getchar();
	while(!isdigit(ch)&&ch!='-')ch=getchar();
	if(ch=='-')t=-1,ch=getchar();
	while(isdigit(ch)){
		x=(x<<1)+(x<<3)+ch-'0';
		ch=getchar();
	}
	return x*t;
}
inline int read_int(){
	int t=1,x=0;
	char ch=getchar();
	while(!isdigit(ch)&&ch!='-')ch=getchar();
	if(ch=='-')t=-1,ch=getchar();
	while(isdigit(ch)){
		x=(x<<1)+(x<<3)+ch-'0';
		ch=getchar();
	}
	return x*t;
}
int main(){
//	freopen("ball.txt","r",stdin);
	n=read_int(),m=read_int();
	fx=read_int(),lx=read_int();
	for(int i=1;i<=m;i++){
		int x=read_int(),y=read_int();
		LL z=read_long();
		G[x].pb(mp(y,z));
		G[y].pb(mp(x,z));
	}
	for(int i=1;i<=n;i++)t[i]=read_int(),c[i]=read_int();
//	system("pause");
	if(fx==lx){
		puts("0");
		return 0;
	}
	for(int i=1;i<=n;i++)for(int j=1;j<=n;j++)d[i][j]=INF;
//	for(int i=1;i<=n;i++){
//		for(int j=1;j<=n;j++)cout<<d[i][j]<<' ';
//		puts("");
//	}
	for(int i=1;i<=n;i++)dijkstra(i);
//	system("pause");
//	for(int i=1;i<=n;i++){
//		for(int j=1;j<=n;j++)cout<<d[i][j]<<' ';
//		puts("");
//	}
	dfs(fx,0);
	if(!flg)puts("-1");
	else cout<<co[lx]<<endl;
	return 0;
}


#include <bits/stdc++.h>
#define LL long long
#define mp make_pair
#define pb push_back
#define INF (LL)1e18
using namespace std;
typedef pair<int,int>pii;
typedef pair<LL,LL>pll;
int n,m,fx,lx;
vector<pair<LL,LL> >G[1010];
LL d[1010][1010];
bool vis[1010];
LL co[1010];
int t[1010],c[1010];
void dijkstra(int s){
	set<pair<LL,LL> >pq;
//	fill(d[s]+1,d[s]+n+1,INF);
	d[s][s]=0;
	pq.insert(mp(0,s));
	while(!pq.empty()){
		LL v=pq.begin()->second;
		pq.erase(pq.begin());
		for(int i=0;i<G[v].size();i++){
			pair<LL,LL> e=G[v][i];
			LL p=e.second,to=e.first;
			if(d[s][to]>d[s][v]+p){
				pq.erase(mp(d[s][to],to));
				d[s][to]=d[s][v]+p;
				pq.insert(mp(d[s][to],to));
			}
		}
	}
}
bool flg=0;
void dfs(int x,LL cost){
	if(vis[x])return;
	if(co[x]&&co[x]<cost)return;
//	cout<<x<<' '<<cost<<endl;
	co[x]=cost;
	vis[x]=1;
	if(x==lx)flg=1;
	for(int i=1;i<=n;i++){
		if(i==x)continue;
		if(d[x][i]>t[x])continue;
		dfs(i,cost+c[x]);
	}
	vis[x]=0;
}
inline LL read_long(){
	LL t=1,x=0;
	char ch=getchar();
	while(!isdigit(ch)&&ch!='-')ch=getchar();
	if(ch=='-')t=-1,ch=getchar();
	while(isdigit(ch)){
		x=(x<<1)+(x<<3)+ch-'0';
		ch=getchar();
	}
	return x*t;
}
inline int read_int(){
	int t=1,x=0;
	char ch=getchar();
	while(!isdigit(ch)&&ch!='-')ch=getchar();
	if(ch=='-')t=-1,ch=getchar();
	while(isdigit(ch)){
		x=(x<<1)+(x<<3)+ch-'0';
		ch=getchar();
	}
	return x*t;
}
int main(){
	freopen("ball.txt","r",stdin);
	n=read_int(),m=read_int();
	fx=read_int(),lx=read_int();
	for(int i=1;i<=m;i++){
		int x=read_int(),y=read_int();
		LL z=read_long();
		G[x].pb(mp(y,z));
		G[y].pb(mp(x,z));
	}
	for(int i=1;i<=n;i++)t[i]=read_int(),c[i]=read_int();
//	system("pause");
	if(fx==lx){
		puts("0");
		return 0;
	}
	for(int i=1;i<=n;i++)for(int j=1;j<=n;j++)d[i][j]=INF;
//	for(int i=1;i<=n;i++){
//		for(int j=1;j<=n;j++)cout<<d[i][j]<<' ';
//		puts("");
//	}
	for(int i=1;i<=n;i++)dijkstra(i);
//	system("pause");
//	for(int i=1;i<=n;i++){
//		for(int j=1;j<=n;j++)cout<<d[i][j]<<' ';
//		puts("");
//	}
	dfs(fx,0);
	if(!flg)puts("-1");
	else cout<<co[lx]<<endl;
	return 0;
}


#include <bits/stdc++.h>

using namespace std;

const int N = 1010;
const long long INF = 1e18 + 10;

int n, m;
int x, y;
int t[N], c[N];
long long dis[N][N];
long long dis2[N][N];

int main() {
  scanf("%d%d", &n, &m);
  scanf("%d%d", &x, &y);
  fill((long long *)dis, (long long *)(dis + N), INF);
  for (int i = 1; i <= n; ++i) {
    dis[i][i] = 0;
  }
  for (int i = 0, u, v, ww; i < m; ++i) {
    scanf("%d%d%d", &u, &v, &ww);
    dis[u][v] = ww;
    dis[v][u] = ww;
  }
  for (int k = 1; k <= n; ++k) {
    for (int i = 1; i <= n; ++i) {
      for (int j = 1; j <= n; ++j) {
        dis[i][j] = min(dis[i][j], dis[i][k] + dis[k][j]);
      }
    }
  }
  /*
  for (int i = 1; i <= n; ++i) {
    for (int j = 1; j <= n; ++j) {
      printf("%I64d ", dis[i][j]);
    }
    puts("");
  }*/
  fill((long long *)dis2, (long long *)(dis2 + N), INF);
  for (int i = 1; i <= n; ++i) {
    dis2[i][i] = 0;
  }
  for (int i = 1; i <= n; ++i) {
    scanf("%d%d", t + i, c + i);
    for (int j = 1; j <= n; ++j) {
      if (j == i) continue;
      if (dis[i][j] <= t[i]) {
        dis2[i][j] = min(dis2[i][j], (long long)c[i]);
      }
    }
  }
  for (int k = 1; k <= n; ++k) {
    for (int i = 1; i <= n; ++i) {
      for (int j = 1; j <= n; ++j) {
        dis2[i][j] = min(dis2[i][j], dis2[i][k] + dis2[k][j]);
      }
    }
  }
  if (dis2[x][y] >= INF) {
    puts("-1");
  }
  else {
    printf("%I64d\n", dis2[x][y]);
  }
  return 0;
}


#include <bits/stdc++.h>

using namespace std;

const int N = 1e3 + 10;
const long long INF = 1e18 + 10;

int n, m;
int x, y;
struct edge {
  int to, c;
};
vector<edge> e;
vector<int> g[N];
vector<int> g2[N];
long long dis[N];
bool used[N];

void dijkstra(int sc) {
  fill(dis, dis + N, INF);
  memset(used, 0, sizeof(used));
  priority_queue<pair<long long, int> > pq;
  pq.push(make_pair(0, sc));
  while (!pq.empty()) {
    pair<int, int> t = pq.top();
    pq.pop();
    int v = t.second;
    long long d = -t.first;
    if (used[v]) {
      continue;
    }
    used[v] = 1;
    dis[v] = d;
    for (int i = 0; i < g[v].size(); ++i) {
      int u = e[g[v][i]].to;
      int w = e[g[v][i]].c;
      if (!used[u]) {
        pq.push(make_pair(- d - w, u));
      }
    }
  }
}

int main() {
  scanf("%d%d", &n, &m);
  scanf("%d%d", &x, &y);
  for (int i = 0, u, v, w; i < m; ++i) {
    scanf("%d%d%d", &u, &v, &w);
    e.push_back(edge{v, w});
    g[u].push_back(e.size() - 1);
    e.push_back(edge{u, w});
    g[v].push_back(e.size() - 1);
  }
  for (int i = 1, t, c; i <= n; ++i) {
    scanf("%d%d", &t, &c);
    dijkstra(i);
    for (int j = 1; j <= n; ++j) {
      if (j == i) continue;
      if (dis[j] <= t) {
        e.push_back(edge{j, c});
        g2[i].push_back(e.size() - 1);
      }
    }
  }
  for (int i = 1; i <= n; ++i) {
//    g[i].swap(g2[i]);
    swap(g[i], g2[i]);
  }
  dijkstra(x);
  if (dis[y] < INF) {
    printf("%I64d\n", dis[y]);
  }
  else {
    puts("-1");
  }
  return 0;
}


#include <bits/stdc++.h>

using namespace std;

const int N = 1e3 + 10;
const long long INF = 1e18 + 10;

int n, m;
int x, y;
struct edge {
  int to, c;
};
vector<edge> e;
vector<int> g[N];
vector<int> g2[N];
long long dis[N];
bool used[N];

void dijkstra(int sc) {
  fill(dis, dis + N, INF);
  memset(used, 0, sizeof(used));
  priority_queue<pair<long long, int> > pq;
  pq.push(make_pair(0, sc));
  while (!pq.empty()) {
    pair<long long, int> t = pq.top();
    pq.pop();
    int v = t.second;
    long long d = -t.first;
    if (used[v]) {
      continue;
    }
    used[v] = 1;
    dis[v] = d;
    for (int i = 0; i < g[v].size(); ++i) {
      int u = e[g[v][i]].to;
      int w = e[g[v][i]].c;
      if (!used[u]) {
        pq.push(make_pair(- d - w, u));
      }
    }
  }
}

int main() {
  scanf("%d%d", &n, &m);
  scanf("%d%d", &x, &y);
  for (int i = 0, u, v, w; i < m; ++i) {
    scanf("%d%d%d", &u, &v, &w);
    e.push_back(edge{v, w});
    g[u].push_back(e.size() - 1);
    e.push_back(edge{u, w});
    g[v].push_back(e.size() - 1);
  }
  for (int i = 1, t, c; i <= n; ++i) {
    scanf("%d%d", &t, &c);
    dijkstra(i);
    for (int j = 1; j <= n; ++j) {
      if (j == i) continue;
      if (dis[j] <= t) {
        e.push_back(edge{j, c});
        g2[i].push_back(e.size() - 1);
      }
    }
  }
  for (int i = 1; i <= n; ++i) {
//    g[i].swap(g2[i]);
    swap(g[i], g2[i]);
  }
  dijkstra(x);
  if (dis[y] < INF) {
    printf("%I64d\n", dis[y]);
  }
  else {
    puts("-1");
  }
  return 0;
}


#include<bits/stdc++.h>

using namespace std;

#define maxn 100000 + 5
#define ls (p << 1)
#define rs (p << 1 | 1)
#define mid ((l + r) >> 1)
#define file(a) freopen(#a".in","r",stdin); freopen(#a".out","w",stdout);
typedef long long ll;
const ll inf = 999999999999999;
struct edge{
	ll v, next, w;
}e[2][maxn << 1];

ll n, m, x, y, u, v, w, t[2];
ll dis[maxn], a[maxn], b[maxn], h[2][maxn];
bool vis[maxn];
queue <ll> q;

ll read(){
	char orz; ll tql = 0, qwq = 1;
	orz = getchar();
	while(orz > '9' || orz < '0'){
		if(orz == '-') qwq = -1;
		orz = getchar();
	}
	while(orz >= '0' && orz <= '9'){
		tql = (tql << 3) + (tql << 1) + orz - '0';
		orz = getchar();
	}
	return tql * qwq;
}

void add(ll u, ll v, ll w, ll p){
	e[p][++t[p]].next = h[p][u];
	e[p][t[p]].v = v;
	e[p][t[p]].w = w;
	h[p][u] = t[p];
}

void init(){
	n = read(); m = read(); x = read(); y = read();
	for(int i = 1; i <= m; i++){
		u = read(); v = read(); w = read();
		add(u, v, w, 0); add(v, u, w, 0);
	}
	for(int i = 1; i <= n; i++) a[i] = read(), b[i] = read();
}

void spfa(ll p, ll f){
	memset(vis, 0, sizeof(vis));
	for(int i = 1; i <= n; i++) dis[i] = inf;
	dis[p] = 0; q.push(p); vis[p] = true;
	while(!q.empty()){
		int u = q.front(); q.pop();
		vis[u] = false;
		for(int i = h[f][u]; i; i = e[f][i].next){
			int v = e[f][i].v;
			if(dis[v] > dis[u] + e[f][i].w){
				dis[v] = dis[u] + e[f][i].w;
				if(!vis[v]) vis[v] = true, q.push(v);
			}
		}
	}
	if(!f)
		for(int i = 1; i <= n; i++)
			if(i != p && dis[i] <= a[p])
				add(p, i, b[p], 1);
}

void solve(){
	for(int i = 1; i <= n; i++) spfa(i, 0);
	spfa(x, 1);
	if(dis[y] != inf) printf("%lld", dis[y]);
	else puts("-1");
}

int main(){
	//file(data);
	init();
	solve();
	return 0;
}


#include<bits/stdc++.h>

using namespace std;

#define maxn 100000 + 5
#define ls (p << 1)
#define rs (p << 1 | 1)
#define mid ((l + r) >> 1)
#define file(a) freopen(#a".in","r",stdin); freopen(#a".out","w",stdout);
const int inf = 123456789;
typedef long long ll;
struct edge{
	int v, next, w;
}e[2][maxn << 1];

int n, m, x, y, u, v, w, t[2];
int dis[maxn], a[maxn], b[maxn], h[2][maxn];
bool vis[maxn];
queue <int> q;

int read(){
	char orz; int tql = 0, qwq = 1;
	orz = getchar();
	while(orz > '9' || orz < '0'){
		if(orz == '-') qwq = -1;
		orz = getchar();
	}
	while(orz >= '0' && orz <= '9'){
		tql = (tql << 3) + (tql << 1) + orz - '0';
		orz = getchar();
	}
	return tql * qwq;
}

void add(int u, int v, int w, int p){
	e[p][++t[p]].next = h[p][u];
	e[p][t[p]].v = v;
	e[p][t[p]].w = w;
	h[p][u] = t[p];
}

void init(){
	n = read(); m = read(); x = read(); y = read();
	for(int i = 1; i <= m; i++){
		u = read(); v = read(); w = read();
		add(u, v, w, 0); add(v, u, w, 0);
	}
	for(int i = 1; i <= n; i++) a[i] = read(), b[i] = read();
}

void dfs(int fa, int p, int res, int s){
	for(int i = h[0][p]; i; i = e[0][i].next){
		if(res - e[0][i].w < 0) continue;
		add(fa, e[0][i].v, s, 1);
		dfs(fa, e[0][i].v, res - e[0][i].w, s);
	}
}

void spfa(){
	for(int i = 1; i <= n; i++) dis[i] = inf;
	dis[x] = 0; q.push(x); vis[x] = true;
	while(!q.empty()){
		int u = q.front(); q.pop();
		vis[u] = false;
		for(int i = h[1][u]; i; i = e[1][i].next){
			int v = e[1][i].v;
			if(dis[v] > dis[u] + e[1][i].w){
				dis[v] = dis[u] + e[1][i].w;
				if(!vis[v]) vis[v] = true, q.push(v);
			}
		}
	}
}

void solve(){
	for(int i = 1; i <= n; i++) dfs(i, i, a[i], b[i]);
	spfa();
	if(dis[y] != inf) printf("%d", dis[y]);
	else puts("-1");
}

int main(){
	//file(data);
	init();
	solve();
	return 0;
}


#include<bits/stdc++.h>

using namespace std;

#define maxn 1000 + 5
#define ls (p << 1)
#define rs (p << 1 | 1)
#define mid ((l + r) >> 1)
#define file(a) freopen(#a".in","r",stdin); freopen(#a".out","w",stdout);
const int inf = 123456789;
typedef long long ll;
struct edge{
	int v, next, w;
}e[2][maxn << 1];

int n, m, x, y, u, v, w, t[2];
int dis[maxn], a[maxn], b[maxn], h[2][maxn];
bool vis[maxn], used[maxn][maxn];
queue <int> q;

int read(){
	char orz; int tql = 0, qwq = 1;
	orz = getchar();
	while(orz > '9' || orz < '0'){
		if(orz == '-') qwq = -1;
		orz = getchar();
	}
	while(orz >= '0' && orz <= '9'){
		tql = (tql << 3) + (tql << 1) + orz - '0';
		orz = getchar();
	}
	return tql * qwq;
}

void add(int u, int v, int w, int p){
	e[p][++t[p]].next = h[p][u];
	e[p][t[p]].v = v;
	e[p][t[p]].w = w;
	h[p][u] = t[p];
}

void init(){
	n = read(); m = read(); x = read(); y = read();
	for(int i = 1; i <= m; i++){
		u = read(); v = read(); w = read();
		add(u, v, w, 0); add(v, u, w, 0);
	}
	for(int i = 1; i <= n; i++) a[i] = read(), b[i] = read();
}

void dfs(int fa, int p, int res, int s){
	//printf("now here is %d %d %d %d\n", fa, p, res, s);
	if(used[p][s]) return;
	used[p][s] = true;
	for(int i = h[0][p]; i; i = e[0][i].next){
		if(res - e[0][i].w < 0) continue;
		add(fa, e[0][i].v, s, 1);
		dfs(fa, e[0][i].v, res - e[0][i].w, s);
	}
}

void spfa(){
	for(int i = 1; i <= n; i++) dis[i] = inf;
	dis[x] = 0; q.push(x); vis[x] = true;
	while(!q.empty()){
		int u = q.front(); q.pop();
		vis[u] = false;
		for(int i = h[1][u]; i; i = e[1][i].next){
			int v = e[1][i].v;
			if(dis[v] > dis[u] + e[1][i].w){
				dis[v] = dis[u] + e[1][i].w;
				if(!vis[v]) vis[v] = true, q.push(v);
			}
		}
	}
}

void solve(){
	for(int i = 1; i <= n; i++) dfs(i, i, a[i], b[i]), memset(used, 0, sizeof(used));
	spfa();
	if(dis[y] != inf) printf("%d", dis[y]);
	else puts("-1");
}

int main(){
	//file(data);
	init();
	solve();
	return 0;
}


#include<bits/stdc++.h>

using namespace std;

#define maxn 10000 + 5
#define ls (p << 1)
#define rs (p << 1 | 1)
#define mid ((l + r) >> 1)
#define file(a) freopen(#a".in","r",stdin); freopen(#a".out","w",stdout);
const int inf = 123456789;
typedef long long ll;
struct edge{
	int v, next, w;
}e[2][maxn << 1];

int n, m, x, y, u, v, w, t[2];
int dis[maxn], a[maxn], b[maxn], h[2][maxn];
bool vis[maxn];
queue <int> q;

int read(){
	char orz; int tql = 0, qwq = 1;
	orz = getchar();
	while(orz > '9' || orz < '0'){
		if(orz == '-') qwq = -1;
		orz = getchar();
	}
	while(orz >= '0' && orz <= '9'){
		tql = (tql << 3) + (tql << 1) + orz - '0';
		orz = getchar();
	}
	return tql * qwq;
}

void add(int u, int v, int w, int p){
	e[p][++t[p]].next = h[p][u];
	e[p][t[p]].v = v;
	e[p][t[p]].w = w;
	h[p][u] = t[p];
}

void init(){
	n = read(); m = read(); x = read(); y = read();
	for(int i = 1; i <= m; i++){
		u = read(); v = read(); w = read();
		add(u, v, w, 0); add(v, u, w, 0);
	}
	for(int i = 1; i <= n; i++) a[i] = read(), b[i] = read();
}

void dfs(int fa, int p, int res, int s){
	for(int i = h[0][p]; i; i = e[0][i].next){
		if(res - e[0][i].w < 0) continue;
		add(fa, e[0][i].v, s, 1);
		dfs(fa, e[0][i].v, res - e[0][i].w, s);
	}
}

void spfa(){
	for(int i = 1; i <= n; i++) dis[i] = inf;
	dis[x] = 0; q.push(x); vis[x] = true;
	while(!q.empty()){
		int u = q.front(); q.pop();
		vis[u] = false;
		for(int i = h[1][u]; i; i = e[1][i].next){
			int v = e[1][i].v;
			if(dis[v] > dis[u] + e[1][i].w){
				dis[v] = dis[u] + e[1][i].w;
				if(!vis[v]) vis[v] = true, q.push(v);
			}
		}
	}
}

void solve(){
	for(int i = 1; i <= n; i++) dfs(i, i, a[i], b[i]);
	spfa();
	if(dis[y] != inf) printf("%d", dis[y]);
	else puts("-1");
}

int main(){
	//file(data);
	init();
	solve();
	return 0;
}


#include<bits/stdc++.h>

using namespace std;

#define maxn 10000 + 5
#define ls (p << 1)
#define rs (p << 1 | 1)
#define mid ((l + r) >> 1)
#define file(a) freopen(#a".in","r",stdin); freopen(#a".out","w",stdout);
typedef long long ll;
const ll inf = 123456789123456789;
struct edge{
	ll v, next, w;
}e[2][maxn << 1];

ll n, m, x, y, u, v, w, t[2];
ll dis[maxn], a[maxn], b[maxn], h[2][maxn];
bool vis[maxn];
queue <ll> q;

ll read(){
	char orz; ll tql = 0, qwq = 1;
	orz = getchar();
	while(orz > '9' || orz < '0'){
		if(orz == '-') qwq = -1;
		orz = getchar();
	}
	while(orz >= '0' && orz <= '9'){
		tql = (tql << 3) + (tql << 1) + orz - '0';
		orz = getchar();
	}
	return tql * qwq;
}

void add(ll u, ll v, ll w, ll p){
	e[p][++t[p]].next = h[p][u];
	e[p][t[p]].v = v;
	e[p][t[p]].w = w;
	h[p][u] = t[p];
}

void init(){
	n = read(); m = read(); x = read(); y = read();
	for(int i = 1; i <= m; i++){
		u = read(); v = read(); w = read();
		add(u, v, w, 0); add(v, u, w, 0);
	}
	for(int i = 1; i <= n; i++) a[i] = read(), b[i] = read();
}

void spfa(ll p, ll f){
	memset(vis, 0, sizeof(vis));
	for(int i = 1; i <= n; i++) dis[i] = inf;
	dis[p] = 0; q.push(p); vis[p] = true;
	while(!q.empty()){
		int u = q.front(); q.pop();
		vis[u] = false;
		for(int i = h[f][u]; i; i = e[f][i].next){
			int v = e[f][i].v;
			if(dis[v] > dis[u] + e[f][i].w){
				dis[v] = dis[u] + e[f][i].w;
				if(!vis[v]) vis[v] = true, q.push(v);
			}
		}
	}
	if(!f)
		for(int i = 1; i <= n; i++)
			if(i != p && dis[i] <= a[p])
				add(p, i, b[p], 1);
}

void solve(){
	for(int i = 1; i <= n; i++) spfa(i, 0);
	spfa(x, 1);
	if(dis[y] != inf) printf("%lld", dis[y]);
	else puts("-1");
}

int main(){
	//file(data);
	init();
	solve();
	return 0;
}


#include<bits/stdc++.h>

using namespace std;

#define maxn 1000 + 5
#define ls (p << 1)
#define rs (p << 1 | 1)
#define mid ((l + r) >> 1)
#define file(a) freopen(#a".in","r",stdin); freopen(#a".out","w",stdout);
typedef long long ll;
const ll inf = 123456789123456789;
struct edge{
	ll v, next, w;
}e[2][maxn << 1];

ll n, m, x, y, u, v, w, t[2];
ll dis[maxn], a[maxn], b[maxn], h[2][maxn], used[maxn][maxn];
bool vis[maxn];
queue <ll> q;

ll read(){
	char orz; ll tql = 0, qwq = 1;
	orz = getchar();
	while(orz > '9' || orz < '0'){
		if(orz == '-') qwq = -1;
		orz = getchar();
	}
	while(orz >= '0' && orz <= '9'){
		tql = (tql << 3) + (tql << 1) + orz - '0';
		orz = getchar();
	}
	return tql * qwq;
}

void add(ll u, ll v, ll w, ll p){
	e[p][++t[p]].next = h[p][u];
	e[p][t[p]].v = v;
	e[p][t[p]].w = w;
	h[p][u] = t[p];
}

void init(){
	n = read(); m = read(); x = read(); y = read();
	for(int i = 1; i <= m; i++){
		u = read(); v = read(); w = read();
		add(u, v, w, 0); add(v, u, w, 0);
	}
	for(int i = 1; i <= n; i++) a[i] = read(), b[i] = read();
}

void spfa(ll p, ll f){
	memset(vis, 0, sizeof(vis));
	for(int i = 1; i <= n; i++) dis[i] = inf;
	dis[p] = 0; q.push(p); vis[p] = true;
	while(!q.empty()){
		int u = q.front(); q.pop();
		vis[u] = false;
		for(int i = h[f][u]; i; i = e[f][i].next){
			int v = e[f][i].v;
			if(dis[v] > dis[u] + e[f][i].w){
				dis[v] = dis[u] + e[f][i].w;
				if(!vis[v]) vis[v] = true, q.push(v);
			}
		}
	}
	if(!f)
		for(int i = 1; i <= n; i++)
			if(i != p && dis[i] <= a[p])
				add(p, i, b[p], 1);
}

void solve(){
	for(int i = 1; i <= n; i++) spfa(i, 0);
	spfa(x, 1);
	if(dis[y] != inf) printf("%lld", dis[y]);
	else puts("-1");
}

int main(){
	//file(data);
	init();
	solve();
	return 0;
}


#include<bits/stdc++.h>

using namespace std;

#define maxn 1000000 + 5
#define ls (p << 1)
#define rs (p << 1 | 1)
#define mid ((l + r) >> 1)
#define file(a) freopen(#a".in","r",stdin); freopen(#a".out","w",stdout);
typedef long long ll;
const ll inf = 999999999999999;
struct edge{
	ll v, next, w;
}e[2][maxn << 1];

ll n, m, x, y, u, v, w, t[2];
ll dis[maxn], a[maxn], b[maxn], h[2][maxn];
bool vis[maxn];
queue <ll> q;

ll read(){
	char orz; ll tql = 0, qwq = 1;
	orz = getchar();
	while(orz > '9' || orz < '0'){
		if(orz == '-') qwq = -1;
		orz = getchar();
	}
	while(orz >= '0' && orz <= '9'){
		tql = (tql << 3) + (tql << 1) + orz - '0';
		orz = getchar();
	}
	return tql * qwq;
}

void add(ll u, ll v, ll w, ll p){
	e[p][++t[p]].next = h[p][u];
	e[p][t[p]].v = v;
	e[p][t[p]].w = w;
	h[p][u] = t[p];
}

void init(){
	n = read(); m = read(); x = read(); y = read();
	for(int i = 1; i <= m; i++){
		u = read(); v = read(); w = read();
		add(u, v, w, 0); add(v, u, w, 0);
	}
	for(int i = 1; i <= n; i++) a[i] = read(), b[i] = read();
}

void spfa(ll p, ll f){
	memset(vis, 0, sizeof(vis));
	for(int i = 1; i <= n; i++) dis[i] = inf;
	dis[p] = 0; q.push(p); vis[p] = true;
	while(!q.empty()){
		int u = q.front(); q.pop();
		vis[u] = false;
		for(int i = h[f][u]; i; i = e[f][i].next){
			int v = e[f][i].v;
			if(dis[v] > dis[u] + e[f][i].w){
				dis[v] = dis[u] + e[f][i].w;
				if(!vis[v]) vis[v] = true, q.push(v);
			}
		}
	}
	if(!f)
		for(int i = 1; i <= n; i++)
			if(i != p && dis[i] <= a[p])
				add(p, i, b[p], 1);
}

void solve(){
	for(int i = 1; i <= n; i++) spfa(i, 0);
	spfa(x, 1);
	if(dis[y] != inf) printf("%lld", dis[y]);
	else puts("-1");
}

int main(){
	//file(data);
	init();
	solve();
	return 0;
}


#include<bits/stdc++.h>

using namespace std;

#define maxn 100000 + 5
#define ls (p << 1)
#define rs (p << 1 | 1)
#define mid ((l + r) >> 1)
#define file(a) freopen(#a".in","r",stdin); freopen(#a".out","w",stdout);
typedef long long ll;
const ll inf = 123456789123456789;
struct edge{
	ll v, next, w;
}e[2][maxn << 1];

ll n, m, x, y, u, v, w, t[2];
ll dis[maxn], a[maxn], b[maxn], h[2][maxn];
bool vis[maxn];
queue <ll> q;

ll read(){
	char orz; ll tql = 0, qwq = 1;
	orz = getchar();
	while(orz > '9' || orz < '0'){
		if(orz == '-') qwq = -1;
		orz = getchar();
	}
	while(orz >= '0' && orz <= '9'){
		tql = (tql << 3) + (tql << 1) + orz - '0';
		orz = getchar();
	}
	return tql * qwq;
}

void add(ll u, ll v, ll w, ll p){
	e[p][++t[p]].next = h[p][u];
	e[p][t[p]].v = v;
	e[p][t[p]].w = w;
	h[p][u] = t[p];
}

void init(){
	n = read(); m = read(); x = read(); y = read();
	for(int i = 1; i <= m; i++){
		u = read(); v = read(); w = read();
		add(u, v, w, 0); add(v, u, w, 0);
	}
	for(int i = 1; i <= n; i++) a[i] = read(), b[i] = read();
}

void spfa(ll p, ll f){
	memset(vis, 0, sizeof(vis));
	for(int i = 1; i <= n; i++) dis[i] = inf;
	dis[p] = 0; q.push(p); vis[p] = true;
	while(!q.empty()){
		int u = q.front(); q.pop();
		vis[u] = false;
		for(int i = h[f][u]; i; i = e[f][i].next){
			int v = e[f][i].v;
			if(dis[v] > dis[u] + e[f][i].w){
				dis[v] = dis[u] + e[f][i].w;
				if(!vis[v]) vis[v] = true, q.push(v);
			}
		}
	}
	if(!f)
		for(int i = 1; i <= n; i++)
			if(i != p && dis[i] <= a[p])
				add(p, i, b[p], 1);
}

void solve(){
	for(int i = 1; i <= n; i++) spfa(i, 0);
	spfa(x, 1);
	if(dis[y] != inf) printf("%lld", dis[y]);
	else puts("-1");
}

int main(){
	//file(data);
	init();
	solve();
	return 0;
}


#include<bits/stdc++.h>

using namespace std;

#define maxn 1000 + 5
#define ls (p << 1)
#define rs (p << 1 | 1)
#define mid ((l + r) >> 1)
#define file(a) freopen(#a".in","r",stdin); freopen(#a".out","w",stdout);
const int inf = 123456789;
typedef long long ll;
struct edge{
	int v, next, w;
}e[2][maxn << 1];

int n, m, x, y, u, v, w, t[2];
int dis[maxn], a[maxn], b[maxn], h[2][maxn];
bool vis[maxn];
queue <int> q;

int read(){
	char orz; int tql = 0, qwq = 1;
	orz = getchar();
	while(orz > '9' || orz < '0'){
		if(orz == '-') qwq = -1;
		orz = getchar();
	}
	while(orz >= '0' && orz <= '9'){
		tql = (tql << 3) + (tql << 1) + orz - '0';
		orz = getchar();
	}
	return tql * qwq;
}

void add(int u, int v, int w, int p){
	e[p][++t[p]].next = h[p][u];
	e[p][t[p]].v = v;
	e[p][t[p]].w = w;
	h[p][u] = t[p];
}

void init(){
	n = read(); m = read(); x = read(); y = read();
	for(int i = 1; i <= m; i++){
		u = read(); v = read(); w = read();
		add(u, v, w, 0); add(v, u, w, 0);
	}
	for(int i = 1; i <= n; i++) a[i] = read(), b[i] = read();
}

void dfs(int fa, int p, int res, int s){
	for(int i = h[0][p]; i; i = e[0][i].next){
		if(res - e[0][i].w < 0) continue;
		add(fa, e[0][i].v, s, 1);
		dfs(fa, e[0][i].v, res - e[0][i].w, s);
	}
}

void spfa(){
	for(int i = 1; i <= n; i++) dis[i] = inf;
	dis[x] = 0; q.push(x); vis[x] = true;
	while(!q.empty()){
		int u = q.front(); q.pop();
		vis[u] = false;
		for(int i = h[1][u]; i; i = e[1][i].next){
			int v = e[1][i].v;
			if(dis[v] > dis[u] + e[1][i].w){
				dis[v] = dis[u] + e[1][i].w;
				if(!vis[v]) vis[v] = true, q.push(v);
			}
		}
	}
}

void solve(){
	for(int i = 1; i <= n; i++) dfs(i, i, a[i], b[i]);
	spfa();
	if(dis[y] != inf) printf("%d", dis[y]);
	else puts("-1");
}

int main(){
	//file(data);
	init();
	solve();
	return 0;
}


#include<bits/stdc++.h>

using namespace std;

#define maxn 1000 + 5
#define ls (p << 1)
#define rs (p << 1 | 1)
#define mid ((l + r) >> 1)
#define file(a) freopen(#a".in","r",stdin); freopen(#a".out","w",stdout);
const int inf = 123456789;
typedef long long ll;
struct edge{
	int v, next, w;
}e[2][maxn << 1];

int n, m, x, y, u, v, w, t[2];
int dis[maxn], a[maxn], b[maxn], h[2][maxn], used[maxn][maxn];
bool vis[maxn];
queue <int> q;

int read(){
	char orz; int tql = 0, qwq = 1;
	orz = getchar();
	while(orz > '9' || orz < '0'){
		if(orz == '-') qwq = -1;
		orz = getchar();
	}
	while(orz >= '0' && orz <= '9'){
		tql = (tql << 3) + (tql << 1) + orz - '0';
		orz = getchar();
	}
	return tql * qwq;
}

void add(int u, int v, int w, int p){
	e[p][++t[p]].next = h[p][u];
	e[p][t[p]].v = v;
	e[p][t[p]].w = w;
	h[p][u] = t[p];
}

void init(){
	n = read(); m = read(); x = read(); y = read();
	for(int i = 1; i <= m; i++){
		u = read(); v = read(); w = read();
		add(u, v, w, 0); add(v, u, w, 0);
	}
	for(int i = 1; i <= n; i++) a[i] = read(), b[i] = read();
}

void spfa(int p, int f){
	memset(vis, 0, sizeof(vis));
	for(int i = 1; i <= n; i++) dis[i] = inf;
	dis[p] = 0; q.push(p); vis[p] = true;
	while(!q.empty()){
		int u = q.front(); q.pop();
		vis[u] = false;
		for(int i = h[f][u]; i; i = e[f][i].next){
			int v = e[f][i].v;
			if(dis[v] > dis[u] + e[f][i].w){
				dis[v] = dis[u] + e[f][i].w;
				if(!vis[v]) vis[v] = true, q.push(v);
			}
		}
	}
	if(!f)
		for(int i = 1; i <= n; i++)
			if(i != p && dis[i] <= a[p])
				add(p, i, b[p], 1);
}

void solve(){
	for(int i = 1; i <= n; i++) spfa(i, 0);
	spfa(x, 1);
	if(dis[y] != inf) printf("%d", dis[y]);
	else puts("-1");
}

int main(){
	//file(data);
	init();
	solve();
	return 0;
}


#include<bits/stdc++.h>

using namespace std;

#define maxn 1000 + 5
#define ls (p << 1)
#define rs (p << 1 | 1)
#define mid ((l + r) >> 1)
#define file(a) freopen(#a".in","r",stdin); freopen(#a".out","w",stdout);
const int inf = 123456789;
typedef long long ll;
struct edge{
	int v, next, w;
}e[2][maxn << 1];

int n, m, x, y, u, v, w, t[2];
int dis[maxn], a[maxn], b[maxn], h[2][maxn], used[maxn][maxn];
bool vis[maxn];
queue <int> q;

int read(){
	char orz; int tql = 0, qwq = 1;
	orz = getchar();
	while(orz > '9' || orz < '0'){
		if(orz == '-') qwq = -1;
		orz = getchar();
	}
	while(orz >= '0' && orz <= '9'){
		tql = (tql << 3) + (tql << 1) + orz - '0';
		orz = getchar();
	}
	return tql * qwq;
}

void add(int u, int v, int w, int p){
	e[p][++t[p]].next = h[p][u];
	e[p][t[p]].v = v;
	e[p][t[p]].w = w;
	h[p][u] = t[p];
}

void init(){
	n = read(); m = read(); x = read(); y = read();
	for(int i = 1; i <= m; i++){
		u = read(); v = read(); w = read();
		add(u, v, w, 0); add(v, u, w, 0);
	}
	for(int i = 1; i <= n; i++) a[i] = read(), b[i] = read();
}

void dfs(int fa, int p, int res, int s){
	//printf("now here is %d %d %d %d\n", fa, p, res, s);
	if(used[fa][p] < s) return;
	used[fa][p] = s;
	for(int i = h[0][p]; i; i = e[0][i].next){
		if(res - e[0][i].w < 0) continue;
		add(fa, e[0][i].v, s, 1);
		dfs(fa, e[0][i].v, res - e[0][i].w, s);
	}
}

void spfa(){
	for(int i = 1; i <= n; i++) dis[i] = inf;
	dis[x] = 0; q.push(x); vis[x] = true;
	while(!q.empty()){
		int u = q.front(); q.pop();
		vis[u] = false;
		for(int i = h[1][u]; i; i = e[1][i].next){
			int v = e[1][i].v;
			if(dis[v] > dis[u] + e[1][i].w){
				dis[v] = dis[u] + e[1][i].w;
				if(!vis[v]) vis[v] = true, q.push(v);
			}
		}
	}
}

void solve(){
	for(int i = 1; i <= n; i++) dfs(i, i, a[i], b[i]), memset(used, 0x7f, sizeof(used));
	spfa();
	if(dis[y] != inf) printf("%d", dis[y]);
	else puts("-1");
}

int main(){
	//file(data);
	init();
	solve();
	return 0;
}


#include<bits/stdc++.h>

using namespace std;

#define maxn 1000000 + 5
#define ls (p << 1)
#define rs (p << 1 | 1)
#define mid ((l + r) >> 1)
#define file(a) freopen(#a".in","r",stdin); freopen(#a".out","w",stdout);
typedef long long ll;
const ll inf = 999999999999999;
struct edge{
	ll v, next, w;
}e[2][maxn << 1];

ll n, m, x, y, u, v, w, t[2];
ll dis[maxn], a[maxn], b[maxn], h[2][maxn];
bool vis[maxn];
queue <ll> q;

ll read(){
	char orz; ll tql = 0, qwq = 1;
	orz = getchar();
	while(orz > '9' || orz < '0'){
		if(orz == '-') qwq = -1;
		orz = getchar();
	}
	while(orz >= '0' && orz <= '9'){
		tql = (tql << 3) + (tql << 1) + orz - '0';
		orz = getchar();
	}
	return tql * qwq;
}

void add(ll u, ll v, ll w, ll p){
	e[p][++t[p]].next = h[p][u];
	e[p][t[p]].v = v;
	e[p][t[p]].w = w;
	h[p][u] = t[p];
}

void init(){
	n = read(); m = read(); x = read(); y = read();
	for(int i = 1; i <= m; i++){
		u = read(); v = read(); w = read();
		add(u, v, w, 0); add(v, u, w, 0);
	}
	for(int i = 1; i <= n; i++) a[i] = read(), b[i] = read();
}

void spfa(ll p, ll f){
	memset(vis, 0, sizeof(vis));
	for(int i = 1; i <= n; i++) dis[i] = inf;
	dis[p] = 0; q.push(p); vis[p] = true;
	while(!q.empty()){
		int u = q.front(); q.pop();
		vis[u] = false;
		for(int i = h[f][u]; i; i = e[f][i].next){
			int v = e[f][i].v;
			if(dis[v] > dis[u] + e[f][i].w){
				dis[v] = dis[u] + e[f][i].w;
				if(!vis[v]) vis[v] = true, q.push(v);
			}
		}
	}
	if(!f)
		for(int i = 1; i <= n; i++)
			if(i != p && dis[i] <= a[p])
				add(p, i, b[p], 1);
}

void solve(){
	for(int i = 1; i <= n; i++) spfa(i, 0);
	spfa(x, 1);
	if(dis[y] != inf) printf("%lld", dis[y]);
	else puts("-1");
}

int main(){
	init();
	solve();
	return 0;
}


#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>
#define int long long
using namespace std;
void r(int &x)
{
	char a;
	int f=1;
	while((a=getchar())<'0'||a>'9')if(a=='-')f=-1;
	x=a-48;
	while((a=getchar())>='0'&&a<='9')
	x=(x<<3)+(x<<1)+a-48;
	x=x*f;
}
struct edge{
	int to,val,nexty;
}e[4050];
int head[2005],cnt;
void add(int a,int b,int c)
{
	e[++cnt].to=b;
	e[cnt].nexty=head[a];
	e[cnt].val=c;
	head[a]=cnt;
}
int dis[2005];
int val[2005],limit[2005];
int vis[2005],vist[2005];
queue<int>q;
void dfs(int x,int sx,int tag)
{
	if(tag>limit[sx])return;
	vist[x]=1;
	if(dis[x]>dis[sx]+val[sx])
	{
		dis[x]=dis[sx]+val[sx];
		if(!vis[x])
		{
			vis[x]=1;
			q.push(x);
		}
	}
	for(int i=head[x];i;i=e[i].nexty)
	{
		int to=e[i].to;
		if(vist[to])continue;
		dfs(to,sx,tag+e[i].val);
	}
}
int n,m,s,t;
void spfa(int st)
{
	for(int i=1;i<=n;i++)dis[i]=2e15;
	dis[st]=0;
	q.push(st);
	while(!q.empty())
	{
		int x=q.front();
		q.pop();
		vis[x]=0;
		for(int i=head[x];i;i=e[i].nexty)
		{
			memset(vist,0,sizeof(vist));
			vist[x]=1;
			int to=e[i].to;
			if(e[i].val>limit[x]) continue;
			dfs(to,x,e[i].val);
		}
	}

}

signed main()
{
	r(n),r(m);
	r(s),r(t);
	for(int i=1,x,y,z;i<=m;i++)
	{
		r(x),r(y),r(z);
		add(x,y,z),add(y,x,z);
	}
	for(int i=1;i<=n;i++)
		r(limit[i]),r(val[i]);
	spfa(s);
	if(dis[t]==2e15) cout<<"-1\n";
	else  cout<<dis[t]<<"\n";
}


#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>
#define int long long
using namespace std;
void r(int &x)
{
	char a;
	int f=1;
	while((a=getchar())<'0'||a>'9')if(a=='-')f=-1;
	x=a-48;
	while((a=getchar())>='0'&&a<='9')
	x=(x<<3)+(x<<1)+a-48;
	x=x*f;
}
struct edge{
	int to,val,nexty;
}e[2050];
int head[1005],cnt;
void add(int a,int b,int c)
{
	e[++cnt].to=b;
	e[cnt].nexty=head[a];
	e[cnt].val=c;
	head[a]=cnt;
}
int dis[1005];
int val[1005],limit[1005];
int vis[1005],vist[1005];
queue<int>q;
void dfs(int x,int sx,int tag)
{
	if(tag>limit[sx])return;
	vist[x]=1;
	if(dis[x]>dis[sx]+val[sx])
	{
		dis[x]=dis[sx]+val[sx];
		if(!vis[x])
		{
			vis[x]=1;
			q.push(x);
		}
	}
	for(int i=head[x];i;i=e[i].nexty)
	{
		int to=e[i].to;
		if(vist[to])continue;
		dfs(to,sx,tag+e[i].val);
	}
}
int n,m,s,t;
void spfa(int st)
{
//	memset(dis,0x3f,sizeof(dis));
	for(int i=1;i<=n;i++)dis[i]=2e14;
	dis[st]=0;
	q.push(st);
	while(!q.empty())
	{
		int x=q.front();
	//	cout<<x<<"\n";
		q.pop();
		vis[x]=0;
		memset(vist,0,sizeof(vist));
		vist[x]=1;
		for(int i=head[x];i;i=e[i].nexty)
		{
			int to=e[i].to;
			if(e[i].val>limit[x])continue;
			dfs(to,x,e[i].val);
		}
	}

}

signed main()
{
	r(n),r(m);
	r(s),r(t);
	for(int i=1,x,y,z;i<=m;i++)
	{
		r(x),r(y),r(z);
		add(x,y,z),add(y,x,z);
	}
	for(int i=1;i<=n;i++)r(limit[i]),r(val[i]);
	spfa(s);
	if(dis[t]==2e14) cout<<"-1\n";
	else cout<<dis[t]<<"\n";
}


#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>
using namespace std;
void r(int &x)
{
	char a;
	int f=1;
	while((a=getchar())<'0'||a>'9')if(a=='-')f=-1;
	x=a-48;
	while((a=getchar())>='0'&&a<='9')
	x=(x<<3)+(x<<1)+a-48;
	x=x*f;
}
struct edge{
	int to,val,nexty;
}e[2050];
int head[1005],cnt;
void add(int a,int b)
{
	e[++cnt].to=b;
	e[cnt].nexty=head[a];
	head[a]=cnt;
}
int dis[1005];
int val[1005],limit[1005];
int vis[1005],vist[1005];
queue<int>q;
void dfs(int x,int sx,int tag)
{
	if(tag==limit[sx])return;
	vist[x]=1;
	if(dis[x]>dis[sx]+val[sx])
	{
		dis[x]=dis[sx]+val[sx];
		if(!vis[x])
		{
			vis[x]=1;
			q.push(x);
		}
	}
	for(int i=head[x];i;i=e[i].nexty)
	{
		int to=e[i].to;
		if(vist[to])continue;
		dfs(to,sx,tag+1);
	}
}
void spfa(int st)
{
	memset(dis,0x3f,sizeof(dis));
	dis[st]=0;
	q.push(st);
	while(!q.empty())
	{
		int x=q.front();
		q.pop();
		vis[x]=0;
		memset(vist,0,sizeof(vist));
		vist[x]=1;
		for(int i=head[x];i;i=e[i].nexty)
		{
			int to=e[i].to;
			dfs(to,x,1);
		}
	}

}
int n,m,s,t;
int main()
{
	r(n),r(m);
	r(s),r(t);
	for(int i=1,x,y,val;i<=m;i++)
	{
		r(x),r(y),r(val);
		add(x,y),add(y,x);
	}
	for(int i=1;i<=n;i++)r(limit[i]),r(val[i]);
	spfa(s);
	cout<<dis[t]<<"\n";
}


#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>
#define int long long
using namespace std;
void r(int &x)
{
	char a;
	int f=1;
	while((a=getchar())<'0'||a>'9')if(a=='-')f=-1;
	x=a-48;
	while((a=getchar())>='0'&&a<='9')
	x=(x<<3)+(x<<1)+a-48;
	x=x*f;
}
struct edge{
	int to,val,nexty;
}e[4050];
int head[2005],cnt;
void add(int a,int b,int c)
{
	e[++cnt].to=b;
	e[cnt].nexty=head[a];
	e[cnt].val=c;
	head[a]=cnt;
}
int dis[2005];
int val[2005],limit[2005];
int vis[2005],vist[2005];
queue<int>q;
void dfs(int x,int sx,int tag)
{
	if(tag>limit[sx])return;
	vist[x]=1;
	if(dis[x]>dis[sx]+val[sx])
	{
		dis[x]=dis[sx]+val[sx];
		if(!vis[x])
		{
			vis[x]=1;
			q.push(x);
		}
	}
	for(int i=head[x];i;i=e[i].nexty)
	{
		int to=e[i].to;
		if(vist[to])continue;
		dfs(to,sx,tag+e[i].val);
	}
}
int n,m,s,t;
void spfa(int st)
{
	for(int i=1;i<=n;i++)dis[i]=2e14;
	dis[st]=0;
	q.push(st);
	while(!q.empty())
	{
		int x=q.front();
		q.pop();
		vis[x]=0;
		for(int i=head[x];i;i=e[i].nexty)
		{
			memset(vist,0,sizeof(vist));
			vist[x]=1;
			int to=e[i].to;
			if(e[i].val>limit[x])continue;
			dfs(to,x,e[i].val);
		}
	}

}

signed main()
{
	r(n),r(m);
	r(s),r(t);
	for(int i=1,x,y,z;i<=m;i++)
	{
		r(x),r(y),r(z);
		add(x,y,z),add(y,x,z);
	}
	for(int i=1;i<=n;i++)
		r(limit[i]),r(val[i]);
	spfa(s);
	if(dis[t]==2e14) cout<<"-1\n";
	else cout<<dis[t]<<"\n";
}


#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>
#define int long long
using namespace std;
void r(int &x)
{
	char a;
	int f=1;
	while((a=getchar())<'0'||a>'9')if(a=='-')f=-1;
	x=a-48;
	while((a=getchar())>='0'&&a<='9')
	x=(x<<3)+(x<<1)+a-48;
	x=x*f;
}
struct edge{
	int to,val,nexty;
}e[4050];
int head[2005],cnt;
void add(int a,int b,int c)
{
	e[++cnt].to=b;
	e[cnt].nexty=head[a];
	e[cnt].val=c;
	head[a]=cnt;
}
int dis[2005];
int val[2005],limit[2005];
int vis[2005],vist[2005];
queue<int>q;
void dfs(int x,int sx,int tag)
{
	if(tag>limit[sx])return;
	vist[x]=1;
	if(dis[x]>dis[sx]+val[sx])
	{
		dis[x]=dis[sx]+val[sx];
		if(!vis[x])
		{
			vis[x]=1;
			q.push(x);
		}
	}
	for(int i=head[x];i;i=e[i].nexty)
	{
		int to=e[i].to;
		if(vist[to])continue;
		dfs(to,sx,tag+e[i].val);
	}
}
int n,m,s,t;
void spfa(int st)
{
	for(int i=1;i<=n;i++)dis[i]=2e14;
	dis[st]=0;
	q.push(st);
	while(!q.empty())
	{
		int x=q.front();
		q.pop();
		vis[x]=0;
		memset(vist,0,sizeof(vist));
		vist[x]=1;
		for(int i=head[x];i;i=e[i].nexty)
		{
			int to=e[i].to;
			if(e[i].val>limit[x])continue;
			dfs(to,x,e[i].val);
		}
	}

}

signed main()
{
	r(n),r(m);
	r(s),r(t);
	for(int i=1,x,y,z;i<=m;i++)
	{
		r(x),r(y),r(z);
		add(x,y,z),add(y,x,z);
	}
	for(int i=1;i<=n;i++)r(limit[i]),r(val[i]);
	spfa(s);
	if(dis[t]==2e14) cout<<"-1\n";
	else cout<<dis[t]<<"\n";
}


#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>
using namespace std;
void r(int &x)
{
	char a;
	int f=1;
	while((a=getchar())<'0'||a>'9')if(a=='-')f=-1;
	x=a-48;
	while((a=getchar())>='0'&&a<='9')
	x=(x<<3)+(x<<1)+a-48;
	x=x*f;
}
struct edge{
	int to,val,nexty;
}e[2050];
int head[1005],cnt;
void add(int a,int b,int c)
{
	e[++cnt].to=b;
	e[cnt].nexty=head[a];
	e[cnt].val=c;
	head[a]=cnt;
}
int dis[1005];
int val[1005],limit[1005];
int vis[1005],vist[1005];
queue<int>q;
void dfs(int x,int sx,int tag)
{
	if(tag>limit[sx])return;
	vist[x]=1;
	if(dis[x]>dis[sx]+val[sx])
	{
		dis[x]=dis[sx]+val[sx];
		if(!vis[x])
		{
			vis[x]=1;
			q.push(x);
		}
	}
	for(int i=head[x];i;i=e[i].nexty)
	{
		int to=e[i].to;
		if(vist[to])continue;
		dfs(to,sx,tag+e[i].val);
	}
}
void spfa(int st)
{
	memset(dis,0x3f,sizeof(dis));
	dis[st]=0;
	q.push(st);
	while(!q.empty())
	{
		int x=q.front();
	//	cout<<x<<"\n";
		q.pop();
		vis[x]=0;
		memset(vist,0,sizeof(vist));
		vist[x]=1;
		for(int i=head[x];i;i=e[i].nexty)
		{
			int to=e[i].to;
			if(e[i].val>limit[x])continue;
			dfs(to,x,e[i].val);
		}
	}

}
int n,m,s,t;
int main()
{
	r(n),r(m);
	r(s),r(t);
	for(int i=1,x,y,z;i<=m;i++)
	{
		r(x),r(y),r(z);
		add(x,y,z),add(y,x,z);
	}
	for(int i=1;i<=n;i++)r(limit[i]),r(val[i]);
	spfa(s);
	cout<<dis[t]<<"\n";
}


#include <iostream>
#include <bits/stdc++.h>
using namespace std;
int n,m;
int cost[1005][1005];
int vis[1005];
vector<pair< int,int> > v[1005];
int main()
{
  cin>>n>>m;
  int x,y;
  cin>>x>>y;
  for(int i=0;i<m;i++)
  {
      int a,b,w;
      cin>>a>>b>>w;
      v[a].push_back(make_pair(b,w));
      v[b].push_back(make_pair(a,w));
  }
  memset(cost,-1,sizeof(cost));
  for(int i=1;i<=n;i++)
  {
      int t,c;
      cin>>t>>c;
      priority_queue< pair<long,long> > pq;
      pq.push(make_pair(t,i));
      int vis[1005];
      memset(vis,0,sizeof(vis));
      while(!pq.empty())
      {
          pair<long,long> p=pq.top();
          pq.pop();
          if(vis[p.second])continue;
          if(cost[i][p.second]==-1)
          {
              cost[i][p.second]=c;
          }else{
            cost[i][p.second]=min(cost[i][p.second],c);
            vis[p.second]=1;
          }
          for(vector< pair<int,int> >::iterator it=v[p.second].begin();it!=v[p.second].end();it++)
          {
              if(it->second<=p.first&&!vis[it->first]){
                pq.push(make_pair(p.first-it->second,it->first));

                }
          }

      }
  }
 // cout<<"FINISH"<<endl;
  for(int i=1;i<=n;i++)
  {
      cost[i][i]=0;

  }
  priority_queue<pair<long,long> ,vector<pair<long,long> >,greater<pair<long,long> > > pq;
  pq.push(make_pair(0,x));
  int vis[1005];
  memset(vis,0,sizeof(vis));
  while(!pq.empty())
  {
      pair<int,int> p=pq.top();
      pq.pop();
      if(vis[p.second])
        continue;
      if(p.second==y){
        cout<<p.first<<endl;
        return 0;
      }
      vis[p.second]=1;
      for(int i=1;i<=n;i++)
      {
          if(cost[p.second][i]!=-1 && !vis[i]){

            pq.push(make_pair(p.first+cost[p.second][i],i));
          }
      }

  }
  cout<<"-1"<<endl;
}


#include <iostream>
#include <bits/stdc++.h>
using namespace std;
int n,m;
int cost[1005][1005];
int vis[1005];
vector<pair< int,int> > v[1005];
int main()
{
  cin>>n>>m;
  int x,y;
  cin>>x>>y;
  for(int i=0;i<m;i++)
  {
      int a,b,w;
      cin>>a>>b>>w;
      v[a].push_back(make_pair(b,w));
      v[b].push_back(make_pair(a,w));
  }
  memset(cost,-1,sizeof(cost));
  for(int i=1;i<=n;i++)
  {
      int t,c;
      cin>>t>>c;
      priority_queue< pair<int,int> > pq;
      pq.push(make_pair(t,i));
      int vis[1005];
      memset(vis,0,sizeof(vis));
      while(!pq.empty())
      {
          pair<int,int> p=pq.top();
          pq.pop();
          if(vis[p.second])continue;
          if(cost[i][p.second]==-1)
          {
              cost[i][p.second]=c;
          }else{
            cost[i][p.second]=min(cost[i][p.second],c);
            vis[p.second]=1;
          }
          for(vector< pair<int,int> >::iterator it=v[p.second].begin();it!=v[p.second].end();it++)
          {
              if(it->second<=p.first&&!vis[it->first]){
                pq.push(make_pair(p.first-it->second,it->first));

                }
          }

      }
  }
  //cout<<"FINISH"<<endl;
  for(int i=1;i<=n;i++)
  {
      cost[i][i]=0;

  }
  priority_queue<pair<int,int> ,vector<pair<int,int> >,greater<pair<int,int> > > pq;
  pq.push(make_pair(0,x));
  int vis[1005];
  memset(vis,0,sizeof(vis));
  while(!pq.empty())
  {
      pair<int,int> p=pq.top();
      pq.pop();
      if(vis[p.second])
        continue;
      if(p.second==y){
        cout<<p.first<<endl;
        return 0;
      }
      vis[p.second]=1;
      for(int i=1;i<=n;i++)
      {
          if(cost[p.second][i]!=-1 && !vis[i]){

            pq.push(make_pair(p.first+cost[p.second][i],i));
          }
      }

  cout<<"-1"<<endl;

  }
}


#include <iostream>
#include <bits/stdc++.h>
using namespace std;
int n,m;
int cost[1005][1005];
int vis[1005];
vector<pair< int,int> > v[1005];
int main()
{
  cin>>n>>m;
  int x,y;
  cin>>x>>y;
  for(int i=0;i<m;i++)
  {
      int a,b,w;
      cin>>a>>b>>w;
      v[a].push_back(make_pair(b,w));
      v[b].push_back(make_pair(a,w));
  }
  memset(cost,-1,sizeof(cost));
  for(int i=1;i<=n;i++)
  {
      int t,c;
      cin>>t>>c;
      priority_queue< pair<int,int> > pq;
      pq.push(make_pair(t,i));
      int vis[1005];
      memset(vis,0,sizeof(vis));
      while(!pq.empty())
      {
          pair<int,int> p=pq.top();
          pq.pop();
          if(vis[p.second])continue;
          if(cost[i][p.second]==-1)
          {
              cost[i][p.second]=c;
          }else{
            cost[i][p.second]=min(cost[i][p.second],c);
            vis[p.second]=1;
          }
          for(vector< pair<int,int> >::iterator it=v[p.second].begin();it!=v[p.second].end();it++)
          {
              if(it->second<=p.first&&!vis[it->first]){
                pq.push(make_pair(p.first-it->second,it->first));

                }
          }

      }
  }
 // cout<<"FINISH"<<endl;
  for(int i=1;i<=n;i++)
  {
      cost[i][i]=0;

  }
  priority_queue<pair<int,int> ,vector<pair<int,int> >,greater<pair<int,int> > > pq;
  pq.push(make_pair(0,x));
  int vis[1005];
  memset(vis,0,sizeof(vis));
  while(!pq.empty())
  {
      pair<int,int> p=pq.top();
      pq.pop();
      if(vis[p.second])
        continue;
      if(p.second==y){
        cout<<p.first<<endl;
        return 0;
      }
      vis[p.second]=1;
      for(int i=1;i<=n;i++)
      {
          if(cost[p.second][i]!=-1 && !vis[i]){

            pq.push(make_pair(p.first+cost[p.second][i],i));
          }
      }

  }
  cout<<"-1"<<endl;
}


#include <iostream>
#include <bits/stdc++.h>

using namespace std;
#define ll long long
int n,m;
int cost[1005][1005];
int vis[1005];
vector<pair< int,int> > v[1005];

int main()
{
  cin>>n>>m;
  int x,y;
  cin>>x>>y;
  for(int i=0;i<m;i++)
  {
      int a,b,w;
      cin>>a>>b>>w;
      v[a].push_back(make_pair(b,w));
      v[b].push_back(make_pair(a,w));
  }
  memset(cost,-1,sizeof(cost));
  for(int i=1;i<=n;i++)
  {
      int t,c;
      cin>>t>>c;
      priority_queue< pair<ll,ll> > pq;
      pq.push(make_pair(t,i));
      int vis[1005];
      memset(vis,0,sizeof(vis));
      while(!pq.empty())
      {
          pair<ll,ll> p=pq.top();
          pq.pop();
          if(vis[p.second])continue;
          if(cost[i][p.second]==-1)
          {
              cost[i][p.second]=c;
          }else{
            cost[i][p.second]=min(cost[i][p.second],c);
            vis[p.second]=1;
          }
          for(vector< pair<int,int> >::iterator it=v[p.second].begin();it!=v[p.second].end();it++)
          {
              if(it->second<=p.first&&!vis[it->first]){
                pq.push(make_pair(p.first-it->second,it->first));

                }
          }

      }
  }
 // cout<<"FINISH"<<endl;
  for(int i=1;i<=n;i++)
  {
      cost[i][i]=0;

  }
  priority_queue<pair<ll,ll> ,vector<pair<ll,ll> >,greater<pair<ll,ll> > > pq;
  pq.push(make_pair(0,x));
  int vis[1005];
  memset(vis,0,sizeof(vis));
  while(!pq.empty())
  {
      pair<ll,ll> p=pq.top();
      pq.pop();
      if(vis[p.second])
        continue;
      if(p.second==y){
        cout<<p.first<<endl;
        return 0;
      }
      vis[p.second]=1;
      for(int i=1;i<=n;i++)
      {
          if(cost[p.second][i]!=-1 && !vis[i]){

            pq.push(make_pair(p.first+0ll+cost[p.second][i],i));
          }
      }

  }
  cout<<"-1"<<endl;
}


#include<algorithm>
#include<cmath>
#include<cstdio>
#include<iostream>
#include<map>
#include<queue>
#include<set>
#include<sstream>
#include<string>
#include<cstring>
#include<vector>

#define forn(i,n) for(int i=0;i<(int)n;i++)
#define dforn(i,n) for(int i=(int)n-1;i>=0;i--)
#define all(v) v.begin(),v.end()
#define MOD 1000000007LL

using namespace std;

string s,t;

int dp[5001][5001];

int main()
{
    cin >> s >> t;
    memset(dp,0,sizeof(dp));
    forn(i,s.size())
    forn(j,t.size())
    if(s[i]==t[j])
    {
        if(j==0)
            dp[i][j] = 1;
        else if(i==0)
            dp[i][j] = dp[i][j-1]+1;
        else
            dp[i][j] = (dp[i][j-1]+dp[i-1][j-1]+1)%MOD;
    }
    else if(j!=0)
            dp[i][j] = dp[i][j-1];
    int res = 0;
    forn(i,s.size())
        res = (res+dp[i][t.size()-1])%MOD;
    cout << res << endl;
}


#include<iostream>
#include<algorithm>
#include<sstream>
#include<set>
#include<map>
#include<queue>
#include<cmath>
#include<cstdio>
#include<vector>

using namespace std;

#define forn(i,n) for(int i=0;i<n;i++)
#define dforn(i,n) for(int i=(int)n-1;i>=0;i--)
#define all(v) v.begin(),v.end()
#define MOD 1000000007LL

string s,t;
long long dp[6000][6000];

int main()
{
    cin >> s >> t;
    int n = s.size(),m=t.size();
    forn(i,n+1)
    forn(j,m+1)
        dp[i][j] = 0;
    long long res = 0;
    for(int i=n-1;i>=0;i--)
    for(int j=m-1;j>=0;j--)
    {
        if(s[i]==t[j])
        {
            dp[i][j] = (dp[i+1][j+1]+1)%MOD;
            res = (res+dp[i][j])%MOD;
            dp[i][j] += dp[i][j+1];
            dp[i][j] %= MOD;
        }
        else
        {
            dp[i][j] = dp[i][j+1];
        }
    }
    cout << res << endl;
}


#include <iostream>
#include <fstream>
#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <bitset>
#include <set>
#include <map>
#include <vector>
#include <cmath>
#include <string>
#include <cstring>
#include <queue>
#include <math.h>
#include <iomanip>
using namespace std;

#define FOR0(i,n) for( i = 0 ; i < n ; i++ )
#define FOR1(i,n) for( i = 1 ; i <= n ; i++ )
#define sys_p system( "pause" )
#define End return 0
#define pb push_back
#define mp make_pair

ifstream Cin("input.txt");
ofstream Cout( "output.txt" );

typedef long long ll ;

main()
{
      string a, b ;
      ll i, j, dp[5001][5001], ans = 0 ;
      cin >> a >> b ;
      for( i = a.length() - 1 ; i >= 0 ; i-- )
        for( j = b.length() - 1 ; j >= 0 ; j-- )
        {
              dp[i][j] = dp[i][j+1] ;
              if( a[i] == b[j] )
                dp[i][j] = ( dp[i][j] + dp[i+1][j+1] + 1 ) % 1000000007 ;
        }
      FOR0( i, a.length() )
        ans += dp[i][0] ;
      cout << ans ;
}


#include <iostream>
#include <fstream>
#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <bitset>
#include <set>
#include <map>
#include <vector>
#include <cmath>
#include <string>
#include <cstring>
#include <queue>
#include <math.h>
#include <iomanip>
using namespace std;

#define FOR0(i,n) for( i = 0 ; i < n ; i++ )
#define FOR1(i,n) for( i = 1 ; i <= n ; i++ )
#define sys_p system( "pause" )
#define End return 0
#define pb push_back
#define mp make_pair

ifstream Cin("input.txt");
ofstream Cout( "output.txt" );

typedef long long ll ;

main()
{
      string a, b ;
      ll i, j, dp[5005][5005] = { }, ans = 0 ;
      cin >> a >> b ;
      for( i = a.length() - 1 ; i >= 0 ; i-- )
        for( j = b.length() - 1 ; j >= 0 ; j-- )
        {
              dp[i][j] = dp[i][j+1] ;
              if( a[i] == b[j] )
                dp[i][j] = ( dp[i][j] + dp[i+1][j+1] + 1 ) % 1000000007 ;
        }
      FOR0( i, a.length() )
        ans += dp[i][0] ;
      cout << ans ;
}


#include <iostream>
#include <fstream>
#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <bitset>
#include <set>
#include <map>
#include <vector>
#include <cmath>
#include <string>
#include <cstring>
#include <queue>
#include <math.h>
#include <iomanip>
using namespace std;

#define FOR0(i,n) for( i = 0 ; i < n ; i++ )
#define FOR1(i,n) for( i = 1 ; i <= n ; i++ )
#define sys_p system( "pause" )
#define End return 0
#define pb push_back
#define mp make_pair

ifstream Cin("input.txt");
ofstream Cout( "output.txt" );

typedef long long ll ;

main()
{
      ll i, j, la, lb, dp[5005][5005] = { }, ans = 0 ;
      char a[5005], b[5005] ;

      cin >> a >> b ;
      la = strlen( a ) ;
      lb = strlen( b ) ;

      for( i = la - 1 ; i >= 0 ; i-- )
        for( j = lb - 1 ; j >= 0 ; j-- )
        {
              dp[i][j] = dp[i][j+1] ;
              if( a[i] == b[j] )
                dp[i][j] = ( dp[i][j] + dp[i+1][j+1] + 1LL ) % 1000000007 ;
        }
      FOR0( i, la )
        ans += dp[i][0] ;
      cout << ans ;
}


#include <iostream>
#include <fstream>
#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <bitset>
#include <set>
#include <map>
#include <vector>
#include <cmath>
#include <string>
#include <cstring>
#include <queue>
#include <math.h>
#include <iomanip>
using namespace std;

#define FOR0(i,n) for( i = 0 ; i < n ; i++ )
#define FOR1(i,n) for( i = 1 ; i <= n ; i++ )
#define sys_p system( "pause" )
#define End return 0
#define pb push_back
#define mp make_pair

ifstream Cin("input.txt");
ofstream Cout( "output.txt" );

typedef long long ll ;

main()
{
      string a, b ;
      ll i, j, dp[5005][5005], ans = 0 ;
      cin >> a >> b ;
      for( i = a.length() - 1 ; i >= 0 ; i-- )
        for( j = b.length() - 1 ; j >= 0 ; j-- )
        {
              dp[i][j] = dp[i][j+1] ;
              if( a[i] == b[j] )
                dp[i][j] = ( dp[i][j] + dp[i+1][j+1] + 1 ) % 1000000007 ;
        }
      FOR0( i, a.length() )
        ans += dp[i][0] ;
      cout << ans ;
}


#include <iostream>
#include <fstream>
#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <bitset>
#include <set>
#include <map>
#include <vector>
#include <cmath>
#include <string>
#include <cstring>
#include <queue>
#include <math.h>
#include <iomanip>
using namespace std;

#define FOR0(i,n) for( i = 0 ; i < n ; i++ )
#define FOR1(i,n) for( i = 1 ; i <= n ; i++ )
#define sys_p system( "pause" )
#define End return 0
#define pb push_back
#define mp make_pair

ifstream Cin("input.txt");
ofstream Cout( "output.txt" );

typedef long long ll ;

main()
{
      ll i, j, la, lb, dp[5005][5005] = { }, ans = 0 ;
      char a[5005], b[5005] ;

      cin >> a >> b ;
      la = strlen( a ) ;
      lb = strlen( b ) ;

      for( i = la - 1 ; i >= 0 ; i-- )
        for( j = lb - 1 ; j >= 0 ; j-- )
        {
              dp[i][j] = dp[i][j+1] ;
              if( a[i] == b[j] )
                dp[i][j] = ( dp[i][j] + dp[i+1][j+1] + 1 ) % 1000000007 ;
        }
      FOR0( i, la )
        ans += dp[i][0] ;
      cout << ans ;
}


#include <iostream>
#include <fstream>
#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <bitset>
#include <set>
#include <map>
#include <vector>
#include <cmath>
#include <string>
#include <cstring>
#include <queue>
#include <math.h>
#include <iomanip>
using namespace std;

#define FOR0(i,n) for( i = 0 ; i < n ; i++ )
#define FOR1(i,n) for( i = 1 ; i <= n ; i++ )
#define sys_p system( "pause" )
#define End return 0
#define pb push_back
#define mp make_pair

ifstream Cin("input.txt");
ofstream Cout( "output.txt" );

typedef long long ll ;

main()
{
      ll i, j, la, lb, dp[5005][5005] = { }, ans = 0 ;
      char a[5005], b[5005] ;

      cin >> a >> b ;
      la = strlen( a ) ;
      lb = strlen( b ) ;

      for( i = la - 1 ; i >= 0 ; i-- )
        for( j = lb - 1 ; j >= 0 ; j-- )
        {
              dp[i][j] = dp[i][j+1] ;
              if( a[i] == b[j] )
                dp[i][j] = dp[i][j] + dp[i+1][j+1] + (long long)1 ;
              dp[i][j] = dp[i][j] % 1000000007 ;
        }
      FOR0( i, la )
        ans += dp[i][0] ;
      cout << ans ;
}


#include <iostream>
#include <fstream>
#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <bitset>
#include <set>
#include <map>
#include <vector>
#include <cmath>
#include <string>
#include <cstring>
#include <queue>
#include <math.h>
#include <iomanip>
using namespace std;

#define FOR0(i,n) for( i = 0 ; i < n ; i++ )
#define FOR1(i,n) for( i = 1 ; i <= n ; i++ )
#define sys_p system( "pause" )
#define End return 0
#define pb push_back
#define mp make_pair

ifstream Cin("input.txt");
ofstream Cout( "output.txt" );

typedef long long ll ;

main()
{
      ll i, j, la, lb, dp[5005][5005] = { }, ans = 0 ;
      char a[5005], b[5005] ;

      cin >> a >> b ;
      la = strlen( a ) ;
      lb = strlen( b ) ;

      for( i = la - 1 ; i >= 0 ; i-- )
        for( j = lb - 1 ; j >= 0 ; j-- )
        {
              dp[i][j] = dp[i][j+1] ;
              if( a[i] == b[j] )
                dp[i][j] = dp[i][j] + dp[i+1][j+1] + (long long)1 ;
              dp[i][j] = dp[i][j] % 1000000007 ;
        }
      FOR0( i, la )
        ans += dp[i][0] , ans %= 1000000007 ;
      cout << ans ;
}


#include <iostream>
#include <fstream>
#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <bitset>
#include <set>
#include <map>
#include <vector>
#include <cmath>
#include <string>
#include <cstring>
#include <queue>
#include <math.h>
#include <iomanip>
using namespace std;

#define FOR0(i,n) for( i = 0 ; i < n ; i++ )
#define FOR1(i,n) for( i = 1 ; i <= n ; i++ )
#define sys_p system( "pause" )
#define End return 0
#define pb push_back
#define mp make_pair

ifstream Cin("input.txt");
ofstream Cout( "output.txt" );

typedef long long ll ;

main()
{
      ll i, j, la, lb, dp[5005][5005] = { }, ans = 0 ;
      char a[5005], b[5005] ;

      cin >> a >> b ;
      la = strlen( a ) ;
      lb = strlen( b ) ;

      for( i = la - 1 ; i >= 0 ; i-- )
        for( j = lb - 1 ; j >= 0 ; j-- )
        {
              dp[i][j] = dp[i][j+1] ;
              if( a[i] == b[j] )
                dp[i][j] = ( dp[i][j] + dp[i+1][j+1] + 1LL ) % 1000000007LL ;
        }
      FOR0( i, la )
        ans += dp[i][0] ;
      cout << ans ;
}


#include <iostream>
#include <cstdlib>
#include <queue>
#include <set>
#include <map>
#include <algorithm>
#include <vector>
#include <string>

#define For(i,a,n) for(int i = a ; i < n ; ++i )
#define n(x) (int)x.size()
#define pb(i) push_back(i)
#define all(x) x.begin(),x.end()
#define feach(i,a) for(typeof (a.begin()) i =  a.begin() ; i!=a.end() ; ++i)

using namespace std;
const int maxn = 5010;
typedef unsigned long long ull;
ull ans;
const ull mod = 1000*1000*1000+7;
ull d[maxn];
ull d2[maxn];
string s1 , s2;
int n , m;

void findans()
{
	For(i,0,m)
	{
		For(j,0,n)
			if(s2[i] == s1[j])
			{
				d2[j+1]+=d[j]+1;
				d2[j+1]%=mod;
			}
		For(j,1,n+1)
		{
			d[j]+=d2[j];
			d[j] = d[j]%mod;
			ans=(ans+d2[j])%mod;
			d2[j] = 0;
		}
	}
}

int main()
{
	ios::sync_with_stdio(false);
	cin >> s1 >> s2;
	n = n(s1);
	m = n(s2);
	findans();
	cout << ans << endl;
	return 0;
}


#include <iostream>
#include <cstdlib>
#include <queue>
#include <set>
#include <map>
#include <algorithm>
#include <vector>
#include <string>

#define For(i,a,n) for(int i = a ; i < n ; ++i )
#define n(x) (int)x.size()
#define pb(i) push_back(i)
#define all(x) x.begin(),x.end()
#define feach(i,a) for(typeof (a.begin()) i =  a.begin() ; i!=a.end() ; ++i)

using namespace std;
const int maxn = 5010;
typedef unsigned long long ull;
ull ans;
const int mod = 1000*1000*1000+7;
int d[maxn];
int d2[maxn];
string s1 , s2;
int n , m;

void findans()
{
	For(i,0,m)
	{
		For(j,0,n)
			if(s2[i] == s1[j])
			{
				d2[j+1]+=d[j]+1;
			}
		For(j,0,n+1)
		{
			d[j]+=d2[j];
			ans=(ans+d2[j])%mod;
			d2[j] = 0;
		}
	}
}

int main()
{
	ios::sync_with_stdio(false);
	cin >> s1 >> s2;
	n = n(s1);
	m = n(s2);
	findans();
	cout << ans << endl;
	return 0;
}


#include <iostream>
#include <cstdlib>
#include <queue>
#include <set>
#include <map>
#include <algorithm>
#include <vector>
#include <string>

#define For(i,a,n) for(int i = a ; i < n ; ++i )
#define n(x) (int)x.size()
#define pb(i) push_back(i)
#define all(x) x.begin(),x.end()
#define feach(i,a) for(typeof (a.begin()) i =  a.begin() ; i!=a.end() ; ++i)

using namespace std;
typedef unsigned long long ull;
typedef pair<ull,ull> puu;
const int p1 = 311;
const int p2 = 10007;
const int mod = 1000*1000*1000+7;
map <puu,int> sub;
map <puu,ull> sub2;
map <puu,ull> subt;
string s1 , s2;
ull ans;
int n , m;

void add(ull& h , char del , char ins , ull p , ull pk)
{
	h=h*p+ins-pk*del;
}

void findans()
{
	ull p1k;
	ull p2k;
	For(i,1,n+1)
	{
		// seting p1k , p2k
		p1k = p2k = 1;
		For(j,0,i)
			p1k=p1k*p1;
		For(j,0,i)
			p2k=p2k*p2;
		// calc all substring s1 with lenght i
		ull h1 = 0, h2 = 0;
		For(j,0,i)
			h1=h1*p1+s1[j];
		For(j,0,i)
			h2=h2*p2+s1[j];
		For(j,0,n-i+1)
		{
			sub[puu(h1,h2)]++;
			if(j!=n-i)
				add(h1,s1[j],s1[j+i],p1,p1k);
			if(j!=n-i)
				add(h2,s1[j],s1[j+i],p2,p2k);
		}
	}
	sub2[puu(0,0)] = 1;
	For(i,0,m)
	{
		subt.clear();
		feach(it,sub2)
		{
			ull h1 = it->first.first,h2= it->first.second;
			h1=h1*p1+s2[i];
			h2=h2*p2+s2[i];
			if(sub[puu(h1,h2)])
			{
				subt[puu(h1,h2)]+=it->second;
				subt[puu(h1,h2)]%=mod;
			}
			else
				sub.erase(puu(h1,h2));
		}
		feach(it,subt)
		{
			sub2[it->first]+=it->second;
			ans=(ans+it->second*sub[it->first])%mod;
		}
	}

}

int main()
{
	ios::sync_with_stdio(false);
	cin >> s1 >> s2;
	n = n(s1);
	m = n(s2);
	findans();
	cout << ans << endl;
	return 0;
}


#include <iostream>
#include <cstdlib>
#include <queue>
#include <set>
#include <map>
#include <algorithm>
#include <vector>
#include <string>

#define For(i,a,n) for(int i = a ; i < n ; ++i )
#define n(x) (int)x.size()
#define pb(i) push_back(i)
#define all(x) x.begin(),x.end()
#define feach(i,a) for(typeof (a.begin()) i =  a.begin() ; i!=a.end() ; ++i)

using namespace std;
const int maxn = 5010;
typedef unsigned long long ull;
ull ans;
const ull mod = 1000*1000*1000+7;
ull d[maxn];
ull d2[maxn];
string s1 , s2;
int n , m;

void findans()
{
	For(i,0,m)
	{
		For(j,0,n)
			if(s2[i] == s1[j])
			{
				d2[j+1]+=d[j]+1;
			}
		For(j,0,n+1)
		{
			d[j]+=d2[j];
			ans=(ans+d2[j])%mod;
			d2[j] = 0;
		}
	}
}

int main()
{
	ios::sync_with_stdio(false);
	cin >> s1 >> s2;
	n = n(s1);
	m = n(s2);
	findans();
	cout << ans << endl;
	return 0;
}


#include <iostream>
#include <cstdlib>
#include <queue>
#include <set>
#include <map>
#include <algorithm>
#include <vector>
#include <string>

#define For(i,a,n) for(int i = a ; i < n ; ++i )
#define n(x) (int)x.size()
#define pb(i) push_back(i)
#define all(x) x.begin(),x.end()
#define feach(i,a) for(typeof (a.begin()) i =  a.begin() ; i!=a.end() ; ++i)

using namespace std;
typedef unsigned long long ull;
typedef pair<ull,ull> puu;
const int p1 = 10007;
const int mod = 1000*1000*1000+7;
map <ull,int> sub;
map <ull,ull> sub2;
map <ull,ull> subt;
string s1 , s2;
ull ans;
int n , m;

void add(ull& h , char del , char ins , ull p , ull pk)
{
	h=h*p+ins-pk*del;
}

void findans()
{
	ull p1k;
	ull p2k;
	For(i,1,n+1)
	{
		// seting p1k , p2k
		p1k = p2k = 1;
		For(j,0,i)
			p1k=p1k*p1;
		// calc all substring s1 with lenght i
		ull h1 = 0;
		For(j,0,i)
			h1=h1*p1+s1[j];
		For(j,0,n-i+1)
		{
			sub[h1]++;
			if(j!=n-i)
				add(h1,s1[j],s1[j+i],p1,p1k);
		}
	}
	sub2[0] = 1;
	For(i,0,m)
	{
		subt.clear();
		feach(it,sub2)
		{
			ull h1 = it->first;
			h1=h1*p1+s2[i];
			if(sub[h1])
			{
				subt[h1]+=it->second;
				subt[h1]%=mod;
			}
			else
				sub.erase(h1);
		}
		feach(it,subt)
		{
			sub2[it->first]+=it->second;
			ans=(ans+it->second*sub[it->first])%mod;
		}
	}

}

int main()
{
	ios::sync_with_stdio(false);
	cin >> s1 >> s2;
	n = n(s1);
	m = n(s2);
	findans();
	cout << ans << endl;
	return 0;
}


#include <bits/stdc++.h>
using namespace std;
char s[5005],t[5005];
long long dp[5005][5005];
int main()
{
    int i,j,mi=INT_MAX,sl,tl;
    long long ans=0,mod=(10e9)+7;
    scanf("%s %s",&s,&t);
    sl=strlen(s);
    tl=strlen(t);
    for(i=0;i<sl;i++)
    {
        if(s[i]==t[0])
        {
            dp[i][0]=1;
        }
        if(i==0)
        {
            for(j=1;j<tl;j++)
            {
                if(s[i]==t[j])
                {
                    dp[i][j]=dp[i][j-1]+1;
                    dp[i][j]=dp[i][j]%mod;
                }
                else
                {
                    dp[i][j]=dp[i][j-1];
                    dp[i][j]=dp[i][j]%mod;
                }
            }
        }
        else
        {
            for(j=1;j<tl;j++)
            {
                if(s[i]==t[j])
                {
                    dp[i][j]=dp[i-1][j-1]+dp[i][j-1]+1;
                    dp[i][j]=dp[i][j]%mod;
                }
                else
                {
                    dp[i][j]=dp[i][j-1];
                    dp[i][j]=dp[i][j]%mod;
                }
            }
        }
        ans+=dp[i][tl-1];
        ans=ans%mod;
    }
    printf("%I64d\n",ans%mod);
    return 0;
}


#include<iostream>
#include<fstream>
#include<string.h>
#define lint long long int
#define MOD	1000000007
#define wait system("pause")
using namespace std;

int main(){
	char s1[5005],s2[5005];
	scanf("%s %s",s1,s2);
	lint res=0,i,j,m=strlen(s1),n=strlen(s2),DP[5005]={0};
	for( i=1;i<=n;i++ )		//s2
		for( j=m;j>=1;j-- )	//s1
			if( s1[j-1]==s2[i-1] ){
				DP[j]+=DP[j-1]+1;
				if(DP[j]>=MOD)
					DP[j]%=MOD;
			}
	for(j=1;j<=m;j++){
		res+=DP[j];
		if(res>=MOD)
			res%=MOD;
	}
	cout<<res<<endl;
//	wait;
}


#include<iostream>
#include<fstream>
#include<string.h>
#define lint long long int
#define MOD	1000000007
#define wait system("pause")
using namespace std;

int DP[5005];

int main(){
	char s1[5005],s2[5005];
	scanf("%s %s",s1,s2);
	int res=0,i,j,m=strlen(s1),n=strlen(s2);
	for( i=0;i<n;i++ )		//s2
		for( j=m-1;j>-1;j-- )	//s1
			if( s1[j]==s2[i] ){
				DP[j]=DP[j]+DP[j-1]+1;
				if(DP[j]>=MOD)
					DP[j]%=MOD;
			}
	for(j=1;j<=m;j++){
		res=res+DP[j];
		if(res>=MOD)
			res%=MOD;
	}
	printf("%d\n",res);
//	wait;
}


#include<iostream>
#include<fstream>
#include<string.h>
#define lint long long int
#define MOD	1000000007
#define wait system("pause")
using namespace std;

int main(){
	char s1[5005],s2[5005];
	scanf("%s %s",s1,s2);
	int res=0,i,j,m=strlen(s1),n=strlen(s2),DP[5005]={0};
	for( i=1;i<=n;i++ )		//s2
		for( j=m;j>=1;j-- )	//s1
			if( s1[j-1]==s2[i-1] ){
				DP[j]+=DP[j-1]+1;
				if(DP[j]>=MOD)
					DP[j]%=MOD;
			}
	for(j=1;j<=m;j++){
		res+=DP[j];
		if(res>=MOD)
			res%=MOD;
	}
	printf("%d\n",res);
//	wait;
}


#include<iostream>
#include<fstream>
#include<string.h>
#define lint long long int
#define MOD	1000000007
#define wait system("pause")
using namespace std;

int main(){
	char s1[5005],s2[5005];
	scanf("%s %s",s1,s2);
	lint res=0,i,j,m=strlen(s1),n=strlen(s2),DP[5005]={0};
	for( i=1;i<=n;i++ )		//s2
		for( j=m;j>=1;j-- )	//s1
			if( s1[j-1]==s2[i-1] ){
				DP[j]=(DP[j]+DP[j-1]+1)%MOD;
			}
	for(j=1;j<=m;j++){
		res=(res+DP[j])%MOD;
	}
	cout<<res<<endl;
//	wait;
}


#include<iostream>
#include<fstream>
#include<string.h>
#define lint long long int
#define MOD	1000000007
#define wait system("pause")
using namespace std;

int main(){
	char s1[5005],s2[5005];
	cin>>s1>>s2;
	lint res=0,i,j,m=strlen(s1),n=strlen(s2),DP[5005]={0};
	for( i=1;i<=n;i++ )		//s2
		for( j=m;j>=1;j-- )	//s1
			if( s1[j-1]==s2[i-1] ){
				DP[j]+=DP[j-1]+1;
				if(DP[j]>=MOD)
					DP[j]%=MOD;
			}
	for(j=1;j<=m;j++){
		res+=DP[j];
		if(res>=MOD)
			res%=MOD;
	}
	cout<<res<<endl;
//	wait;
}


#include<iostream>
#include<fstream>
#include<string.h>
#define lint long long int
#define MOD	1000000007
#define wait system("pause")
using namespace std;

int main(){
	char s1[5005],s2[5005];
	scanf("%s %s",s1,s2);
	lint res=0,i,j,m=strlen(s1),n=strlen(s2),DP[5005]={0};
	for( i=1;i<=n;i++ )		//s2
		for( j=m;j>=1;j-- )	//s1
			if( s1[j-1]==s2[i-1] ){
				DP[j]+=DP[j-1]+1;
				if(DP[j]==MOD)
					DP[j]=0;
			}
	for(j=1;j<=m;j++){
		res+=DP[j];
		if(res>=MOD)
			res%=MOD;
	}
	cout<<res<<endl;
//	wait;
}


#include<iostream>
#include<fstream>
#include<string.h>
#define lint long long int
#define MOD	1000000007
#define wait system("pause")
using namespace std;

int DP[5005];

int main(){
	char s1[5005],s2[5005];
	scanf("%s %s",s1,s2);
	int res=0,i,j,m=strlen(s1),n=strlen(s2);
	for( i=1;i<=n;i++ )		//s2
		for( j=m;j>=1;--j )	//s1
			if( s1[j-1]==s2[i-1] ){
				DP[j]+=DP[j-1]+1;
				if(DP[j]>=MOD)
					DP[j]%=MOD;
			}
	for(j=1;j<=m;j++){
		res+=DP[j];
		if(res>=MOD)
			res%=MOD;
	}
	printf("%d\n",res);
//	wait;
}


#include<iostream>
#include<fstream>
#include<string.h>
#define lint long long int
#define MOD	1000000007
#define wait system("pause")
using namespace std;

int DP[5005];

int main(){
	char s1[5005],s2[5005];
	scanf("%s %s",s1,s2);
	int res=0,i,j,m=strlen(s1),n=strlen(s2);
	for( i=1;i<=n;i++ )		//s2
		for( j=m;j>0;j-- )	//s1
			if( s1[j-1]==s2[i-1] ){
				DP[j]=DP[j]+DP[j-1]+1;
				if(DP[j]>=MOD)
					DP[j]%=MOD;
			}
	for(j=1;j<=m;j++){
		res=res+DP[j];
		if(res>=MOD)
			res%=MOD;
	}
	printf("%d\n",res);
//	wait;
}


#include<iostream>
#include<fstream>
#include<string.h>
#define lint long long int
#define MOD	1000000007
#define wait system("pause")
using namespace std;

int DP[5005];

int main(){
	char s1[5005],s2[5005];
	scanf("%s %s",s1,s2);
	int res=0,i,j,m=strlen(s1),n=strlen(s2);
	for( i=1;i<=n;i++ )		//s2
		for( j=m;j>0;j-- )	//s1
			if( s1[j-1]==s2[i-1] ){
				DP[j]=DP[j]+DP[j-1]+1;
				if(DP[j]>=MOD)
					DP[j]=DP[j]-MOD;
			}
	for(j=1;j<=m;j++){
		res=res+DP[j];
		if(res>=MOD)
			res=res-MOD;
	}
	printf("%d\n",res);
//	wait;
}


#include<iostream>
#include<fstream>
#include<string.h>
#define lint long long int
#define MOD	1000000007
#define wait system("pause")
using namespace std;

int main(){
	char s1[5005],s2[5005];
	cin>>s1>>s2;
	int res=0,i,j,m=strlen(s1),n=strlen(s2),DP[5005]={0};
	for( i=1;i<=n;i++ )		//s2
		for( j=m;j>=1;j-- )	//s1
			if( s1[j-1]==s2[i-1] ){
				DP[j]+=DP[j-1]+1;
				if(DP[j]>=MOD)
					DP[j]%=MOD;
			}
	for(j=1;j<=m;j++){
		res+=DP[j];
		if(res>=MOD)
			res%=MOD;
	}
	cout<<res<<endl;
//	wait;
}


#include<iostream>
#include<fstream>
#include<string.h>
#define lint long long int
#define MOD	1000000007
#define wait system("pause")
using namespace std;

int DP[5005];

int main(){
	char s1[5005],s2[5005];
	scanf("%s %s",s1,s2);
	int res=0,i,j,m=strlen(s1),n=strlen(s2);
	for( i=1;i<=n;i++ )		//s2
		for( j=m;j>=1;--j )	//s1
			if( s1[j-1]==s2[i-1] ){
				DP[j]=DP[j]+DP[j-1]+1;
				if(DP[j]>=MOD)
					DP[j]%=MOD;
			}
	for(j=1;j<=m;j++){
		res=res+DP[j];
		if(res>=MOD)
			res%=MOD;
	}
	printf("%d\n",res);
//	wait;
}


#include<iostream>
#include<fstream>
#include<string.h>
#define lint long long int
#define MOD	1000000007
#define wait system("pause")
using namespace std;

int DP[5005];

int main(){
	char s1[5005],s2[5005];
	scanf("%s %s",s1,s2);
	int res=0,i,j,m=strlen(s1),n=strlen(s2),t;
	for( i=0;i<n;i++ )		//s2
		for( j=m-1;j>-1;j-- )	//s1
			if( s1[j]==s2[i] ){
				t=j+1;
				DP[t]=DP[t]+DP[j]+1;
				if(DP[t]>=MOD)
					DP[t]%=MOD;
			}
	for(j=1;j<=m;j++){
		res=res+DP[j];
		if(res>=MOD)
			res%=MOD;
	}
	printf("%d\n",res);
//	wait;
}


#include<iostream>
#include<fstream>
#define lint long long int
#define MOD	1000000007
#define wait system("pause")
using namespace std;

int main(){
	char s1[5005],s2[5005];
	scanf("%s %s",s1,s2);
	lint res=0,i,j,m=strlen(s1),n=strlen(s2),DP[5005]={0};
	for( i=1;i<=n;i++ )		//s2
		for( j=m;j>=1;j-- )	//s1
			if( s1[j-1]==s2[i-1] ){
				DP[j]+=DP[j-1]+1;
				if(DP[j]==MOD)
					DP[j]=0;
			}
	for(j=1;j<=m;j++){
		res+=DP[j];
		if(res>=MOD)
			res%=MOD;
	}
	cout<<res<<endl;
//	wait;
}


#include <cstdio>
#include <cstring>
using namespace std;

const int maxlen = 10000;
const int MOD = 1000000009;
char s[maxlen], t[maxlen];
int n, m;
int f[2][maxlen], g[2][maxlen];

void init() {
    scanf("%s", &s);
    scanf("%s", &t);
    n = strlen(s);
    m = strlen(t);
}

void work() {
    memset(f, 0, sizeof(f));
    memset(g, 0, sizeof(g));
    int ans = 0;
    for (int i = 0; i < n; i ++)
        for (int j = 0; j < m; j ++) {
            f[i%2][j] = 0;
            if (s[i] == t[j]) {
                f[i%2][j] = 1;
                f[i%2][j] = (f[i%2][j] + g[1-i%2][j-1]) % MOD;
            }
            ans = (ans + f[i%2][j]) % MOD;
            g[i%2][j] = (g[i%2][j-1] + f[i%2][j]) % MOD;
        }
    printf("%d\n", ans);
}

int main() {
    //freopen("A.in","r",stdin);
    //freopen("A.out","w",stdout);
    init();
    work();
    return 0;
}


#include <cstdio>
#include <cstring>
using namespace std;

const int maxlen = 10000;
const int MOD = 1000000009;
char s[maxlen], t[maxlen];
int n, m;
int f[2][maxlen], g[2][maxlen];

void init() {
    scanf("%s", &s);
    scanf("%s", &t);
    n = strlen(s);
    m = strlen(t);
}

void work() {
    memset(f, 0, sizeof(f));
    memset(g, 0, sizeof(g));
    int ans = 0;
    for (int i = 0; i < n; i ++)
        for (int j = 0; j < m; j ++) {
            f[i%2][j] = 0;
            if (s[i] == t[j]) {
                f[i%2][j] = 1;
                if (j > 0)
                    f[i%2][j] = (f[i%2][j] + g[1-i%2][j-1]) % MOD;
            }
            ans = (ans + f[i%2][j]) % MOD;
            if (j > 0)
                g[i%2][j] = (g[i%2][j-1] + f[i%2][j]) % MOD;
            else
                g[i%2][j] = f[i%2][j] % MOD;
        }
    printf("%d\n", ans);
}

int main() {
    //freopen("A.in","r",stdin);
    //freopen("A.out","w",stdout);
    init();
    work();
    return 0;
}


#include <cstdio>
#include <cstring>
using namespace std;

const int maxlen = 10000;
const int MOD = 1000000007;
char s[maxlen], t[maxlen];
int n, m;
int f[2][maxlen], g[2][maxlen];

void init() {
    scanf("%s", &s);
    scanf("%s", &t);
    n = strlen(s);
    m = strlen(t);
}

void work() {
    memset(f, 0, sizeof(f));
    memset(g, 0, sizeof(g));
    int ans = 0;
    for (int i = 0; i < n; i ++)
        for (int j = 0; j < m; j ++) {
            f[i%2][j] = 0;
            if (s[i] == t[j]) {
                f[i%2][j] = 1;
                if (j > 0)
                    f[i%2][j] = (f[i%2][j] + g[1-i%2][j-1]) % MOD;
            }
            ans = (ans + f[i%2][j]) % MOD;
            if (j > 0)
                g[i%2][j] = (g[i%2][j-1] + f[i%2][j]) % MOD;
            else
                g[i%2][j] = f[i%2][j] % MOD;
        }
    printf("%d\n", ans);
}

int main() {
    //freopen("A.in","r",stdin);
    //freopen("A.out","w",stdout);
    init();
    work();
    return 0;
}


#include <cstdio>
#include <cstring>
using namespace std;

const int maxlen = 10000;
const int MOD = 1000000009;
char s[maxlen], t[maxlen];
int n, m;
int f[2][maxlen], g[2][maxlen];

void init() {
    scanf("%s", &s);
    scanf("%s", &t);
    n = strlen(s);
    m = strlen(t);
}

void work() {
    memset(f, 0, sizeof(f));
    memset(g, 0, sizeof(g));
    int ans = 0;
    for (int i = 0; i < n; i ++)
        for (int j = 0; j < m; j ++) {
            f[i%2][j] = 0;
            if (s[i] == t[j]) {
                f[i%2][j] = 1;
                if (j > 0)
                    f[i%2][j] = (f[i%2][j] + g[1-i%2][j-1]) % MOD;
            }
            ans = (ans + f[i%2][j]) % MOD;
            if (j > 0)
                g[i%2][j] = (g[i%2][j-1] + f[i%2][j]) % MOD;
            else
                g[i%2][j] = f[i%2][j];
        }
    printf("%d\n", ans);
}

int main() {
    //freopen("A.in","r",stdin);
    //freopen("A.out","w",stdout);
    init();
    work();
    return 0;
}


#include <cstdio>
#include <cstring>
#include <iostream>

using namespace std;

int f[5010][5010];

int main(){
    char str[5010],str2[5010];
    scanf("%s%s",str,str2);
    int n=strlen(str),m=strlen(str2);
    for(int i=0;i<=n;++i)f[i][m]=0;
    for(int j=0;j<=m;++j)f[n][j]=0;
    f[n][m]=0;
    for(int i=n-1;i>=0;--i){
        for(int j=m-1;j>=0;--j){
            f[i][j]=f[i][j+1];
            if(str[i]==str2[j])
                f[i][j]+=1+f[i+1][j+1];
        }
    }
    int sum=0;
    for(int i=0;i<=n;++i)sum+=f[i][0];
    printf("%d\n",sum);
}


#include <cstdio>
#include <cstring>
#include <iostream>

using namespace std;

int f[5010][5010];

int main(){
    char str[5010],str2[5010];
    scanf("%s%s",str,str2);
    int n=strlen(str),m=strlen(str2);
    for(int i=0;i<=n;++i)f[i][m]=0;
    for(int j=0;j<=m;++j)f[n][j]=0;
    f[n][m]=0;
    for(int i=n-1;i>=0;--i){
        for(int j=m-1;j>=0;--j){
            f[i][j]=f[i][j+1];
            if(str[i]==str2[j])
                f[i][j]+=1+f[i+1][j+1];
        }
    }
    long long sum=0;
    for(int i=0;i<=n;++i)sum=(sum+f[i][0])%1000000007;
    printf("%d\n",sum);
}


#include <cstdio>
#include <string>
#include <iostream>

using namespace std;

int f[5010][5010];

int main(){
    char str[5010],str2[5010];
    scanf("%s%s",str,str2);
    int n=strlen(str),m=strlen(str2);
    for(int i=0;i<=n;++i)f[i][m]=0;
    for(int j=0;j<=m;++j)f[n][j]=0;
    f[n][m]=0;
    for(int i=n-1;i>=0;--i){
        for(int j=m-1;j>=0;--j){
            f[i][j]=f[i][j+1];
            if(str[i]==str2[j])
                f[i][j]+=1+f[i+1][j+1];
        }
    }
    int sum=0;
    for(int i=0;i<=n;++i)sum+=f[i][0];
    printf("%d\n",sum);
}


#include <cstdio>
#include <cstring>
#include <iostream>

using namespace std;

int f[5010][5010];

int main(){
    char str[5010],str2[5010];
    scanf("%s%s",str,str2);
    int n=strlen(str),m=strlen(str2);
    for(int i=0;i<=n;++i)f[i][m]=0;
    for(int j=0;j<=m;++j)f[n][j]=0;
    f[n][m]=0;
    for(int i=n-1;i>=0;--i){
        for(int j=m-1;j>=0;--j){
            f[i][j]=f[i][j+1];
            if(str[i]==str2[j])
                f[i][j]+=1+f[i+1][j+1];
        }
    }
    int sum=0;
    for(int i=0;i<=n;++i)sum=(sum+f[i][0])%1000000007;
    printf("%d\n",sum);
}


#include <cstdio>
#include <cstring>
#include <iostream>

using namespace std;

long long f[5010][5010];

long long mod = 1000000007LL;
int main(){
    char str[5010],str2[5010];
    scanf("%s%s",str,str2);
    int n=strlen(str),m=strlen(str2);
    for(int i=0;i<=n;++i)f[i][m]=0;
    for(int j=0;j<=m;++j)f[n][j]=0;
    f[n][m]=0;
    for(int i=n-1;i>=0;--i){
        for(int j=m-1;j>=0;--j){
            f[i][j]=f[i][j+1];
            if(str[i]==str2[j])
                f[i][j]+=(1+f[i+1][j+1])%mod;
        }
    }
    long long sum=0;
    for(int i=0;i<=n;++i)sum=(sum+f[i][0])%mod;
    printf("%d\n",sum);
}


#include <cstdio>
#include <cstring>
#include <iostream>

using namespace std;

long long f[5010][5010];

int main(){
    char str[5010],str2[5010];
    scanf("%s%s",str,str2);
    int n=strlen(str),m=strlen(str2);
    for(int i=0;i<=n;++i)f[i][m]=0;
    for(int j=0;j<=m;++j)f[n][j]=0;
    f[n][m]=0;
    for(int i=n-1;i>=0;--i){
        for(int j=m-1;j>=0;--j){
            f[i][j]=f[i][j+1];
            if(str[i]==str2[j])
                f[i][j]+=1+f[i+1][j+1];
        }
    }
    long long sum=0;
    for(int i=0;i<=n;++i)sum=(sum+f[i][0])%1000000007;
    printf("%d\n",sum);
}


#include <cstdio>
#include <string>
using namespace std;

int f[5010][5010];

int main(){
    char str[5010],str2[5010];
    scanf("%s%s",str,str2);
    int n=strlen(str),m=strlen(str2);
    for(int i=0;i<=n;++i)f[i][m]=0;
    for(int j=0;j<=m;++j)f[n][j]=0;
    f[n][m]=0;
    for(int i=n-1;i>=0;--i){
        for(int j=m-1;j>=0;--j){
            f[i][j]=f[i][j+1];
            if(str[i]==str2[j])
                f[i][j]+=1+f[i+1][j+1];
        }
    }
    int sum=0;
    for(int i=0;i<=n;++i)sum+=f[i][0];
    printf("%d\n",sum);
}


#include <cstdio>
#include <cstring>
#include <iostream>

using namespace std;

long long f[5010][5010];

int main(){
    char str[5010],str2[5010];
    scanf("%s%s",str,str2);
    int n=strlen(str),m=strlen(str2);
    for(int i=0;i<=n;++i)f[i][m]=0;
    for(int j=0;j<=m;++j)f[n][j]=0;
    f[n][m]=0;
    for(int i=n-1;i>=0;--i){
        for(int j=m-1;j>=0;--j){
            f[i][j]=f[i][j+1];
            if(str[i]==str2[j])
                f[i][j]+=1+f[i+1][j+1];
        }
    }
    long long sum=0;
    for(int i=0;i<=n;++i)sum=(sum+f[i][0])%1000000007LL;
    printf("%d\n",sum);
}


#include <cstdio>
#include <cstring>
#include <iostream>

using namespace std;

long long f[5010][5010];

    long long mod = 1000000007LL:
int main(){
    char str[5010],str2[5010];
    scanf("%s%s",str,str2);
    int n=strlen(str),m=strlen(str2);
    for(int i=0;i<=n;++i)f[i][m]=0;
    for(int j=0;j<=m;++j)f[n][j]=0;
    f[n][m]=0;
    for(int i=n-1;i>=0;--i){
        for(int j=m-1;j>=0;--j){
            f[i][j]=f[i][j+1];
            if(str[i]==str2[j])
                f[i][j]+=(1+f[i+1][j+1])%mod;
        }
    }
    long long sum=0;
    for(int i=0;i<=n;++i)sum=(sum+f[i][0])%mod;
    printf("%d\n",sum);
}


#include <iostream>
#include <string>

#define MAXN 5001
#define L 1000000007

using namespace std;

int d[MAXN][MAXN] = {0};

char s[MAXN], t[MAXN];

int main()
{
//    freopen("input.txt", "r", stdin);

    cin >> s;
    cin >> t;

    int ans = 0;

    for (int i = 0; i < strlen(s); i++)
    {
        for (int j = 0; j < strlen(t); j++)
        {
            d[i + 1][j + 1] = d[i + 1][j];
            if (s[i] == t[j]) d[i + 1][j + 1] = (d[i + 1][j + 1] + d[i][j] + 1) % L;
//            cout << d[i + 1][j + 1] << " ";
        }
        ans = (ans + d[i + 1][strlen(t)]) % L;
//        cout << endl;
    }

    cout << ans;

    return 0;
}