#include<vector>
template<typename T> class SegmentTree {
 public:
  SegmentTree(int n) : size_(1) {
    while(size_ < n) size_ <<= 1;
    node_.assign(size_ << 1, 0);
    lazy_.assign(size_ << 1, 0);
  }
  T find(int left, int right) {return find(left, right + 1, 1, 0, size_);}
  void add(int left, int right, T value) {add(left, right + 1, value, 1, 0, size_);}
 private:
  int left_child(int node) const {return node << 1;}
  int right_child(int node) const {return (node << 1) + 1;}
  T find(int a, int b, int k, int l, int r) {
    if(b <= l || r <= a) return 0;
    if(a <= l && r <= b) return node_.at(k) + (r - l) * lazy_.at(k);
    lazy_.at(left_child(k)) += lazy_.at(k);
    lazy_.at(right_child(k)) += lazy_.at(k);
    node_.at(k) += (r - l) * lazy_.at(k);
    lazy_.at(k) = 0;
    auto vl = find(a, b, left_child(k), l, (l + r) / 2);
    auto vr = find(a, b, right_child(k), (l + r) / 2, r);
    return vl + vr;
  }
  T add(int a, int b, T value, int k, int l, int r) {
    if(b <= l || r <= a) return node_.at(k) + (r - l) * lazy_.at(k);
    if(a <= l && r <= b) return node_.at(k) + (r - l) * (lazy_.at(k) += value);
    lazy_.at(left_child(k)) += lazy_.at(k);
    lazy_.at(right_child(k)) += lazy_.at(k);
    lazy_.at(k) = 0;
    auto vl = add(a, b, value, left_child(k), l, (l + r) / 2);
    auto vr = add(a, b, value, right_child(k), (l + r) / 2, r);
    return node_.at(k) = vl + vr;
  }
  int size_;
  std::vector<T> node_;
  std::vector<T> lazy_;
};

// ??°??????
template<typename T, T M = T(1e9 + 7)>
struct ModInt {
  T number;
  ModInt(T n = 0) : number(n % M) {while(number < 0) number += M;}
  // ??£??\??????
  ModInt& operator+=(const ModInt& m) {return *this = *this + m;}
  ModInt& operator-=(const ModInt& m) {return *this = *this - m;}
  ModInt& operator*=(const ModInt& m) {return *this = *this * m;}
  ModInt& operator/=(const ModInt& m) {return *this = *this / m;}
  ModInt& operator%=(const ModInt& m) {return *this = *this % m;}
  // ????????????
  friend const ModInt operator+(const ModInt& lhs, const ModInt& rhs) {return lhs.number + rhs.number;}
  friend const ModInt operator-(const ModInt& lhs, const ModInt& rhs) {return lhs.number - rhs.number;}
  friend const ModInt operator*(const ModInt& lhs, const ModInt& rhs) {return lhs.number * rhs.number;}
  friend const ModInt operator/(const ModInt& lhs, const ModInt& rhs) {return lhs.number * modpow(rhs.number, M - 2, M);}
  friend const ModInt operator%(const ModInt& lhs, const ModInt& rhs) {return lhs.number % rhs.number;}
  // ??¢?????????
  friend bool operator==(const ModInt& lhs, const ModInt& rhs) {return lhs.number == rhs.number;}
  friend bool operator!=(const ModInt& lhs, const ModInt& rhs) {return lhs.number != rhs.number;}
  friend bool operator<=(const ModInt& lhs, const ModInt& rhs) {return lhs.number <= rhs.number;}
  friend bool operator>=(const ModInt& lhs, const ModInt& rhs) {return lhs.number >= rhs.number;}
  friend bool operator<(const ModInt& lhs, const ModInt& rhs) {return lhs.number < rhs.number;}
  friend bool operator>(const ModInt& lhs, const ModInt& rhs) {return lhs.number > rhs.number;}
};
// ??\?????????????????????
#include<iostream>
template<typename T, T M> inline std::istream& operator>>(std::istream& is, ModInt<T, M>& m) {return is >> m.number;}
template<typename T, T M> inline std::ostream& operator<<(std::ostream& os, const ModInt<T, M>& m) {return os << m.number;}

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

int main() {
  string T, B;
  cin >> T >> B;

  SegmentTree<ModInt<long long>> cur(T.size());
  cur.add(0, T.size() - 1, 1);
  for(int i = B.size() - 1; 1 <= i; --i) {
    SegmentTree<ModInt<long long>> nex(T.size());
    auto ok = false;
    for(int j = T.size() - 1; 0 <= j; --j) {
      if(cur.find(j, j) != 0) ok = true;
      if(ok && T[j] == B[i]) nex.add(0, j - 1, cur.find(j, j));
    }
    swap(cur, nex);
  }

  ModInt<long long> ans;
  for(int j = 0; j < T.size(); ++j) if(T[j] == B.front()) ans += cur.find(j, j);
  cout << ans << endl;
}

Measured memory_bytes: 3256