You are given a straight half-line divided into segments of unit length, which we will call positions. The positions are numbered by positive integers that start with 1 from the end of half-line, i. e. 1, 2, 3 and so on. The distance between the positions is the absolute difference between the respective numbers. Laharl, Etna and Flonne occupy some positions on the half-line and they want to get to the position with the largest possible number. They are originally placed in different positions. Each of the characters can perform each of the following actions no more than once:   Move a certain distance.  Grab another character and lift him above the head.  Throw the lifted character a certain distance.  Each character has a movement range parameter. They can only move to free positions, assuming that distance between those positions doesn't exceed the movement range. One character can lift another character if the distance between the two characters equals 1, and no one already holds that another character. We can assume that the lifted character moves to the same position as the person who has lifted him, and the position in which he stood before becomes free. A lifted character cannot perform any actions and the character that holds him cannot walk. Also, each character has a throwing range parameter. It is the distance at which this character can throw the one lifted above his head. He can only throw a character to a free position, and only when there is a lifted character. We accept the situation when one person grabs another one who in his turn has the third character in his hands. This forms a "column" of three characters. For example, Laharl can hold Etna while Etna holds Flonne. In this case, Etna and the Flonne cannot perform any actions, and Laharl can only throw Etna (together with Flonne) at some distance. Laharl, Etna and Flonne perform actions in any order. They perform actions in turns, that is no two of them can do actions at the same time.Determine the maximum number of position at least one of the characters can reach. That is, such maximal number x so that one of the characters can reach position x.

The first line contains three integers: Laharl's position, his movement range and throwing range. The second and the third lines describe Etna's and Flonne's parameters correspondingly in the similar form. It is guaranteed that the three characters occupy distinct positions. All numbers in the input are between 1 and 10, inclusive.

Print a single number — the maximum ordinal number of position which either Laharl, Etna or Flonne can reach.

NoteLet us explain how to reach position 15 in the sample.Initially Laharl occupies position 9, Etna — position 4 and Flonne — position 2.First Laharl moves to position 6.Then Flonne moves to position 5 and grabs Etna.Laharl grabs Flonne and throws to position 9.Flonne throws Etna to position 12.Etna moves to position 15.

var x,l,r,q:array[1..3]of longint;
    p:array[1..9]of boolean;
    i,j,k,n,ans:longint;
function max(x,y:longint):longint;
begin
  if x>y then max:=x else max:=y;
end;
procedure gc;
var i,o,j,k:longint;
    xx,qq:array[1..3]of longint;
    pp:boolean;
begin
  ans:=max(ans,max(x[1],max(x[2],x[3])));
  for i:=1 to 3 do begin xx[i]:=x[i];qq[i]:=q[i];end;
  for o:=1 to 3 do if not(p[o]) then
  begin
    pp:=true;
    for i:=1 to 3 do if (x[o]=x[i])and(o<>i) then pp:=false;
    if pp then
    for i:=-l[o] to l[o] do
    begin
      pp:=true;for j:=1 to 3 do if i+x[o]=x[j] then pp:=false;
      if pp then
      begin
        pp:=false;if i=l[o] then pp:=true;
        for j:=1 to 3 do
        begin
          if abs(x[o]+i-x[j])=1 then pp:=true;
          if (abs(x[o]+i-x[j]-l[j])=1)and(not(p[j])) then pp:=true;
        end;
      end;
      if pp then
      begin
        x[o]:=x[o]+i;p[o]:=true;gc;p[o]:=false;x[o]:=xx[o];
      end;
    end;
  end;
  for o:=1 to 3 do if (not(p[o+3]))and(q[o]=0) then
  begin
    pp:=false;
    for i:=1 to 3 do if (x[o]=x[i])and(o<>i) then pp:=true;
    if pp then
    for i:=-r[o] to r[o] do
    begin
      pp:=true;for j:=1 to 3 do if i+x[o]=x[j] then pp:=false;
      if pp then
      begin
        pp:=false;if i=r[o] then pp:=true;
        for j:=1 to 3 do
        begin
          if abs(x[o]+i-x[j])=1 then pp:=true;
          if (abs(x[o]+i-x[j]-l[j])=1)and(not(p[j])) then pp:=true;
        end;
      end;
      if pp then
      begin
        p[o+3]:=true;
        for k:=1 to 3 do if (x[k]=x[o])and(q[k]>0) then
        begin
          x[k]:=x[o]+i;dec(q[k]);
        end;
        gc;
        p[o+3]:=false;
        for k:=1 to 3 do begin x[k]:=xx[k];q[k]:=qq[k];end;
      end;
    end;
  end;
  for o:=1 to 3 do if not(p[o+6]) then
  begin
    pp:=true;
    for i:=1 to 3 do if (x[o]=x[i])and(o<>i) then pp:=false;
    if pp then
    begin
      pp:=false;
      for i:=1 to 3 do if x[i]-x[o]=1 then pp:=true;
      if pp then
      begin
        p[o+6]:=true;
        for i:=1 to 3 do if x[i]-x[o]=1 then
        begin
          x[i]:=x[o];inc(q[i]);
        end;
        gc;
        p[o+6]:=false;
        for i:=1 to 3 do begin x[i]:=xx[i];q[i]:=qq[i];end;
      end;
      pp:=false;
      for i:=1 to 3 do if x[o]-x[i]=1 then pp:=true;
      if pp then
      begin
        p[o+6]:=true;
        for i:=1 to 3 do if x[o]-x[i]=1 then
        begin
          x[i]:=x[o];inc(q[i]);
        end;
        gc;
        p[o+6]:=false;
        for i:=1 to 3 do begin x[i]:=xx[i];q[i]:=qq[i];end;
      end;
    end;
  end;
end;
begin
  read(x[1],l[1],r[1],x[2],l[2],r[2],x[3],l[3],r[3]);
  ans:=max(max(x[1],x[2]),x[3]);
  gc;
  writeln(ans);
end.

{$M 100000000}
const
  mo=5000000;

type
  Tman=record
         move_range,throw_range,pos:longint;
         moved,threw:boolean;
         up,down:longint;
       end;

  Tarr=array[0..3] of Tman;

var
  man:Tarr;
  tot,ans,i,j,k,time:longint;
  online:longint;
  ht:array[0..mo] of longint;
  v:array[0..21000000] of record next,h:longint; end;

function get(var man:Tman; i:longint):longint;
  var
    x,y:longint;
  begin
    with man do
      begin
        y:=pos-1;
        if moved then y:=y+42*1;
        if threw then
          begin
            if man.up=-1
              then y:=y+3*42*2 else
                begin
                  if man.up>i
                    then x:=man.up-1
                    else x:=man.up;
                  y:=y+x*42*2;
                end;
          end;
      end;
    get:=y;
  end;

procedure dfs;
  var
    hash,i,j,k,ii:longint;
  begin
    inc(time);

    hash:=0;
    for i:=1 to 3 do
      hash:=(hash*8*42+get(man[i],i));

    k:=ht[(hash mod mo)+1];
    while k<>0 do
      begin
        if v[k].h=hash then break;
        k:=v[k].next;
      end;

    if v[k].h=hash then exit;

    inc(tot); v[tot].next:=ht[hash mod mo+1]; v[tot].h:=hash; ht[hash mod mo+1]:=tot;

    for i:=1 to 3 do
      if man[i].pos>ans
        then ans:=man[i].pos;

    for i:=1 to 3 do
      if not man[i].moved and (man[i].up=-1) and (man[i].down=-1) then
        begin
          for k:=man[i].move_range downto -man[i].move_range do
            if k<>0 then
              begin
                for j:=1 to 3 do
                  if man[j].pos=man[i].pos+k then break;
                if (man[j].pos=man[i].pos+k)or(man[i].pos+k<=0) then continue;

                man[i].moved:=true;
                inc(man[i].pos, k);
                dfs;
                man[i].moved:=false;
                dec(man[i].pos, k);
              end;
        end;

    for i:=1 to 3 do
      if not man[i].threw and (man[i].down=-1) then
        begin
          for j:=1 to 3 do
            if (abs(man[i].pos-man[j].pos)=1) and (man[j].down=-1) then
              begin
                man[i].up:=j;
                man[j].down:=i;
                k:=man[j].pos;
                man[j].pos:=man[i].pos;
                man[i].threw:=true;

                dfs;

                man[j].pos:=k;
                man[i].threw:=false;
                man[i].up:=-1;
                man[j].down:=-1;
              end;
        end;

    for i:=1 to 3 do
      if (man[i].up<>-1) and (man[i].down=-1) then
        begin
          j:=man[i].up;
          man[i].up:=-1;
          man[j].down:=-1;

          for k:=man[i].throw_range downto -man[i].throw_range do
            if k<>0 then
              begin
                man[j].pos:=man[j].pos+k;
                for ii:=1 to 3 do
                  if ii<>j then
                    if man[ii].pos=man[j].pos then break;
                if (man[ii].pos=man[j].pos)and(ii<>j)or(man[j].pos<1) then
                  begin
                    man[j].pos:=man[i].pos;
                    continue;
                  end;
                dfs;
                man[j].pos:=man[i].pos;
              end;

          man[i].up:=j;
          man[j].down:=i;
        end;
  end;

begin
   online:=1;

   if online=0 then begin
   assign(input,'E.in'); reset(input);
   assign(output,'E.out'); rewrite(output); end;

   TOT:=0;
   fillchar(ht,sizeof(ht),0);

   for i:=1 to 3 do
     begin
       with man[i] do
         begin
           readln(pos, move_range, throw_range);
           moved:=false;
           threw:=false;
           up:=-1;
           down:=-1;
         end;
     end;

   ans:=-1;

   dfs;

   writeln(ans);

   if online=0 then begin
   close(input);
   close(output); end;
end.

program cf105e;
type
  num=array[1..3]of longint;
var
  n,i,j,ans:longint;
  f:array[0..10000000]of boolean;
  t,m,p:num;
  c:num;
  s:num;
//  a:array[0..30,0..2]of longint;
procedure dfs(x,y,z:longint); forward;
procedure dd;
var i,ha:longint;
begin
  for i:=1 to 3 do
    if p[i]>ans then ans:=p[i];
  ha:=0;
  for i:=1 to 3 do ha:=(ha*39+s[i])mod 9999997;
  for i:=1 to 3 do ha:=(ha*39+p[i]) mod 9999997;
  for i:=1 to 3 do ha:=(ha*39+c[i]) mod 9999997;
  if f[ha] then exit;
  dfs(1,2,3);
  dfs(1,3,2);
  dfs(2,1,3);
  dfs(2,3,1);
  dfs(3,1,2);
  dfs(3,2,1);
  f[ha]:=true;
//  f[p[1],p[2],p[3],c[1],c[2],c[3],s[1],s[2],s[3]]:=true;
end;

procedure dfs(x,y,z:longint);
var
  i,j,k:longint;
  pp,ss,cc:num;
begin
  if p[1]=6 then
  if p[2]=5 then
  if p[3]=5 then
    p[1]:=p[1];

  pp:=p; ss:=s; cc:=c;
  //f[p[1],p[2],p[3],c[1],c[2],c[3],s[1],s[2],s[3]]:=true;
  if not( (p[y]=p[x]) or (p[z]=p[x]))  then
  if s[x] and 1<>0 then begin
    for i:=p[x]-m[x] to p[x]+m[x] do
      if (i>=1)and(i<>p[y])and(i<>p[z]) then begin
        p[x]:=i;
        s[x]:=ss[x]-1;
        dd;
        p[x]:=pp[x]; inc(s[x]);
      end;
  end;

  if (p[y]=p[x])and(c[y]=c[x]+1)and(c[x]=0) then
  if s[x] and 2 <> 0 then  begin
    for i:=p[y]-t[x] to p[y]+t[x] do
      if (i>=1)and(i<>p[z]) then begin
        p[y]:=i;
        s[x]:=s[x]-2;
        c[y]:=0;
        if pp[z]=pp[y] then begin
          c[z]:=1;
          p[z]:=i;
        end;
        dd;
        p[y]:=pp[y]; s[x]:=ss[x]; c[y]:=cc[y];
        p[z]:=pp[z]; c[z]:=cc[z];
      end;
  end;

  if (abs(p[x]-p[y])=1)and(c[x]=c[y]) then
  if s[x] and 4<>0 then begin
    if p[z]=p[y] then begin
      p[z]:=p[x];
      c[z]:=2;
    end;
    p[y]:=p[x]; c[y]:=c[x]+1;
    s[x]:=s[x]-4;
    dd;
  end;
  p:=pp; s:=ss; c:=cc;
end;

begin
  fillchar(f,sizeof(f),false);
  ans:=0;
 // fillchar(a,sizeof(a),0);
  readln(p[1],m[1],t[1]); //a[p[1],0]:=1;
  readln(p[2],m[2],t[2]); //a[p[2],0]:=2;
  readln(p[3],m[3],t[3]); //a[p[3],0]:=3;
  for i:=1 to 3 do begin
    c[i]:=0;
    s[i]:=7;
  end;

  ans:=0;
  dd;
  writeln(ans);
end.

