#include <iomanip>
#include <iostream>
#include <unordered_map>
#include <vector>
#define rep(i, n) for (int i = 0; i < (n); i++)
using namespace std;

const int64_t mod = 1e9 + 7;
unordered_map<int64_t, int64_t> memo;

int64_t mod_pow(int64_t x, int64_t n) {
  int64_t key = x * 1e6 + n;
  if (memo.count(key)) return memo[key];
  int64_t ret = 1;
  while (n) {
    if (n % 2) {
      ret = (ret * x) % mod;
    }
    x = x * x % mod;
    n /= 2;
  }
  return memo[key] = ret;
}
int main(void) {
  ios::sync_with_stdio(false);
  int H, W;
  cin >> H >> W;
  vector<string> S(H);
  int K = 0;
  rep(i, H) {
    cin >> S[i];
    rep(j, W) {
      if (S[i][j] == '.') K++;
    }
  }

  vector<vector<int>> left(H, vector<int>(W));
  rep(i, H) {
    left[i][0] = (S[i][0] == '.') ? 1 : 0;
    for (int j = 1; j < W; ++j) {
      if (S[i][j] == '#') {
        left[i][j] = 0;
      } else {
        left[i][j] = left[i][j - 1] + 1;
      }
    }
  }
  vector<vector<int>> right(H, vector<int>(W));
  rep(i, H) {
    right[i][W - 1] = (S[i][W - 1] == '.') ? 1 : 0;
    for (int j = W - 2; j >= 0; --j) {
      if (S[i][j] == '#') {
        right[i][j] = 0;
      } else {
        right[i][j] = right[i][j + 1] + 1;
      }
    }
  }
  vector<vector<int>> up(H, vector<int>(W));
  rep(j, W) {
    up[0][j] = (S[0][j] == '.') ? 1 : 0;
    for (int i = 1; i < H; ++i) {
      if (S[i][j] == '#') {
        up[i][j] = 0;
      } else {
        up[i][j] = up[i - 1][j] + 1;
      }
    }
  }
  vector<vector<int>> down(H, vector<int>(W));
  rep(j, W) {
    down[H - 1][j] = (S[H - 1][j] == '.') ? 1 : 0;
    for (int i = H - 2; i >= 0; --i) {
      if (S[i][j] == '#') {
        down[i][j] = 0;
      } else {
        down[i][j] = down[i + 1][j] + 1;
      }
    }
  }

  int64_t answer = 0;
  rep(i, H) {
    rep(j, W) {
      if (S[i][j] == '#') continue;
      int lamps = up[i][j] + down[i][j] + left[i][j] + right[i][j] + 1 - 4;
      // cout << "i=" << i << " j=" << j << " lamps=" << lamps << endl;
      // cout << "up=" << up[i][j] << " down=" << down[i][j]
      //     << " left=" << left[i][j] << " right= " << right[i][j] << endl;
      int64_t add = mod_pow(2, lamps);
      add = (add - 1 + mod) % mod;
      int64_t mult = mod_pow(2, K - lamps);
      add = (add * mult) % mod;
      // cout << add << endl;
      answer = (answer + add) % mod;
    }
  }
  cout << answer << endl;
  return 0;
}

#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define ld long double
#define REP(i,m,n) for(int i=(int)(m); i<(int)(n); i++)
#define rep(i,n) REP(i,0,n)
#define RREP(i,m,n) for(int i=(int)(m); i>=(int)(n); i--)
#define rrep(i,n) RREP(i,(n)-1,0)
#define all(v) v.begin(), v.end()
#define endk '\n'
const int inf = 1e9+7;
const ll longinf = 1LL<<60;
const ll mod = 1e9+7;
const ll mod2 = 998244353;
const ld eps = 1e-10;
template<typename T1, typename T2> inline void chmin(T1 &a, T2 b){if(a>b) a=b;}
template<typename T1, typename T2> inline void chmax(T1 &a, T2 b){if(a<b) a=b;}

int main() {
  cin.tie(0);
  ios::sync_with_stdio(false);
  int n, k; cin >> n >> k;
  vector<vector<int>> G(n);
  rep(i, n-1) {
    int u, v; cin >> u >> v;
    u--; v--;
    G[u].push_back(v);
    G[v].push_back(u);
  }
  auto test = [&](int x) {
    int need = 0;
    vector<int> dist(n);
    auto dfs = [&](auto dfs, int cur, int par) -> void {
      vector<int> tmp;
      for(int ne: G[cur]) {
        if(ne != par) {
          dfs(dfs, ne, cur);
          chmax(dist[cur], dist[ne]+1);
          tmp.push_back(dist[ne]+1);
        }
      }
      if(tmp.empty()) return;
      sort(all(tmp));
      int mn = *tmp.begin();
      int mx = *tmp.rbegin();
      if(mn + mx < 0) {
        chmin(dist[cur], mn);
        return;
      }
      if(cur == 0 || dist[cur] == x) {
        need++;
        dist[cur] = -x-1;
      }
    };
    dfs(dfs, 0, -1);
    return need <= k;
  };
  auto bsearch = [&]() {
    int ok = n-1, ng = 0;
    while(ok-ng>1) {
      int mid = (ok+ng)/2;
      (test(mid) ? ok : ng) = mid;
    }
    return ok;
  };
  cout << bsearch() << endk;
  return 0;
}
