Problem p04024 (C++)

Buggy submission (status: Runtime Error):
#include <algorithm>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
using namespace std;
const int mod = 1000000007;
int fpow(int x, long long y) {
  if (y == 0)
    return 1;
  int ret = fpow(x, y >> 1);
  ret = (long long)ret * ret % mod;
  if (y & 1)
    ret = (long long)ret * x % mod;
  return ret;
}
int inv(int x) { return fpow(x, mod - 2); }
char s[1010][1010];
int main() {
  int n, m;
  int cnt, cnt1, cnt2, cnt11, cnt22;
  long long k;
  long long ans, q;
  scanf("%d%d%lld", &n, &m, &k);
  for (int i = 1; i <= n; i++)
    scanf("%s", s[i] + 1);
  if (k == 0) {
    printf("1");
    return 0;
  }
  k--;
  cnt = cnt1 = cnt2 = 0;
  cnt11 = cnt22 = 0;
  for (int i = 1; i <= n; i++)
    for (int j = 1; j <= m; j++)
      if (s[i][j] == '#')
        cnt++;
  if (m > 1) {
    for (int i = 1; i <= n; i++)
      if (s[i][1] == '#' && s[i][m] == '#')
        cnt1++;
    for (int i = 1; i <= n; i++)
      for (int j = 2; j <= m; j++)
        if (s[i][j] == '#' && s[i][j - 1] == '#')
          cnt11++;
  }
  if (n > 1) {
    for (int j = 1; j <= m; j++)
      if (s[1][j] == '#' && s[n][j] == '#')
        cnt2++;
    for (int i = 2; i <= n; i++)
      for (int j = 1; j <= m; j++)
        if (s[i - 1][j] == '#' && s[i][j] == '#')
          cnt22++;
  }
  if (cnt1 && cnt2) {
    printf("1");
    return 0;
  } else if (cnt1 == 0 && cnt2 == 0) {
    printf("%d", fpow(cnt, k));
    return 0;
  }
  if (cnt2) {
    cnt1 = cnt2;
    cnt11 = cnt22;
  }
  q = (long long)cnt1 * inv(cnt) % mod;
  ans = fpow(cnt, k) - (long long)fpow(cnt, k - 1) * cnt11 % mod *
                           (mod + 1 - fpow(q, k)) % mod * inv(mod + 1 - q) %
                           mod;
  (ans += mod) %= mod;
  printf("%lld", ans);
  return 0;
}

Fixed submission:
#include <algorithm>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
using namespace std;
const int mod = 1000000007;
int fpow(int x, long long y) {
  if (y == 0)
    return 1;
  int ret = fpow(x, y >> 1);
  ret = (long long)ret * ret % mod;
  if (y & 1)
    ret = (long long)ret * x % mod;
  return ret;
}
int inv(int x) { return fpow(x, mod - 2); }
char s[1010][1010];
int main() {
  int n, m;
  int cnt, cnt1, cnt2, cnt11, cnt22;
  long long k;
  long long ans, q;
  scanf("%d%d%lld", &n, &m, &k);
  for (int i = 1; i <= n; i++)
    scanf("%s", s[i] + 1);
  if (k <= 1) {
    printf("1");
    return 0;
  }
  k--;
  cnt = cnt1 = cnt2 = 0;
  cnt11 = cnt22 = 0;
  for (int i = 1; i <= n; i++)
    for (int j = 1; j <= m; j++)
      if (s[i][j] == '#')
        cnt++;
  if (m > 1) {
    for (int i = 1; i <= n; i++)
      if (s[i][1] == '#' && s[i][m] == '#')
        cnt1++;
    for (int i = 1; i <= n; i++)
      for (int j = 2; j <= m; j++)
        if (s[i][j] == '#' && s[i][j - 1] == '#')
          cnt11++;
  }
  if (n > 1) {
    for (int j = 1; j <= m; j++)
      if (s[1][j] == '#' && s[n][j] == '#')
        cnt2++;
    for (int i = 2; i <= n; i++)
      for (int j = 1; j <= m; j++)
        if (s[i - 1][j] == '#' && s[i][j] == '#')
          cnt22++;
  }
  if (cnt1 && cnt2) {
    printf("1");
    return 0;
  } else if (cnt1 == 0 && cnt2 == 0) {
    printf("%d", fpow(cnt, k));
    return 0;
  }
  if (cnt2) {
    cnt1 = cnt2;
    cnt11 = cnt22;
  }
  q = (long long)cnt1 * inv(cnt) % mod;
  ans = fpow(cnt, k) - (long long)fpow(cnt, k - 1) * cnt11 % mod *
                           (mod + 1 - fpow(q, k)) % mod * inv(mod + 1 - q) %
                           mod;
  (ans += mod) %= mod;
  printf("%lld", ans);
  return 0;
}