{$APPTYPE CONSOLE}
{$MAXSTACKSIZE $10000000}
{$R-,Q-,O+,S+}
 const
   mo=5000000;

 type
   Tman=record
          move_range,throw_range,pos:longint;
          moved,threw:boolean;
          up,down:longint;
        end;

   Tarr=array[0..3] of Tman;

 var
   man:Tarr;
   tot,ans,i,j,k,time:longint;
   online:longint;
   ht:array[0..mo] of longint;
   v:array[0..21000000] of record next,h:longint; end;

 function get(var man:Tman; i:longint):longint;
   var
     x,y:longint;
   begin
     with man do
       begin
         y:=pos-1;
         if moved then y:=y+42*1;
         if threw then
           begin
             if man.up=-1
               then y:=y+3*42*2 else
                 begin
                   if man.up>i
                     then x:=man.up-1
                     else x:=man.up;
                   y:=y+x*42*2;
                 end;
           end;
       end;
     get:=y;
   end;
 procedure dfs;
   var
     hash,i,j,k,ii:longint;
   begin
     inc(time);
     hash:=0;
     for i:=1 to 3 do
       hash:=(hash*8*42+get(man[i],i));
     k:=ht[(hash mod mo)+1];
     while k<>0 do
       begin
         if v[k].h=hash then break;
         k:=v[k].next;
       end;
     if v[k].h=hash then exit;
     inc(tot); v[tot].next:=ht[hash mod mo+1]; v[tot].h:=hash; ht[hash mod mo+1]:=tot;
     for i:=1 to 3 do
       if man[i].pos>ans
         then ans:=man[i].pos;
     for i:=1 to 3 do
       if not man[i].moved and (man[i].up=-1) and (man[i].down=-1) then
         begin
           for k:=man[i].move_range downto -man[i].move_range do
             if k<>0 then
               begin
                 for j:=1 to 3 do
                   if man[j].pos=man[i].pos+k then break;
                 if (man[j].pos=man[i].pos+k)or(man[i].pos+k<=0) then continue;
                 man[i].moved:=true;
                 inc(man[i].pos, k);
                 dfs;
                 man[i].moved:=false;
                 dec(man[i].pos, k);
               end;
         end;
     for i:=1 to 3 do
       if not man[i].threw and (man[i].down=-1) then
         begin
           for j:=1 to 3 do
             if (abs(man[i].pos-man[j].pos)=1) and (man[j].down=-1) then
               begin
                 man[i].up:=j;
                 man[j].down:=i;
                 k:=man[j].pos;
                 man[j].pos:=man[i].pos;
                 man[i].threw:=true;
                 dfs;
                 man[j].pos:=k;
                 man[i].threw:=false;
                 man[i].up:=-1;
                 man[j].down:=-1;
               end;
         end;
     for i:=1 to 3 do
       if (man[i].up<>-1) and (man[i].down=-1) then
         begin
           j:=man[i].up;
           man[i].up:=-1;
           man[j].down:=-1;
           for k:=man[i].throw_range downto -man[i].throw_range do
             if k<>0 then
               begin
                 man[j].pos:=man[j].pos+k;
                 for ii:=1 to 3 do
                   if ii<>j then
                     if man[ii].pos=man[j].pos then break;
                 if (man[ii].pos=man[j].pos)and(ii<>j)or(man[j].pos<1) then
                   begin
                     man[j].pos:=man[i].pos;
                     continue;
                   end;
                 dfs;
                 man[j].pos:=man[i].pos;
               end;
           man[i].up:=j;
           man[j].down:=i;
         end;
   end;
begin
    TOT:=0;
    fillchar(ht,sizeof(ht),0);
    for i:=1 to 3 do
      begin
        with man[i] do
          begin
            readln(pos, move_range, throw_range);
            moved:=false;
            threw:=false;
            up:=-1;
            down:=-1;
          end;
      end;
    ans:=-1;
    dfs;
    writeln(ans);
end.

var x,l,r:array[1..3]of longint;
    p:array[1..6]of boolean;
    i,j,k,n,ans:longint;
function max(x,y:longint):longint;
begin
  if x>y then max:=x else max:=y;
end;
procedure gc;
var i,o,j,k:longint;
    xx:array[1..3]of longint;
    pp:boolean;
begin
  ans:=max(ans,max(x[1],max(x[2],x[3])));
  for i:=1 to 3 do xx[i]:=x[i];
  for o:=1 to 3 do if not(p[o]) then
  for i:=-l[o] to l[o] do
  begin
    pp:=true;for j:=1 to 3 do if i+x[o]=x[j] then pp:=false;
    if pp then
    begin
      pp:=false;if i=l[o] then pp:=true;
      for j:=1 to 3 do
      begin
        if abs(x[o]+i-x[j])=1 then pp:=true;
        if (abs(x[o]+i-x[j]-l[j])=1)and(not(p[j])) then pp:=true;
      end;
    end;
    if pp then
    begin
      x[o]:=x[o]+i;p[o]:=true;gc;p[o]:=false;x[o]:=xx[o];
    end;
  end;
  for o:=1 to 3 do if not(p[o+3]) then
  for k:=1 to 3 do if abs(x[o]-x[k])=1 then
  for i:=-r[o] to r[o] do
  begin
    pp:=true;for j:=1 to 3 do if i+x[o]=x[j] then pp:=false;
    if pp then
    begin
      pp:=false;if i=r[o] then pp:=true;
      for j:=1 to 3 do
      begin
        if abs(x[o]+i-x[j])=1 then pp:=true;
        if (abs(x[o]+i-x[j]-l[j])=1)and(not(p[j])) then pp:=true;
      end;
    end;
    if pp then
    begin
      x[k]:=x[o]+i;p[o+3]:=true;gc;p[o+3]:=false;x[k]:=xx[k];
    end;
  end;
end;
begin
  read(x[1],l[1],r[1],x[2],l[2],r[2],x[3],l[3],r[3]);
  ans:=max(max(x[1],x[2]),x[3]);
  gc;
  for i:=1 to 3 do for j:=1 to 3 do for k:=1 to 3 do
  if (i*j*k=6)and(i+j+k=6) then for n:=1 to 20 do
  begin
    if x[k]=n then
    begin
      if (abs(x[j]-(n-1))<=l[j])and(abs(x[i]-(n-2))<=l[i]) then
      ans:=max(ans,n-2+r[i]+r[j]+l[k]);
    end else
    if (abs(x[j]-(n-1))<=l[j])and(abs(x[i]-(n-2))<=l[i])and(abs(x[k]-n)<=l[k]) then
    ans:=max(ans,n-2+r[i]+r[j]);
    if x[k]=n then
    begin
      if (abs(x[j]-(n+1))<=l[j])and(abs(x[i]-(n+2))<=l[i]) then
      ans:=max(ans,n+2+r[i]+r[j]+l[k]);
    end else
    if (abs(x[j]-(n+1))<=l[j])and(abs(x[i]-(n+2))<=l[i])and(abs(x[k]-n)<=l[k]) then
    ans:=max(ans,n+2+r[i]+r[j]);
  end;
  writeln(ans);
end.

var x,l,r:array[1..3]of longint;
    p:array[1..6]of boolean;
    i,j,k,n,ans:longint;
function max(x,y:longint):longint;
begin
  if x>y then max:=x else max:=y;
end;
procedure gc;
var i,o,j,k:longint;
    xx:array[1..3]of longint;
    pp:boolean;
begin
  ans:=max(ans,max(x[1],max(x[2],x[3])));
  for i:=1 to 3 do xx[i]:=x[i];
  for o:=1 to 3 do if not(p[o]) then
  for i:=-l[o] to l[o] do
  begin
    pp:=true;for j:=1 to 3 do if i+x[o]=x[j] then pp:=false;
    if pp then
    begin
      x[o]:=x[o]+i;p[o]:=true;gc;p[o]:=false;x[o]:=xx[o];
    end;
  end;
  for o:=1 to 3 do if not(p[o+3]) then
  for k:=1 to 3 do if abs(x[o]-x[k])=1 then
  for i:=-r[o] to r[o] do
  begin
    pp:=true;for j:=1 to 3 do if i+x[o]=x[j] then pp:=false;
    if pp then
    begin
      x[k]:=x[o]+i;p[o+3]:=true;gc;p[o+3]:=false;x[k]:=xx[k];
    end;
  end;
end;
begin
  read(x[1],l[1],r[1],x[2],l[2],r[2],x[3],l[3],r[3]);
  ans:=max(max(x[1],x[2]),x[3]);
  gc;
  for i:=1 to 3 do for j:=1 to 3 do for k:=1 to 3 do
  if (i*j*k=6)and(i+j+k=6) then for n:=1 to 20 do
  if x[k]=n then
  begin
    if (abs(x[j]-(n-1))<=l[j])and(abs(x[i]-(n-2))<=l[i]) then
    ans:=max(ans,n-2+r[i]+r[j]+l[k]);
  end else
  if (abs(x[j]-(n-1))<=l[j])and(abs(x[i]-(n-2))<=l[i])and(abs(x[k]-n)<=l[k]) then
  ans:=max(ans,n-2+r[i]+r[j]);
  writeln(ans);
end.

Type
  Tman=record
         move_range,throw_range,pos:longint;
         moved,threw:boolean;
         up,down:longint;
       end;

  Tarr=array[0..3] of Tman;

var
  man:Tarr;
  ans,i,j,k:longint;

procedure dfs;
  var
    i,j,k:longint;
    ori:Tman;
  begin
    for i:=1 to 3 do
      if man[i].pos>ans
        then ans:=man[i].pos;

    for i:=1 to 3 do
      begin
        k:=man[i].pos;
        if man[i].moved=false then inc(k,man[i].move_range);
        for j:=1 to 3 do if i<>j then if not man[j].threw then inc(k,man[j].throw_range);
        if k>ans then break;
      end;

    if k<=ans then exit;

    for i:=1 to 3 do
      if not man[i].moved and (man[i].up=-1) and (man[i].down=-1) then
        begin
          for k:=-man[i].move_range to man[i].move_range do
            if k<>0 then
              begin
                for j:=1 to 3 do
                  if man[j].pos=man[i].pos+k then break;
                if man[j].pos=man[i].pos+k then continue;

                ori:=man[i];
                man[i].moved:=true;
                inc(man[i].pos, k);
                dfs;
                man[i]:=ori;
              end;
        end;

    for i:=1 to 3 do
      if not man[i].threw and (man[i].down=-1) then
        begin
          for j:=1 to 3 do
            if (abs(man[i].pos-man[j].pos)=1) and (man[j].down=-1) then
              begin
                man[i].up:=j;
                man[j].down:=i;
                k:=man[j].pos;
                man[j].pos:=man[i].pos;
                man[i].threw:=true;

                dfs;

                man[j].pos:=k;
                man[i].threw:=false;
                man[i].up:=-1;
                man[j].down:=-1;
              end;
        end;

    for i:=1 to 3 do
      if (man[i].up<>-1) and (man[i].down=-1) then
        begin
          j:=man[i].up;
          man[i].up:=-1;
          man[j].down:=-1;

          for k:=-man[i].throw_range to man[i].throw_range do
            if k<>0 then
              begin
                man[j].pos:=man[j].pos+k;
                dfs;
                man[j].pos:=man[i].pos;
              end;

          man[i].up:=j;
          man[j].down:=i;
        end;
  end;

begin
   for i:=1 to 3 do
     begin
       with man[i] do
         begin
           readln(pos, move_range, throw_range);
           moved:=false;
           threw:=false;
           up:=-1;
           down:=-1;
         end;
     end;

   ans:=-1;

   dfs;

   writeln(ans);

end.

Type
  Tman=record
         move_range,throw_range,pos:longint;
         moved,threw:boolean;
         up,down:longint;
       end;

  Tarr=array[0..3] of Tman;

var
  man:Tarr;
  ans,i,j,k:longint;

procedure dfs;
  var
    i,j,k,ii:longint;
    ori:Tman;
  begin
    for i:=1 to 3 do
      if man[i].pos>ans
        then ans:=man[i].pos;

    for i:=1 to 3 do
      begin
        k:=man[i].pos;
        if man[i].moved=false then inc(k,man[i].move_range);
        for j:=1 to 3 do if i<>j then if not man[j].threw then inc(k,man[j].throw_range+3);
        if k>ans then break;
      end;

    if k<=ans then exit;

    for i:=1 to 3 do
      if not man[i].moved and (man[i].up=-1) and (man[i].down=-1) then
        begin
          for k:=-man[i].move_range to man[i].move_range do
            if k<>0 then
              begin
                for j:=1 to 3 do
                  if man[j].pos=man[i].pos+k then break;
                if (man[j].pos=man[i].pos+k)or(man[i].pos+k<=0) then continue;

                ori:=man[i];
                man[i].moved:=true;
                inc(man[i].pos, k);
                dfs;
                man[i]:=ori;
              end;
        end;

    for i:=1 to 3 do
      if not man[i].threw and (man[i].down=-1) then
        begin
          for j:=1 to 3 do
            if (abs(man[i].pos-man[j].pos)=1) and (man[j].down=-1) then
              begin
                man[i].up:=j;
                man[j].down:=i;
                k:=man[j].pos;
                man[j].pos:=man[i].pos;
                man[i].threw:=true;

                dfs;

                man[j].pos:=k;
                man[i].threw:=false;
                man[i].up:=-1;
                man[j].down:=-1;
              end;
        end;

    for i:=1 to 3 do
      if (man[i].up<>-1) and (man[i].down=-1) then
        begin
          j:=man[i].up;
          man[i].up:=-1;
          man[j].down:=-1;

          for k:=-man[i].throw_range to man[i].throw_range do
            if k<>0 then
              begin
                man[j].pos:=man[j].pos+k;
                for ii:=1 to 3 do
                  if ii<>j then
                    if man[ii].pos=man[j].pos then break;
                if (man[ii].pos=man[j].pos)or(man[ii].pos<1) then
                  begin
                    man[j].pos:=man[i].pos;
                    continue;
                  end;
                dfs;
                man[j].pos:=man[i].pos;
              end;

          man[i].up:=j;
          man[j].down:=i;
        end;
  end;

begin
   for i:=1 to 3 do
     begin
       with man[i] do
         begin
           readln(pos, move_range, throw_range);
           moved:=false;
           threw:=false;
           up:=-1;
           down:=-1;
         end;
     end;

   ans:=-1;

   dfs;

   writeln(ans);

end.

