#include <bits/stdc++.h>

#define MAXN 41
#define re register
#define xx x + fx[i][0]
#define yy y + fx[i][1]
#define INF 0x7ffffff
#define mp(a, b) make_pair(a, b)

using namespace std;

struct node {
  int step;
  pair<int, int> p[MAXN * 10];
  int cnt;
  bool used[MAXN * 10];
};

int n, m, endx, endy, hardcnt, specflag = true;
int imap[MAXN][MAXN], vis[MAXN][MAXN], minn[MAXN][MAXN];
int fx[4][2] = {{1, 0}, {0, 1}, {-1, 0}, {0, -1}};
pair<int, int> hard[MAXN * MAXN];

queue<node> q;

inline void File() {
#ifndef Mr_Chen
  freopen("haner.in", "r", stdin);
  freopen("haner.out", "w", stdout);
#endif
}

inline int read() {
  re int res = 0;
  re bool f = 1;
  re char ch = getchar();
  while (ch < '0' || ch > '9') {
    if (ch == '-')
      f = 0;
    ch = getchar();
  }
  while (ch >= '0' && ch <= '9') {
    res = (res << 3) + (res << 1) + (ch & 15);
    ch = getchar();
  }
  return f ? res : -res;
}

inline bool disap(re int x, re int y) {
  return imap[x][y] == 1 && !((imap[x - 1][y] && imap[x + 1][y]) ||
                              (imap[x][y - 1] && imap[x][y + 1]));
}

void killp(re int x, re int y) {
  // printf("<%d,%d> killed\\n",x,y);
  imap[x][y] = 0;
  for (re int i = 0; i < 4; ++i)
    if (xx > 0 && xx <= n && yy > 0 && yy <= m && disap(xx, yy))
      killp(xx, yy);
}

inline void clac() {
  for (re int i = 1; i <= n; ++i)
    for (re int j = 1; j <= m; ++j)
      if (disap(i, j))
        killp(i, j);
}

inline int bfs() {
  re node start;
  start.step = 0;
  start.cnt = 0;
  memset(start.used, 0, sizeof start.used);
  // memset(start.p,0,sizeof start.p);
  q.push(start);
  while (!q.empty()) {
    re node now = q.front();
    q.pop();
    for (re int j = 1; j <= now.cnt; ++j)
      imap[now.p[j].first][now.p[j].second] = 1;
    for (re int i = 1; i <= hardcnt; ++i) {
      if (now.used[i])
        continue;
      imap[hard[i].first][hard[i].second] = 1;
      clac();
      if (imap[endx][endy] == 0)
        return now.step + 1;
      imap[hard[i].first][hard[i].second] = 2;
      re node t = now;
      ++t.step;
      t.p[++t.cnt] = hard[i];
      t.used[i] = true;
      q.push(t);
    }
    for (re int j = 1; j <= now.cnt; ++j)
      imap[now.p[j].first][now.p[j].second] = 2;
  }
}

int main() {
  char ch;
  n = read(), m = read();
  for (re int i = 1; i <= n; ++i) {
    for (re int j = 1; j <= m; ++j) {
      do
        ch = getchar();
      while (ch == '\\n' || ch == ' ');
      if (ch == '+')
        imap[i][j] = 1;
      else if (ch == '#') {
        imap[i][j] = 2;
        hard[++hardcnt] = mp(i, j);
        specflag = false;
      } else if (ch == 'P') {
        imap[i][j] = 1;
        endx = i, endy = j;
      } else
        puts("ZYH && ALSaoBen && wzr AK IOI");
    }
  }
  if (specflag) {
    printf("0\\n");
    return 0;
  }
  clac();
  if (imap[endx][endy] == 0) {
    printf("0\\n");
    return 0;
  }
  /*for(re int i=1;i<=n;++i)
  {
          for(re int j=1;j<=m;++j)
                  printf("%d ",imap[i][j]);
          printf("\\n");
  }*/
  printf("%d\\n", bfs());
  return 0;
}

/************************************************
 * Au: Hany01
 * Prob: haner
 * Email: hany01dxx@gmail.com & hany01@foxmail.com
 * Inst: Yali High School
 ************************************************/

#include <bits/stdc++.h>

using namespace std;

