Dima and Figure

Dima loves making pictures on a piece of squared paper. And yet more than that Dima loves the pictures that depict one of his favorite figures.

A piece of squared paper of size n × m is represented by a table, consisting of n rows and m columns. All squares are white on blank squared paper. Dima defines a picture as an image on a blank piece of paper, obtained by painting some squares black.

The picture portrays one of Dima’s favorite figures, if the following conditions hold:

  • The picture contains at least one painted cell;
  • All painted cells form a connected set, that is, you can get from any painted cell to any other one (you can move from one cell to a side-adjacent one);
  • The minimum number of moves needed to go from the painted cell at coordinates (x 1, y 1) to the painted cell at coordinates (x 2, y 2), moving only through the colored cells, equals |x 1 - x 2| + |y 1 - y 2|.

Now Dima is wondering: how many paintings are on an n × m piece of paper, that depict one of his favorite figures? Count this number modulo 1000000007 (109 + 7).

Input

The first line contains two integers n and m — the sizes of the piece of paper (1 ≤ n, m ≤ 150).

Output

In a single line print the remainder after dividing the answer to the problem by number 1000000007 (109 + 7).

Examples

input

2 2

output

13

input

3 4

output

571

Solution:

#include <iostream>
#include <iomanip>
#include <stdio.h>
#include <set>
#include <vector>
#include <map>
#include <cmath>
#include <algorithm>
#include <memory.h>
#include <string>
#include <sstream>

using namespace std;

const int md = 1000000007;

void add(int &a, int b) {
a += b;
if (a >= md) a -= md;
}

int f[155][155][2][2], oldf[155][155][2][2], trueoldf[155][155][2][2];

int main() {
int n, m;
scanf("%d %d", &n, &m);
memset(f, 0, sizeof(f));
for (int a=1;a<=m;a++)
    for (int b=a;b<=m;b++) f[a][b][1][1] = 1;
  int ans = 0;
  for (int i=1;i<=n;i++) {
    long long cnt = 0;
    for (int a=1;a<=m;a++)
      for (int b=a;b<=m;b++)
        for (int ka=0;ka<=1;ka++)
          for (int kb=0;kb<=1;kb++) cnt += f[a][b][ka][kb];
    ans = (ans+cnt*(n-i+1)) % md;

    for (int a=1;a<=m;a++)
      for (int b=a+1;b<=m;b++)
        for (int kb=0;kb<=1;kb++) {
          add(f[a+1][b][0][kb], f[a][b][0][kb]);
          add(f[a+1][b][0][kb], f[a][b][1][kb]);
        }
    for (int a=1;a<=m;a++)
      for (int b=m;b>=a+1;b--)
for (int ka=0;ka<=1;ka++) {
          add(f[a][b-1][ka][0], f[a][b][ka][0]);
          add(f[a][b-1][ka][0], f[a][b][ka][1]);
        }
    for (int a=m;a>=2;a--)
for (int b=a;b<=m;b++)
        for (int kb=0;kb<=1;kb++) {
          add(f[a-1][b][1][kb], f[a][b][1][kb]);
        }
    for (int a=m;a>=1;a--)
for (int b=a;b<=m-1;b++)
        for (int ka=0;ka<=1;ka++) {
          add(f[a][b+1][ka][1], f[a][b][ka][1]);
        }
  }
  printf("%d\n", ans);
  return 0;
}