Type
  Tman=record
         move_range,throw_range,pos:longint;
         moved,threw:boolean;
         up,down:longint;
       end;

  Tarr=array[0..3] of Tman;

var
  man:Tarr;
  ans,i,j,k:longint;
  online:longint;

procedure dfs;
  var
    i,j,k,ii:longint;
    ori:Tman;
  begin
    for i:=1 to 3 do
      if man[i].pos>ans
        then ans:=man[i].pos;

    for i:=1 to 3 do
      begin
        k:=man[i].pos;
        if man[i].moved=false then inc(k,man[i].move_range);
        for j:=1 to 3 do if i<>j then {if not man[j].threw then} inc(k,man[j].throw_range);
        if k>ans then break;
      end;
    if k<=ans then exit;

    for i:=1 to 3 do
      if not man[i].moved and (man[i].up=-1) and (man[i].down=-1) then
        begin
          for k:=man[i].move_range downto -man[i].move_range do
            if k<>0 then
              begin
                for j:=1 to 3 do
                  if man[j].pos=man[i].pos+k then break;
                if (man[j].pos=man[i].pos+k)or(man[i].pos+k<=0) then continue;

                man[i].moved:=true;
                inc(man[i].pos, k);
                dfs;
                man[i].moved:=false;
                dec(man[i].pos, k);
              end;
        end;

    for i:=1 to 3 do
      if not man[i].threw and (man[i].down=-1) then
        begin
          for j:=1 to 3 do
            if (abs(man[i].pos-man[j].pos)=1) and (man[j].down=-1) then
              begin
                man[i].up:=j;
                man[j].down:=i;
                k:=man[j].pos;
                man[j].pos:=man[i].pos;
                man[i].threw:=true;

                dfs;

                man[j].pos:=k;
                man[i].threw:=false;
                man[i].up:=-1;
                man[j].down:=-1;
              end;
        end;

    for i:=1 to 3 do
      if (man[i].up<>-1) and (man[i].down=-1) then
        begin
          j:=man[i].up;
          man[i].up:=-1;
          man[j].down:=-1;

          for k:=man[i].throw_range downto -man[i].throw_range do
            if k<>0 then
              begin
                man[j].pos:=man[j].pos+k;
                for ii:=1 to 3 do
                  if ii<>j then
                    if man[ii].pos=man[j].pos then break;
                if (man[ii].pos=man[j].pos)and(ii<>j)or(man[ii].pos<1) then
                  begin
                    man[j].pos:=man[i].pos;
                    continue;
                  end;
                dfs;
                man[j].pos:=man[i].pos;
              end;

          man[i].up:=j;
          man[j].down:=i;
        end;
  end;

begin
   online:=1;

   if online=0 then begin
   assign(input,'E.in'); reset(input);
   assign(output,'E.out'); rewrite(output); end;

   for i:=1 to 3 do
     begin
       with man[i] do
         begin
           readln(pos, move_range, throw_range);
           moved:=false;
           threw:=false;
           up:=-1;
           down:=-1;
         end;
     end;

   ans:=-1;

   dfs;

   writeln(ans);

   if online=0 then begin
   close(input);
   close(output); end;
end.

type
  Tman=record
         move_range,throw_range,pos:longint;
         moved,threw:boolean;
         up,down:longint;
       end;

  Tarr=array[0..3] of Tman;

var
  man:Tarr;
  tot,ans,i,j,k:longint;
  online:longint;
  ht:array[0..5000000] of longint;
  v:array[0..21000000] of record next,h:longint; end;

function get(var man:Tman; i:longint):longint;
  var
    x,y:longint;
  begin
    with man do
      begin
        y:=pos-1;
        if moved then y:=y+42*1;
        if threw then
          begin
            if man.up=-1
              then y:=y+3*42*2 else
                begin
                  if man.up>i
                    then x:=man.up-1
                    else x:=man.up;
                  y:=y+x*3*42*2;
                end;
          end;
      end;
    get:=y;
  end;

procedure dfs;
  var
    hash,i,j,k,ii:longint;
    ori:Tman;
  begin

    hash:=0;
    for i:=1 to 3 do
      hash:=(hash*8*43+get(man[i],i));

    k:=ht[hash mod 5000000+1];
    while k<>0 do
      begin
        if v[k].h=hash then break;
        k:=v[k].next;
      end;

    if v[k].h=hash then exit;

    inc(tot); v[tot].next:=ht[hash mod 5000000+1]; v[tot].h:=hash; ht[hash mod 5000000+1]:=tot;

    for i:=1 to 3 do
      if man[i].pos>ans
        then ans:=man[i].pos;

    for i:=1 to 3 do
      begin
        k:=man[i].pos;
        if man[i].moved=false then inc(k,man[i].move_range);
        for j:=1 to 3 do if i<>j then {if not man[j].threw then} inc(k,man[j].throw_range);
        if k>ans then break;
      end;
    if k<=ans then exit;

    for i:=1 to 3 do
      if not man[i].moved and (man[i].up=-1) and (man[i].down=-1) then
        begin
          for k:=man[i].move_range downto -man[i].move_range do
            if k<>0 then
              begin
                for j:=1 to 3 do
                  if man[j].pos=man[i].pos+k then break;
                if (man[j].pos=man[i].pos+k)or(man[i].pos+k<=0) then continue;

                man[i].moved:=true;
                inc(man[i].pos, k);
                dfs;
                man[i].moved:=false;
                dec(man[i].pos, k);
              end;
        end;

    for i:=1 to 3 do
      if not man[i].threw and (man[i].down=-1) then
        begin
          for j:=1 to 3 do
            if (abs(man[i].pos-man[j].pos)=1) and (man[j].down=-1) then
              begin
                man[i].up:=j;
                man[j].down:=i;
                k:=man[j].pos;
                man[j].pos:=man[i].pos;
                man[i].threw:=true;

                dfs;

                man[j].pos:=k;
                man[i].threw:=false;
                man[i].up:=-1;
                man[j].down:=-1;
              end;
        end;

    for i:=1 to 3 do
      if (man[i].up<>-1) and (man[i].down=-1) then
        begin
          j:=man[i].up;
          man[i].up:=-1;
          man[j].down:=-1;

          for k:=man[i].throw_range downto -man[i].throw_range do
            if k<>0 then
              begin
                man[j].pos:=man[j].pos+k;
                for ii:=1 to 3 do
                  if ii<>j then
                    if man[ii].pos=man[j].pos then break;
                if (man[ii].pos=man[j].pos)and(ii<>j)or(man[ii].pos<1) then
                  begin
                    man[j].pos:=man[i].pos;
                    continue;
                  end;
                dfs;
                man[j].pos:=man[i].pos;
              end;

          man[i].up:=j;
          man[j].down:=i;
        end;
  end;

begin
   online:=1;

   if online=0 then begin
   assign(input,'E.in'); reset(input);
   assign(output,'E.out'); rewrite(output); end;

   TOT:=0;
   fillchar(ht,sizeof(ht),0);

   for i:=1 to 3 do
     begin
       with man[i] do
         begin
           readln(pos, move_range, throw_range);
           moved:=false;
           threw:=false;
           up:=-1;
           down:=-1;
         end;
     end;

   ans:=-1;

   dfs;

   writeln(ans);

   if online=0 then begin
   close(input);
   close(output); end;
end.

Type
  Tman=record
         move_range,throw_range,pos:longint;
         moved,threw:boolean;
         up,down:longint;
       end;

  Tarr=array[0..3] of Tman;

var
  man:Tarr;
  ans,i,j,k:longint;

procedure dfs;
  var
    i,j,k,ii:longint;
    ori:Tman;
  begin
    for i:=1 to 3 do
      if man[i].pos>ans
        then ans:=man[i].pos;

    for i:=1 to 3 do
      begin
        k:=man[i].pos;
        if man[i].moved=false then inc(k,man[i].move_range);
        for j:=1 to 3 do if i<>j then if not man[j].threw then inc(k,man[j].throw_range+1);
        if k>ans then break;
      end;

    if k<=ans then exit;

    for i:=1 to 3 do
      if not man[i].moved and (man[i].up=-1) and (man[i].down=-1) then
        begin
          for k:=-man[i].move_range to man[i].move_range do
            if k<>0 then
              begin
                for j:=1 to 3 do
                  if man[j].pos=man[i].pos+k then break;
                if (man[j].pos=man[i].pos+k)or(man[i].pos+k<=0) then continue;

                ori:=man[i];
                man[i].moved:=true;
                inc(man[i].pos, k);
                dfs;
                man[i]:=ori;
              end;
        end;

    for i:=1 to 3 do
      if not man[i].threw and (man[i].down=-1) then
        begin
          for j:=1 to 3 do
            if (abs(man[i].pos-man[j].pos)=1) and (man[j].down=-1) then
              begin
                man[i].up:=j;
                man[j].down:=i;
                k:=man[j].pos;
                man[j].pos:=man[i].pos;
                man[i].threw:=true;

                dfs;

                man[j].pos:=k;
                man[i].threw:=false;
                man[i].up:=-1;
                man[j].down:=-1;
              end;
        end;

    for i:=1 to 3 do
      if (man[i].up<>-1) and (man[i].down=-1) then
        begin
          j:=man[i].up;
          man[i].up:=-1;
          man[j].down:=-1;

          for k:=-man[i].throw_range to man[i].throw_range do
            if k<>0 then
              begin
                man[j].pos:=man[j].pos+k;
                for ii:=1 to 3 do
                  if ii<>j then
                    if man[ii].pos=man[j].pos then break;
                if (man[ii].pos=man[j].pos)or(man[ii].pos<1) then
                  begin
                    man[j].pos:=man[i].pos;
                    continue;
                  end;
                dfs;
                man[j].pos:=man[i].pos;
              end;

          man[i].up:=j;
          man[j].down:=i;
        end;
  end;

begin
   for i:=1 to 3 do
     begin
       with man[i] do
         begin
           readln(pos, move_range, throw_range);
           moved:=false;
           threw:=false;
           up:=-1;
           down:=-1;
         end;
     end;

   ans:=-1;

   dfs;

   writeln(ans);

end.

Type
  Tman=record
         move_range,throw_range,pos:longint;
         moved,threw:boolean;
         up,down:longint;
       end;

  Tarr=array[0..3] of Tman;

var
  man:Tarr;
  ans,i,j,k:longint;

procedure dfs;
  var
    i,j,k,ii:longint;
    ori:Tman;
  begin
    for i:=1 to 3 do
      if man[i].pos>ans
        then ans:=man[i].pos;

    for i:=1 to 3 do
      begin
        k:=man[i].pos;
        if man[i].moved=false then inc(k,man[i].move_range);
        for j:=1 to 3 do if i<>j then if not man[j].threw then inc(k,man[j].throw_range);
        if k>ans then break;
      end;

    if k<=ans then exit;

    for i:=1 to 3 do
      if not man[i].moved and (man[i].up=-1) and (man[i].down=-1) then
        begin
          for k:=man[i].move_range downto -man[i].move_range do
            if k<>0 then
              begin
                for j:=1 to 3 do
                  if man[j].pos=man[i].pos+k then break;
                if (man[j].pos=man[i].pos+k)or(man[i].pos+k<=0) then continue;

                ori:=man[i];
                man[i].moved:=true;
                inc(man[i].pos, k);
                dfs;
                man[i]:=ori;
              end;
        end;

    for i:=1 to 3 do
      if not man[i].threw and (man[i].down=-1) then
        begin
          for j:=1 to 3 do
            if (abs(man[i].pos-man[j].pos)=1) and (man[j].down=-1) then
              begin
                man[i].up:=j;
                man[j].down:=i;
                k:=man[j].pos;
                man[j].pos:=man[i].pos;
                man[i].threw:=true;

                dfs;

                man[j].pos:=k;
                man[i].threw:=false;
                man[i].up:=-1;
                man[j].down:=-1;
              end;
        end;

    for i:=1 to 3 do
      if (man[i].up<>-1) and (man[i].down=-1) then
        begin
          j:=man[i].up;
          man[i].up:=-1;
          man[j].down:=-1;

          for k:=man[i].throw_range downto -man[i].throw_range do
            if k<>0 then
              begin
                man[j].pos:=man[j].pos+k;
                for ii:=1 to 3 do
                  if ii<>j then
                    if man[ii].pos=man[j].pos then break;
                if (man[ii].pos=man[j].pos)or(man[ii].pos<1) then
                  begin
                    man[j].pos:=man[i].pos;
                    continue;
                  end;
                dfs;
                man[j].pos:=man[i].pos;
              end;

          man[i].up:=j;
          man[j].down:=i;
        end;
  end;

begin
   for i:=1 to 3 do
     begin
       with man[i] do
         begin
           readln(pos, move_range, throw_range);
           moved:=false;
           threw:=false;
           up:=-1;
           down:=-1;
         end;
     end;

   ans:=-1;

   dfs;

   writeln(ans);

end.