typedef long long LL;
typedef long double LD;
typedef pair<int, int> PII;
#define Rep(i, j) for (register int i = 0, i##_end_ = (j); i < i##_end_; ++i)
#define For(i, j, k)                                                           \\
  for (register int i = (j), i##_end_ = (k); i <= i##_end_; ++i)
#define Fordown(i, j, k)                                                       \\
  for (register int i = (j), i##_end_ = (k); i >= i##_end_; --i)
#define Set(a, b) memset(a, b, sizeof(a))
#define Cpy(a, b) memcpy(a, b, sizeof(a))
#define X first
#define Y second
#define PB(a) push_back(a)
#define MP(a, b) make_pair(a, b)
#define SZ(a) ((int)(a).size())
#define ALL(a) a.begin(), a.end()
#define INF (0x3f3f3f3f)
#define INF1 (2139062143)
#define debug(...) fprintf(stderr, __VA_ARGS__)
#define y1 wozenmezhemecaia

template <typename T> inline bool chkmax(T &a, T b) {
  return a < b ? a = b, 1 : 0;
}
template <typename T> inline bool chkmin(T &a, T b) {
  return b < a ? a = b, 1 : 0;
}

template <typename T> inline T read() {
  static T _, __;
  static char c_;
  for (_ = 0, __ = 1, c_ = getchar(); c_ < '0' || c_ > '9'; c_ = getchar())
    if (c_ == '-')
      __ = -1;
  for (; c_ >= '0' && c_ <= '9'; c_ = getchar())
    _ = (_ << 1) + (_ << 3) + (c_ ^ 48);
  return _ * __;
}
// EOT

const int maxn = 45;

int n, m;
int sum[maxn][maxn], dp[maxn][maxn][maxn][maxn], x, y,
    vis[maxn][maxn][maxn][maxn];

inline void Init() {
  static char str[maxn];
  n = read<int>(), m = read<int>();
  For(i, 1, n) {
    scanf("%s", str + 1);
    For(j, 1, m) if (str[j] == 'P') x = i, y = j;
    else if (str[j] == '#') sum[i][j] = 1;
  }
  For(i, 1, n) For(j, 1, m) sum[i][j] +=
      sum[i - 1][j] + sum[i][j - 1] - sum[i - 1][j - 1];
}

inline int getsum(int x1, int y1, int x2, int y2) {
  // if (sum[x2][y2] - sum[x2][y1 - 1] - sum[x1 - 1][y2] + sum[x1 - 1][y1 - 1] <
  // 0) cout << x1 << ' ' << y1 << ' ' << x2 << ' ' << y2 << endl;
  return sum[x2][y2] - sum[x2][y1 - 1] - sum[x1 - 1][y2] + sum[x1 - 1][y1 - 1];
}

int DFS(int x1, int y1, int x2, int y2) {
  if (!chkmax(vis[x1][y1][x2][y2], 1))
    return dp[x1][y1][x2][y2];
  int &ans = dp[x1][y1][x2][y2] = INF;
  chkmin(ans, getsum(x1, y1, x, y));
  chkmin(ans, getsum(x1, y, x, y2));
  chkmin(ans, getsum(x, y1, x2, y));
  chkmin(ans, getsum(x, y, x2, y2));
  For(i, x1 + 1, x) For(j, y1 + 1, y) if (i != x1 || j != y1)
      chkmin(ans, DFS(i, j, x2, y2) + getsum(i, y1, x2, j - 1) +
                      getsum(x1, j, i - 1, y2));
  For(i, x, x2 - 1) For(j, y, y2 - 1) if (i != x2 || j != y2)
      chkmin(ans, DFS(x1, y1, i, j) + getsum(i + 1, y1, x2, j) +
                      getsum(x1, j + 1, i, y2));
  For(i, x, x2 - 1) For(j, y1 + 1, y) if (i != x2 || j != y1)
      chkmin(ans, DFS(x1, j, i, y2) + getsum(x1, y1, i, j - 1) +
                      getsum(i + 1, j, x2, y2));
  For(i, x1 + 1, x) For(j, y, y2 - 1) if (i != x1 || j != y2)
      chkmin(ans, DFS(i, y1, x2, j) + getsum(x1, y1, i - 1, j) +
                      getsum(i, j + 1, x2, y2));
  return ans;
}

int main() {

  Init();
  printf("%d\\n", DFS(1, 1, n, m));

  return 0;
}


#include <bits/stdc++.h>
#define FU(i, l, r)                                                            \\
  for (register int i = (l), _end_ = (int)(r); i <= _end_; ++i)
#define FD(i, r, l)                                                            \\
  for (register int i = (r), _end_ = (int)(l); i >= _end_; --i)
#define X first
#define Y second
#define Set(a, b) memset(a, b, sizeof(a))
#define Cpy(a, b) memcpy(a, b, sizeof(a))
#define SZ(a) ((int)(a).size())
#define lowbit(x) x & (-x)
#define pii pair<int, int>
#define LL long long
#define INF 0x3f3f3f3f
#define file(a) freopen(a ".in", "r", stdin), freopen(a ".out", "w", stdout);
using namespace std;

template <typename T> inline bool chkmax(T &a, T b) {
  return (a < b) ? a = b, 1 : 0;
}
template <typename T> inline bool chkmin(T &a, T b) {
  return (b < a) ? a = b, 1 : 0;
}

template <typename T> inline T read() {
  static T __;
  static char c_;
  static bool flag_;
  __ = 0;
  c_ = getchar();
  flag_ = false;
  while (c_ > '9' || c_ < '0') {
    flag_ |= c_ == '-';
    c_ = getchar();
  }
  while (c_ >= '0' && c_ <= '9') {
    __ = (__ << 1) + (__ << 3) + (c_ ^ 48);
    c_ = getchar();
  }
  return flag_ ? -__ : __;
}

template <typename T> inline T write(T a) {
  if (a < 0) {
    putchar('-');
    a = -a;
  }
  if (a > 9)
    write(a / 10);
  putchar(a % 10 + '0');
  return 0;
}

const int maxN = 40 + 4;

int n, m, sum[maxN][maxN], dp[maxN][maxN][maxN][maxN], dx, dy, ans;
char tmp;

inline int getsum(int x, int y, int u, int v) {
  if (x > u || y > v)
    return 0;
  return sum[u][v] - sum[x - 1][v] - sum[u][y - 1] + sum[x - 1][y - 1];
}

inline void Input() {
  ios::sync_with_stdio(false);
  file("haner") cin >> n >> m;
  ans = INF;
  for (register int i = 1; i <= n; ++i) {
    for (register int j = 1; j <= m; ++j) {
      cin >> tmp;
      sum[i][j] =
          sum[i - 1][j] + sum[i][j - 1] - sum[i - 1][j - 1] + (tmp == '#');
      if (tmp == 'H')
        dx = i, dy = j;
    }
  }
  memset(dp, 0x3f, sizeof(dp));
  return;
}

inline void Solve() {
  dp[1][1][n][m] = 0;
  for (register int i = 1; i <= dx; ++i)
    for (register int j = 1; j <= dy; ++j)
      for (register int k = n; k >= dx; --k)
        for (register int l = m; l >= dy; --l) {
          chkmin(ans, dp[i][j][k][l] +
                          min(min(getsum(i, j, dx, dy), getsum(i, dy, dx, l)),
                              min(getsum(dx, j, k, dy), getsum(dx, dy, k, l))));
          for (register int s = i; s <= k; ++s)
            for (register int t = j; t <= l; ++t) {
              if (s <= dx && t <= dy)
                chkmin(dp[i][j][s][t], dp[i][j][k][l] + getsum(i, t, s - 1, l) +
                                           getsum(s, j, k, t - 1));
              if (s >= dx && t <= dy)
                chkmin(dp[i][j][s][t], dp[i][j][k][l] + getsum(i, j, s, t - 1) +
                                           getsum(s + 1, t, k, l));
              if (s >= dx && t >= dy)
                chkmin(dp[i][j][s][t], dp[i][j][k][l] + getsum(i, t + 1, s, l) +
                                           getsum(s + 1, j, k, t));
              if (s <= dx && t >= dy)
                chkmin(dp[i][j][s][t], dp[i][j][k][l] + getsum(i, j, s - 1, t) +
                                           getsum(s, t + 1, k, l));
            }
        }
  return;
}

inline void Output() {
  write(ans);
  putchar('\\n');
  return;
}

int main() {
  Input();
  Solve();
  Output();
  return 0;
}

#include <bits/stdc++.h>
#define FU(i, a, b) for (register int i = a; i <= b; ++i)
#define FD(i, a, b) for (register int i = a; i >= b; --i)
#define set_max(a) memset(a, 0x3f, sizeof a)
#define set_min(a) memset(a, ~0x3f, sizeof a)
#define clear(a) memset(a, 0, sizeof a)

using namespace std;

template <typename T> inline void chkmax(T &a, T b) {
  if (a < b)
    a = b;
}
template <typename T> inline void chkmin(T &a, T b) {
  if (a > b)
    a = b;
}

template <typename T> inline T read() {
  int res = 0, flag = 1;
  char ch = getchar();
  while (!isdigit(ch)) {
    if (ch == '-')
      flag = -1;
    ch = getchar();
  }
  while (isdigit(ch)) {
    res = (res << 3) + (res << 1) + ch - '0';
    ch = getchar();
  }
  return res * flag;
}

template <typename T> inline void write(T x) {
  if (x / 10)
    write(x / 10);
  putchar(x % 10 + '0');
}

const int INF = 0x3f3f3f3f;
const int N = 4e1;
int n, m, hx, hy;
int ice[N + 5][N + 5], dp[N + 5][N + 5][N + 5][N + 5];

inline void Input() {
  n = read<int>();
  m = read<int>();

  char ch;
  for (register int i = 1; i <= n; ++i)
    for (register int j = 1; j <= m; ++j) {
      cin >> ch;
      ice[i][j] =
          ice[i - 1][j] + ice[i][j - 1] - ice[i - 1][j - 1] + (ch == '#');
      if (ch == 'P') {
        hx = i;
        hy = j;
      }
    }
}

inline int thick(int dx, int dy, int rx, int ry) {
  // if(dx > rx || dy > ry) return 0;
  return ice[rx][ry] - ice[rx][dy - 1] - ice[dx - 1][ry] + ice[dx - 1][dy - 1];
}

inline int MIN(int a, int b, int c, int d) { return min(min(a, b), min(c, d)); }

inline void Solve() {
  int ans = INF;
  set_max(dp);
  dp[1][1][n][m] = 0;
  for (register int i = 1; i <= hx; ++i)
    for (register int j = 1; j <= hy; ++j)
      for (register int k = n; k >= hx; --k)
        for (register int p = m; p >= hy; --p) {
          chkmin(ans, dp[i][j][k][p] +
                          MIN(thick(i, j, hx, hy), thick(hx, hy, k, p),
                              thick(hx, j, k, hy), thick(i, hy, hx, p)));
          for (register int s = i; s <= k; ++s)
            for (register int t = j; t <= p; ++t) {
              if (s >= hx && t >= hy)
                chkmin(dp[i][j][s][t], dp[i][j][k][p] + thick(s + 1, j, k, t) +
                                           thick(i, t + 1, s, p));
              if (s <= hx && t <= hy)
                chkmin(dp[s][t][k][p], dp[i][j][k][p] + thick(s, j, k, t - 1) +
                                           thick(i, t, s - 1, p));
              if (s >= hx && t <= hy)
                chkmin(dp[i][t][s][p], dp[i][j][k][p] + thick(i, j, s, t - 1) +
                                           thick(s + 1, t, k, p));
              if (s <= hx && t >= hy)
                chkmin(dp[s][j][k][t], dp[i][j][k][p] + thick(i, j, s - 1, t) +
                                           thick(s, t + 1, k, p));
            }
        }

  write(ans);
  putchar('\\n');
}

inline void File() {
  freopen("haner.in", "r", stdin);
  freopen("haner.out", "w", stdout);
}

int main() {
  // File();

  Input();
  Solve();

  return 0;
}


#include <bits/stdc++.h>

#define I inline
#define fi first
#define se second
#define R register
#define LL long long
#define mp make_pair
#define reg register int
#define pii pair<int, int>
#define fo(i, a, b) for (reg i = a; i <= b; i++)
#define fd(i, a, b) for (reg i = a; i >= b; i--)
#define cr const reg &
using namespace std;
const int N = 41;

I int _max(cr x, cr y) { return x > y ? x : y; }
I int _min(cr x, cr y) { return x < y ? x : y; }
I int read() {
  reg x = 0, f = 1;
  char ch = getchar();
  while (ch < '0' || ch > '9') {
    if (ch == '-')
      f = -1;
    ch = getchar();
  }
  while (ch >= '0' && ch <= '9')
    x = (x << 3) + (x << 1) + (ch ^ 48), ch = getchar();
  return x * f;
}
I void ptt(LL x) {
  if (x >= 10)
    ptt(x / 10);
  putchar(x % 10 + '0');
}
I void put(LL x) { x < 0 ? putchar('-'), ptt(-x) : ptt(x); }
I void pr1(LL x) { put(x), putchar(' '); }
I void pr2(LL x) { put(x), puts(""); }

char ss[N][N];
int s[N][N], f[N][N][N][N];

I int S(cr a, cr b, cr c, cr d) {
  return s[c][d] - s[a - 1][d] - s[c][b - 1] + s[a - 1][b - 1];
}
I void upd(int &x, int c) { x = _min(x, c); }

int main() {
  reg n = read(), m = read(), px, py;
  fo(i, 1, n) {
    scanf("%s", ss[i] + 1);
    fo(j, 1, m) {
      if (ss[i][j] == 'P')
        px = i, py = j;
      else if (ss[i][j] == '#')
        s[i][j] = 1;
      s[i][j] += s[i - 1][j] + s[i][j - 1] - s[i - 1][j - 1];
    }
  }
  memset(f, 63, sizeof(f));
  reg ans = f[0][0][0][0];
  f[1][1][n][m] = 0;
  fo(i, 1, n) fo(j, 1, m) fd(k, n, i)
      fd(h, m, j) if (i <= px && j <= py && k >= px && h >= py) {
    reg c = f[i][j][k][h];
    fo(u, i, k) fo(v, j, h) {
      reg s1 = S(i, j, u, v) + S(u + 1, v + 1, k, h);
      reg s2 = S(i, v + 1, u, h) + S(u + 1, j, k, v);
      upd(f[i][j][u][v], c + s2), upd(f[u + 1][v + 1][k][h], c + s2);
      upd(f[i][v + 1][u][j], c + s1), upd(f[u + 1][j][k][v], c + s1);
    }
    ans = _min(ans, c + _min(_min(S(i, j, px, py), S(i, py, px, h)),
                             _min(S(px, j, k, py), S(px, py, k, h))));
  }
  pr2(ans);
  return 0;
}

#include <bits/stdc++.h>

#define I inline
#define fi first
#define se second
#define R register
#define LL long long
#define mp make_pair
#define reg register int
#define pii pair<int, int>
#define fo(i, a, b) for (reg i = a; i <= b; i++)
#define fd(i, a, b) for (reg i = a; i >= b; i--)
#define cr const reg &
using namespace std;
const int N = 42;

I int _max(cr x, cr y) { return x > y ? x : y; }
I int _min(cr x, cr y) { return x < y ? x : y; }
I int read() {
  reg x = 0, f = 1;
  char ch = getchar();
  while (ch < '0' || ch > '9') {
    if (ch == '-')
      f = -1;
    ch = getchar();
  }
  while (ch >= '0' && ch <= '9')
    x = (x << 3) + (x << 1) + (ch ^ 48), ch = getchar();
  return x * f;
}
I void ptt(LL x) {
  if (x >= 10)
    ptt(x / 10);
  putchar(x % 10 + '0');
}
I void put(LL x) { x < 0 ? putchar('-'), ptt(-x) : ptt(x); }
I void pr1(LL x) { put(x), putchar(' '); }
I void pr2(LL x) { put(x), puts(""); }

char ss[N][N];
int s[N][N], f[N][N][N][N];

I int S(cr a, cr b, cr c, cr d) {
  return s[c][d] - s[a - 1][d] - s[c][b - 1] + s[a - 1][b - 1];
}
I void upd(int &x, int c) { x = _min(x, c); }

int main() {
  reg n = read(), m = read(), px, py;
  fo(i, 1, n) {
    scanf("%s", ss[i] + 1);
    fo(j, 1, m) {
      if (ss[i][j] == 'P')
        px = i, py = j;
      else if (ss[i][j] == '#')
        s[i][j] = 1;
      s[i][j] += s[i - 1][j] + s[i][j - 1] - s[i - 1][j - 1];
    }
  }
  memset(f, 63, sizeof(f));
  reg ans = f[0][0][0][0];
  f[1][1][n][m] = 0;
  fo(i, 1, n) fo(j, 1, m) fd(k, n, i)
      fd(h, m, j) if (i <= px && j <= py && k >= px && h >= py) {
    reg c = f[i][j][k][h];
    fo(u, i, k) fo(v, j, h) {
      reg s1 = S(i, j, u, v) + S(u + 1, v + 1, k, h);
      reg s2 = S(i, v + 1, u, h) + S(u + 1, j, k, v);
      upd(f[i][j][u][v], c + s2), upd(f[u + 1][v + 1][k][h], c + s2);
      upd(f[i][v + 1][u][h], c + s1), upd(f[u + 1][j][k][v], c + s1);
    }
    ans = _min(ans, c + _min(_min(S(i, j, px, py), S(i, py, px, h)),
                             _min(S(px, j, k, py), S(px, py, k, h))));
  }
  pr2(ans);
  return 0;
}


#include <bits/stdc++.h>

#define MAXN 41
#define re register
#define xx x + fx[i][0]
#define yy y + fx[i][1]
#define INF 0x7ffffff
#define mp(a, b) make_pair(a, b)

using namespace std;

struct node {
  int step;
  pair<int, int> p[MAXN * 10];
  int cnt;
  bool used[MAXN * 10];
};

int n, m, endx, endy, hardcnt, specflag = true;
int imap[MAXN][MAXN], vis[MAXN][MAXN], minn[MAXN][MAXN];
int fx[4][2] = {{1, 0}, {0, 1}, {-1, 0}, {0, -1}};
pair<int, int> hard[MAXN * MAXN];

queue<node> q;

inline void File() {
#ifndef Mr_Chen
  freopen("haner.in", "r", stdin);
  freopen("haner.out", "w", stdout);
#endif
}

inline int read() {
  re int res = 0;
  re bool f = 1;
  re char ch = getchar();
  while (ch < '0' || ch > '9') {
    if (ch == '-')
      f = 0;
    ch = getchar();
  }
  while (ch >= '0' && ch <= '9') {
    res = (res << 3) + (res << 1) + (ch & 15);
    ch = getchar();
  }
  return f ? res : -res;
}

inline bool disap(re int x, re int y) {
  return imap[x][y] == 1 && !((imap[x - 1][y] && imap[x + 1][y]) ||
                              (imap[x][y - 1] && imap[x][y + 1]));
}

void killp(re int x, re int y) {
  // printf("<%d,%d> killed\\n",x,y);
  imap[x][y] = 0;
  for (re int i = 0; i < 4; ++i)
    if (xx > 0 && xx <= n && yy > 0 && yy <= m && disap(xx, yy))
      killp(xx, yy);
}

inline void clac() {
  for (re int i = 1; i <= n; ++i)
    for (re int j = 1; j <= m; ++j)
      if (disap(i, j))
        killp(i, j);
}

inline int bfs() {
  re node start;
  start.step = 0;
  start.cnt = 0;
  memset(start.used, 0, sizeof start.used);
  // memset(start.p,0,sizeof start.p);
  q.push(start);
  while (!q.empty()) {
    re node now = q.front();
    q.pop();
    for (re int j = 1; j <= now.cnt; ++j)
      imap[now.p[j].first][now.p[j].second] = 1;
    for (re int i = 1; i <= hardcnt; ++i) {
      if (now.used[i])
        continue;
      imap[hard[i].first][hard[i].second] = 1;
      clac();
      if (imap[endx][endy] == 0)
        return now.step + 1;
      imap[hard[i].first][hard[i].second] = 2;
      re node t = now;
      ++t.step;
      t.p[++t.cnt] = hard[i];
      t.used[i] = true;
      q.push(t);
    }
    for (re int j = 1; j <= now.cnt; ++j)
      imap[now.p[j].first][now.p[j].second] = 2;
  }
}

int main() {
  char ch;
  n = read(), m = read();
  for (re int i = 1; i <= n; ++i) {
    for (re int j = 1; j <= m; ++j) {
      do
        ch = getchar();
      while (ch == '\\n' || ch == ' ');
      if (ch == '+')
        imap[i][j] = 1;
      else if (ch == '#') {
        imap[i][j] = 2;
        hard[++hardcnt] = mp(i, j);
        specflag = false;
      } else if (ch == 'P') {
        imap[i][j] = 1;
        endx = i, endy = j;
      } else
        puts("ZYH && ALSaoBen && wzr AK IOI");
    }
  }
  if (specflag) {
    return 0;
  }
  clac();
  if (imap[endx][endy] == 0) {
    return 0;
  }
  /*for(re int i=1;i<=n;++i)
  {
          for(re int j=1;j<=m;++j)
                  printf("%d ",imap[i][j]);
          printf("\\n");
  }*/
  printf("%d\\n", bfs());
  return 0;
}

// Code by muq
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <set>
#define ll long long
#define inf 2147483647
#define rep(i, a, b) for (int i = a; i <= b; ++i)
#define repp(i, a, b, c) for (int i = a; i <= b; i += c)
#define reph(i, a, b) for (i = a; i <= b; ++i)
#define reg(i, head, d, a) for (int i = head[d]; i; i = a[i].next)
#define rap(i, a, b) for (int i = a; i >= b; --i)
#define me(a, b) memset(a, b, sizeof(a));
#define poi(lx, ly, rx, ry)                                                    \\
  ((lx > rx or ly > ry) ? 0                                                    \\
                        : (ice[rx][ry] + ice[lx - 1][ly - 1] -                 \\
                           ice[rx][ly - 1] - ice[lx - 1][ry]))

int n, m, sx, sy;
int ice[45][45], ans = inf, f[45][45][45][45];
char temp;

using namespace std;

int main(void) {
  ios::sync_with_stdio(0);

  cin >> n >> m;
  me(f, 0x7f);
  f[1][1][n][m] = 0;
  rep(i, 1, n) {
    rep(j, 1, m) {
      cin >> temp;
      if (temp == 'P')
        sx = i, sy = j;
      ice[i][j] = ice[i - 1][j] + ice[i][j - 1] - ice[i - 1][j - 1] +
                  ((temp == '#') ? 1 : 0);
    }
  }
  rep(i, 1, sx) {
    rep(j, 1, sy) {
      rap(o, n, sx) {
        rap(p, m, sy) {
          ans = min(ans, f[i][j][o][p] +
                             min(min(poi(i, j, sx, sy), poi(i, sy, sx, p)),
                                 min(poi(sx, j, o, sy), poi(sx, sy, o, p))));
          rep(s, i, o) {
            rep(t, j, p) {
              if (sx <= s and sy <= t)
                f[i][j][s][t] =
                    min(f[i][j][s][t], f[i][j][o][p] + poi(i, t + 1, s, p) +
                                           poi(s + 1, j, o, t));
              if (sx <= s and sy >= t)
                f[i][t][s][p] =
                    min(f[i][t][s][p], f[i][j][o][p] + poi(i, j, s, t - 1) +
                                           poi(s + 1, t, o, p));
              if (sx >= s and sy >= t)
                f[s][t][o][p] =
                    min(f[s][t][o][p], f[i][j][o][p] + poi(i, t, s - 1, p) +
                                           poi(s, j, o, t - 1));
              if (sx >= s and sy <= t)
                f[s][j][o][t] =
                    min(f[s][j][o][t], f[i][j][o][p] + poi(i, j, s - 1, t) +
                                           poi(s, t + 1, o, p));
            }
          }
        }
      }
    }
  }
  cout << ans << endl;
  return 0;
}


#include <bits/stdc++.h>

using namespace std;

#define REP(i, a, b) for (int i = (a), i##_end_ = (b); i < i##_end_; ++i)
#define debug(...) fprintf(stderr, __VA_ARGS__)
#define mp make_pair
#define x first
#define y second
#define pb push_back
#define SZ(x) (int((x).size()))
#define ALL(x) (x).begin(), (x).end()

template <typename T> inline bool chkmin(T &a, const T &b) {
  return b < a ? a = b, 1 : 0;
}
template <typename T> inline bool chkmax(T &a, const T &b) {
  return a < b ? a = b, 1 : 0;
}

typedef long long LL;

const int oo = 0x3f3f3f3f;

const int maxn = 50;

int n, m;

char g[maxn + 5][maxn + 5];

int dp[maxn + 5][maxn + 5][maxn + 5][maxn + 5];

int sum[maxn + 5][maxn + 5];

inline int get_sum(int xl, int yl, int xr, int yr) {
  return sum[xr][yr] - sum[xl][yr] - sum[xr][yl] + sum[xl][yl];
}

int px, py;

int ans = oo;

int main() {
#ifdef matthew99
  freopen("input.txt", "r", stdin);
  freopen("output.txt", "w", stdout);
#endif
  scanf("%d%d", &n, &m);
  assert(n == m);
  REP(i, 0, n) scanf("%s", g[i]);
  px = py = -1;
  REP(i, 0, n) REP(j, 0, m) if (g[i][j] == 'P') px = i, py = j;
  REP(i, 0, n)
  REP(j, 0, m) sum[i + 1][j + 1] =
      sum[i + 1][j] + sum[i][j + 1] - sum[i][j] + (g[i][j] == '#');
  memset(dp, oo, sizeof dp);
  dp[0][0][n][m] = 0;
  REP(xl, 0, n)
  REP(yl, 0, m) REP(xr, xl + 1, n + 1)
      REP(yr, yl + 1, m + 1) if (dp[xl][yl][xr][yr] < oo) {
    REP(xmid, xl + 1, xr) REP(ymid, yl + 1, yr) {
      chkmin(dp[xl][yl][xmid][ymid], dp[xl][yl][xr][yr] +
                                         get_sum(xl, ymid, xmid, yr) +
                                         get_sum(xmid, yl, xr, ymid));
      chkmin(dp[xmid][ymid][xr][yr], dp[xl][yl][xr][yr] +
                                         get_sum(xl, ymid, xmid, yr) +
                                         get_sum(xmid, yl, xr, ymid));
      chkmin(dp[xl][ymid][xmid][yr], dp[xl][yl][xr][yr] +
                                         get_sum(xl, yl, xmid, ymid) +
                                         get_sum(xmid, ymid, xr, yr));
      chkmin(dp[xmid][yl][xr][ymid], dp[xl][yl][xr][yr] +
                                         get_sum(xl, yl, xmid, ymid) +
                                         get_sum(xmid, ymid, xr, yr));
    }
  }
  ans = oo;
  REP(xl, 0, px + 1)
  REP(yl, 0, py + 1) REP(xr, px + 1, n + 1)
      REP(yr, py + 1, m + 1) if (dp[xl][yl][xr][yr] < oo) {
    chkmin(ans, dp[xl][yl][xr][yr] + min({get_sum(xl, yl, px + 1, py + 1),
                                          get_sum(xl, py, px + 1, yr),
                                          get_sum(px, yl, xr, py + 1),
                                          get_sum(px, py, xr, yr)}));
  }
  printf("%d\\n", ans);
  return 0;
}

#include <bits/stdc++.h>

using namespace std;

#define REP(i, a, b) for (int i = (a), i##_end_ = (b); i < i##_end_; ++i)
#define debug(...) fprintf(stderr, __VA_ARGS__)
#define mp make_pair
#define x first
#define y second
#define pb push_back
#define SZ(x) (int((x).size()))
#define ALL(x) (x).begin(), (x).end()

template <typename T> inline bool chkmin(T &a, const T &b) {
  return b < a ? a = b, 1 : 0;
}
template <typename T> inline bool chkmax(T &a, const T &b) {
  return a < b ? a = b, 1 : 0;
}

typedef long long LL;

const int oo = 0x3f3f3f3f;

const int maxn = 50;

int n, m;

char g[maxn + 5][maxn + 5];

int dp[maxn + 5][maxn + 5][maxn + 5][maxn + 5];

int sum[maxn + 5][maxn + 5];

inline int get_sum(int xl, int yl, int xr, int yr) {
  return sum[xr][yr] - sum[xl][yr] - sum[xr][yl] + sum[xl][yl];
}

int px, py;

int ans = oo;

int main() {
#ifdef matthew99
  freopen("input.txt", "r", stdin);
  freopen("output.txt", "w", stdout);
#endif
  scanf("%d%d", &n, &m);
  REP(i, 0, n) scanf("%s", g[i]);
  px = py = -1;
  REP(i, 0, n) REP(j, 0, m) if (g[i][j] == 'P') px = i, py = j;
  REP(i, 0, n)
  REP(j, 0, m) sum[i + 1][j + 1] =
      sum[i + 1][j] + sum[i][j + 1] - sum[i][j] + (g[i][j] == '#');
  memset(dp, oo, sizeof dp);
  dp[0][0][n][m] = 0;
  REP(xl, 0, n)
  REP(yl, 0, m) for (int xr = n; xr > xl;
                     --xr) for (int yr = m; yr > yl;
                                --yr) if (dp[xl][yl][xr][yr] < oo) {
    REP(xmid, xl + 1, xr) REP(ymid, yl + 1, yr) {
      chkmin(dp[xl][yl][xmid][ymid], dp[xl][yl][xr][yr] +
                                         get_sum(xl, ymid, xmid, yr) +
                                         get_sum(xmid, yl, xr, ymid));
      chkmin(dp[xmid][ymid][xr][yr], dp[xl][yl][xr][yr] +
                                         get_sum(xl, ymid, xmid, yr) +
                                         get_sum(xmid, yl, xr, ymid));
      chkmin(dp[xl][ymid][xmid][yr], dp[xl][yl][xr][yr] +
                                         get_sum(xl, yl, xmid, ymid) +
                                         get_sum(xmid, ymid, xr, yr));
      chkmin(dp[xmid][yl][xr][ymid], dp[xl][yl][xr][yr] +
                                         get_sum(xl, yl, xmid, ymid) +
                                         get_sum(xmid, ymid, xr, yr));
    }
  }
  ans = oo;
  REP(xl, 0, px + 1)
  REP(yl, 0, py + 1) REP(xr, px + 1, n + 1)
      REP(yr, py + 1, m + 1) if (dp[xl][yl][xr][yr] < oo) {
    chkmin(ans, dp[xl][yl][xr][yr] + min({get_sum(xl, yl, px + 1, py + 1),
                                          get_sum(xl, py, px + 1, yr),
                                          get_sum(px, yl, xr, py + 1),
                                          get_sum(px, py, xr, yr)}));
  }
  printf("%d\\n", ans);
  return 0;
}


/************************************************
 * Au: Hany01
 * Prob: haner
 * Email: hany01dxx@gmail.com & hany01@foxmail.com
 * Inst: Yali High School
 ************************************************/

#include <bits/stdc++.h>

using namespace std;

typedef long long LL;
typedef long double LD;
typedef pair<int, int> PII;
#define Rep(i, j) for (register int i = 0, i##_end_ = (j); i < i##_end_; ++i)
#define For(i, j, k)                                                           \\
  for (register int i = (j), i##_end_ = (k); i <= i##_end_; ++i)
#define Fordown(i, j, k)                                                       \\
  for (register int i = (j), i##_end_ = (k); i >= i##_end_; --i)
#define Set(a, b) memset(a, b, sizeof(a))
#define Cpy(a, b) memcpy(a, b, sizeof(a))
#define X first
#define Y second
#define PB(a) push_back(a)
#define MP(a, b) make_pair(a, b)
#define SZ(a) ((int)(a).size())
#define ALL(a) a.begin(), a.end()
#define INF (0x3f3f3f3f)
#define INF1 (2139062143)
#define debug(...) fprintf(stderr, __VA_ARGS__)
#define y1 wozenmezhemecaia

template <typename T> inline bool chkmax(T &a, T b) {
  return a < b ? a = b, 1 : 0;
}
template <typename T> inline bool chkmin(T &a, T b) {
  return b < a ? a = b, 1 : 0;
}

template <typename T> inline T read() {
  static T _, __;
  static char c_;
  for (_ = 0, __ = 1, c_ = getchar(); c_ < '0' || c_ > '9'; c_ = getchar())
    if (c_ == '-')
      __ = -1;
  for (; c_ >= '0' && c_ <= '9'; c_ = getchar())
    _ = (_ << 1) + (_ << 3) + (c_ ^ 48);
  return _ * __;
}
// EOT

const int maxn = 45;

int n, m;
int sum[maxn][maxn], dp[maxn][maxn][maxn][maxn], x, y,
    vis[maxn][maxn][maxn][maxn];

inline void Init() {
  static char str[maxn];
  n = read<int>(), m = read<int>();
  For(i, 1, n) {
    scanf("%s", str + 1);
    For(j, 1, m) if (str[j] == 'p') x = i, y = j;
    else if (str[j] == '#') sum[i][j] = 1;
  }
  For(i, 1, n) For(j, 1, m) sum[i][j] +=
      sum[i - 1][j] + sum[i][j - 1] - sum[i - 1][j - 1];
}

inline int getsum(int x1, int y1, int x2, int y2) {
  // if (sum[x2][y2] - sum[x2][y1 - 1] - sum[x1 - 1][y2] + sum[x1 - 1][y1 - 1] <
  // 0) cout << x1 << ' ' << y1 << ' ' << x2 << ' ' << y2 << endl;
  return sum[x2][y2] - sum[x2][y1 - 1] - sum[x1 - 1][y2] + sum[x1 - 1][y1 - 1];
}

int DFS(int x1, int y1, int x2, int y2) {
  if (!chkmax(vis[x1][y1][x2][y2], 1))
    return dp[x1][y1][x2][y2];
  int &ans = dp[x1][y1][x2][y2] = INF;
  chkmin(ans, getsum(x1, y1, x, y));
  chkmin(ans, getsum(x1, y, x, y2));
  chkmin(ans, getsum(x, y1, x2, y));
  chkmin(ans, getsum(x, y, x2, y2));
  For(i, x1 + 1, x) For(j, y1 + 1, y) if (i != x1 || j != y1)
      chkmin(ans, DFS(i, j, x2, y2) + getsum(i, y1, x2, j - 1) +
                      getsum(x1, j, i - 1, y2));
  For(i, x, x2 - 1) For(j, y, y2 - 1) if (i != x2 || j != y2)
      chkmin(ans, DFS(x1, y1, i, j) + getsum(i + 1, y1, x2, j) +
                      getsum(x1, j + 1, i, y2));
  For(i, x, x2 - 1) For(j, y1 + 1, y) if (i != x2 || j != y1)
      chkmin(ans, DFS(x1, j, i, y2) + getsum(x1, y1, i, j - 1) +
                      getsum(i + 1, j, x2, y2));
  For(i, x1 + 1, x) For(j, y, y2 - 1) if (i != x1 || j != y2)
      chkmin(ans, DFS(i, y1, x2, j) + getsum(x1, y1, i - 1, j) +
                      getsum(i, j + 1, x2, y2));
  return ans;
}

int main() {
  freopen("haner.in", "r", stdin);
  freopen("haner.out", "w", stdout);

  Init();
  printf("%d\\n", DFS(1, 1, n, m));

  return 0;
}

#include <algorithm>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <set>
#define ll long long
#define inf 2147483647
#define rep(i, a, b) for (int i = a; i <= b; ++i)
#define repp(i, a, b, c) for (int i = a; i <= b; i += c)
#define reph(i, a, b) for (i = a; i <= b; ++i)
#define reg(i, head, d, a) for (int i = head[d]; i; i = a[i].next)
#define rap(i, a, b) for (int i = a; i >= b; --i)
#define me(a, b) memset(a, b, sizeof(a));
#define poi(lx, ly, rx, ry)                                                    \\
  ((lx > rx or ly > ry) ? 0                                                    \\
                        : (ice[rx][ry] + ice[lx - 1][ly - 1] -                 \\
                           ice[rx][ly - 1] - ice[lx - 1][ry]))
int n, m, sx, sy;
int ice[45][45], ans = inf, f[45][45][45][45];
char temp;

using namespace std;

int main() {
  ios::sync_with_stdio(0);

  cin >> n >> m;
  me(f, 0x7f);
  f[1][1][n][m] = 0;
  rep(i, 1, n) {
    rep(j, 1, m) {
      cin >> temp;
      if (temp == 'P')
        sx = i, sy = j;
      ice[i][j] = ice[i - 1][j] + ice[i][j - 1] - ice[i - 1][j - 1] +
                  ((temp == '#') ? 1 : 0);
    }
  }
  rep(i, 1, sx) {
    rep(j, 1, sy) {
      rap(o, n, sx) {
        rap(p, m, sy) {
          ans = min(ans, f[i][j][o][p] +
                             min(min(poi(i, j, sx, sy), poi(i, sy, sx, p)),
                                 min(poi(sx, j, o, sy), poi(sx, sy, o, p))));
          rep(s, i, o) {
            rep(t, j, p) {
              if (sx <= s and sy <= t)
                f[i][j][s][t] =
                    min(f[i][j][s][t], f[i][j][o][p] + poi(i, t + 1, s, p) +
                                           poi(s + 1, j, o, t));
              if (sx <= s and sy >= t)
                f[i][t][s][p] =
                    min(f[i][t][s][p], f[i][j][o][p] + poi(i, j, s, t - 1) +
                                           poi(s + 1, t, o, p));
              if (sx >= s and sy >= t)
                f[s][t][o][p] =
                    min(f[s][t][o][p], f[i][j][o][p] + poi(i, t, s - 1, p) +
                                           poi(s, j, o, t - 1));
              if (sx >= s and sy <= t)
                f[s][j][o][t] =
                    min(f[s][j][o][t], f[i][j][o][p] + poi(i, j, s - 1, t) +
                                           poi(s, t + 1, o, p));
            }
          }
        }
      }
    }
  }
  cout << ans << endl;
  return 0;
}


#include <stdio.h>
#define inf 9999998
#define GC getchar()
#define g(a, b, c, d) g[a][b][c][d]
using namespace std;
inline void min(int &a, int b) { a = a < b ? a : b; }
int n, m, f[45][45][45][45], xx, yy, sum[45][45], g[45][45][45][45];
bool mk[45][45][45][45];
char mp[45][45];
// inline int g(int xa,int ya,int xb,int yb){
//	return sum[xb][yb]-sum[xb][ya-1]-sum[xa-1][yb]+sum[xa-1][ya-1];
// }
inline bool is(int xa, int ya, int xb, int yb) {
  if (xa > xx || xb < xx || ya > yy || yb < yy)
    return 0;
  return 1;
}
void dfs(int xa, int ya, int xb, int yb) {
  // if(mk[xa][ya][xb][yb])return;
  // if(!mk[xa][ya][xb][yb])mk[xa][ya][xb][yb]=1;
  for (int i = xa; i < xb; i++) {
    for (int j = ya; j < yb; j++) {
      // if(g(xa,j+1,i,yb)>0||g(i+1,ya,xb,j)>0)continue;
      if (is(xa, ya, i, j)) {
        dfs(xa, ya, i, j);
        min(f[xa][ya][i][j],
            f[xa][ya][xb][yb] + g(xa, j + 1, i, yb) + g(i + 1, ya, xb, j));
      }
      if (is(i + 1, j + 1, xb, yb)) {
        dfs(i + 1, j + 1, xb, yb);
        min(f[i + 1][j + 1][xb][yb],
            f[xa][ya][xb][yb] + g(xa, j + 1, i, yb) + g(i + 1, ya, xb, j));
      }
      if (is(i + 1, ya, xb, j)) {
        dfs(i + 1, ya, xb, j);
        min(f[i + 1][ya][xb][j],
            f[xa][ya][xb][yb] + g(xa, ya, i, j) + g(i + 1, j + 1, xb, yb));
      }
      if (is(xa, j + 1, i, yb)) {
        dfs(xa, j + 1, i, yb);
        min(f[xa][j + 1][i][yb],
            f[xa][ya][xb][yb] + g(xa, ya, i, j) + g(i + 1, j + 1, xb, yb));
      }
    }
  } // printf("%d %d %d %d %d\\n",xa,ya,xb,yb,f[xa][ya][xb][yb]);
}
int main() {
  // freopen("haner3.in","r",stdin);
  // freopen("haner.out","w",stdout);
  scanf("%d%d", &n, &m);
  for (int i = 1; i <= n; i++) {
    for (int j = 1; j <= m; j++) {
      char ch = GC;
      while (ch != '+' && ch != '#' && ch != 'P')
        ch = GC;
      mp[j][i] = ch;
      if (ch == 'P')
        xx = j, yy = i;
    }
  }
  for (int i = 1; i <= m; i++) {
    for (int j = 1; j <= n; j++) {
      sum[i][j] =
          sum[i - 1][j] + sum[i][j - 1] - sum[i - 1][j - 1] + (mp[i][j] == '#');
    }
  }
  for (int i = 1; i <= m; i++) {
    for (int j = 1; j <= n; j++) {
      for (int ii = i; ii <= m; ii++) {
        for (int jj = j; jj <= n; jj++) {
          f[i][j][ii][jj] = inf;
          g[i][j][ii][jj] =
              sum[ii][jj] - sum[ii][j - 1] - sum[i - 1][jj] + sum[i - 1][j - 1];
        }
      }
    }
  }
  f[1][1][m][n] = 0;
  dfs(1, 1, m, n);
  int ans = inf;
  for (int i = 1; i <= xx; i++) {
    for (int j = 1; j <= yy; j++) {
      for (int ii = xx; ii <= m; ii++) {
        for (int jj = yy; jj <= n; jj++) {
          min(ans, f[i][j][ii][jj] + g(i, j, xx, yy));
          min(ans, f[i][j][ii][jj] + g(xx, j, ii, yy));
          min(ans, f[i][j][ii][jj] + g(i, yy, xx, jj));
          min(ans, f[i][j][ii][jj] + g(xx, yy, ii, jj));
        }
      }
    }
  }
  printf("%d", ans);
}

/*
2 3
#H#
###
*/

#include <bits/stdc++.h>

#define REP(i, a, b) for (int i = a, i##_end_ = b; i <= i##_end_; ++i)
#define DREP(i, a, b) for (int i = a, i##_end_ = b; i >= i##_end_; --i)
#define MREP(i, x) for (int i = beg[x], v; v = to[i], i; i = las[i])
#define debug(x) cout << #x << "=" << x << endl
#define fi first
#define se second
#define mk make_pair
#define pb push_back
#define y1 asdasd
typedef long long ll;

using namespace std;

void File() {
  freopen("haner.in", "r", stdin);
  freopen("haner.out", "w", stdout);
}

template <typename T> void read(T &_) {
  T __ = 0, mul = 1;
  char ch = getchar();
  while (!isdigit(ch)) {
    if (ch == '-')
      mul = -1;
    ch = getchar();
  }
  while (isdigit(ch))
    __ = (__ << 1) + (__ << 3) + (ch ^ '0'), ch = getchar();
  _ = __ * mul;
}

const int maxn = 40 + 10;
const int inf = 0x3f3f3f3f;
int n, m, px, py, dp[maxn][maxn][maxn][maxn], sum[maxn][maxn], ans = inf;
char s[maxn][maxn];

int S(int x1, int y1, int x2, int y2) {
  return sum[x2][y2] - sum[x1 - 1][y2] - sum[x2][y1 - 1] + sum[x1 - 1][y1 - 1];
}

template <typename T> void chkmin(T &_, T __) { _ = _ < __ ? _ : __; }

int main() {
  read(n);
  read(m);
  REP(i, 1, n) scanf("%s", s[i] + 1);
  REP(i, 1, n) {
    REP(j, 1, m) {
      if (s[i][j] == 'P') {
        px = i;
        py = j;
        s[i][j] = '+';
      }
      sum[i][j] =
          sum[i - 1][j] + sum[i][j - 1] - sum[i - 1][j - 1] + (s[i][j] == '#');
      // cout<<sum[i][j]<<" ";
    }
    // cout<<endl;
  }
  memset(dp, 63, sizeof(dp));
  dp[1][1][n][m] = 0; // 代表将(1,1,n,m)这个矩形独立的最小代价为0。
  REP(x1, 1, n) REP(y1, 1, m) DREP(x2, n, x1) DREP(y2, m, y1) {
    if (x1 <= px && x2 >= px && y1 <= py && y2 >= py) {
      int w = dp[x1][y1][x2][y2];
      REP(x, x1, x2) REP(y, y1, y2) {
        int cost1 = S(x1, y1, x, y) + S(x + 1, y + 1, x2, y2);
        int cost2 = S(x1, y + 1, x, y2) + S(x + 1, y1, x2, y);
        chkmin(dp[x1][y + 1][x][y2], cost1 + w);
        chkmin(dp[x + 1][y1][x2][y], cost1 + w);
        chkmin(dp[x1][y1][x][y], cost2 + w);
        chkmin(dp[x + 1][y + 1][x2][y2], cost2 + w);
      }
      // cout<<x1<<" "<<y1<<" "<<x2<<" "<<y2<<" "<<w<<endl;
      chkmin(ans, w + S(x1, y1, px, py));
      chkmin(ans, w + S(px, py, x2, y2));
      chkmin(ans, w + S(px, y1, x2, py));
      chkmin(ans, w + S(x1, py, px, y2));
    }
  }
  printf("%d\\n", ans);
  return 0;
}


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

int n, A[1 << 18], l[1 << 18], r[1 << 18];
vector<int> add[1 << 18], del[1 << 18];
struct cmp {
  bool operator()(int p, int q) { return r[p] > r[q]; }
};
priority_queue<int, vector<int>, cmp> q;

int main() {
  scanf("%d", &n);
  for (int i = 0; i < 1 << n; ++i) {
    scanf("%d", A + i);
    if (A[i])
      l[i] = r[i] = A[i];
    else
      l[i] = 1, r[i] = 1 << n;
  }
  for (int i = 0; i < 1 << n; ++i)
    for (int j = 0; j < n; ++j)
      if (!(i >> j & 1))
        l[i ^ (1 << j)] = max(l[i ^ (1 << j)], l[i] + 1);
  for (int i = (1 << n) - 1; i >= 0; --i)
    for (int j = 0; j < n; ++j)
      if (i >> j & 1)
        r[i ^ (1 << j)] = min(r[i ^ (1 << j)], r[i] - 1);
  for (int i = 0; i < 1 << n; ++i) {
    if (l[i] > r[i])
      return puts("NO"), 0;
    add[l[i]].push_back(i);
    del[r[i]].push_back(i);
  }
  for (int i = 0; i < 1 << n; ++i) {
    for (int x : add[i])
      q.push(x);
    while (!q.empty() && A[q.top()])
      q.pop();
    if (!q.empty())
      A[q.top()] = i;
    for (int x : del[i])
      if (!A[x])
        return puts("NO"), 0;
  }
  for (int i = 0, j = 0; i < 1 << n; ++i) {
    if (i > j)
      swap(A[i], A[j]);
    for (int k = 1 << n - 1; (j ^= k) < k; k >>= 1)
      ;
  }
  puts("YES");
  for (int i = 0; i < 1 << n; ++i)
    printf("%d%c", A[i], " \\n "[i + 1 == 1 << n]);
  return 0;
}


#include <bits/stdc++.h>

using namespace std;

#define REP(i, a, b) for (int i = (a), i##_end_ = (b); i < i##_end_; ++i)
#define debug(...) fprintf(stderr, __VA_ARGS__)
#define mp make_pair
#define x first
#define y second
#define pb push_back
#define SZ(x) (int((x).size()))
#define ALL(x) (x).begin(), (x).end()
#define EXIT(...) printf(__VA_ARGS__), exit(0)

template <typename T> inline bool chkmin(T &a, const T &b) {
  return b < a ? a = b, 1 : 0;
}
template <typename T> inline bool chkmax(T &a, const T &b) {
  return a < b ? a = b, 1 : 0;
}

typedef long long LL;

const int oo = 0x3f3f3f3f;

const int maxn = 280000;

int n, L;
int a[maxn + 5];

int ans[maxn + 5];

int pos[maxn + 5];
bool vis[maxn + 5];

int bitrev[maxn + 5];

int pre[maxn + 5];

int get_pre(int x) { return pre[x] == x ? x : pre[x] = get_pre(pre[x]); }

void dfs(int x) {
  if (vis[x])
    return;
  vis[x] = 1;
  int tmp = oo;
  REP(i, 0, L) if (!(x >> i & 1)) {
    dfs(x | (1 << i));
    chkmin(tmp, a[x | (1 << i)]);
  }
  if (!~a[x]) {
    tmp = get_pre(tmp);
    if (tmp == n)
      EXIT("NO\\n");
    a[x] = tmp;
    if (!tmp)
      pre[tmp] = n;
    else
      pre[tmp] = get_pre(tmp - 1);
  } else if (tmp < a[x])
    EXIT("NO\\n");
}

int main() {
#ifdef matthew99
  freopen("input.txt", "r", stdin);
  freopen("output.txt", "w", stdout);
#endif
  scanf("%d", &L), n = 1 << L;
  REP(i, 0, n) scanf("%d", a + i), --a[i], pos[i] = i;
  sort(pos, pos + n, [&](int x, int y) { return a[x] > a[y]; });
  REP(i, 0, n + 1) pre[i] = i;
  REP(i, 0, n) if (~a[i]) {
    if (!a[i])
      pre[a[i]] = n;
    else
      pre[a[i]] = get_pre(a[i] - 1);
  }
  memset(vis, 0, sizeof vis);
  REP(i, 0, n) if (!vis[pos[i]]) { dfs(pos[i]); }
  REP(i, 0, n) bitrev[i] = bitrev[i >> 1] >> 1 | ((i & 1) << (L - 1));
  REP(i, 0, n) { ans[bitrev[a[i]]] = i; }
  puts("YES");
  REP(i, 0, n) printf("%d ", ans[i] + 1);
  printf("\\n");
  return 0;
}

#include <bits/stdc++.h>

using namespace std;

#define REP(i, a, b) for (int i = (a), i##_end_ = (b); i < i##_end_; ++i)
#define debug(...) fprintf(stderr, __VA_ARGS__)
#define mp make_pair
#define x first
#define y second
#define pb push_back
#define SZ(x) (int((x).size()))
#define ALL(x) (x).begin(), (x).end()
#define EXIT(...) printf(__VA_ARGS__), exit(0)

template <typename T> inline bool chkmin(T &a, const T &b) {
  return b < a ? a = b, 1 : 0;
}
template <typename T> inline bool chkmax(T &a, const T &b) {
  return a < b ? a = b, 1 : 0;
}

typedef long long LL;

const int oo = 0x3f3f3f3f;

const int maxn = 280000;

int n, L;
int a[maxn + 5];

int ans[maxn + 5];

int pos[maxn + 5];
bool vis[maxn + 5];

int bitrev[maxn + 5];

int pre[maxn + 5];

int get_pre(int x) { return pre[x] == x ? x : pre[x] = get_pre(pre[x]); }

void dfs(int x) {
  if (vis[x])
    return;
  vis[x] = 1;
  int tmp = n - 1;
  REP(i, 0, L) if (!(x >> i & 1)) {
    dfs(x | (1 << i));
    chkmin(tmp, a[x | (1 << i)]);
  }
  if (!~a[x]) {
    tmp = get_pre(tmp);
    if (tmp == n)
      EXIT("NO\\n");
    a[x] = tmp;
    if (!tmp)
      pre[tmp] = n;
    else
      pre[tmp] = get_pre(tmp - 1);
  } else if (tmp < a[x])
    EXIT("NO\\n");
}

int main() {
#ifdef matthew99
  freopen("input.txt", "r", stdin);
  freopen("output.txt", "w", stdout);
#endif
  scanf("%d", &L), n = 1 << L;
  REP(i, 0, n) scanf("%d", a + i), --a[i], pos[i] = i;
  sort(pos, pos + n, [&](int x, int y) { return a[x] > a[y]; });
  REP(i, 0, n + 1) pre[i] = i;
  REP(i, 0, n) if (~a[i]) {
    if (!a[i])
      pre[a[i]] = n;
    else
      pre[a[i]] = get_pre(a[i] - 1);
  }
  memset(vis, 0, sizeof vis);
  REP(i, 0, n) if (!vis[pos[i]]) { dfs(pos[i]); }
  REP(i, 0, n) bitrev[i] = bitrev[i >> 1] >> 1 | ((i & 1) << (L - 1));
  REP(i, 0, n) { ans[bitrev[i]] = a[i]; }
  REP(i, 0, n) debug("%d ", a[i]);
  debug("\\n");
  puts("YES");
  REP(i, 0, n) printf("%d ", ans[i] + 1);
  printf("\\n");
  return 0;
}


#include <bits/stdc++.h>
#define Impossible                                                             \\
  {                                                                            \\
    cout << "NO\\n";                                                            \\
    return 0;                                                                  \\
  }

using namespace std;

const int Nmax = 1 << 18;

int N, n, i, j, x;
int L[Nmax], R[Nmax], A[Nmax];
bool used[Nmax];
vector<int> open[Nmax];
priority_queue<pair<int, int>> heap;

int reversed(int x) {
  int i, y = 0;
  for (i = 0; i < n; ++i)
    y = (y << 1) | ((x & (1 << i)) > 0);
  return y;
}

int main() {
  //    freopen("input", "r", stdin);
  //   freopen("output", "w", stdout);
  cin.sync_with_stdio(false);

  cin >> n;
  N = (1 << n);

  for (i = 0; i < N; ++i)
    L[i] = 0, R[i] = N - 1;

  for (i = 0; i < N; ++i) {
    cin >> A[i];
    --A[i];
    if (A[i] == -1)
      continue;

    L[i] = R[i] = A[i];
    used[A[i]] = 1;
  }

  for (i = 0; i < N; ++i)
    for (j = 0; j < n; ++j)
      if (!(i & (1 << j))) {
        x = i ^ (1 << j);
        L[x] = max(L[x], L[i] + 1);
      }

  for (i = N - 1; i >= 0; --i)
    for (j = 0; j < n; ++j)
      if (i & (1 << j)) {
        x = i ^ (1 << j);
        R[x] = min(R[x], R[i] - 1);
      }

  for (i = 0; i < N; ++i)
    open[R[i]].push_back(i);

  for (i = N - 1; i >= 0; --i) {
    for (auto it : open[i])
      heap.push({L[it], it + (A[it] != -1 ? N : 0)});

    if (heap.empty())
      Impossible;

    if (heap.top().second < N)
      A[heap.top().second] = i;
    heap.pop();
  }

  cout << "YES\\n";
  for (i = 0; i < N; ++i)
    cout << A[reversed(i)] + 1 << ' ';

  return 0;
}

#include <bits/stdc++.h>
#define Impossible                                                             \\
  {                                                                            \\
    cout << "NO\\n";                                                            \\
    return 0;                                                                  \\
  }

using namespace std;

const int Nmax = 1 << 18;

int N, n, i, j, x;
int L[Nmax], R[Nmax], A[Nmax];
bool used[Nmax];
vector<int> open[Nmax];
priority_queue<pair<int, int>> heap;

int reversed(int x) {
  int i, y = 0;
  for (i = 0; i < n; ++i)
    y = (y << 1) | ((x & (1 << i)) > 0);
  return y;
}

int main() {
  //    freopen("input", "r", stdin);
  //    freopen("output", "w", stdout);
  cin.sync_with_stdio(false);

  cin >> n;
  N = (1 << n);

  for (i = 0; i < N; ++i)
    L[i] = 0, R[i] = N - 1;

  for (i = 0; i < N; ++i) {
    cin >> A[i];
    --A[i];
    if (A[i] == -1)
      continue;

    L[i] = R[i] = A[i];
    used[A[i]] = 1;
  }

  for (i = 0; i < N; ++i)
    for (j = 0; j < n; ++j)
      if (!(i & (1 << j))) {
        x = i ^ (1 << j);
        L[x] = max(L[x], L[i] + 1);
      }

  for (i = N - 1; i >= 0; --i)
    for (j = 0; j < n; ++j)
      if (i & (1 << j)) {
        x = i ^ (1 << j);
        R[x] = min(R[x], R[i] - 1);
      }

  for (i = 0; i < N; ++i) {
    if (L[i] > N - 1 || R[i] < 0 || L[i] > R[i])
      Impossible;
    open[R[i]].push_back(i);
  }

  for (i = N - 1; i >= 0; --i) {
    for (auto it : open[i])
      heap.push({L[it], it + (A[it] != -1 ? N : 0)});

    if (heap.empty())
      Impossible;

    if (heap.top().second < N) {
      A[heap.top().second] = i;
      if (L[heap.top().second] > i)
        Impossible;
    }

    heap.pop();
  }

  cout << "YES\\n";
  for (i = 0; i < N; ++i)
    cout << A[reversed(i)] + 1 << ' ';

  return 0;
}


#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <ctime>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <string>
#include <vector>

#define N 300005
#define M 19

#define ls (t << 1)
#define rs ((t << 1) | 1)
#define mid ((l + r) >> 1)

#define mk make_pair
#define pb push_back
#define fi first
#define se second

using namespace std;

int i, j, m, n, p, k, r, A[1 << M], vis[(1 << M) + 5], Q[(1 << M) + 5],
    deg[1 << M], que[(1 << M) + 5], Qt[(1 << M) + 5], B[1 << M], G[1 << M],
    H[1 << M], F[1 << M];

vector<int> ve[1 << M];

inline int cmp(int a, int b) { return A[a] < A[b]; }

inline int cmp2(int a, int b) {
  if (G[a] != G[b])
    return G[a] < G[b];
  return H[a] > H[b];
}

int ojbk(int x) {
  que[que[0] = 1] = x;
  int i, l;
  for (l = 1; l <= que[0]; ++l) {
    int p = que[l];
    for (i = 0; i < (int)ve[p].size(); ++i) {
      int k = ve[p][i];
      if (A[k]) {
        if (A[k] >= A[x])
          return 0;
      } else
        que[++que[0]] = k, A[k] = -1;
    }
  }
  for (l = 2; l <= que[0]; ++l) {
    int p = que[l];
    for (j = 0; j < (int)ve[p].size(); ++j) {
      int k = ve[p][j];
      if (A[k] == -1)
        deg[k]++;
    }
  }
  Qt[0] = 0;
  for (l = 2; l <= que[0]; ++l) {
    int p = que[l];
    if (!deg[p])
      Qt[++Qt[0]] = p;
  }
  for (l = 1; l <= Qt[0]; ++l) {
    int p = Qt[l];
    for (i = 0; i < (int)ve[p].size(); ++i) {
      int k = ve[p][i];
      if (A[k] == -1) {
        deg[k]--;
        if (!deg[k])
          Qt[++Qt[0]] = k;
      }
    }
  }
  for (i = Qt[0]; i >= 1; --i) {
    int p = Qt[i];
    H[Qt[i]] = i;
    for (j = 0; j < (int)ve[p].size(); ++j) {
      int k = ve[p][j];
      G[p] = max(G[p], G[k]);
    }
  }
  sort(Qt + 1, Qt + Qt[0] + 1, cmp2);
  F[0] = Qt[0] + 1;
  for (i = 1; i <= Qt[0]; ++i)
    F[i + 1] = Qt[i];
  F[1] = x;
  for (i = 1; i <= Qt[0]; ++i) {
    int p = Qt[i];
    for (; vis[r]; ++r)
      ;
    if (r > A[x] || r <= G[p])
      return 0;
    A[p] = r;
    vis[r] = 1;
  }
  for (i = F[0]; i; --i) {
    int p = F[i];
    G[p] = A[p];
    for (j = 0; j < (int)ve[p].size(); ++j) {
      int k = ve[p][j];
      G[p] = max(G[p], G[k]);
    }
  }
  return 1;
}
int ojbkall() {
  int i, l;
  que[0] = 0;
  for (i = 0; i < m; ++i)
    if (!A[i])
      que[++que[0]] = i;
  for (l = 1; l <= que[0]; ++l) {
    int p = que[l];
    for (j = 0; j < (int)ve[p].size(); ++j) {
      int k = ve[p][j];
      if (A[k] == 0)
        deg[k]++;
    }
  }
  Qt[0] = 0;
  for (l = 1; l <= que[0]; ++l) {
    int p = que[l];
    if (!deg[p])
      Qt[++Qt[0]] = p;
  }
  for (l = 1; l <= Qt[0]; ++l) {
    int p = Qt[l];
    for (i = 0; i < (int)ve[p].size(); ++i) {
      int k = ve[p][i];
      if (A[k] == 0) {
        deg[k]--;
        if (!deg[k])
          Qt[++Qt[0]] = k;
      }
    }
  }
  for (i = 1; i <= Qt[0]; ++i)
    H[Qt[i]] = i;
  for (i = 0; i < m; ++i)
    G[i] = A[i];
  for (i = 0; i < m; ++i) {
    int p = i;
    for (j = 0; j < (int)ve[p].size(); ++j)
      G[p] = max(G[p], G[ve[p][j]]);
  }
  sort(Qt + 1, Qt + Qt[0] + 1, cmp2);
  for (i = 1; i <= Qt[0]; ++i) {
    int p = Qt[i];
    for (; vis[r]; ++r)
      ;
    if (G[p] >= r)
      return 0;
    A[p] = r;
    vis[r] = 1;
  }
  return 1;
}

int main() {
  scanf("%d", &n);
  m = 1 << n;
  for (i = 0; i < m; ++i) {
    scanf("%d", &A[i]);
    if (A[i])
      vis[A[i]] = 1, Q[++Q[0]] = i, G[i] = A[i];
  }
  r = 1;
  for (i = 0; i < n; ++i) {
    for (j = 0; j < m; ++j) {
      int p = j ^ (1 << i);
      if (p < j)
        ve[j].pb(p);
    }
  }
  sort(Q + 1, Q + Q[0] + 1, cmp);
  for (i = 1; i <= Q[0]; ++i) {
    if (!ojbk(Q[i])) {
      puts("NO");
      for (;;)
        ;
      return 0;
    }
  }
  //		for (i=0;i<n;++i)
  //		{
  //				for (j=0;j<m;++j)
  //				{
  //						int p=j^(1<<i);
  //						if (p<j&&A[p]&&A[j]&&A[p]>=A[j]) for
  //(;;);
  //				}
  //		}
  if (!ojbkall()) {
    puts("NO");
    for (;;)
      ;
    return 0;
  }
  printf("YES\\n");
  //		for (;vis[r];++r);
  //		if (r!=(1<<n)+1) for (;;);
  /*
                  for (i=0;i<n;++i)
                  {
                                  for (j=0;j<m;++j)
                                  {
                                                  int p=j^(1<<i);
                                                  if (p<j&&A[p]>=A[j]) for (;;);
                                  }
                  }
                  */
  //		sort(A,A+m);
  //		for (i=0;i<m-1;++i) if (A[i]==A[i+1]) for (;;);
  Q[Q[0] = 1] = 0;
  for (i = 0; i < n; ++i) {
    for (j = 1; j <= (1 << i); ++j)
      Q[++Q[0]] = Q[j] + (1 << (n - 1 - i));
  }
  for (i = 1; i <= m; ++i)
    B[Q[i]] = A[i - 1];
  for (i = 0; i < m; ++i)
    printf("%d ", B[i]);
}

#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <ctime>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <string>
#include <vector>

#define N 500005
#define M 8000005

#define ls (t << 1)
#define rs ((t << 1) | 1)
#define mid ((l + r) >> 1)

#define mk make_pair
#define pb push_back
#define fi first
#define se second

using namespace std;

int i, j, m, n, p, k, A[N], L[N], R[N], Q[N], B[N];

vector<pair<int, int>> v[N];

set<pair<int, int>> st;

int main() {
  scanf("%d", &n);
  m = 1 << n;
  for (i = 0; i < m; ++i)
    scanf("%d", &A[i]);
  for (i = m - 1; i >= 0; --i) {
    R[i] = m;
    if (A[i])
      R[i] = A[i];
    for (j = 0; j < n; ++j)
      if ((i ^ (1 << j)) > i)
        R[i] = min(R[i], R[i ^ (1 << j)]);
  }
  for (i = 0; i < m; ++i) {
    L[i] = 1;
    if (A[i])
      L[i] = A[i];
    for (j = 0; j < n; ++j)
      if ((i ^ (1 << j)) < i)
        L[i] = max(L[i], L[i ^ (1 << j)]);
  }
  for (i = 0; i < m; ++i)
    v[L[i]].pb(mk(R[i], i));
  for (i = 1; i <= m; ++i) {
    for (j = 0; j < (int)v[i].size(); ++j)
      st.insert(v[i][j]);
    if (!st.size() || (*st.begin()).fi < i) {
      puts("NO");
      return 0;
    }
    A[(*st.begin()).se] = i;
    st.erase(st.begin());
  }
  puts("YES");
  Q[Q[0] = 1] = 0;
  for (i = 0; i < n; ++i) {
    for (j = 1; j <= (1 << i); ++j)
      Q[++Q[0]] = Q[j] + (1 << (n - 1 - i));
  }
  for (i = 1; i <= m; ++i)
    B[Q[i]] = A[i - 1];
  for (i = 0; i < m; ++i)
    printf("%d ", B[i]);
}


#include <bits/stdc++.h>
using ll = long long;
using ld = long double;
using namespace std;

const int N = 18;
const int MN = (1 << N);

vector<int> e[MN];
vector<int> reve[MN];

int c[MN];

int req[MN];
int a[MN];

int cur;

set<int> avail;

void no() {
  cout << "NO\\n";
  exit(0);
}

int dfs(int x) {
  if (a[x] != -1) {
    return a[x];
  }

  int vl = MN;

  for (int y : e[x]) {
    vl = min(vl, dfs(y));
  }

  auto it = avail.lower_bound(vl);

  if (it == avail.begin()) {
    no();
  }

  --it;
  vl = a[x] = *it;
  avail.erase(it);

  return vl;
}

int buf[N];
int b[N];
int inita[N];

void dfsgo(int v, int val) {
  for (int u : e[v]) {
    if (dfs(u) <= val) {
      no();
    }
  }

  a[v] = val;
}

int n, k;

void cool() {
  for (int i = k; i > 0; --i) {
    copy(a, a + n, buf);
    int c = 1 << i;
    for (int l = 0; l < n; l += c) {
      int r = l + c;
      int md = (l + r) / 2;
      for (int cc = 0; cc < (md - l); ++cc) {
        a[l + cc] = buf[l + cc * 2];
        a[md + cc] = buf[l + cc * 2 + 1];
      }
    }
  }

  for (int i = 0; i < n; ++i) {
    // assert(a[i] == inita[i]);
  }
}

int main() {
#ifdef PAUNSVOKNO
  freopen("input.txt", "r", stdin);
  freopen("output.txt", "w", stdout);
#endif

  cin >> k;
  n = (1 << k);
  cur = n - 1;
  fill(req, req + n, -1);

  for (int i = 0; i < n; ++i) {
    for (int j = 0; j < k; ++j) {
      if ((i & (1 << j)) == 0) {
        e[i].push_back(i + (1 << j));
      }
    }
  }

  for (int i = 0; i < n; ++i) {
    cin >> a[i];
    --a[i];
    if (a[i] >= 0) {
      req[a[i]] = i;
    }
  }

  for (int i = 0; i < n; ++i) {
    if (req[i] == -1) {
      avail.insert(i);
    }
  }

  for (int i = n - 1; i >= 0; --i) {
    if (req[i] != -1) {
      dfsgo(req[i], i);
    }
  }

  if (a[0] > 0) {
    no();
  }

  dfsgo(0, 0);
  copy(a, a + n, inita);

  for (int i = 2; i <= k; ++i) {
    copy(a, a + n, buf);
    for (int j = 0; j < (1 << (k - i)); ++j) {
      int l = (j << i);
      int r = ((j + 1) << i);
      int m = (l + r) / 2;

      for (int i2 = 0; i2 < (1 << (i - 1)); ++i2) {
        a[l + i2 * 2] = buf[l + i2];
        a[l + i2 * 2 + 1] = buf[m + i2];
      }
    }
  }

  cout << "YES\\n";
  for (int i = 0; i < n; ++i) {
    cout << a[i] + 1 << " ";
  }

  cool();
}

#include <bits/stdc++.h>
using ll = long long;
using ld = long double;
using namespace std;

const int N = 18;
const int MN = (1 << N);

vector<int> e[MN];
vector<int> reve[MN];

int c[MN];

int req[MN];
int a[MN];

int cur;

set<int> avail;

void no() {
  cout << "NO\\n";
  exit(0);
}

int dfs(int x) {
  if (a[x] != -1) {
    return a[x];
  }

  int vl = MN;

  for (int y : e[x]) {
    vl = min(vl, dfs(y));
  }

  auto it = avail.lower_bound(vl);

  if (it == avail.begin()) {
    no();
  }

  --it;
  vl = a[x] = *it;
  avail.erase(it);

  return vl;
}

int buf[MN];
int b[MN];
int inita[MN];

void dfsgo(int v, int val) {
  for (int u : e[v]) {
    if (dfs(u) <= val) {
      no();
    }
  }

  a[v] = val;
}

int n, k;

void cool() {
  for (int i = k; i > 0; --i) {
    copy(a, a + n, buf);
    int c = 1 << i;
    for (int l = 0; l < n; l += c) {
      int r = l + c;
      int md = (l + r) / 2;
      for (int cc = 0; cc < (md - l); ++cc) {
        a[l + cc] = buf[l + cc * 2];
        a[md + cc] = buf[l + cc * 2 + 1];
      }
    }
  }

  for (int i = 0; i < n; ++i) {
    assert(a[i] == inita[i]);
  }
}

int main() {
#ifdef PAUNSVOKNO
  freopen("input.txt", "r", stdin);
  freopen("output.txt", "w", stdout);
#endif

  cin >> k;
  n = (1 << k);
  cur = n - 1;
  fill(req, req + n, -1);

  for (int i = 0; i < n; ++i) {
    for (int j = 0; j < k; ++j) {
      if ((i & (1 << j)) == 0) {
        e[i].push_back(i + (1 << j));
      }
    }
  }

  for (int i = 0; i < n; ++i) {
    cin >> a[i];
    --a[i];
    if (a[i] >= 0) {
      req[a[i]] = i;
    }
  }

  for (int i = 0; i < n; ++i) {
    if (req[i] == -1) {
      avail.insert(i);
    }
  }

  for (int i = n - 1; i >= 0; --i) {
    if (req[i] != -1) {
      dfsgo(req[i], i);
    }
  }

  if (a[0] > 0) {
    no();
  }

  dfsgo(0, 0);
  copy(a, a + n, inita);

  for (int i = 2; i <= k; ++i) {
    copy(a, a + n, buf);
    for (int j = 0; j < (1 << (k - i)); ++j) {
      int l = (j << i);
      int r = ((j + 1) << i);
      int m = (l + r) / 2;

      for (int i2 = 0; i2 < (1 << (i - 1)); ++i2) {
        a[l + i2 * 2] = buf[l + i2];
        a[l + i2 * 2 + 1] = buf[m + i2];
      }
    }
  }

  cout << "YES\\n";
  for (int i = 0; i < n; ++i) {
    cout << a[i] + 1 << " ";
  }

  cool();
}


// need
#include <algorithm>
#include <iostream>
// data structure
#include <bitset>
#include <complex>
#include <map>
#include <queue>
#include <set>
#include <stack>
#include <string>
#include <utility>
#include <vector>
// #include <deque>
#include <array>
#include <unordered_map>
#include <unordered_set>
#include <valarray>
// stream
// #include <istream>
#include <sstream>
// #include <ostream>
#include <fstream>
// etc
#include <cassert>
#include <chrono>
#include <cmath>
#include <functional>
#include <iomanip>
#include <numeric>
#include <random>

// input
#define INIT                                                                   \\
  std::ios::sync_with_stdio(false);                                            \\
  std::cin.tie(0);
#define VAR(type, ...)                                                         \\
  type __VA_ARGS__;                                                            \\
  MACRO_VAR_Scan(__VA_ARGS__);
template <typename T> void MACRO_VAR_Scan(T &t) { std::cin >> t; }
template <typename First, typename... Rest>
void MACRO_VAR_Scan(First &first, Rest &...rest) {
  std::cin >> first;
  MACRO_VAR_Scan(rest...);
}
#define VEC_ROW(type, n, ...)                                                  \\
  std::vector<type> __VA_ARGS__;                                               \\
  MACRO_VEC_ROW_Init(n, __VA_ARGS__);                                          \\
  for (int w_ = 0; w_ < n; ++w_) {                                             \\
    MACRO_VEC_ROW_Scan(w_, __VA_ARGS__);                                       \\
  }
template <typename T> void MACRO_VEC_ROW_Init(int n, T &t) { t.resize(n); }
template <typename First, typename... Rest>
void MACRO_VEC_ROW_Init(int n, First &first, Rest &...rest) {
  first.resize(n);
  MACRO_VEC_ROW_Init(n, rest...);
}
template <typename T> void MACRO_VEC_ROW_Scan(int p, T &t) { std::cin >> t[p]; }
template <typename First, typename... Rest>
void MACRO_VEC_ROW_Scan(int p, First &first, Rest &...rest) {
  std::cin >> first[p];
  MACRO_VEC_ROW_Scan(p, rest...);
}
#define VEC(type, c, n)                                                        \\
  std::vector<type> c(n);                                                      \\
  for (auto &i : c)                                                            \\
    std::cin >> i;
#define MAT(type, c, m, n)                                                     \\
  std::vector<std::vector<type>> c(m, std::vector<type>(n));                   \\
  for (auto &R : c)                                                            \\
    for (auto &w : R)                                                          \\
      std::cin >> w;
// output
#define OUT(dist) std::cout << (dist);
#define FOUT(n, dist) std::cout << std::fixed << std::setprecision(n) << (dist);
#define SOUT(n, c, dist) std::cout << std::setw(n) << std::setfill(c) << (dist);
#define SP std::cout << " ";
#define TAB std::cout << "\\t";
#define BR std::cout << "\\n";
#define SPBR(w, n) std::cout << (w + 1 == n ? '\\n' : ' ');
#define ENDL std::cout << std::endl;
#define FLUSH std::cout << std::flush;
#define SHOW(dist)                                                             \\
  { std::cerr << #dist << "\\t:" << (dist) << "\\n"; }
#define SHOWVECTOR(v)                                                          \\
  {                                                                            \\
    std::cerr << #v << "\\t:";                                                  \\
    for (const auto &xxx : v) {                                                \\
      std::cerr << xxx << " ";                                                 \\
    }                                                                          \\
    std::cerr << "\\n";                                                         \\
  }
#define SHOWVECTOR2(v)                                                         \\
  {                                                                            \\
    std::cerr << #v << "\\t:\\n";                                                \\
    for (const auto &xxx : v) {                                                \\
      for (const auto &yyy : xxx) {                                            \\
        std::cerr << yyy << " ";                                               \\
      }                                                                        \\
      std::cerr << "\\n";                                                       \\
    }                                                                          \\
  }
#define SHOWQUEUE(a)                                                           \\
  {                                                                            \\
    auto tmp(a);                                                               \\
    std::cerr << #a << "\\t:";                                                  \\
    while (!tmp.empty()) {                                                     \\
      std::cerr << tmp.front() << " ";                                         \\
      tmp.pop();                                                               \\
    }                                                                          \\
    std::cerr << "\\n";                                                         \\
  }
// utility
#define ALL(a) (a).begin(), (a).end()
#define FOR(w, a, n) for (int w = (a); w < (n); ++w)
#define RFOR(w, a, n) for (int w = (n)-1; w >= (a); --w)
#define REP(w, n) for (int w = 0; w < int(n); ++w)
#define RREP(w, n) for (int w = int(n) - 1; w >= 0; --w)
#define FORLL(w, a, n) for (ll w = ll(a); w < ll(n); ++w)
#define RFORLL(w, a, n) for (ll w = ll(n) - 1; w >= ll(a); --w)
#define REPLL(w, n) for (ll w = 0; w < ll(n); ++w)
#define RREPLL(w, n) for (ll w = ll(n) - 1; w >= 0; --w)
#define IN(a, x, b) (a <= x && x < b)
template <class T> inline T CHMAX(T &a, const T b) {
  return a = (a < b) ? b : a;
}
template <class T> inline T CHMIN(T &a, const T b) {
  return a = (a > b) ? b : a;
}
#define EXCEPTION(msg)                                                         \\
  throw std::string("Exception : " msg " [ in ") + __func__ + " : " +          \\
      std::to_string(__LINE__) + " lines ]"
#define TRY(cond, msg)                                                         \\
  try {                                                                        \\
    if (cond)                                                                  \\
      EXCEPTION(msg);                                                          \\
  } catch (std::string s) {                                                    \\
    std::cerr << s << std::endl;                                               \\
  }
// void CHECKTIME(std::function<void()> f) { auto start =
// std::chrono::system_clock::now(); f(); auto end =
// std::chrono::system_clock::now(); auto res =
// std::chrono::duration_cast<std::chrono::nanoseconds>((end - start)).count();
// std::cerr << "[Time:" << res << "ns  (" << res / (1.0e9) << "s)]\\n"; }
//  test
template <class T> using V = std::vector<T>;
template <class T> using VV = V<V<T>>;

template <typename S, typename T>
std::ostream &operator<<(std::ostream &os, std::pair<S, T> p) {
  os << "(" << p.first << ", " << p.second << ")";
  return os;
}

#define random_shuffle "USE std::shuffle!";

// type/const
#define int ll
using ll = long long;
using ull = unsigned long long;
using ld = long double;
using PAIR = std::pair<int, int>;
using PAIRLL = std::pair<ll, ll>;
constexpr int INFINT = 1 << 30;                         // 1.07x10^ 9
constexpr int INFINT_LIM = (1LL << 31) - 1;             // 2.15x10^ 9
constexpr ll INFLL = 1LL << 60;                         // 1.15x10^18
constexpr ll INFLL_LIM = (1LL << 62) - 1 + (1LL << 62); // 9.22x10^18
constexpr double EPS = 1e-6;
constexpr int MOD = 998244353;
constexpr double PI = 3.141592653589793238462643383279;
template <class T, size_t N> void FILL(T (&a)[N], const T &val) {
  for (auto &x : a)
    x = val;
}
template <class ARY, size_t N, size_t M, class T>
void FILL(ARY (&a)[N][M], const T &val) {
  for (auto &b : a)
    FILL(b, val);
}
template <class T> void FILL(std::vector<T> &a, const T &val) {
  for (auto &x : a)
    x = val;
}
template <class ARY, class T>
void FILL(std::vector<std::vector<ARY>> &a, const T &val) {
  for (auto &b : a)
    FILL(b, val);
}
// ------------>8------------------------------------->8------------

void add(char &c, int d) {
  int t = c - 'a' + d;
  t %= 26;
  if (t < 0)
    t += 26;
  c = 'a' + t;
}

bool calc() {
  VAR(std::string, s);
  VAR(int, n);
  VEC_ROW(int, n, l, r);

  std::string t(s.rbegin(), s.rend());
  int M = s.size();
  int m = M / 2;
  s.resize(m);
  t.resize(m);

  std::vector<std::vector<int>> seg(m + 1);

  REP(i, n) {
    --l[i];
    --r[i];
    if (r[i] < m)
      continue;
    if (l[i] >= M - m) {
      l[i] = M - 1 - l[i];
      r[i] = M - 1 - r[i];
      std::swap(l[i], r[i]);
      continue;
    }
    r[i] = M - 1 - r[i];
    if (l[i] == r[i]) {
      l[i] = r[i] = -1;
    } else if (l[i] < r[i]) {
      --r[i];
    } else if (r[i] < l[i]) {
      --l[i];
      std::swap(l[i], r[i]);
    }
  }

  REP(i, n) {
    if (l[i] == -1)
      continue;
    seg[l[i]].emplace_back(r[i]);
  }

  REP(i, m) {
    std::sort(ALL(seg[i]));
    FOR(j, 1, seg[i].size()) {
      if (seg[i][0] + 1 <= seg[i][j])
        seg[seg[i][0] + 1].emplace_back(seg[i][j]);
    }
    if (seg[i].size() > 1)
      seg[i].resize(1);
  }

  std::vector<int> imos(m + 1, 0);
  REP(i, m) {
    add(s[i], imos[i]);
    if (s[i] != t[i]) {
      if (seg[i].empty())
        return false;

      int d = t[i] - s[i];
      if (d < 0)
        d += 26;
      add(s[i], d);
      assert(s[i] == t[i]);

      imos[i] += d;
      imos[seg[i][0] + 1] -= d;
    }
    (imos[i + 1] += imos[i]) %= 26;
  }
  assert(s == t);

  return true;
}

signed main() {
  INIT;

  OUT(calc() ? "YES" : "NO") BR;

  return 0;
}

// need
#include <algorithm>
#include <iostream>
// data structure
#include <bitset>
#include <complex>
#include <map>
#include <queue>
#include <set>
#include <stack>
#include <string>
#include <utility>
#include <vector>
// #include <deque>
#include <array>
#include <unordered_map>
#include <unordered_set>
#include <valarray>
// stream
// #include <istream>
#include <sstream>
// #include <ostream>
#include <fstream>
// etc
#include <cassert>
#include <chrono>
#include <cmath>
#include <functional>
#include <iomanip>
#include <numeric>
#include <random>

// input
#define INIT                                                                   \\
  std::ios::sync_with_stdio(false);                                            \\
  std::cin.tie(0);
#define VAR(type, ...)                                                         \\
  type __VA_ARGS__;                                                            \\
  MACRO_VAR_Scan(__VA_ARGS__);
template <typename T> void MACRO_VAR_Scan(T &t) { std::cin >> t; }
template <typename First, typename... Rest>
void MACRO_VAR_Scan(First &first, Rest &...rest) {
  std::cin >> first;
  MACRO_VAR_Scan(rest...);
}
#define VEC_ROW(type, n, ...)                                                  \\
  std::vector<type> __VA_ARGS__;                                               \\
  MACRO_VEC_ROW_Init(n, __VA_ARGS__);                                          \\
  for (int w_ = 0; w_ < n; ++w_) {                                             \\
    MACRO_VEC_ROW_Scan(w_, __VA_ARGS__);                                       \\
  }
template <typename T> void MACRO_VEC_ROW_Init(int n, T &t) { t.resize(n); }
template <typename First, typename... Rest>
void MACRO_VEC_ROW_Init(int n, First &first, Rest &...rest) {
  first.resize(n);
  MACRO_VEC_ROW_Init(n, rest...);
}
template <typename T> void MACRO_VEC_ROW_Scan(int p, T &t) { std::cin >> t[p]; }
template <typename First, typename... Rest>
void MACRO_VEC_ROW_Scan(int p, First &first, Rest &...rest) {
  std::cin >> first[p];
  MACRO_VEC_ROW_Scan(p, rest...);
}
#define VEC(type, c, n)                                                        \\
  std::vector<type> c(n);                                                      \\
  for (auto &i : c)                                                            \\
    std::cin >> i;
#define MAT(type, c, m, n)                                                     \\
  std::vector<std::vector<type>> c(m, std::vector<type>(n));                   \\
  for (auto &R : c)                                                            \\
    for (auto &w : R)                                                          \\
      std::cin >> w;
// output
#define OUT(dist) std::cout << (dist);
#define FOUT(n, dist) std::cout << std::fixed << std::setprecision(n) << (dist);
#define SOUT(n, c, dist) std::cout << std::setw(n) << std::setfill(c) << (dist);
#define SP std::cout << " ";
#define TAB std::cout << "\\t";
#define BR std::cout << "\\n";
#define SPBR(w, n) std::cout << (w + 1 == n ? '\\n' : ' ');
#define ENDL std::cout << std::endl;
#define FLUSH std::cout << std::flush;
#define SHOW(dist)                                                             \\
  { std::cerr << #dist << "\\t:" << (dist) << "\\n"; }
#define SHOWVECTOR(v)                                                          \\
  {                                                                            \\
    std::cerr << #v << "\\t:";                                                  \\
    for (const auto &xxx : v) {                                                \\
      std::cerr << xxx << " ";                                                 \\
    }                                                                          \\
    std::cerr << "\\n";                                                         \\
  }
#define SHOWVECTOR2(v)                                                         \\
  {                                                                            \\
    std::cerr << #v << "\\t:\\n";                                                \\
    for (const auto &xxx : v) {                                                \\
      for (const auto &yyy : xxx) {                                            \\
        std::cerr << yyy << " ";                                               \\
      }                                                                        \\
      std::cerr << "\\n";                                                       \\
    }                                                                          \\
  }
#define SHOWQUEUE(a)                                                           \\
  {                                                                            \\
    auto tmp(a);                                                               \\
    std::cerr << #a << "\\t:";                                                  \\
    while (!tmp.empty()) {                                                     \\
      std::cerr << tmp.front() << " ";                                         \\
      tmp.pop();                                                               \\
    }                                                                          \\
    std::cerr << "\\n";                                                         \\
  }
// utility
#define ALL(a) (a).begin(), (a).end()
#define FOR(w, a, n) for (int w = (a); w < (n); ++w)
#define RFOR(w, a, n) for (int w = (n)-1; w >= (a); --w)
#define REP(w, n) for (int w = 0; w < int(n); ++w)
#define RREP(w, n) for (int w = int(n) - 1; w >= 0; --w)
#define FORLL(w, a, n) for (ll w = ll(a); w < ll(n); ++w)
#define RFORLL(w, a, n) for (ll w = ll(n) - 1; w >= ll(a); --w)
#define REPLL(w, n) for (ll w = 0; w < ll(n); ++w)
#define RREPLL(w, n) for (ll w = ll(n) - 1; w >= 0; --w)
#define IN(a, x, b) (a <= x && x < b)
template <class T> inline T CHMAX(T &a, const T b) {
  return a = (a < b) ? b : a;
}
template <class T> inline T CHMIN(T &a, const T b) {
  return a = (a > b) ? b : a;
}
#define EXCEPTION(msg)                                                         \\
  throw std::string("Exception : " msg " [ in ") + __func__ + " : " +          \\
      std::to_string(__LINE__) + " lines ]"
#define TRY(cond, msg)                                                         \\
  try {                                                                        \\
    if (cond)                                                                  \\
      EXCEPTION(msg);                                                          \\
  } catch (std::string s) {                                                    \\
    std::cerr << s << std::endl;                                               \\
  }
// void CHECKTIME(std::function<void()> f) { auto start =
// std::chrono::system_clock::now(); f(); auto end =
// std::chrono::system_clock::now(); auto res =
// std::chrono::duration_cast<std::chrono::nanoseconds>((end - start)).count();
// std::cerr << "[Time:" << res << "ns  (" << res / (1.0e9) << "s)]\\n"; }
//  test
template <class T> using V = std::vector<T>;
template <class T> using VV = V<V<T>>;

template <typename S, typename T>
std::ostream &operator<<(std::ostream &os, std::pair<S, T> p) {
  os << "(" << p.first << ", " << p.second << ")";
  return os;
}

#define random_shuffle "USE std::shuffle!";

// type/const
#define int ll
using ll = long long;
using ull = unsigned long long;
using ld = long double;
using PAIR = std::pair<int, int>;
using PAIRLL = std::pair<ll, ll>;
constexpr int INFINT = 1 << 30;                         // 1.07x10^ 9
constexpr int INFINT_LIM = (1LL << 31) - 1;             // 2.15x10^ 9
constexpr ll INFLL = 1LL << 60;                         // 1.15x10^18
constexpr ll INFLL_LIM = (1LL << 62) - 1 + (1LL << 62); // 9.22x10^18
constexpr double EPS = 1e-6;
constexpr int MOD = 998244353;
constexpr double PI = 3.141592653589793238462643383279;
template <class T, size_t N> void FILL(T (&a)[N], const T &val) {
  for (auto &x : a)
    x = val;
}
template <class ARY, size_t N, size_t M, class T>
void FILL(ARY (&a)[N][M], const T &val) {
  for (auto &b : a)
    FILL(b, val);
}
template <class T> void FILL(std::vector<T> &a, const T &val) {
  for (auto &x : a)
    x = val;
}
template <class ARY, class T>
void FILL(std::vector<std::vector<ARY>> &a, const T &val) {
  for (auto &b : a)
    FILL(b, val);
}
// ------------>8------------------------------------->8------------

void add(char &c, int d) {
  int t = c - 'a' + d;
  t %= 26;
  if (t < 0)
    t += 26;
  c = 'a' + t;
}

bool calc() {
  VAR(std::string, s);
  VAR(int, n);
  VEC_ROW(int, n, l, r);

  std::string t(s.rbegin(), s.rend());
  int M = s.size();
  int m = M / 2;
  s.resize(m);
  t.resize(m);

  std::vector<std::set<int>> segset(m + 1);
  std::vector<int> seg(m + 1, -1);

  REP(i, n) {
    --l[i];
    --r[i];
    if (r[i] < m)
      continue;
    if (l[i] >= M - m) {
      l[i] = M - 1 - l[i];
      r[i] = M - 1 - r[i];
      std::swap(l[i], r[i]);
      continue;
    }
    r[i] = M - 1 - r[i];
    if (l[i] == r[i]) {
      l[i] = r[i] = -1;
    } else if (l[i] < r[i]) {
      --r[i];
    } else if (r[i] < l[i]) {
      --l[i];
      std::swap(l[i], r[i]);
    }
  }

  REP(i, n) {
    if (l[i] == -1)
      continue;
    segset[l[i]].insert(r[i]);
  }

  REP(i, m) {
    int pre = -1;
    for (auto &x : segset[i]) {
      if (pre != -1) {
        if (pre + 1 <= x)
          segset[pre + 1].insert(x);
      }
      pre = x;
    }
    if (!segset[i].empty()) {
      seg[i] = *segset[i].begin();
    }
    segset[i].clear();
  }

  std::vector<int> imos(m + 1, 0);
  REP(i, m) {
    add(s[i], imos[i]);
    if (s[i] != t[i]) {
      if (seg[i] == -1)
        return false;

      int d = t[i] - s[i];
      if (d < 0)
        d += 26;
      add(s[i], d);
      assert(s[i] == t[i]);

      imos[i] += d;
      imos[seg[i] + 1] -= d;
    }
    (imos[i + 1] += imos[i]) %= 26;
  }
  assert(s == t);

  return true;
}

signed main() {
  INIT;

  OUT(calc() ? "YES" : "NO") BR;

  return 0;
}


#include <bits/stdc++.h>
#define REP(i, a, n) for (ll i = ((ll)a); i < ((ll)n); i++)
using namespace std;
typedef long long ll;

string S;
ll N, L[100000], R[100000];
vector<ll> E[100000];
vector<ll> d;
bool visited[100000];

ll dfs(ll v) {
  if (visited[v])
    return 0;
  visited[v] = true;

  ll ret = d[v];
  for (ll u : E[v])
    ret += dfs(u);
  return ret;
}

int main(void) {
  cin >> S >> N;
  REP(i, 0, N) cin >> L[i] >> R[i], L[i]--, R[i];

  S = "a" + S + "a";
  REP(i, 0, S.length() - 1) d.push_back((S[i + 1] - S[i] + 26) % 26);

  REP(i, 0, N) {
    E[L[i]].push_back(R[i]);
    E[R[i]].push_back(L[i]);
  }
  REP(i, 0, (d.size()) / 2) {
    E[i].push_back(d.size() - 1 - i);
    E[d.size() - 1 - i].push_back(i);
  }

  bool ans = true;
  REP(i, 0, S.length() - 1) visited[i] = false;
  REP(i, 0, S.length() - 1) {
    ll sum = dfs(i) % 26;
    if (sum != 0)
      ans = false;
  }
  cout << (ans ? "YES" : "NO") << endl;
}

#include <bits/stdc++.h>
#define REP(i, a, n) for (ll i = ((ll)a); i < ((ll)n); i++)
using namespace std;
typedef long long ll;

string S;
ll N, L[200000], R[200000];
vector<ll> E[200000];
vector<ll> d;
bool visited[200000];

ll dfs(ll v) {
  if (visited[v])
    return 0;
  visited[v] = true;

  ll ret = d[v];
  for (ll u : E[v])
    ret += dfs(u);
  return ret;
}

int main(void) {
  cin >> S >> N;
  REP(i, 0, N) cin >> L[i] >> R[i], L[i]--, R[i];

  S = "a" + S + "a";
  REP(i, 0, S.length() - 1) d.push_back((S[i + 1] - S[i] + 26) % 26);

  REP(i, 0, N) {
    E[L[i]].push_back(R[i]);
    E[R[i]].push_back(L[i]);
  }
  REP(i, 0, (d.size()) / 2) {
    E[i].push_back(d.size() - 1 - i);
    E[d.size() - 1 - i].push_back(i);
  }

  bool ans = true;
  REP(i, 0, d.size()) visited[i] = false;
  REP(i, 0, d.size()) {
    ll sum = dfs(i) % 26;
    if (sum != 0)
      ans = false;
  }
  cout << (ans ? "YES" : "NO") << endl;
}


#include <bits/stdc++.h>
using namespace std;
#define GET_MACRO(_1, _2, _3, NAME, ...) NAME
#define _repl(i, a, b) for (int i = (int)(a); i < (int)(b); i++)
#define _rep(i, n) _repl(i, 0, n)
#define rep(...) GET_MACRO(__VA_ARGS__, _repl, _rep)(__VA_ARGS__)
#define mp(a, b) make_pair((a), (b))
#define pb(a) push_back((a))
#define all(x) (x).begin(), (x).end()
#define uniq(x) sort(all(x)), (x).erase(unique(all(x)), end(x))
#define fi first
#define se second
#define dbg(...) _dbg(#__VA_ARGS__, __VA_ARGS__)
void _dbg(string) { cout << endl; }
template <class H, class... T> void _dbg(string s, H h, T... t) {
  int l = s.find(',');
  cout << s.substr(0, l) << " = " << h << ", ";
  _dbg(s.substr(l + 1), t...);
}
template <class T, class U>
ostream &operator<<(ostream &o, const pair<T, U> &p) {
  o << "(" << p.fi << "," << p.se << ")";
  return o;
}
template <class T> ostream &operator<<(ostream &o, const vector<T> &v) {
  o << "[";
  for (T t : v) {
    o << t << ",";
  }
  o << "]";
  return o;
}

#define INF 1120000000

class UnionFind {
public:
  vector<int> par, rank;
  // if par is negative, it is a root, of which tree size is the abs-value.
  // rank represents depth
  UnionFind(int sz) : par(sz, -1), rank(sz, 0) {}
  int find(int x) {
    if (par[x] < 0)
      return x;
    else
      return par[x] = find(par[x]);
  }
  void unite(int x, int y) {
    x = find(x);
    y = find(y);
    if (x == y)
      return;
    if (rank[x] < rank[y])
      swap(x, y);
    par[x] += par[y];
    par[y] = x;
    if (rank[x] == rank[y])
      rank[x]++;
  }
  inline bool same(int x, int y) { return find(x) == find(y); }
  inline int size(int x) { return -par[find(x)]; }
};

bool solve() {
  string s;
  int q;
  cin >> s >> q;
  int n = s.size();
  vector<int> l(q), r(q);
  rep(i, q) cin >> l[i] >> r[i];

  if (n == 1)
    return true;

  rep(i, q) {
    l[i]--;
    if (l[i] < n / 2 && (n + 1) / 2 < r[i]) {
      if (l[i] < n - r[i]) {
        r[i] = n - r[i];
      } else if (n - r[i] < l[i]) {
        int ll = l[i];
        int rr = r[i];
        l[i] = n - rr;
        r[i] = ll;
      } else {
        l[i] = (n + 1) / 2;
        r[i] = (n + 1) / 2;
      }
    } else if (n / 2 <= l[i]) {
      swap(l[i], r[i]);
      l[i] = n - l[i];
      r[i] = n - r[i];
    }
  }

  UnionFind uf(q);

  map<int, int> pos;
  // positions -> idx
  rep(i, q) {
    if (pos.count(l[i])) {
      uf.unite(i, pos[l[i]]);
    } else {
      pos[l[i]] = i;
    }
    if (pos.count(r[i])) {
      uf.unite(i, pos[r[i]]);
    } else {
      pos[r[i]] = i;
    }
  }
  // rep(i,q)dbg(l[i],r[i]);

  // build range group
  map<int, vector<int>> gp;
  rep(i, q) {
    gp[uf.find(i)].pb(l[i]);
    gp[uf.find(i)].pb(r[i]);
  }

  vector<int> ranges(n / 2 + 1, -1); // begin -> end
  for (auto &&pv : gp) {
    auto &&v = pv.second;
    if (v.size()) {
      uniq(v);
      assert(v.size() >= 2);
      rep(i, v.size() - 1) { ranges[v[i]] = v[i + 1]; }
    }
  }
  // dbg(ranges);

  int crnt = 0;
  vector<int> memo(n / 2 + 1, 0);
  rep(i, n / 2) {
    int req = (s[n - i - 1] - s[i] + 26) % 26;
    crnt = (crnt + memo[i] + 26) % 26;
    if (crnt != req) {
      if (ranges[i] == -1)
        return false;
      int add = (req + 26 - crnt) % 26;
      assert(memo[ranges[i]] == 0 && add > 0);
      memo[ranges[i]] = -add;
      crnt = (crnt + add) % 26;
    }
    assert(crnt == req);
  }

  return true;
}

int main() {
  if (solve())
    cout << "YES" << endl;
  else
    cout << "NO" << endl;

  return 0;
}

#include <bits/stdc++.h>
using namespace std;
#define GET_MACRO(_1, _2, _3, NAME, ...) NAME
#define _repl(i, a, b) for (int i = (int)(a); i < (int)(b); i++)
#define _rep(i, n) _repl(i, 0, n)
#define rep(...) GET_MACRO(__VA_ARGS__, _repl, _rep)(__VA_ARGS__)
#define mp(a, b) make_pair((a), (b))
#define pb(a) push_back((a))
#define all(x) (x).begin(), (x).end()
#define uniq(x) sort(all(x)), (x).erase(unique(all(x)), end(x))
#define fi first
#define se second
#define dbg(...) _dbg(#__VA_ARGS__, __VA_ARGS__)
void _dbg(string) { cout << endl; }
template <class H, class... T> void _dbg(string s, H h, T... t) {
  int l = s.find(',');
  cout << s.substr(0, l) << " = " << h << ", ";
  _dbg(s.substr(l + 1), t...);
}
template <class T, class U>
ostream &operator<<(ostream &o, const pair<T, U> &p) {
  o << "(" << p.fi << "," << p.se << ")";
  return o;
}
template <class T> ostream &operator<<(ostream &o, const vector<T> &v) {
  o << "[";
  for (T t : v) {
    o << t << ",";
  }
  o << "]";
  return o;
}

#define INF 1120000000

class UnionFind {
public:
  vector<int> par, rank;
  // if par is negative, it is a root, of which tree size is the abs-value.
  // rank represents depth
  UnionFind(int sz) : par(sz, -1), rank(sz, 0) {}
  int find(int x) {
    if (par[x] < 0)
      return x;
    else
      return par[x] = find(par[x]);
  }
  void unite(int x, int y) {
    x = find(x);
    y = find(y);
    if (x == y)
      return;
    if (rank[x] < rank[y])
      swap(x, y);
    par[x] += par[y];
    par[y] = x;
    if (rank[x] == rank[y])
      rank[x]++;
  }
  inline bool same(int x, int y) { return find(x) == find(y); }
  inline int size(int x) { return -par[find(x)]; }
};

bool solve() {
  string s;
  int q;
  cin >> s >> q;
  int n = s.size();
  vector<int> l(q), r(q);
  rep(i, q) cin >> l[i] >> r[i];

  if (n == 1)
    return true;

  rep(i, q) {
    l[i]--;
    if (l[i] < n / 2 && (n + 1) / 2 < r[i]) {
      if (l[i] < n - r[i]) {
        r[i] = n - r[i];
      } else if (n - r[i] < l[i]) {
        int ll = l[i];
        int rr = r[i];
        l[i] = n - rr;
        r[i] = ll;
      } else {
        l[i] = (n + 1) / 2;
        r[i] = (n + 1) / 2;
      }
    } else if (n / 2 <= l[i]) {
      swap(l[i], r[i]);
      l[i] = n - l[i];
      r[i] = n - r[i];
    }
  }

  UnionFind uf(q);

  map<int, int> pos;
  // positions -> idx
  rep(i, q) {
    if (pos.count(l[i])) {
      uf.unite(i, pos[l[i]]);
    } else {
      pos[l[i]] = i;
    }
    if (pos.count(r[i])) {
      uf.unite(i, pos[r[i]]);
    } else {
      pos[r[i]] = i;
    }
  }
  // rep(i,q)dbg(l[i],r[i]);

  // build range group
  map<int, vector<int>> gp;
  rep(i, q) {
    gp[uf.find(i)].pb(l[i]);
    gp[uf.find(i)].pb(r[i]);
  }

  vector<int> ranges(n / 2 + 1, -1); // begin -> end
  for (auto &&pv : gp) {
    auto &&v = pv.second;
    if (v.size()) {
      uniq(v);
      rep(i, v.size() - 1) { ranges[v[i]] = v[i + 1]; }
    }
  }
  // dbg(ranges);

  int crnt = 0;
  vector<int> memo(n / 2 + 1, 0);
  rep(i, n / 2) {
    int req = (s[n - i - 1] - s[i] + 26) % 26;
    crnt = (crnt + memo[i]) % 26;
    if (crnt != req) {
      if (ranges[i] == -1)
        return false;
      int add = (req + 26 - crnt) % 26;
      memo[ranges[i]] = 26 - add;
      crnt = (crnt + add) % 26;
    }
    assert(crnt == req);
  }

  return true;
}

int main() {
  if (solve())
    cout << "YES" << endl;
  else
    cout << "NO" << endl;

  return 0;
}


#include <iostream>
#include <set>
#include <vector>

using namespace std;

void failure() {
  cout << "NO" << endl;
  exit(0);
}

typedef long long ll;

const int MOD = 26; // change if needed

struct Modint {
  ll val;

  Modint(ll _val = 0) : val(_val % MOD) {}

  Modint operator+(Modint other) const { return Modint(val + other.val); }

  void operator+=(Modint other) {
    val += other.val;
    val %= MOD;
  }

  Modint operator-() const { return Modint(MOD - val); }

  Modint operator-(Modint other) const { return Modint(val + MOD - other.val); }

  void operator-=(Modint other) {
    val += MOD - other.val;
    val %= MOD;
  }

  Modint operator*(Modint other) const { return Modint(val * other.val); }

  void operator*=(Modint other) {
    val *= other.val;
    val %= MOD;
  }

  bool operator==(Modint other) const { return val == other.val; }

  bool operator!=(Modint other) const { return val != other.val; }
};

Modint exp(Modint a, int k) {
  if (k == 0) {
    return Modint(1);
  } else if (k % 2 == 0) {
    Modint half = exp(a, k / 2);
    return half * half;
  } else {
    return a * exp(a, k - 1);
  }
}

Modint inv(Modint a) { return exp(a, MOD - 2); }

ostream &operator<<(ostream &out, Modint p) {
  out << p.val;
  return out;
}

typedef pair<int, int> interval;
#define l first
#define r second

const int MAX_Q = 1e5 + 5;

interval qs[MAX_Q];
set<int> rs[MAX_Q];
Modint sub[MAX_Q];

Modint A[MAX_Q];
Modint B[MAX_Q];

int main() {
  ios::sync_with_stdio(false);

  string s;
  cin >> s;

  int qc;
  cin >> qc;

  for (int i = 0; i < qc; i++) {
    cin >> qs[i].l >> qs[i].r;
    qs[i].l--;
    qs[i].r--;
  }

  if ((int)s.size() % 2 == 1) {
    int mid = (int)s.size() / 2;
    string t;
    for (int i = 0; i < (int)s.size(); i++) {
      if (i != mid) {
        t += s[i];
      }
    }
    s = t;

    for (int i = 0; i < qc; i++) {
      if (qs[i].l > mid) {
        qs[i].l--;
      }

      if (qs[i].r >= mid) {
        qs[i].r--;
      }
    }
  }

  int n = s.size();
  int m = n / 2;

  for (int i = 0; i < qc; i++) {
    if (qs[i].l <= qs[i].r) {
      int l = qs[i].l;
      int r = qs[i].r;

      int flips = 0;
      if (l >= m) {
        l = n - l - 1;
        flips++;
      }
      if (r >= m) {
        r = n - r - 1;
        flips++;
      }
      if (l > r)
        swap(l, r);
      if (flips == 1) {
        r--;
      }

      if (l <= r) {
        rs[l].insert(r);
      }
    }
  }

  for (int i = 0; i < m; i++) {
    A[i] = Modint(s[i] - 'a');
  }

  for (int i = 0; i < m; i++) {
    B[i] = Modint(s[n - i - 1] - 'a');
  }

  Modint cur(0);
  for (int i = 0; i < m; i++) {
    cur -= sub[i];
    Modint need = B[i] - (A[i] + cur);
    bool can = !rs[i].empty();

    if (can) {
      int nl = *rs[i].begin() + 1;
      rs[i].erase(nl - 1);

      for (int r : rs[i]) {
        if (r >= nl) {
          rs[nl].insert(r);
        }
      }

      cur += need;
      sub[nl] += need;
    } else if (need != Modint(0)) {
      failure();
    }
  }

  cout << "YES" << endl;
}

#include <iostream>
#include <set>
#include <vector>

using namespace std;

void failure() {
  cout << "NO" << endl;
  exit(0);
}

typedef long long ll;

const int MOD = 26; // change if needed

struct Modint {
  ll val;

  Modint(ll _val = 0) : val(_val % MOD) {}

  Modint operator+(Modint other) const { return Modint(val + other.val); }

  void operator+=(Modint other) {
    val += other.val;
    val %= MOD;
  }

  Modint operator-() const { return Modint(MOD - val); }

  Modint operator-(Modint other) const { return Modint(val + MOD - other.val); }

  void operator-=(Modint other) {
    val += MOD - other.val;
    val %= MOD;
  }

  Modint operator*(Modint other) const { return Modint(val * other.val); }

  void operator*=(Modint other) {
    val *= other.val;
    val %= MOD;
  }

  bool operator==(Modint other) const { return val == other.val; }

  bool operator!=(Modint other) const { return val != other.val; }
};

Modint exp(Modint a, int k) {
  if (k == 0) {
    return Modint(1);
  } else if (k % 2 == 0) {
    Modint half = exp(a, k / 2);
    return half * half;
  } else {
    return a * exp(a, k - 1);
  }
}

Modint inv(Modint a) { return exp(a, MOD - 2); }

ostream &operator<<(ostream &out, Modint p) {
  out << p.val;
  return out;
}

typedef pair<int, int> interval;
#define l first
#define r second

const int MAX_Q = 1e5 + 5;

interval qs[MAX_Q];
set<int> *rs[MAX_Q];
Modint sub[MAX_Q];

Modint A[MAX_Q];
Modint B[MAX_Q];

set<int> *merge(set<int> *p, set<int> *q) {
  if (p->size() < q->size()) {
    swap(p, q);
  }

  for (auto it = q->begin(); it != q->end(); it++) {
    p->insert(*it);
  }
  return p;
}

int main() {
  ios::sync_with_stdio(false);

  string s;
  cin >> s;

  int qc;
  cin >> qc;

  for (int i = 0; i < qc; i++) {
    cin >> qs[i].l >> qs[i].r;
    qs[i].l--;
    qs[i].r--;
  }

  if ((int)s.size() % 2 == 1) {
    int mid = (int)s.size() / 2;
    string t;
    for (int i = 0; i < (int)s.size(); i++) {
      if (i != mid) {
        t += s[i];
      }
    }
    s = t;

    for (int i = 0; i < qc; i++) {
      if (qs[i].l > mid) {
        qs[i].l--;
      }

      if (qs[i].r >= mid) {
        qs[i].r--;
      }
    }
  }

  int n = s.size();
  int m = n / 2;

  for (int i = 0; i < n; i++) {
    rs[i] = new set<int>();
  }

  for (int i = 0; i < qc; i++) {
    if (qs[i].l <= qs[i].r) {
      int l = qs[i].l;
      int r = qs[i].r;

      int flips = 0;
      if (l >= m) {
        l = n - l - 1;
        flips++;
      }
      if (r >= m) {
        r = n - r - 1;
        flips++;
      }
      if (l > r)
        swap(l, r);
      if (flips == 1) {
        r--;
      }

      if (l <= r) {
        rs[l]->insert(r);
      }
    }
  }

  for (int i = 0; i < m; i++) {
    A[i] = Modint(s[i] - 'a');
  }

  for (int i = 0; i < m; i++) {
    B[i] = Modint(s[n - i - 1] - 'a');
  }

  Modint cur(0);
  for (int i = 0; i < m; i++) {
    cur -= sub[i];
    Modint need = B[i] - (A[i] + cur);
    bool can = !rs[i]->empty();

    if (can) {
      int nl = *(rs[i]->begin()) + 1;
      rs[i]->erase(nl - 1);
      rs[nl] = merge(rs[i], rs[nl]);

      cur += need;
      sub[nl] += need;
    } else if (need != Modint(0)) {
      failure();
    }
  }

  cout << "YES" << endl;
}


#include <algorithm>
#include <bitset>
#include <cassert>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <iomanip>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <string>
#include <vector>
using namespace std;

typedef pair<int, int> P;
#define rep(i, n) for (int i = 0; i < (n); i++)
#define all(c) (c).begin(), (c).end()
#define uniq(c) c.erase(unique(all(c)), (c).end())
#define index(xs, x) (int)(lower_bound(all(xs), x) - xs.begin())
#define _1 first
#define _2 second
#define pb push_back
#define INF 1145141919
#define MOD 1000000007
int U[100001];
set<int> R[100001];

int find(int x) {
  if (U[x] == x)
    return x;
  return U[x] = find(U[x]);
}

void unite(int x, int y) {
  x = find(x), y = find(y);
  if (x == y)
    return;
  if (R[x].size() < R[y].size())
    swap(x, y);
  U[y] = x;
  for (int e : R[y])
    R[x].insert(e);
  R[y].clear();
}

bool same(int x, int y) { return find(x) == find(y); }
inline int mins(int v) { return (26 - (v % 26)) % 26; }

int N, M;
string S;
int A[100001];
bool done[100001];
void add(int p, int v) {
  v = (26 + v) % 26;
  A[p] = (A[p] + v) % 26;
}
bool go(int pos, int v) {
  v = (26 + v) % 26;
  if (R[find(pos)].empty())
    return false;
  int a = A[pos];
  int left = *R[find(pos)].begin(), right = *R[find(pos)].rbegin();
  if (!done[left]) {
    add(left, a - v);
    add(pos, v - a);
    assert(A[pos] == v);
    return true;
  }
  if (!done[right]) {
    add(right, a - v);
    add(pos, v - a);
    assert(A[pos] == v);
    return true;
  }
  return false;
}

signed main() {
  ios::sync_with_stdio(false);
  cin.tie(0);
  cin >> S >> M;
  N = S.length();
  rep(i, N + 1) U[i] = i, R[i].insert(i);
  rep(i, M) {
    int l, r;
    cin >> l >> r;
    l--;
    unite(l, r);
  }
  rep(i, N) A[i] = S[i] - (i > 0 ? S[i - 1] : 'a');
  rep(i, N) A[i] = ((A[i] % 26) + 26) % 26;
  A[N] = 0;
  N++;
  if (N % 2 == 1) {
    int pos = (N - 1) / 2;
    // pos -> 0
    if (A[pos] != 0) {
      if (!go(pos, 0)) {
        cout << "NO\\n";
        return 0;
      }
    }
    done[pos] = true;
  }
  for (int p = N / 2 - 1; p >= 1; p--) {
    int right = N - 1 - p;
    done[p] = done[right] = true;
    if (A[p] == mins(A[right]))
      continue;
    if (go(p, -A[right]) || go(right, -A[p])) {
      unite(p, right);
    } else {
      cout << "NO\\n";
      return 0;
    }
  }
  cout << "YES\\n";
  return 0;
}

#include <algorithm>
#include <bitset>
#include <cassert>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <iomanip>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <string>
#include <vector>
using namespace std;

typedef pair<int, int> P;
#define rep(i, n) for (int i = 0; i < (n); i++)
#define all(c) (c).begin(), (c).end()
#define uniq(c) c.erase(unique(all(c)), (c).end())
#define index(xs, x) (int)(lower_bound(all(xs), x) - xs.begin())
#define _1 first
#define _2 second
#define pb push_back
#define INF 1145141919
#define MOD 1000000007
int U[100001];
set<int> R[100001];

int find(int x) {
  if (U[x] == x)
    return x;
  return U[x] = find(U[x]);
}

void unite(int x, int y) {
  x = find(x), y = find(y);
  if (x == y)
    return;
  if (R[x].size() < R[y].size())
    swap(x, y);
  U[y] = x;
  for (int e : R[y])
    R[x].insert(e);
  R[y].clear();
}

bool same(int x, int y) { return find(x) == find(y); }
inline int mins(int v) { return (26 - (v % 26)) % 26; }

int N, M;
string S;
int A[100001];
bool done[100001];
void add(int p, int v) {
  v = (26 + v) % 26;
  A[p] = (A[p] + v) % 26;
}
bool go(int pos, int v) {
  v = (26 + v) % 26;
  if (R[find(pos)].empty())
    return false;
  int a = A[pos];
  int left = *R[find(pos)].begin(), right = *R[find(pos)].rbegin();
  if (!done[left]) {
    add(left, a - v);
    add(pos, v - a);
    assert(A[pos] == v);
    return true;
  }
  if (!done[right]) {
    add(right, a - v);
    add(pos, v - a);
    assert(A[pos] == v);
    return true;
  }
  return false;
}

signed main() {
  ios::sync_with_stdio(false);
  cin.tie(0);
  cin >> S >> M;
  N = S.length();
  rep(i, N + 1) U[i] = i, R[i].insert(i);
  rep(i, M) {
    int l, r;
    cin >> l >> r;
    l--;
    unite(l, r);
  }
  rep(i, N) A[i] = S[i] - (i > 0 ? S[i - 1] : 'a');
  rep(i, N) A[i] = ((A[i] % 26) + 26) % 26;
  A[N] = 0;
  N++;
  for (int p = N / 2 - 1; p >= 0; p--) {
    int right = N - 1 - p;
    unite(p, right);
  }
  if (N % 2 == 1) {
    int pos = (N - 1) / 2;
    // pos -> 0
    done[pos] = true;
    if (A[pos] != 0) {
      if (!go(pos, 0)) {
        cout << "NO\\n";
        return 0;
      }
    }
  }
  int hoge = N / 2;
  for (int p = N / 2 - 1; p >= 1; p--) {
    int right = N - 1 - p;
    done[p] = done[right] = true;
    if (A[p] == mins(A[right]))
      continue;
    if (go(p, mins(A[right])) || go(right, mins(A[p]))) {
    } else {
      cout << "NO\\n";
      return 0;
    }
  }
  cout << "YES\\n";
  return 0;
}