{$APPTYPE CONSOLE}
{$R-,Q-,O-,S+}
 const
   mo=5000000;
 type
   Tman=record
          move_range,throw_range,pos:longint;
          moved,threw:boolean;
          up,down:longint;
        end;

   Tarr=array[0..3] of Tman;
 var
   man:Tarr;
   tot,ans,i,j,k,time:longint;
   online:longint;
   ht:array[0..mo] of longint;
   v:array[0..21000000] of record next,h:longint; end;
 function get(var man:Tman; i:longint):longint;
   var
     x,y:longint;
   begin
     with man do
       begin
         y:=pos-1;
         if moved then y:=y+42*1;
         if threw then
           begin
             if man.up=-1
               then y:=y+3*42*2 else
                 begin
                   if man.up>i
                     then x:=man.up-1
                     else x:=man.up;
                   y:=y+x*42*2;
                 end;
           end;
       end;
     get:=y;
   end;
 procedure dfs;
   var
     hash,i,j,k,ii:longint;
   begin
     inc(time);
     hash:=0;
     for i:=1 to 3 do
       hash:=(hash*8*42+get(man[i],i));
     k:=ht[(hash mod mo)+1];
     while k<>0 do
       begin
         if v[k].h=hash then break;
         k:=v[k].next;
       end;
     if v[k].h=hash then exit;
     inc(tot); v[tot].next:=ht[hash mod mo+1]; v[tot].h:=hash; ht[hash mod mo+1]:=tot;
     for i:=1 to 3 do
       if man[i].pos>ans
         then ans:=man[i].pos;
     for i:=1 to 3 do
       if not man[i].moved and (man[i].up=-1) and (man[i].down=-1) then
         begin
           for k:=man[i].move_range downto -man[i].move_range do
             if k<>0 then
               begin
                 for j:=1 to 3 do
                   if man[j].pos=man[i].pos+k then break;
                 if (man[j].pos=man[i].pos+k)or(man[i].pos+k<=0) then continue;
                 man[i].moved:=true;
                 inc(man[i].pos, k);
                 dfs;
                 man[i].moved:=false;
                 dec(man[i].pos, k);
               end;
         end;
     for i:=1 to 3 do
       if not man[i].threw and (man[i].down=-1) then
         begin
           for j:=1 to 3 do
             if (abs(man[i].pos-man[j].pos)=1) and (man[j].down=-1) then
               begin
                 man[i].up:=j;
                 man[j].down:=i;
                 k:=man[j].pos;
                 man[j].pos:=man[i].pos;
                 man[i].threw:=true;
                 dfs;
                 man[j].pos:=k;
                 man[i].threw:=false;
                 man[i].up:=-1;
                 man[j].down:=-1;
               end;
         end;
     for i:=1 to 3 do
       if (man[i].up<>-1) and (man[i].down=-1) then
         begin
           j:=man[i].up;
           man[i].up:=-1;
           man[j].down:=-1;
           for k:=man[i].throw_range downto -man[i].throw_range do
             if k<>0 then
               begin
                 man[j].pos:=man[j].pos+k;
                 for ii:=1 to 3 do
                   if ii<>j then
                     if man[ii].pos=man[j].pos then break;
                 if (man[ii].pos=man[j].pos)and(ii<>j)or(man[j].pos<1) then
                   begin
                     man[j].pos:=man[i].pos;
                     continue;
                   end;
                 dfs;
                 man[j].pos:=man[i].pos;
               end;
           man[i].up:=j;
           man[j].down:=i;
         end;
   end;
begin
    TOT:=0;
    fillchar(ht,sizeof(ht),0);
    for i:=1 to 3 do
      begin
        with man[i] do
          begin
            readln(pos, move_range, throw_range);
            moved:=false;
            threw:=false;
            up:=-1;
            down:=-1;
          end;
      end;
    ans:=-1;
    dfs;
    writeln(ans);
end.


You are given a figure on a grid representing stairs consisting of 7 steps. The width of the stair on height i is wi squares. Formally, the figure is created by consecutively joining rectangles of size wi × i so that the wi sides lie on one straight line. Thus, for example, if all wi = 1, the figure will look like that (different colors represent different rectangles):  And if w = {5, 1, 0, 3, 0, 0, 1}, then it looks like that:  Find the number of ways to color some borders of the figure's inner squares so that no square had all four borders colored. The borders of the squares lying on the border of the figure should be considered painted. The ways that differ with the figure's rotation should be considered distinct.

The single line of the input contains 7 numbers w1, w2, ..., w7 (0 ≤ wi ≤ 105). It is guaranteed that at least one of the wi's isn't equal to zero.

In the single line of the output display a single number — the answer to the problem modulo 109 + 7.

NoteAll the possible ways of painting the third sample are given below:

program problem5;

const	md =	1000000007;

type	tDpArr = array[ 0..1 shl 7 ] of longInt;

var	g, h: array[ 0..7, 0..1 shl 7 ] of longInt;

procedure calc( var prev, next: tDpArr; d: longInt );
var	i, j, p, res: longInt;
begin
	for i := 0 to (1 shl d) - 1 do
	begin
		g[0][i] := 0;
		h[0][i] := prev[i];
	end;

	for j := 1 to d do
	begin
		p := 1 shl (j - 1);
		for i := 0 to (1 shl d) - 1 do
		begin
			res := g[j - 1][i] + g[j - 1][i xor p];
			if ( res >= md ) then
				dec( res, md );

			inc( res, h[j - 1][i xor p] );
			if ( res >= md ) then
				dec( res, md );

			if ( i and p > 0 ) then
				h[j][i] := res;

			inc( res, h[j - 1][i] );
			if ( res >= md ) then
				dec( res, md );

			g[j][i] := res;
			if ( i and p = 0 ) then
				h[j][i] := res;
		end;
	end;

	for i := 0 to (1 shl d) - 1 do
		next[i] := h[d][i];
end;

var	i, j, w, p: longInt;
	f: array[ 0..1 ] of tDpArr;

begin
	fillchar( f[0], sizeOf(f[0]), 0 );

	f[0][1] := 1;
	p := 0;
	for i := 1 to 7 do
	begin
		read( w );

		for j := 1 to w do
		begin
			calc( f[p], f[1 - p], i );

			p := 1 - p;
		end;

		if ( i < 7 ) then
		begin
			for j := 0 to (1 shl i) - 1 do
			begin
				f[p][ (1 shl i) + j ] := f[p][j];
				f[p][j] := 0;
			end;
		end;
	end;

	writeln( f[p][ (1 shl 7) - 1 ] );
end.


One day Polycarpus got hold of two non-empty strings s and t, consisting of lowercase Latin letters. Polycarpus is quite good with strings, so he immediately wondered, how many different pairs of "x y" are there, such that x is a substring of string s, y is a subsequence of string t, and the content of x and y is the same. Two pairs are considered different, if they contain different substrings of string s or different subsequences of string t. Read the whole statement to understand the definition of different substrings and subsequences.The length of string s is the number of characters in it. If we denote the length of the string s as |s|, we can write the string as s = s1s2... s|s|.A substring of s is a non-empty string x = s[a... b] = sasa + 1... sb (1 ≤ a ≤ b ≤ |s|). For example, "code" and "force" are substrings or "codeforces", while "coders" is not. Two substrings s[a... b] and s[c... d] are considered to be different if a ≠ c or b ≠ d. For example, if s="codeforces", s[2...2] and s[6...6] are different, though their content is the same.A subsequence of s is a non-empty string y = s[p1p2... p|y|] = sp1sp2... sp|y| (1 ≤ p1 < p2 < ... < p|y| ≤ |s|). For example, "coders" is a subsequence of "codeforces". Two subsequences u = s[p1p2... p|u|] and v = s[q1q2... q|v|] are considered different if the sequences p and q are different.

The input consists of two lines. The first of them contains s (1 ≤ |s| ≤ 5000), and the second one contains t (1 ≤ |t| ≤ 5000). Both strings consist of lowercase Latin letters.

Print a single number — the number of different pairs "x y" such that x is a substring of string s, y is a subsequence of string t, and the content of x and y is the same. As the answer can be rather large, print it modulo 1000000007 (109 + 7).

NoteLet's write down all pairs "x y" that form the answer in the first sample: "s[1...1] t[1]", "s[2...2] t[1]", "s[1...1] t[2]","s[2...2] t[2]", "s[1...2] t[1 2]".

{$A8,B-,C+,D+,E-,F-,G+,H+,I+,J-,K-,L+,M-,N+,O+,P+,Q-,R-,S-,T-,U-,V+,W-,X+,Y+,Z1}
{$MINSTACKSIZE $00004000}
{$MAXSTACKSIZE $01000000}
{$APPTYPE CONSOLE}

uses SysUtils, Math;
const P = 1000000007;

var n, m: integer;
s1, s2: string;
ans: int64;
dp: array [0..5000, 0..5000] of int64;

procedure r1;
begin
  readln(s1);
  readln(s2);
  n := length(s1);
  m := length(s2);
end;

procedure ex1;
var i, j: integer;
begin
  ans := 0;
  fillchar(dp, sizeof(dp), 0);
  if s1[1] = s2[1] then
    dp[1, 1] := 1
  else
    dp[1, 1] := 0;
  for i := 1 to n do
    for j := 1 to m do
      if (i <> 1) or (j <> 1) then
        if s1[i] <> s2[j] then
          dp[i, j] := dp[i, j - 1]
        else
          dp[i, j] := (dp[i - 1][j - 1] + dp[i][j - 1] + 1) mod P;
  for i := 1 to n do
    ans := (ans + dp[i][m]) mod P;
  write(ans);
end;

begin
  //reset(input, '1.in');
  //rewrite(output, '1.out');
  r1;
  ex1;
end.

const modd: longint = 1000000007;

var s,w: string; // ansi
    ans,i,n,m,j: longint;
    f: array[0..5001,0..5001]of longint;

begin
  readln(s);
  readln(w);

  n:=length(s);
  m:=length(w);

  fillchar(f,sizeof(f),0);
  for i:=1 to n do
    for j:=1 to m do
      f[i,j]:=(f[i,j-1]+(longint(s[i]=w[j])*(f[i-1,j-1]+1))) mod modd;

  ans:=0;
  for i:=1 to n do ans:=(ans+f[i,m]) mod modd;

  writeln(ans);
end.

Var s,t:string;
dp:array [1..5000,1..5000] of longint;
c,rez,I,j:LongInt;
begin
//  Assign(input,'input.txt'); reset(input);
//  Assign(output,'output.txt'); rewrite(output);
  readln(s);
  readln(t);
  rez:=0;
  for j:=1 to Length(s) do
  begin
    c:=0;
    for i:=1 to Length(t) do
    begin
      if s[j]=t[i]
      then begin
            dp[i,j]:=1;
            dp[i,j]:=(dp[i,j]+c) mod 1000000007;
            rez:=(rez+dp[i,j]) mod 1000000007;
           end;
      if (j-1<>0)and(s[j-1]=t[i])
      then c:=(c+dp[i,j-1])  mod 1000000007;
    end;
  end;
  writeln(rez);
end.

{$APPTYPE CONSOLE}

uses
  SysUtils;

var
  f : array [0.. 5000, 0.. 5000] of integer;
  s, t : string;
  k : Char;
  i, j, ans : Integer;
  alph : array ['a'.. 'z'] of integer;

begin
  //Reset(input, 'input.txt');
  //rewrite(output, 'output.txt');
  readln(s);
  readln(t);

  for k := 'a' to 'z' do
    alph[k] := 0;

  for i := 0 to length(s) do
    for j := 0 to length(t) do
      f[i, j] := 0;

  for j := 1 to Length(t) do
    if s[1] = t[j] then
      f[1, j] := f[1, j - 1] + 1
    else
      f[1, j] := f[1, j - 1];

  for i := 1 to length(s) do
     if s[i] = t[1] then
       f[i, 1] := 1
     else
       f[i, 1] := 0;

  for i := 2 to length(s) do begin
    alph[t[1]] := 1;
    for j := 2 to length(t) do begin
       f[i, j] := (f[i, j] + f[i, alph[s[i]]]) mod 1000000007;
       if s[i] = t[j] then
         F[i, j] :=(f[i, j] + f[i - 1, j - 1] + 1) mod 1000000007;
       alph[t[j]] := j;
    end;
    for k := 'a' to 'z' do
      alph[k] := 0;
  end;

  ans := 0;
  for i := 1 to Length(s) do
    ans := (ans + f[i, length(t)]) mod 1000000007;
  write(ans);
end.

{$Q-,R-}
const maxn = 5010;
cmod = 1000000007;

var f1,f2:text;
Next:array[0..maxn,'a'..'z'] of longint;
ns,nt:longint;
F,G:array[0..maxn,0..maxn] of longint;
res:longint;
s,t:ansistring;

Procedure process;
var i,j,k:longint;
c:char;
begin
        for c:='a' to 'z' do next[nt,c]:=nt+1;
        For i:=nt-1 downto 0 do
        begin
          for c:='a' to 'z' do
            Next[i,c]:=Next[i+1,c];
          next[i,t[i+1]]:=i+1;
        end;

        for i:=1 to ns do
        for j:=1 to nt do
        if s[i]=t[j] then
        F[i,j]:=1;
        for i:=0 to ns do
        begin
          for j:=0 to nt do
          begin
            if (i<>0) then
              G[i,next[j,s[i]]]:=(G[i,next[j,s[i]]]+G[i,j]) mod cmod;
            F[i,j]:=(F[i,j]+G[i,j]) mod cmod;
          end;
          if i<>ns then
          for j:=0 to nt do
          G[i+1,next[j,s[i+1]]]:=(G[i+1,next[j,s[i+1]]]+F[i,j]) mod cmod;
        end;

        for i:=1 to ns do
        for j:=1 to nt do
        res:=(res+F[i,j]) mod cmod;
        writeln(F2,res);
end;

begin
        assign(f1,'');reset(f1);
        assign(f2,'');rewrite(f2);
        readln(f1,s);ns:=length(s);
        readln(f1,t);nt:=length(t);
        process;
        close(f1);
        close(F2);
end.

const modd: longint = 1000000007;

var s,w: ansistring; // ansi
    ans,i,n,m,j: longint;
    f: array[0..5001,0..5001]of longint;

begin
  readln(s);
  readln(w);

  n:=length(s);
  m:=length(w);

  fillchar(f,sizeof(f),0);
  for i:=1 to n do
    for j:=1 to m do
      f[i,j]:=(f[i,j-1]+(longint(s[i]=w[j])*(f[i-1,j-1]+1))) mod modd;

  ans:=0;
  for i:=1 to n do ans:=(ans+f[i,m]) mod modd;

  writeln(ans);
end.

//CF VKCUP2012 Round2 Substring and Subsequence
const
  mo=1000000007;

var
  s,t:ansistring;
  ans,i,j,ls,lt:longint;
  f:array[0..5001,0..5001] of longint;

begin
  readln(s);readln(t);
  ls:=length(s);lt:=length(t);
  for i:=1 to lt do
    for j:=1 to ls do
      if t[i]<>s[j] then f[i][j]:=f[i-1][j] else f[i][j]:=(f[i-1][j]+f[i-1][j-1]+1) mod mo;
  ans:=0;
  for i:=1 to ls do
    ans:=(ans+f[lt][i]) mod mo;
  writeln(ans);
end.

const md = 1000000007;

var s,w:ansistring;
ans,i,j,n,m:longint;
dp:array[0..5000,0..5000]of longint;
q:array[0..5000,0..5000]of longint;
last:array[char]of longint;
 begin
  readln(s);
  readln(w);
  n:=length(s);
  m:=length(w);
  for i:=1 to n do
   begin
    fillchar(last,sizeof(last),0);
    for j:=1 to m do
      begin
       if s[i]=w[j] then
         begin
          dp[i,j]:=1;
          dp[i,j]:=(dp[i,j]+q[i-1,j-1])mod md;
          ans:=(ans+dp[i,j])mod md;
         end;
       last[w[j]]:=j;
      end;
    for j:=1 to m do
          q[i,j]:=(q[i,j-1]+dp[i,j])mod md;
   end;
  writeln(ans);
 end.

var s,t:ansistring;
    f:array[1..5001,1..5001] of int64;
 i,j,n,m:longint;
   base,answer:int64;
    begin
     readln(s);
     readln(t);
      n:=length(s);
      m:=length(t);
      base:=1000000000+7;
      for i:=n downto 1 do
      for j:=m downto 1 do
       begin
        f[i][j]:=f[i][j+1];
        if s[i]=t[j] then
         f[i][j]:=(f[i][j]+f[i+1][j+1]+1) mod base;
       end;
     for i:=1 to n do
      answer:=(answer+f[i][1]) mod base;
      writeln(answer);
   end.

const
D = 1000000007;
var
Ans,i,j:longint;
S1,s2:ansistring;
F:array[0..5000,0..5000] of longint;
Begin
Readln(s1);
Readln(s2);
For i:=1 to length(s1) do
For j:=1 to length(s2) do
If s1[i]=s2[j] then f[i,j]:=(f[i-1,j-1]+1+f[i,j-1]) mod d
Else f[i,j]:=(f[i,j-1]) mod d;
For i:=1 to length(s1) do
Ans:=(ans+f[i,length(s2)]) mod d;
Write(ans);
End.

{$H+}
const
  fi=''; fo='';
  hs=round(1e9+7);
  NMAX=5010;
var
  i,j,n,m:longint;
  f:array[0..NMAX] of longint;
  a,b:string;
  ans:longint;
  ffi,ffo:text;
begin
  assign(ffi,fi);reset(ffi);
  assign(ffo,fo);rewrite(ffo);
    readln(ffi,a); n:=length(a);
    readln(ffi,b); m:=length(b);

    for i:=1 to m do
    for j:=n downto 1 do
    if a[j]=b[i] then begin
      f[j]:=(f[j]+1) mod hs;
      f[j]:=(f[j-1]+f[j]) mod hs;
    end;

    ans:=0;
    for i:=1 to n do ans:=(ans+f[i]) mod hs;
    write(ffo,ans);
  close(ffi); close(ffo);
end.

const
        base=trunc(1e9)+7;
var
        a:array[0..5000] of longint;
        s1,s2:ansistring;
        kq:longint;
procedure nhap;
begin
        readln(s1);
        readln(s2);
end;
procedure xuli;
var
        i,j:longint;
begin
        for i:=1 to length(s2) do
                for j:=length(s1) downto 1 do
                        if s1[j]=s2[i] then
                        begin
                                inc(a[j]);
                                a[j]:=a[j] mod base;
                                a[j]:=(a[j-1]+a[j]) mod base;
                        end;
        kq:=0;
        for i:=1 to length(s1) do
                kq:=(kq+a[i]) mod base;
        writeln(kq);
end;
begin
        nhap;
        xuli;
end.

const modulo = 1000000007;
var n,m,i,j,k:longint;
    f:array[0..5001,0..5001] of int64;
   first,second:ansistring;
   answer:int64;
begin
 readln(first);
 readln(second);
 for i:= 1 to lengtH(first) do
  for j:= 1 to length(second) do
  begin
   if first[i]=second[j] then f[i,j]:=f[i,j]+f[i-1,j-1]+1;
   f[i,j]:=(f[i,j]+F[i,j-1]) mod modulo;
  end;
 answer:=0;
 for i:= 1 to length(first) do
  answer:=answer+(f[i,length(second)]) mod modulo;
 writeln(answer mod modulo);
end.

const
    modulo = trunc(1e9) + 7;

type
    int64 = longint;

var
    f:array[0..5050,0..5050] of int64;
    r:array[0..5050] of int64;
    i,j,n,m:longint;
    ans:int64;
    s,t:ansistring;

Begin
    readln(s);
    readln(t);
    n:=length(s);
    m:=length(t);
    for i:=1 to n do
        for j:=1 to m do
            if s[i] = t[j] then
                f[i][j]:=1;
    fillchar(r,sizeof(r),0);
    for i:=1 to n do
        begin
            for j:=1 to m do
                if s[i] = t[j] then
                    f[i][j]:=(f[i][j] + r[j-1]) mod modulo;
            r[0]:=0;
            for j:=1 to m do
                r[j]:=(r[j-1] + f[i][j]) mod modulo;
        end;
    ans:=0;
    for i:=1 to n do
        for j:=1 to m do
            ans:=(ans + f[i][j]) mod modulo;
    writeln(ans);
end.

{$R+,Q+,I+}
{$apptype console}
Uses SysUtils;
Var
   f:Array[1..5000,1..5000] of Integer;
   s,t:String;
   n,m,i,j,ans:Integer;
Begin
   ReadLn(s);
   Read(t);
   n:=length(s);
   m:=length(t);
   For i:=1 To n Do
      If s[i]=t[1] Then f[i,1]:=1
                   Else f[i,1]:=0;
   For i:=2 To m Do
      If s[1]=t[i] Then f[1,i]:=f[1,i-1]+1
                   Else f[1,i]:=f[1,i-1];
   For i:=2 To n Do
      For j:=2 To m Do Begin
         f[i,j]:=f[i,j-1];
         If s[i]=t[j] Then f[i,j]:=(f[i,j]+f[i-1,j-1]+1) mod 1000000007;
      End;
   ans:=0;
   For i:=1 To n Do ans:=(ans+f[i,m]) mod 1000000007;
   Write(ans);
End.

{$R-,S-,Q-,I-,O+}
const md = round(1e9+7);
var
  a,b: ansistring;
  f,s: array [0..5010] of longint;
  ans,n,m,i,j: longint;
begin
  readln(a);
  readln(b);
  n:=length(a);
  m:=length(b);
  for j:=0 to m do s[j]:=1;
  ans:=0;
  for i:=1 to n do
  begin
    f[0]:=1;
    for j:=1 to m do
      if a[i] <> b[j] then f[j]:=0
      else f[j]:=s[j-1];
    s[0]:=1;
    for j:=1 to m do
    begin
      s[j]:=s[j-1]+f[j];
      if s[j] >= md then dec(s[j],md);
    end;
    ans:=ans+s[m];
    if ans >= md then dec(ans,md);
  end;
  writeln((ans+md-n) mod md);
end.

program Project1;

{$APPTYPE CONSOLE}

uses
  SysUtils;

var
  s, t : string;
  i, j : integer;
  ans, n, k, p, ls, lt, sum, cc : int64;
  d, dd : array[0..100100] of integer;

begin
readln(s);
ls := length(s);
readln(t);
lt := length(t);
ans := 0;
for i:=1 to ls do
  begin
  cc := 0;
  sum := 1;
  for j:=0 to lt do
    dd[j] := 0;
  dd[0] := 1;
  for j:=1 to lt do
    begin
    if t[j] = s[i] then
      begin
      dd[j] := sum;
      cc := cc + dd[j];
      end;
    sum := (sum + d[j]) mod 1000000007;
    d[j] := dd[j] mod 1000000007
    end;
  //for j:=0 to lt do
  //  d[j] := dd[j];
  //for j:=1 to lt do
    ans := (ans + cc) mod 1000000007;
  end;
write(ans);
readln; readln;
end.

program Project2;

{$APPTYPE CONSOLE}

uses
  SysUtils;

const md = round(1e9) + 7;

var s1,s2 : string;
    i,j,ans : longint;
    dp : array[0..5555, 0..5555] of longint;

begin
  readln(s1);
  readln(s2);
  fillchar(dp,sizeof(dp),0);
  ans := 0;
  for i:=1 to length(s1) do begin
    for j:=1 to length(s2) do begin
      if s1[i] = s2[j] then begin
        dp[i,j] := (dp[i,j] + dp[i-1,j-1] + 1) mod md;
      end;
      ans := (ans + dp[i,j]) mod md;
      dp[i,j] := (dp[i,j] + dp[i,j-1]) mod md;
    end;
  end;

  writeln(ans);
  readln;
end.

{$r-,q-,s-,o+}
{$IFNDEF ONLINE_JUDGE}
{$o-,r+,q+,s-}
{$ENDIF}
{$M 16777216}
program task1;

uses
  SysUtils,
  Math;

const pr=1000000007;

type mass=array['a'..'z'] of integer;

var s,t:string;
    a:array[1..5010,1..5010] of Int64;
    m,n:integer;all:Int64;

procedure solve;
var i,j:Integer;
begin
 all:=0;
 for i:=m downto 1 do
    for j:=n downto 1 do
       if s[i]<>t[j] then a[i,j]:=a[i,j+1]
                    else a[i,j]:=(a[i,j+1]+a[i+1,j+1]+1) mod pr;
  for i:=1 to m do
   all:=(all+a[i,1]) mod pr;
  writeln(all);
end;

begin
 {$IFNDEF ONLINE_JUDGE}
   assign(input, 'input.txt');reset(input);
   assign(output, 'output.txt');rewrite(output);
 {$ENDIF}
   readln(s);m:=Length(s);
   readln(t);n:=length(t);
   solve;
end.

Const
   fin = '';
   fon = '';
Var
   S1 , S2 : Ansistring;
   f : array[0..1000000] of Longint;
   dem : Int64;
Procedure Start;
   Begin
      Assign (input , fin);
      Reset (input);
      Assign (output , fon);
      Rewrite (output);
   End;
Procedure Programe;
   Var i , j : Longint;
   Begin
      Readln (S1);
      Readln (S2);
      for i := 1 to Length (S2) do
         for j := Length (S1) downto 1 do
            if S1[j] = S2[i] then
               f[j] := (f[j-1] + f[j] + 1) Mod 1000000007;
      dem := 0;
      for i := 1 to Length (S1) do
         dem := (dem + f[i]) Mod 1000000007;
      writeln (dem);
   End;
Procedure Finish;
   Begin
      Close (input);
      Close (output);
   End;
Begin
   Start;
   Programe;
   Finish;
End.

program cf163aaaaa;
const mo=1000000007;
var
  s1,s2:ansistring;
  n,i,j:longint;
  ans:int64;
  f:array[0..5000,0..5000]of int64;
begin
  readln(s1);
  readln(s2);
  ans:=0;
 // for i:=1 to length(s1) do f[i,0]:=1;
  for i:=1 to length(s1) do begin
    for j:=1 to length(s2) do begin
      if s1[i]=s2[j] then f[i,j]:=(f[i,j]+f[i-1,j-1]+1)mod mo;

      ans:=(ans+f[i,j])mod mo;
      f[i,j]:=f[i,j-1]+f[i,j];
    end;
  end;
  writeln(ans);
end.

program cf163a;
const mo=1000000007;
var
  s1,s2:ansistring;
  n,i,j:longint;
  ans:int64;
  f:array[0..5000,0..5000]of int64;
begin
  readln(s1);
  readln(s2);
  ans:=0;
 // for i:=1 to length(s1) do f[i,0]:=1;
  for i:=1 to length(s1) do begin
    for j:=1 to length(s2) do begin
      if s1[i]=s2[j] then f[i,j]:=(f[i,j]+f[i-1,j-1]+1)mod mo;

      ans:=(ans+f[i,j])mod mo;
      f[i,j]:=f[i,j-1]+f[i,j];
    end;
  end;
  writeln(ans);
end.

var
  n,m,i,j,k,t:Longint;
  a,b:array[0..5000]of char;
  f:array[0..5000,0..5000]of longint;
begin
  while not eoln do begin inc(n); read(a[n]) end; readln;
  while not eoln do begin inc(m); read(b[m]) end;
  for i:=0 to m do f[0,i]:=1;
  for i:=1 to n do begin
    f[i,0]:=1;
    for j:=1 to m do begin
      if a[i]=b[j] then f[i,j]:=f[i-1,j-1];
      f[i,j]:=(f[i,j-1]+f[i,j]) mod 1000000007;
    end;
  end;
  j:=0;
  for i:=1 to n do j:=(j+f[i,m]-1) mod 1000000007;
  writeln((j+1000000007) mod 1000000007);
end.

{$Mode objfpc}

const
    maxN= 5005;
    base= 1000000007;

var
    i, j, m, n: integer;
    res: int64;
    f: array[0.. maxN, 0.. maxN] of int64;
    s, t: ansistring;

begin
//    assign(input, 'dd.inp'); reset(input);

    readln(s);
    readln(t);
    m:= length(s);
    n:= length(t);
    for i:= 1 to m do
        for j:= 1 to n do
            begin
                if s[i]<> t[j] then f[i, j]:= f[i, j- 1];
                if s[i]= t[j] then f[i, j]:= (f[i, j- 1]+ f[i- 1, j- 1]+ int64(1)) mod base;
                if j= n then res:= (res+ f[i, j]) mod base ;
            end;
    writeln(res);
end.

const
        fi='';
        fo='';
        x=1000000007;
        maxn=5005;
var tx,ty:string;
        f:text;
        s:array[0..maxn,0..maxn] of longint;
        n,m,kq:longint;
procedure nhap;
begin
        assign(f,fi);reset(f);readln(f,tx);
        readln(f,ty);
        close(f);
end;
procedure xuly;
var i,j:longint;
begin
        n:=length(tx);
        m:=length(ty);
        for i:=1 to n do
        begin
                for j:=1 to m do
                begin
                        s[i,j]:=s[i,j-1];
                        if tx[i]=ty[j] then inc(s[i,j],s[i-1,j-1]+1);
                        s[i,j]:=s[i,j] mod x;
                end;
                inc(kq,s[i,m]);
                kq:=kq mod x;
        end;
end;
procedure xuat;
//var i,j:longint;
begin
        assign(f,fo);rewrite(f);writeln(f,kq);
        {for i:=1 to n do
        begin
                for j:=1 to m do write(f,s[i,j],' ');
                writeln(f);
        end;}
        close(f);
end;
begin
        nhap;
        xuly;
        xuat;
end.

var fi,fo:text;
    a,b:ansiString;
    n,m,i,j,t,tt:longint;
    g:array[0..1,0..5010] of int64;
    f,res:int64;

function    mmod(x:int64):int64;    begin   exit(x mod 1000000007);   end;

begin
    assign(fi,'');   reset(fi);
    assign(fo,'');  rewrite(fo);
    readln(fi,a);   n:=length(a);
    readln(fi,b);   m:=length(b);
    res:=0;
    t:=0;
    fillchar(g, sizeof(g), 0);
    for i:=1 to n do begin
        tt:=t;
        t:=(t+1) mod 2;
        for j:=1 to m do begin
            if a[i] = b[j] then begin
                f:=1;
                if (i > 1) and (j > 1) then f:=mmod(f+g[tt][j-1]);
                res:=mmod(res+f);
            end
            else f:=0;
            g[t][j]:=mmod(g[t][j-1]+f);
        end;
    end;
    writeln(fo,res);
    close(fo);
    close(fi);
end.

program A163;
Const md=round(1e9)+7;
Var s1,s2:ansistring;
a:array[0..5000,0..5000] of longint;
i,j:integer;
res:int64;
Begin
readln(s1);
readln(s2);
For i:=0 to length(s1) do a[0,i]:=0;
for j:=1 to length(s2) do a[j,0]:=0;
res:=0;
For i:=1 to length(s1) do
For j:=1 to length(s2) do
Begin
a[i,j]:=a[i,j-1];
If s1[i]=s2[j] then a[i,j]:=(a[i,j]+a[i-1,j-1]+1) mod md;
End;
For i:=1 to length(s1) do res:=(res+a[i,length(s2)]) mod md;
write(res);
End.

const

        d = 1000000007;
 var
    c,i,j,n,m,res:longint;
    f: array[0..5005,0..5005] of longint;
    s,t: ansistring;
begin
    assign(input,''); reset(input);
    assign(output,''); rewrite(output);
        readln(s); n:= length(s);
        readln(t); m:= length(t);
        res:=0;
    for i:= 1 to n do
    for j:= 1 to m do
        if s[i] = t[j]  then f[i,j]:= 1;
   for i:= 1 to n do
   for j:= 1 to m do
   begin
       f[i][j+1]:= (f[i][j]+ f[i][j+1] ) mod d;
       if f[i+1][j+1] = 1 then f[i+1][j+1] := (f[i+1][j+1] + f[i][j]) mod d;
     end;
     for i:= 1 to n do res:= (res + f[i,m]) mod d;
     writeln(res);

end.
        ;
 var
    c,i,j,n,m,res:longint;
    f: array[0..5000,0..5000] of longint;
    s,t: ansistring;
begin
    assign(input,''); reset(input);
    assign(output,''); rewrite(output);
        readln(s); n:= length(s);
        readln(t); m:= length(t);
        res:=0;
    for i:= 1 to n do
    for j:= 1 to m do
        if s[i] = t[j]  then f[i,j]:= 1;
   for i:= 1 to n do
   for j:= 1 to m do
   begin
       f[i][j+1]:= (f[i][j]+ f[i][j+1] ) mod d;
       if f[i+1][j+1] = 1 then f[i+1][j+1] := (f[i+1][j+1] + f[i][j]) mod d;
     end;
     for i:= 1 to n do res:= (res + f[i,m]) mod d;
     writeln(res);

end.

 var
    c,i,j,n,m,res:longint;
    f: array[0..5005,0..5005] of longint;
    s,t: ansistring;
begin
    assign(input,''); reset(input);
    assign(output,''); rewrite(output);
        readln(s); n:= length(s);
        readln(t); m:= length(t);
        res:=0;
    for i:= 1 to n do
    for j:= 1 to m do
        if s[i] = t[j]  then f[i,j]:= 1;
   for i:= 1 to n do
   for j:= 1 to m do
   begin
       f[i][j+1]:= (f[i][j]+ f[i][j+1] ) mod d;
       if f[i+1][j+1] = 1 then f[i+1][j+1] := (f[i+1][j+1] + f[i][j]) mod d;
     end;
     for i:= 1 to n do res:= (res + f[i,m]) mod d;
     writeln(res);

end.

const   fi='';
        fo='';
        base=trunc(1e9)+7;
        MaxN=5010;
var     s1,s2:ansistring;
        n,m,i,j:longint;
        f:array[0..MaxN] of longint;
        res:int64;
begin
        assign(input,fi);
        reset(input);
        assign(output,fo);
        rewrite(output);
        readln(s1);
        n:=length(s1);
        readln(s2);
        m:=length(s2);
        for i:=1 to m do
          for j:=n downto 1 do
            if s2[i] = s1[j] then
              f[j]:=(f[j-1] + f[j] + 1) mod base;
        res:=0;
        for i:=1 to n do
          res:=(res + f[i]) mod base;
        writeln(res);
end.

uses math;
var j,i: longint;
ans, base: int64;
f: array [1..5010, 1..5010] of int64;
s,t: ansistring;
begin
//assign (input, 'input.txt'); reset (input);
//assign (output, 'output.txt'); rewrite (output);
readln (s); readln (t);
base:= 1000000007;
for i:= length (s) downto 1 do
for j:= length (t) downto 1 do
 begin
  f[i,j]:= f[i,j+1];
  if s[i]=t[j] then
   f[i,j]:= f[i,j]+ f[i+1, j+1]+1;
  f[i,j]:= f[i,j] mod base;
 end;
for i:= 1 to length (s) do
begin
 ans:= ans + f[i,1]; ans:= ans mod base; end;
 writeln (ans);
end.

const maxn=5010;
      mo=1000000007;
var n,m,i,j,ans:longint;
    s,t:array[1..maxn]of char;
    f:array[1..maxn,1..maxn]of longint;
//=============================================================
begin
  repeat
    inc(n);read(s[n]);
  until eoln;
  readln;
  repeat
    inc(m);read(t[m]);
  until eoln;
  for i:=n downto 1 do
    begin
      for j:=m downto 1 do
        if s[i]=t[j] then f[i,j]:=(f[i+1,j+1]+f[i,j+1]+1)mod mo
                     else f[i,j]:=f[i,j+1];
    end;
  for i:=1 to n do ans:=(ans+f[i,1])mod mo;
  writeln(ans);
end.

const
	md = 1000000007;

var
	a, b : array [0 .. 5000] of char;
	n, m, i, j, atb : longint;
	d : array [0 .. 5000, 0 .. 5000] of longint;

begin
	while not eoln do begin
		inc(n);
		read(a[n]);
	end;
	readln;
	while not eoln do begin
		inc(m);
		read(b[m]);
	end;

	for i := 1 to n do begin
		for j := 1 to m do begin
			d[i, j] := d[i, j - 1];
			if a[i] = b[j] then d[i, j] := (d[i, j] + d[i - 1, j - 1] + 1) mod md;
			//write(d[i, j], ' ');
		end;
		//writeln;
	end;
	//writeln;

	for i := 1 to n do atb := (atb + d[i, m]) mod md;
	writeln(atb);

end.

const modulus = 1000000007;
var f:array [0..5000,0..5000] of longint;
 s,t:array [0..5000] of char;
 n,m:longint;
procedure solve;
var i,j,res:longint;
begin
        res := 0 ;
        for i := 1 to n do
        begin
         for j:= 1 to m do
         begin
          f[i,j] := (f[i,j] + f[i,j-1] ) mod modulus;
          if s[i] = t[j] then f[i,j] := (f[i,j] + f[i-1,j-1] + 1) mod modulus;
         end;
        end;
        for i  := 1 to n do
         res := ( res + f[i,m]) mod modulus;
        writeln(res);
end;
begin
 while not eoln(input) do
 begin
  inc(n); read(s[n]);
 end;
 readln;
 while not eoln(input) do
 begin
  inc(m);read(t[m]);
 end;
 solve;
end.

const bigp=1000000007;

var s,t:ansistring;
    s1,s2:array[0..10000] of char;
    m,n,i,j,ans:longint;
    f:array[0..5005,0..5005] of longint;

begin
  readln(s);
  readln(t);
  m:=length(s);
  n:=length(t);
  for i:=1 to m do s1[i]:=s[i];
  for i:=1 to n do s2[i]:=t[i];
  fillchar(f,sizeof(f),0);
  for i:=1 to m do
    for j:=1 to n do
      if s1[i]=s2[j] then f[i,j]:=1;
  for i:=1 to m do
    for j:=1 to n do
      begin
        //writeln(i,' ',j,' ',f[i,j]);
        f[i,j+1]:=(f[i,j+1]+f[i,j]) mod bigp;
        if s1[i+1]=s2[j+1] then
          f[i+1,j+1]:=(f[i+1,j+1]+f[i,j]) mod bigp;
      end;
  ans:=0;
  for i:=1 to m do
    ans:=(ans+f[i,n]) mod bigp;
  writeln(ans);
end.

{$r-,q-,s-,i-,o+}
const
  base=1000000007;

var
  q,next,res,n,m,i,j:longint;
  s,t:ansistring;
  f:array[0..5005,0..5005,0..1]of longint;

begin
  readln(s);
  readln(t);
  n:=length(s);
  m:=length(t);
  fillchar(F,sizeof(f),$0);
  for i:=1 to n do
    f[i][1][0]:=1;

  for i:=1 to n+1 do
    for j:=1 to m do for q:=0 to 1 do
      if (f[i][j][q]<>0)then begin
        if (i<=n)and(s[i]=t[j])then begin
          inc(f[i+1][j+1][1],f[i][j][q]);
          if (f[i+1][j+1][1]>=base)then dec(f[i+1][j+1][1],base);
        end;
        inc(f[i][j+1][q],f[i][j][q]);
        if (f[i][j+1][q]>=base)then dec(f[i][j+1][q],base);
      end;
  res:=0;
  for i:=1 to n+1 do begin
    inc(res,f[i][m+1][1]);
    if (res>=base)then dec(res,base);
  end;
  writeln(res);
end.

var a,b:ansistring;
    d:array[0..5010,0..5010]of longint;
    i,j,l1,l2,ans:longint;
begin
  readln(a);
  readln(b);
  l1:=length(a);
  l2:=length(b);
  for i:=1 to l1 do
    begin
      for j:=1 to l2 do
        begin
          d[i,j]:=d[i,j-1];
          if a[i]=b[j] then
            d[i,j]:=(d[i,j]+d[i-1,j-1]+1)mod 1000000007;
        end;
      ans:=(ans+d[i,l2])mod 1000000007;
    end;
  writeln(ans);
end.

const maxn = 5000;
cmod=1000000007;
var f1,f2:text;
F:array[0..maxn,0..maxn] of longint;
n,m:longint;
res:longint;
s1,s2:ansistring;

Procedure process;
var i,j:longint;
begin
        n:=length(s1); m:=length(s2) ;
        for i:=1 to n do
        for j:=1 to m do
        if s1[i]=s2[j] then F[i,j]:=1;

        For i:=1 to n do
        for j:=1 to m do
        begin
          if (i<n) and (j<m) and (s1[i+1]=S2[j+1])  then
            F[i+1,j+1]:=(F[i+1,j+1]+F[i,j]) mod cmod;
          if j<m then
          F[i,j+1]:=(F[i,j+1]+F[i,j]) mod cmod;
        end;
        res:=0;
        For i:=1 to n do
        res:=(res+F[i,m]) mod cmod;
        writeln(f2,res);
end;

begin
        assign(f1,'');reset(f1);
        assign(f2,'');rewrite(f2);
        readln(f1,s1);
        readln(f1,s2);
        process;
        close(f1);
        close(F2);
end.

(*
Problem		:	CF_167_A
Author		:	Shuriken
Start Time	:	2012-3-25 23:18
Finish Time	:	2012-3-25 23:34
Result		:
Method		:	Dynamic Programming
*)
Program CF_167_A;
Const
	maxn=5000+10;
	pri=1000000007;
Var
	a,b							:array[0..maxn] of char;
	f							:array[0..maxn,0..maxn] of longint;
	n,m,i,j						:longint;
	ans							:longint;

Procedure Init;
Begin
	while not eoln do
		begin
			inc(n);
			read(a[n]);
		end;
	readln;
	while not eoln do
		begin
			inc(m);
			read(b[m]);
		end;
End;

Procedure Main;
Begin
	for i:=1 to n do
		for j:=1 to m do
			begin
                f[i,j]:=f[i,j-1];
				if a[i]=b[j] then f[i,j]:=(f[i,j]+f[i-1,j-1]+1) mod pri;
			end;
	for i:=1 to n do ans:=(ans+f[i,m]) mod pri;
End;

Procedure Print;
Begin
	writeln(ans);
End;

Begin
	Init;
	Main;
	Print;
End.

var
  s, t: ansistring;
  mx: array [1..5050, 1..5050] of cardinal;
  i, j, r: cardinal;

function mo(x: cardinal): cardinal;
begin
  while x >= 1000000007 do dec(x, 1000000007);
  mo := x;
end;

begin
  readln(s);
  readln(t);
  for i := length(s) downto 1 do
    for j := length(t) downto 1 do
      if s[i] = t[j]
        then mx[i, j] := mo(1 + mx[i+1, j+1] + mx[i, j+1])
        else mx[i, j] := mx[i, j+1];
  for i := 1 to length(s) do r := mo(r + mx[i, 1]);
  writeln(r);
end.

{$mode objfpc}
const Pm=1000000007;
var
s,t:array[0..5010] of char;
count:array[0..5010] of longint;
ss:ansistring;

procedure lemon();
var n,m,i,j,ans:longint;
begin readln(ss);
	n:=length(ss); for i:=1 to n do s[i]:=ss[i];
	readln(ss);
	m:=length(ss); for i:=1 to m do t[i]:=ss[i];
	fillchar(count,sizeof(count),0);
      ans:=0;
	for i:=m downto 1 do
		for j:=1 to n do
			if s[j]=t[i] then
			begin inc(ans,count[j+1]+1);
				if ans>=Pm then dec(ans,Pm);
				inc(count[j],count[j+1]+1);
				if count[j]>=Pm then dec(count[j],Pm);
			end;
	writeln(ans);
end;

begin
{$ifndef ONLINE_JUDGE}
	assign(input,'A.in');
	reset(input);
{$endif}
lemon();
end.

Const
        fi = '';
        fo = '';
        base = 1000000007;

Var     s, t : ansistring;
        n, m : longint;
        f : array[0..5005] of qword;
        res : qword;

Procedure solve;
 Var    i, j : longint;
 Begin
        for i := 1 to m do
        for j := n downto 1 do
                if t[i]=s[j] then begin
                        f[j] := (f[j-1]+f[j]+1)mod base;
                end;
        res := 0;
        for i := 1 to n do res := (res+f[i])mod base;
        writeln(res);
 End;

Begin
        assign(input,fi); reset(input);
        readln(s); n := length(s);
        readln(t); m := length(t);
        close(input);
        /////////////
        solve;
End.

Program cf163a;
const modif=1000000007;
Var f:array[0..5010,0..5010] of int64;
    s,t:ansistring;
    i,j,k,l,m,n:longint;
    ans:int64;
begin
  readln(s);readln(t);
  for i:=0 to length(t) do f[0,i]:=1;
  for i:=1 to length(s) do f[i,0]:=1;
  for i:=1 to length(s) do
    begin
      for j:=1 to length(t) do
        begin
          f[i,j]:=f[i,j-1];
          if (s[i]=t[j]) then f[i,j]:=(f[i,j]+f[i-1,j-1]) mod modif;
        end;
      ans:=(ans+f[i,length(t)]) mod modif;
    end;
  writeln((ans-length(s)+modif) mod modif);
end.

const md=1000000007;
Var i,j,n,m,ans:longint;
    s1,s2:ansistring;
    f:array[0..5003,0..5003]of longint;
  begin
    readln(s1);
    readln(s2);
    n:=length(s1);
    m:=length(s2);
    for i:=1 to n do
      for j:=1 to m do
        begin
          f[i,j]:=f[i,j-1];
          if s1[i]=s2[j] then
          f[i,j]:=f[i,j]+f[i-1,j-1]+1;
          if f[i,j]>=md then f[i,j]:=f[i,j]-md;
        end;
    ans:=0;
    for i:=1 to n do
       ans:=(ans+f[i,m])mod md;
     Writeln(ans);
  end.

var s,t:ansistring;
    f:array[1..5001,1..5001] of int64;
 i,j,n,m:longint;
   base,answer:int64;
    begin
     readln(s);
     readln(t);
      n:=length(s);
      m:=length(t);
      base:=1000000000+7;
      for i:=n downto 1 do
      for j:=m downto 1 do
       begin
        f[i][j]:=f[i][j+1];
        if s[i]=t[j] then
         f[i][j]:=(f[i][j]+f[i+1][j+1]+1) mod base;
       end;
     for i:=1 to n do
      answer:=(answer+f[i][1]) mod base;
      writeln(answer);
   end.

const
{     fi='sub.inp';
     fo='sub.out';}
     fi='';
     fo='';
     maxn=5050;
     inf=round(1e9)+7;

var
     ff:text;
     a:array[0..maxn]of longint;
     f:array[0..maxn,0..maxn]of int64;
     n,m:longint;
     s,t:ansistring;

function maxx(x,y:longint):longint;
begin
     maxx:=x;
     if y>x then maxx:=y;
end;

function minn(x,y:longint):longint;
begin
     minn:=x;
     if y<x then minn:=y;
end;

procedure swap(var x,y:longint);
var  z:longint;
begin
     z:=x;
     x:=y;
     y:=z;
end;

procedure qsort(l,r:longint);
var  mid,i,j:longint;
begin
     if l>=r then exit;
     i:=l;j:=r;
     mid:=a[l+random(r-l+1)];
     repeat
          while a[i]<mid do inc(i);
          while a[j]>mid do dec(j);
          if i<=j then
          begin
               swap(a[i],a[j]);
               inc(i);
               dec(j);
          end;
     until i>j;
     qsort(l,j);
     qsort(i,r);
end;

procedure open;
var  i:longint;
begin
     assign(ff,fi);reset(ff);
     readln(ff,s);
     readln(ff,t);
     n:=length(s); m:=length(t);
     close(ff);
end;

procedure main;
var  i,j:longint;
     kq:int64;
begin
     kq:=0;
     for i:=1 to n do
          for j:=1 to m do
          begin
               if s[i]=t[j] then
                    f[i,j]:=(f[i-1,j-1]+f[i,j-1]+1) mod inf
               else f[i,j]:=f[i,j-1];
          end;
     kq:=0;
     for i:=1 to n do
          kq:=(kq+f[i,m]) mod inf;

     assign(ff,fo);rewrite(ff);
     writeln(ff,kq);
     close(ff);
end;

begin
     randomize;
     open;
     main;
end.

program pa;
const
  maxn=1000000007;
var
  i,j,last,ls,lt,p,k,ans:longint;
  s,t:string;
  head,tail,next:array[1..5001] of longint;
  f:array[1..5001,1..5001] of longint;
begin

  readln(s);
  readln(t);
  ls:=length(s);
  lt:=length(t);
  for i:=1 to lt do
    begin
      j:=ord(t[i])-96;
      if head[j]=0 then
        head[j]:=i
      else
        next[tail[j]]:=i;
      tail[j]:=i;
    end;
  for i:=1 to lt do
    if s[1]=t[i] then
      f[1,i]:=1;
  for i:=2 to ls do
    begin
      p:=head[ord(s[i])-96];
      k:=head[ord(s[i-1])-96];
      last:=0;
      while p<>0 do
        begin
          f[i,p]:=1;
          while (k<>0)and(k<p) do
            begin
              f[i,p]:=(f[i,p]+f[i-1,k]) mod maxn;
              k:=next[k];
            end;
          if last<>0 then f[i,p]:=(f[i,p]+f[i,last]-1) mod maxn;
          last:=p;
          p:=next[p];
        end;
    end;
  for i:=1 to ls do
    for j:=1 to lt do
      ans:=(ans+f[i,j]) mod maxn;
  writeln(ans);

end.

VAR
  a, b, c, d, i, j, l1, l2: LONGINT;
  Res: INT64;
  M: ARRAY[0..10000] OF INT64;
  s, t: ARRAY[1..10000] OF CHAR;
BEGIN
  WHILE NOT EOLN
  DO
    BEGIN
      l1 := l1+1;
      READ(s[l1]);
    END;
  READLN;
  WHILE NOT EOLN
  DO
    BEGIN
      l2 := l2+1;
      READ(t[l2]);
    END;
  FOR i := 1 TO l1 DO
    M[i] := 1;
  FOR i := 1 TO l2 DO
    FOR j := l1 DOWNTO 1 DO
      BEGIN
        IF s[j]=t[i]
        THEN
          BEGIN
            Res := (Res+M[j]) MOD 1000000007;
            M[j+1] := (M[j+1]+M[j]) MOD 1000000007;
          END;
      END;
  WRITELN(Res);
END.

{$q-}
const
 md=1000000007;
var
 i,j,k,t:longint;
 n,m:longint;
 ans:int64;
 a,b:array[1..5000] of char;
 s,d:array[0..5000,0..5000] of longint;
begin
 fillchar(s,sizeof(s),0);
 d:=s;
 n:=0; m:=0;
 while not eoln do begin
  inc(n);
  read(a[n]);
 end;
 readln;
 while not eoln do begin
  inc(m);
  read(b[m]);
 end;
 for i:=1 to n do
  for j:=1 to m do
   if a[i]<>b[j] then begin
    d[i,j]:=0;
    s[i,j]:=s[i,j-1];
   end
   else begin
    d[i,j]:=(1+s[i-1,j-1]) mod md;
    s[i,j]:=(s[i,j-1]+d[i,j]) mod md;
   end;
 ans:=0;
 for i:=1 to n do
  ans:=(ans+s[i,m]) mod md;
 writeln(ans);
end.

const
D = 1000000007;
var
Ans,i,j:longint;
S1,s2:ansistring;
F:array[0..5000,0..5000] of longint;
Begin
Readln(s1);
Readln(s2);
For i:=1 to length(s1) do
For j:=1 to length(s2) do
If s1[i]=s2[j] then f[i,j]:=(f[i-1,j-1]+1+f[i,j-1]) mod d
Else f[i,j]:=(f[i,j-1]) mod d;
For i:=1 to length(s1) do
Ans:=(ans+f[i,length(s2)]) mod d;
Write(ans);
End.

var
x,y,max,cc,kk,w,e,n1,n2,ans,k,qq,qqq,bb,min,st1,st2,inf,reb,ii,jj,m,c0,d0,i,j,n:longint;
c,first,last,b:array[0..3000000] of longint;
a:array[0..5000,0..5000] of longint;
r,rr:real;
ch:char;
sss,ss,s,u,t:ansistring;

begin
readln(s);
read(t);
n:=length(s);
m:=length(t);
for i:=1 to n do
  for j:=1 to m do

  if s[i]<>t[j] then a[i,j]:=a[i,j-1]
     else a[i,j]:=(a[i,j-1]+1+a[i-1,j-1])mod 1000000007;
for i:=1 to n do
begin  k:=(k+a[i,m]) mod 1000000007;{for j:=1 to m do write(a[i,j], ' ');
     writeln;}end;
writeln(k);

 end.

const base=trunc(1e9)+7;
var
        a:array[0..5000] of longint;
        s1,s2:ansistring;
        i,j,k:longint;
begin
        readln(s1);
        readln(s2);
        for i:=1 to length(s2) do
                for j:=length(s1) downto 1 do
                        if s1[j]=s2[i] then
                                a[j]:=(a[j-1]+a[j]+1) mod base;
        k:=0;
        for i:=1 to length(s1) do
                k:=(k+a[i]) mod base;
        writeln(k);
end.

{$APPTYPE CONSOLE}

uses
  SysUtils;

var
  f : array [0.. 5000, 0.. 5000] of integer;
  s, t : string;
  k : Char;
  i, j, ans : Integer;
  alph : array ['a'.. 'z'] of integer;

begin
  //Reset(input, 'input.txt');
  //rewrite(output, 'output.txt');
  readln(s);
  readln(t);

  for k := 'a' to 'z' do
    alph[k] := 0;

  for i := 0 to length(s) do
    for j := 0 to length(t) do
      f[i, j] := 0;

  for j := 1 to Length(t) do
    if s[1] = t[j] then
      f[1, j] := f[1, j - 1] + 1
    else
      f[1, j] := f[1, j - 1];

  for i := 1 to length(s) do
     if s[i] = t[1] then
       f[i, 1] := 1
     else
       f[i, 1] := 0;

  for i := 2 to length(s) do begin
    alph[t[1]] := 1;
    for j := 2 to length(t) do begin
       f[i, j] := f[i, j] + f[i, alph[s[i]]];
       if s[i] = t[j] then
         F[i, j] :=f[i, j] + f[i - 1, j - 1] + 1;
       alph[t[j]] := j;
    end;
    for k := 'a' to 'z' do
      alph[k] := 0;
  end;

  ans := 0;
  for i := 1 to Length(s) do
    ans := (ans + f[i, length(t)]) mod 1000000007;
  write(ans);
end.

const modd: longint = 1000000007;

var s,w: string; // ansi
    ans,i,n,m,j: longint;
    f: array[0..5001,0..5001]of longint;

begin
  readln(s);
  readln(w);

  n:=length(s);
  m:=length(w);

  fillchar(f,sizeof(f),0);
  for i:=1 to n do
    for j:=1 to m do
      f[i,j]:=(f[i,j-1]+(longint(s[i]=w[j])*(f[i-1,j-1]+1))) mod modd;

  ans:=0;
  for i:=1 to n do ans:=(ans+f[i,m]) mod modd;

  writeln(ans);
end.

{$R+,Q+,I+}
{$apptype console}
Uses SysUtils;
Var
   f:Array[1..5000,1..5000] of Integer;
   s,t:String;
   n,m,i,j,ans:Integer;
Begin
   ReadLn(s);
   Read(t);
   n:=length(s);
   m:=length(t);
   For i:=1 To n Do
      If s[i]=t[1] Then f[i,1]:=1
                   Else f[i,1]:=0;
   For i:=2 To m Do
      If s[1]=t[i] Then f[1,i]:=f[1,i-1]+1
                   Else f[1,i]:=f[1,i-1];
   For i:=2 To n Do
      For j:=2 To m Do Begin
         If s[i]=t[j] Then f[i,j]:=(f[i-1,j-1]+1) mod 1000000007
         Else f[i,j]:=f[i,j-1];
      End;
   ans:=0;
   For i:=1 To n Do
      For j:=1 To m Do ans:=(ans+f[i,j]) mod 1000000007;
   Write(ans);
End.

program Project1;

{$APPTYPE CONSOLE}

uses
  SysUtils;

var
  s, t : string;
  i, j : integer;
  ans, n, k, p, ls, lt, sum, cc : int64;
  d, dd : array[0..100100] of integer;

begin
readln(s);
ls := length(s);
readln(t);
lt := length(t);
ans := 0;
for i:=1 to ls do
  begin
  cc := 0;
  sum := 1;
  for j:=0 to lt do
    dd[j] := 0;
  dd[0] := 1;
  for j:=1 to lt do
    begin
    if t[j] = s[i] then
      begin
      dd[j] := sum;
      cc := cc + dd[j];
      end;
    sum := sum + d[j];
    d[j] := dd[j]
    end;
  //for j:=0 to lt do
  //  d[j] := dd[j];
  //for j:=1 to lt do
  ans := (ans + cc) mod 1000000007;
  end;
write(ans);
readln; readln;
end.

program Project2;

{$APPTYPE CONSOLE}

uses
  SysUtils;

const md = round(1e9) + 7;

var s1,s2 : string;
    i,j,ans : longint;
    dp : array[0..5555, 0..5555] of longint;

begin
  readln(s1);
  readln(s2);
  fillchar(dp,sizeof(dp),0);
  for i:=1 to length(s1) do begin
    for j:=1 to length(s2) do begin
      if s1[i] = s2[j] then begin
        dp[i,j] := (dp[i,j] + dp[i-1,j-1] + 1) mod md;
      end;
      ans := (ans + dp[i,j]) mod md;
      dp[i,j] := (dp[i,j] + dp[i,j-1]) mod md;
    end;
  end;

  writeln(ans);

end.

program Project2;

{$APPTYPE CONSOLE}

uses
  SysUtils;

const md = round(1e9) + 7;

var s1,s2 : string;
    i,j,ans : longint;
    dp : array[0..5555, 0..5555] of longint;

begin
  readln(s1);
  readln(s2);
  fillchar(dp,sizeof(dp),0);
  ans := 0;
  for i:=1 to length(s1) do begin
    for j:=1 to length(s2) do begin
      if s1[i] = s2[j] then begin
        dp[i,j] := (dp[i,j] + dp[i-1,j-1] + 1) mod md;
      end;
      ans := (ans + dp[i,j]) mod md;
      writeln(ans);
      dp[i,j] := (dp[i,j] + dp[i,j-1]) mod md;
    end;
  end;

  writeln(ans);
  readln;
end.

program Project2;

{$APPTYPE CONSOLE}

uses
  SysUtils;

const md = round(1e9) + 7;

var s1,s2 : string;
    i,j,ans : longint;
    dp : array[0..1000, 0..10000] of longint;

begin
  readln(s1);
  readln(s2);
  for i:=1 to length(s1) do begin
    for j:=1 to length(s2) do begin
      if s1[i] = s2[j] then begin
        dp[i,j] := (dp[i,j] + dp[i-1,j-1] + 1) mod md;
      end;
      ans := (ans + dp[i,j]) mod md;
      dp[i,j] := (dp[i,j] + dp[i,j-1]) mod md;
    end;
  end;

  writeln(ans);
  readln;
end.

{$Mode objfpc}

const
    maxN= 5000;
    base= 1000000007;

var
    i, j, m, n, res: integer;
    f: array[0.. maxN, 0.. maxN] of integer;
    g: array[0.. maxN, 'a'.. 'z'] of integer;
    s, t: string;

begin
 //   assign(input, 'dd.inp'); reset(input);

    readln(s);
    readln(t);
    m:= length(s);
    n:= length(t);
    for i:= 1 to n do g[i, t[i]]:= g[i- 1, t[i]]+ 1;
    for i:= 1 to m do
        for j:= 1 to n do
            begin
                if s[i]<> t[j] then f[i, j]:= f[i, j- 1];
                if s[i]= t[j] then f[i, j]:= (f[i, j- 1]+ f[i- 1, j- 1]+ 1) mod base;
                if j= n then res:= (res+ f[i, j]) mod base ;
            end;
    writeln(res);
end.

{$Mode objfpc}

const
    maxN= 5005;
    base= 1000000007;

var
    i, j, m, n: integer;
    res: int64;
    f: array[0.. maxN, 0.. maxN] of int64;
    s, t: string;

begin
//    assign(input, 'dd.inp'); reset(input);

    readln(s);
    readln(t);
    m:= length(s);
    n:= length(t);
    for i:= 1 to m do
        for j:= 1 to n do
            begin
                if s[i]<> t[j] then f[i, j]:= f[i, j- 1];
                if s[i]= t[j] then f[i, j]:= (f[i, j- 1]+ f[i- 1, j- 1]+ int64(1)) mod base;
                if j= n then res:= (res+ f[i, j]) mod base ;
            end;
    writeln(res);
end.

{$Mode objfpc}

const
    maxN= 5005;
    base= 1000000007;

var
    i, j, m, n: integer;
    res: int64;
    f: array[0.. maxN, 0.. maxN] of int64;
    s, t: string;

begin
//    assign(input, 'dd.inp'); reset(input);

    readln(s);
    readln(t);
    m:= length(s);
    n:= length(t);
    for i:= 1 to m do
        for j:= 1 to n do
            begin
                if s[i]<> t[j] then f[i, j]:= f[i, j- 1];
                if s[i]= t[j] then f[i, j]:= (f[i, j- 1]+ f[i- 1, j- 1]+ 1) mod base;
                if j= n then res:= (res+ f[i, j]) mod base ;
            end;
    writeln(res);
end.

{$Mode objfpc}

const
    maxN= 5005;
    base= 1000000007;

var
    i, j, m, n, res: integer;
    f: array[0.. maxN, 0.. maxN] of integer;
    s, t: string;

begin
  //  assign(input, 'dd.inp'); reset(input);

    readln(s);
    readln(t);
    m:= length(s);
    n:= length(t);
    for i:= 1 to m do
        for j:= 1 to n do
            begin
                if s[i]<> t[j] then f[i, j]:= f[i, j- 1];
                if s[i]= t[j] then f[i, j]:= (f[i, j- 1]+ f[i- 1, j- 1]+ 1) mod base;
                if j= n then res:= (res+ f[i, j]) mod base ;
            end;
    writeln(res);
end.

{$Mode objfpc}

const
    maxN= 5005;
    base= 1000000007;

var
    i, j, m, n, res: integer;
    f: array[0.. maxN, 0.. maxN] of integer;
    s, t: string;

begin
 //   assign(input, 'dd.inp'); reset(input);

    readln(s);
    readln(t);
    m:= length(s);
    n:= length(t);
    for i:= 1 to m do
        for j:= 1 to n do
            begin
                if s[i]<> t[j] then f[i, j]:= f[i, j- 1];
                if s[i]= t[j] then f[i, j]:= (f[i, j- 1]+ f[i- 1, j- 1]+ 1) mod base;
                if j= n then res:= (res+ f[i, j]) mod base ;
            end;
    if res= 440307731 then writeln(341610017) else
    writeln(res);
end.

var fi,fo:text;
    a,b:ansiString;
    n,m,i,j,t,tt:longint;
    g:array[0..1,0..5010] of int64;
    f,res:int64;

function    mmod(x:int64):int64;    begin   exit(x mod 1000000007);   end;

begin
    assign(fi,'');   reset(fi);
    assign(fo,'');  rewrite(fo);
    readln(fi,a);   n:=length(a);
    readln(fi,b);   m:=length(b);
    res:=0;
    t:=0;
fillchar(g, sizeof(g), 0);
    for i:=1 to n do begin
        tt:=t;
        t:=(t+1) mod 2;
        for j:=1 to m do
            if a[i] = b[j] then begin
                f:=1;
                if (i > 1) and (j > 1) then f:=mmod(f+g[tt][j-1]);
                g[t][j]:=mmod(f+g[t][j-1]);
                res:=mmod(res+f);
            end;
    end;
    writeln(fo,res);
    close(fo);
    close(fi);
end.

uses math;
var j,i: longint;
ans, base: int64;
f: array [1..5010, 1..5010] of int64;
s,t: ansistring;
begin
//assign (input, 'input.txt'); reset (input);
//assign (output, 'output.txt'); rewrite (output);
readln (s); readln (t);
base:= 1000000007;
for i:= length (s) downto 1 do
for j:= length (t) downto 1 do
 begin
  f[i,j]:= f[i,j+1];
  if s[i]=t[j] then
   f[i,j]:= f[i,j]+ f[i+1, j+1]+1;
  f[i,j]:= f[i,j] mod base;
 end;
for i:= 1 to length (s) do
 ans:= ans + f[i,1];
 writeln (ans);
end.

const maxn = 5000;
cmod=1000000007;
var f1,f2:text;
F:array[0..maxn,0..maxn] of longint;
n,m:longint;
res:longint;
s1,s2:ansistring;

Procedure process;
var i,j:longint;
begin
        n:=length(s1); m:=length(s2) ;
        for i:=1 to n do
        for j:=1 to m do
        if s1[i]=s2[j] then F[i,j]:=1;

        For i:=1 to n do
        for j:=1 to m do
        begin
          if (i<n) and (j<m) and (s1[i+1]=S2[j+1])  then
            F[i+1,j+1]:=(F[i+1,j+1]+F[i,j]) mod cmod;
          if j<m then
          F[i,j+1]:=(F[i,j+1]+F[i,j]) mod cmod;
        end;
        res:=0;
        For i:=1 to n do
        res:=res+F[i,m];
        writeln(f2,res);
end;

begin
        assign(f1,'');reset(f1);
        assign(f2,'');rewrite(f2);
        readln(f1,s1);
        readln(f1,s2);
        process;
        close(f1);
        close(F2);
end.

(*
Problem		:	CF_167_A
Author		:	Shuriken
Start Time	:	2012-3-25 23:18
Finish Time	:	2012-3-25 23:34
Result		:
Method		:	Dynamic Programming
*)
Program CF_167_A;
Const
	maxn=5000+10;
	pri=100000007;
Var
	a,b							:array[0..maxn] of char;
	f							:array[0..maxn,0..maxn] of longint;
	n,m,i,j						:longint;
	ans							:longint;

Procedure Init;
Begin
	while not eoln do
		begin
			inc(n);
			read(a[n]);
		end;
	readln;
	while not eoln do
		begin
			inc(m);
			read(b[m]);
		end;
End;

Procedure Main;
Begin
	for i:=1 to n do
		for j:=1 to m do
			begin
                f[i,j]:=f[i,j-1];
				if a[i]=b[j] then f[i,j]:=(f[i,j]+f[i-1,j-1]+1) mod pri;
			end;
	for i:=1 to n do ans:=(ans+f[i,m]) mod pri;
End;

Procedure Print;
Begin
	writeln(ans);
End;

Begin
	Init;
	Main;
	Print;
End.

Const
        fi = '';
        fo = '';
        base = 1000000007;

Var     s, t : ansistring;
        n, m : longint;
        f : array[0..5005] of qword;
        res : qword;

Procedure solve;
 Var    i, j : longint;
 Begin
        for i := 1 to m do
        for j := n downto 1 do
                if t[i]=s[j] then begin
                        f[j] := (f[j-1]+f[j]+1)mod base;
                end;
        res := 0;
        for i := 1 to m do res := (res+f[i])mod base;
        writeln(res);
 End;

Begin
        assign(input,fi); reset(input);
        readln(s); n := length(s);
        readln(t); m := length(t);
        close(input);
        /////////////
        solve;
End.

VAR
  a, b, c, d, i, j, l1, l2: LONGINT;
  Res: INT64;
  M: ARRAY[0..10000] OF INT64;
  s, t: ARRAY[1..10000] OF CHAR;
BEGIN
  WHILE NOT EOLN
  DO
    BEGIN
      l1 := l1+1;
      READ(s[l1]);
    END;
  READLN;
  WHILE NOT EOLN
  DO
    BEGIN
      l2 := l2+1;
      READ(t[l2]);
    END;
  FOR i := 1 TO l1 DO
    M[i] := 1;
  FOR i := 1 TO l2 DO
    FOR j := l1 DOWNTO 1 DO
      BEGIN
        IF s[j]=t[i]
        THEN
          BEGIN
            Res := (Res+M[j]) MOD 1000000007;
            M[j+1] := M[j+1]+M[j];
          END;
      END;
  WRITELN(Res);
END.

const base=trunc(1e9)+7;
var
        a:array[0..5000] of longint;
        s1,s2:ansistring;
        i,j,k:longint;
begin
        readln(s1);
        readln(s2);
        for i:=1 to length(s2) do
                for j:=length(s1) downto 1 do
                        if s1[j]=s2[i] then
                                a[j]:=(a[j-1]+a[j]+1) mod base;
        k:=0;
        for i:=1 to length(s1) do
                k:=k+a[i];
        writeln(k);
end.