#include <bits/stdc++.h>

using namespace std;

vector<vector<long long> > g;
long long n, m, a, b;
vector<bool> used;

void dfs(long long u, long long c){
    if(u == c)
        return;
    used[u] = 1;
    for(long long i = 0; i < g[u].size(); ++i)
        if(!used[g[u][i]])
            dfs(g[u][i], c);
}

int main()
{
    long long t; cin >> t;
    for(long long q = 0; q < t; ++q){
        cin >> n >> m >> a >> b;
        --b, --a;
        g.assign(n, vector<long long> ());
        used.assign(n, 0);
        for(long long i = 0; i < m; ++i){
            long long x, y; cin >> x >> y;
            --x, --y;
            g[x].push_back(y);
            g[y].push_back(x);
        }
        long long cnt = 0, cnt1 = 0;
        dfs(b, a);
        for(long long i = 0; i < n; ++i)
            if(!used[i] && i != a)
                ++cnt;
        used.assign(n, 0);
        dfs(a, b);
        for(long long i = 0; i < n; ++i)
            if(!used[i] && i != b)
                ++cnt1;
        cout << cnt1 * cnt << '\n';
    }
    return 0;
}


#include <bits/stdc++.h>

#define ll long long
#define ld long double
#define all(x) x.begin(),x.end()
#define fori(n) for (int i = 0; i < n; ++i)
#define forj(n) for (int j = 0; j < n; j++)
#define ss second
#define ff first
#define pb push_back

//#pragma GCC optimize("Ofast", "unroll-loops", "fast-math", "O3")
#define fast ios_base::sync_with_stdio(0);cin.tie(0);cout.tie(0);
using namespace std;

const ll mod = 1e9 + 9;
const ll p = 179;
const ll INF = 1e9 + 9;
vector<int> g[200000];
bool us[200000];
int cnt = 0;

void dfs(int v, int b) {
    us[v] = true;
    cnt++;
    for (auto i : g[v]) {
        if (i == b)
            continue;
        if (us[i])
            continue;
        dfs(i, b);
    }
}

void solve() {
    int n, m, a, b;
    cin >> n >> m >> a >> b;
    a--;
    b--;
    for (int i = 0; i < n; i++) {
        us[i] = false;
        g[i].clear();
    }
    for (int i = 0; i < m; i++) {
        int a, b;
        cin >> a >> b;
        g[--a].emplace_back(--b);
        g[b].emplace_back(a);
    }
    cnt = 0;
    dfs(a, b);
    ll A = n - cnt - 1;
    for (int i = 0; i < n; i++) {
        us[i] = false;
    }
    cnt = 0;
    dfs(b, a);
    ll B = n - cnt - 1;
    cout << A * B;
}

int main() {
    fast
    int t;
    cin >> t;
    while (t--) {
        solve();
        cout << '\n';
    }
}
//
// 1 3 5


#include <bits/stdc++.h>

using namespace std;
// #define int long long
mt19937 rnd(time(0));
typedef long long ll;
typedef long double ld;

// #define _GLIBCXX_DEBUG
#define f first
#define s second
#define pb push_back
#define pii pair<int, int>
#define vi vector<int>
#define int ll

void solve(){
    int n, m, a, b;
    cin >> n >> m >> a >> b;
    vector<vi> r(n);
    for (int i = 0; i < m; ++i) {
        int x, y;
        cin >> x >> y;
        x--;
        y--;
        r[x].pb(y);
        r[y].pb(x);
    }
    queue<int> q;
    int d[n], d2[n];
    a--;
    b--;
    memset(d, 127, sizeof(d));
    memset(d2, 127, sizeof(d2));
    int lol = d[0];
    d[a] = 0;
    d2[b] = 0;
    q.push(a);
    while (q.size()) {
        auto x = q.front();
        q.pop();
        for (auto &u : r[x]) {
            if (u == b)
                continue;
            if (d[u] > d[x] + 1) {
                d[u] = d[x] + 1;
                q.push(u);
            }
        }
    }
    q.push(b);
    while (q.size()) {
        auto x = q.front();
        q.pop();
        for (auto &u : r[x]) {
            if (u == a)
                continue;
            if (d2[u] > d2[x] + 1) {
                d2[u] = d2[x] + 1;
                q.push(u);
            }
        }
    }
    int x = 0, y = 0;
    for (int i = 0; i < n; ++i) {
        if (i == a || i == b)
            continue;

        if (d[i] < lol && d2[i] >= lol) {
            x++;
        } else if(d2[i] <lol && d[i] >= lol) {
            y++;
        }
    }
    cout << x * y << endl;
}

signed main(){
    ios_base::sync_with_stdio(0);
    cin.tie(0);

    int t = 1;
    cin >> t;
    while(t--){
        solve();
    }

    return 0;
}


#include <bits/stdc++.h>
#include<ext/pb_ds/assoc_container.hpp>
using namespace __gnu_pbds;
using namespace std;
#define ll long long
#define st string
#define ld long double
#define fi first
#define se second
#define pb push_back
#define mk make_pair
#define endl '\n'

void file() {
    ios_base::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
//    freopen ("milkvisits.in", "r", stdin); freopen ("milkvisits.out", "w", stdout);
}

const ll N = 2e5 + 7;
const ll MOD = 1e9 + 7;

ll n, m, k, l, a[N], used[5][N], p;
vector <ll> v[N];

void bfs1 (ll x) {
    queue <ll> q;
    q.push(x);
    while (q.size()) {
        x = q.front();
        q.pop();
        for (auto i : v[x]) {
//            cout << 1 << "    " << x << " " << i << " " << used[1][i] << endl;
            if (i != l + p && !used[1][i]) q.push(i), used[1][i]++;
        }
    }
}

void bfs2 (ll x) {
    queue <ll> q;
    q.push(x);
    while (q.size()) {
        x = q.front();
        q.pop();
        for (auto i : v[x]) {
//            cout << 2 << "    " << x << " " << i << " " << used[2][i] << endl;
            if (i != k + p && !used[2][i]) q.push(i), used[2][i]++;
        }
    }
}

void bfs (ll x) {
    queue <ll> q;
    q.push(x);
    while (q.size()) {
        ll x = q.front();
        q.pop();
        for (auto i : v[x]) {
            if (!used[3][i]) q.push(i), used[3][i]++;
        }
    }
}

int main()
{
    file();
    ll nn;
    cin >> nn;
    while (nn--) {
        cin >> n >> m >> k >> l;
        --k, --l;
        for (int i = 0; i < m; ++i) {
            ll x, y;
            cin >> x >> y;
            x = p + x - 1; y = p + y - 1;
//            cout << x << " " << y << endl;
            v[x].pb(y);
            v[y].pb(x);
        }
//        cout << k + p << " " << l + p << endl;
//        for (int i = 0; i < n; ++i) {
//            cout << i + p << " " << used[1][i + p] << " " << used[2][i + p] << endl;
//        }
        bfs1(k + p); bfs2(l + p); bfs(k + p);
        ll x, y;
        x = y = 0;
        for (int i = 0; i < n; ++i) {
//            cout << i + p << " " << used[1][i + p] << " " << used[2][i + p] << " " << used[3][i + p] << endl;
            if (!used[3][i + p] || i == k || i == l) continue;
            if (!used[1][i + p] && used[2][i + p]) ++x;
            if (used[1][i + p] && !used[2][i + p]) ++y;
        }
        p += n;
        cout << x * y << endl;
//        cout << endl;
    }
}

/**
1
5
10
01
010
100
001

01
10
010
001
100

1
4
0001
1000
0010
1001
*/


#include <bits/stdc++.h>

using namespace std;

void QuickStart(){
    ios_base::sync_with_stdio(0); cin.tie(0);
}

typedef long long ll;

vector<vector<int> >g;
vector<bool>used;
long long to = 0, to1 = 0;

void dfs(int v, int no){
    to++;
    used[v] = 1;
    for(int i = 0; i < g[v].size(); i++){
        if(!used[g[v][i]] && g[v][i] != no){
            dfs(g[v][i], no);
        }
    }
}

void solve(){
    int n, m, x, y;
    cin >> n >> m >> x >> y;
    g.assign(n, vector<int>());
    used.assign(n, 0);
    to = 0;
    for(int i = 0; i < m; i++){
        int a, b;
        cin >> a >> b;
        g[a - 1].push_back(b - 1);
        g[b - 1].push_back(a - 1);
    }
    to = 0;
    dfs(y - 1, x - 1);
    ll ans1 = n - to;
    used.assign(n, 0);
    to = 0;
    dfs(x - 1, y - 1);
    ll ans2 = n - to;
    cout << (ans1 - 1) * (ans2 - 1) << endl;
}

int main()
{
    QuickStart();
    int t; cin >> t;
    for(int i = 0; i < t; i++){
        solve();
    }
    return 0;
}


#define _CRT_SECURE_NO_WARNINGS
#define pii pair<int, int>
#define pll pair<long, long>
#define pss pair<string, string>
#define forn(n,i) for (int i = 0; i < n; i++)
#define fordown(n,i) for (int i = n - 1; i >= 0; --i)
#define sorted(a) sort(a.begin(), a.end())
#define mp(x, y) make_pair(x, y)

#include <iostream>
#include <algorithm>
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include <cmath>
#include <string>
#include <string.h>
#include <vector>
#include <stack>
#include <queue>
#include <deque>
#include <set>
#include <map>
#include <bitset>
#include <time.h>
#include <random>

using namespace std;

typedef long long ll;
typedef double db;
typedef long double ldb;

set <ll> sa;
set <ll> sb;
ll n, m, a, b;
ll x, y;
vector<int> used;
ll t;
vector <ll> gs[200100];
void dfsa(ll x) {
	used[x] = 1;
	forn(gs[x].size(), i) {
		if (gs[x][i] != b && used[gs[x][i]] != 1) {
			sa.insert(gs[x][i]);
			dfsa(gs[x][i]);
		}
	}
}
void dfsb(ll x) {
	used[x] = 1;
	forn(gs[x].size(), i) {
		if (gs[x][i] != a && used[gs[x][i]] != 1) {
			sb.insert(gs[x][i]);
			dfsb(gs[x][i]);
		}
	}
}

int main() {
//	freopen("input.txt", "r", stdin); freopen("output.txt", "w", stdout);
	cin >> t;
	int prev = 0;
	forn(t, ind) {

		cin >> n >> m >> a >> b;
		for (int i = 0; i < prev; i++) {
			gs[i].clear();
		}
		used.assign(n + 1, 0);
		a--; b--;
		prev = n;
		forn(m, i) {
			cin >> x >> y;
			x--; y--;
			gs[x].push_back(y);
			gs[y].push_back(x);
		}
		sa.clear();
		sb.clear();
		//memset(used, 0, sizeof(used));
		dfsa(a);
		used.assign(n + 1, 0);
	//	memset(used, 0, sizeof(used));
		dfsb(b);
		ll cola = 0;
		ll colb = 0;
		for (auto i : sa) {
			if (sb.find(i) == sb.end()) {
				cola += 1;
			}
		}
		for (auto i : sb) {
			if (sa.find(i) == sa.end()) {
				colb += 1;
			}
		}
		cout << cola * colb << endl;
	}
}


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

#define int long long

using namespace std;

vector<int> g[200000];
bool used[200000];
int num;

void dfs(int v)
{
    used[v] = true;
    num++;
    for (int i = 0; i < g[v].size(); i++)
    {
        if (!used[g[v][i]])
        {
            dfs(g[v][i]);
        }
    }
}

signed main() {
    int t;
    cin >> t;
    for (int q = 0; q < t; q++)
    {
        int n, m, a, b;
        cin >> n >> m >> a >> b;
        a--;
        b--;
        for (int i = 0; i < m; i++)
        {
            int f, t;
            cin >> f >> t;
            f--;
            t--;
            g[f].push_back(t);
            g[t].push_back(f);
        }

        used[a] = true;
        int cnt = 0;
        for (int i = 0; i < n; i++)
        {
            if (!used[i])
            {
                cnt++;
                dfs(i);
            }
        }
        if (cnt == 1)
        {
            cout << 0 << '\n';
            for (int i = 0; i < n; i++)
            {
                g[i].clear();
                used[i] = false;
            }
            continue;
        }
        for (int i = 0; i < n; i++)
        {
            used[i] = false;
        }

        used[b] = true;
        cnt = 0;
        for (int i = 0; i < n; i++)
        {
            if (!used[i])
            {
                cnt++;
                dfs(i);
            }
        }
        if (cnt == 1)
        {
            cout << 0 << '\n';
            for (int i = 0; i < n; i++)
            {
                g[i].clear();
                used[i] = false;
            }
            continue;
        }
        for (int i = 0; i < n; i++)
        {
            used[i] = false;
        }

        int m1 = 0, m2 = 0;

        used[a] = true;
        num = 0;
        dfs(b);
        m1 = n - num - 1;
        for (int i = 0; i < n; i++)
        {
            used[i] = false;
        }

        used[b] = true;
        num = 0;
        dfs(a);
        m2 = n - num - 1;
        for (int i = 0; i < n; i++)
        {
            g[i].clear();
            used[i] = false;
        }

        cout << m1 * m2 << '\n';
    }
    return 0;
}


//lxrtxdy!
#include <bits/stdc++.h>

using namespace std;

long long C[777][777];

int r, c;
long long total;
long long best = (long long) 1e18, best_z = -1;

void dfs(long long x, long long y, int v1, int v2) {
  long long diff = abs(x - y);
  if (best <= 1 || diff - C[v1][r] * C[v2][r] >= best) {
    return;
  }
  if (v1 == r - 1 && v2 == r - 1) {
    long long diff = abs(x - y);
    if (diff < best) {
      best = diff;
      best_z = x;
    }
    return;
  }
  if (v1 >= r) {
    long long cur1 = C[v1][r] - C[v1 - 1][r];
    long long sum2 = C[v2][r];
    dfs(x, y + cur1 * sum2, v1 - 1, v2);
  }
  if (v2 >= r) {
    long long sum1 = C[v1][r];
    long long cur2 = C[v2][r] - C[v2 - 1][r];
    dfs(x + sum1 * cur2, y, v1, v2 - 1);
  }
}

char s[12345];
int cntA[12345], cntB[12345];
map<long long, long long> mp;

long long solve(long long x, long long y, int v1, int v2) {
  long long state = x * 10000 + v1 * 100 + v2;
  if (mp.find(state) != mp.end()) {
    return mp[state];
  }
  long long &res = mp[state];
  long long diff = abs(x - y);
  if (diff - C[v1][r] * C[v2][r] > best) {
    return res = 0;
  }
  if (v1 < r || v2 < r) {
    if (v1 >= cntA[v1 + v2] && v2 >= cntB[v1 + v2]) {
      int sum = v1 + v2;
      v1 -= cntA[sum];
      v2 -= cntB[sum];
      return res = C[v1 + v2][v1];
    }
    return res = 0;
  }
  res = 0;
  char c = s[v1 + v2 - 1];
  if (c != 'B') {
    long long cur1 = C[v1][r] - C[v1 - 1][r];
    long long sum2 = C[v2][r];
    res += solve(x, y + cur1 * sum2, v1 - 1, v2);
  }
  if (c != 'A') {
    long long sum1 = C[v1][r];
    long long cur2 = C[v2][r] - C[v2 - 1][r];
    res += solve(x + sum1 * cur2, y, v1, v2 - 1);
  }
  return res;
}

int main() {
  scanf("%d %d", &r, &c);
  for (int i = 0; i <= 2 * (r + c); i++) {
    for (int j = 0; j <= 2 * (r + c); j++) {
      if (j == 0) C[i][j] = 1; else
      if (i == 0) C[i][j] = 0;
      else C[i][j] = (C[i - 1][j] + C[i - 1][j - 1]);
    }
  }
  total = C[r + c][r] * C[r + c][r];
  {
    long long x = 0, y = 0;
    int v1 = r + c, v2 = r + c;
    while (v1 >= r && v2 >= r) {
      if (x > y) {
        long long cur1 = C[v1][r] - C[v1 - 1][r];
        long long sum2 = C[v2][r];
        y += cur1 * sum2;
        v1--;
      } else {
        long long sum1 = C[v1][r];
        long long cur2 = C[v2][r] - C[v2 - 1][r];
        x += sum1 * cur2;
        v2--;
      }
    }
    best = abs(x - y);
  }
  dfs(0, 0, r + c, r + c);
  scanf("%s", s);
  cntA[0] = cntB[0] = 0;
  for (int i = 0; i < 2 * (r + c); i++) {
    cntA[i + 1] = cntA[i] + (s[i] == 'A');
    cntB[i + 1] = cntB[i] + (s[i] == 'B');
  }
  long long ans = solve(0, 0, r + c, r + c);
  cout << ans << endl;
  return 0;
}
//orzlxr!


#include <bits/stdc++.h>

using namespace std;

long long C[777][777];

int r, c;
long long total;
long long best = (long long) 1e18, best_z = -1;

void dfs(long long x, long long y, int v1, int v2)
{
	long long diff = abs(x - y);
	if (best <= 1 || diff - C[v1][r] * C[v2][r] >= best)
		return;

  if (v1 == r - 1 && v2 == r - 1)
  {
    long long diff = abs(x - y);
    if (diff < best) {
      best = diff;
      best_z = x;
    }
    return;
  }
	if (v1 >= r)
		{
    	long long cur1 = C[v1][r] - C[v1 - 1][r];
		long long sum2 = C[v2][r];
    	dfs(x, y + cur1 * sum2, v1 - 1, v2);
	}
	if (v2 >= r)
	{
		long long sum1 = C[v1][r];
		long long cur2 = C[v2][r] - C[v2 - 1][r];
		dfs(x + sum1 * cur2, y, v1, v2 - 1);
	}
}

char s[12345];
int cntA[12345], cntB[12345];
map<long long, long long> mp;

long long solve(long long x, long long y, int v1, int v2)
{
	long long state = x * 10000 + v1 * 100 + v2;
	if(mp.find(state) != mp.end())
		return mp[state];

  long long &res = mp[state];
  long long diff = abs(x - y);
  if (diff - C[v1][r] * C[v2][r] > best) {
    return res = 0;
  }
  if (v1 < r || v2 < r) {
    if (v1 >= cntA[v1 + v2] && v2 >= cntB[v1 + v2]) {
      int sum = v1 + v2;
      v1 -= cntA[sum];
      v2 -= cntB[sum];
      return res = C[v1 + v2][v1];
    }
    return res = 0;
  }
	res = 0;
	char c = s[v1 + v2 - 1];
	if (c != 'B')
	{
		long long cur1 = C[v1][r] - C[v1 - 1][r];
		long long sum2 = C[v2][r];
		res += solve(x, y + cur1 * sum2, v1 - 1, v2);
	}
	if (c != 'A')
	{
		long long sum1 = C[v1][r];
		long long cur2 = C[v2][r] - C[v2 - 1][r];
		res += solve(x + sum1 * cur2, y, v1, v2 - 1);
	}
	return res;
}

int main() {
  scanf("%d %d", &r, &c);
  for (int i = 0; i <= 2 * (r + c); i++) {
    for (int j = 0; j <= 2 * (r + c); j++) {
      if (j == 0) C[i][j] = 1; else
      if (i == 0) C[i][j] = 0;
      else C[i][j] = (C[i - 1][j] + C[i - 1][j - 1]);
    }
  }
  total = C[r + c][r] * C[r + c][r];
  {
    long long x = 0, y = 0;
    int v1 = r + c, v2 = r + c;
    while (v1 >= r && v2 >= r) {
      if (x > y) {
        long long cur1 = C[v1][r] - C[v1 - 1][r];
        long long sum2 = C[v2][r];
        y += cur1 * sum2;
        v1--;
      } else {
        long long sum1 = C[v1][r];
        long long cur2 = C[v2][r] - C[v2 - 1][r];
        x += sum1 * cur2;
        v2--;
      }
    }
    best = abs(x - y);
  }
  dfs(0, 0, r + c, r + c);
  scanf("%s", s);
  cntA[0] = cntB[0] = 0;
  for (int i = 0; i < 2 * (r + c); i++) {
    cntA[i + 1] = cntA[i] + (s[i] == 'A');
    cntB[i + 1] = cntB[i] + (s[i] == 'B');
  }
  long long ans = solve(0, 0, r + c, r + c);
  cout << ans << endl;
  return 0;
}


#include <bits/stdc++.h>
#ifndef ONLINE_JUDGE
# include <sys/time.h>
# include <sys/resource.h>
#endif

/*** TEMPLATE CODE STARTS HERE ***/

#ifndef M_PI
#define M_PI 3.1415926535897932384626433832795028841971693993751
#endif

using namespace std;

typedef vector<string> vs;
typedef long long ll;
typedef complex<double> pnt;
typedef vector<int> vi;
typedef vector<ll> vll;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;

#define RA(x) begin(x), end(x)
#define FE(i, x) for (auto i = begin(x); i != end(x); ++i)
#define SZ(x) ((ll) (x).size())

template<class T>
void splitstr(const string &s, vector<T> &out)
{
    istringstream in(s);
    out.clear();
    copy(istream_iterator<T>(in), istream_iterator<T>(), back_inserter(out));
}

template<class T> T gcd(T a, T b) { return b ? gcd(b, a % b) : a; }

static void redirect(int argc, const char **argv)
{
#ifndef ONLINE_JUDGE
    struct rlimit rlim;
    getrlimit(RLIMIT_STACK, &rlim);
    rlim.rlim_cur = 256 * 1024 * 1024;
    setrlimit(RLIMIT_STACK, &rlim);
#ifndef __SANITIZE_ADDRESS__
    getrlimit(RLIMIT_DATA, &rlim);
    rlim.rlim_cur = 256 * 1024 * 1024;
    setrlimit(RLIMIT_DATA, &rlim);
#endif
#endif

    ios::sync_with_stdio(false);
    cin.tie(NULL);
    if (argc > 1)
    {
        static filebuf f;
        f.open(argv[1], ios::in);
        cin.rdbuf(&f);
        if (!cin)
        {
            cerr << "Failed to open '" << argv[1] << "'" << endl;
            exit(1);
        }
    }

    if (argc > 2)
    {
        static filebuf f;
        f.open(argv[2], ios::out | ios::trunc);
        cout.rdbuf(&f);
        if (!cout)
        {
            cerr << "Failed to open '" << argv[2] << "'" << endl;
        }
    }
}

/*** TEMPLATE CODE ENDS HERE */

static vector<vll> chooset;

static ll choose(int n, int r)
{
    assert(n <= SZ(chooset));
    if (r < 0 || r > n)
        return 0;
    else
        return chooset[n][r];
}

static int R, C;

static ll bit(int x)
{
    return 1LL << x;
}

static void recurse(int L, int N, int a, int na, ll req, ll excl, ll cur, vll &sums)
{
    if (na > N - L)
        return;
    else if (L == N)
    {
        sums.push_back(cur);
        return;
    }

    ll mask = bit(L);
    if (!(req & mask))
        recurse(L + 1, N, a, na, req, excl, cur, sums);
    if (na > 0 && !(excl & mask))
    {
        ll nxt = cur + choose(a, R - 1) * choose(L - a, R);
        recurse(L + 1, N, a + 1, na - 1, req, excl, nxt, sums);
    }
}

static pll solve(const string &pattern)
{
    int N = SZ(pattern);
    ll base = 0;
    for (int i = 0; i < R + C; i++)
        base += choose(i, R - 1) * choose(N - i - 1, R);
    ll unfair = LLONG_MAX;
    ll trg = 2 * base - choose(N, 2 * R);

    ll req = 0, excl = 0;
    ll ans = 0;
    for (int i = 0; i < N; i++)
    {
        if (pattern[i] == 'A')
            req |= bit(i);
        else if (pattern[i] == 'B')
            excl |= bit(i);
    }

    vector<vll> dp(R + C + 1, vll(R + C + 1));
    dp[0][0] = 1;
    for (int j = 0; j <= R + C; j++)
        for (int k = 0; k <= R + C; k++)
        {
            if (j >= R - 1 && k >= R)
                break;
            if (j < R + C && pattern[j + k] != 'B')
                dp[j + 1][k] += dp[j][k];
            if (k < R + C && pattern[j + k] != 'A')
                dp[j][k + 1] += dp[j][k];
        }

    int M = N - C;
    vector<vll> asums2(R + C + 1);
    for (int al = R - 1; al <= R + C; al++)
    {
        recurse(M, N, al, R + C - al, req, excl, 0, asums2[al]);
        sort(RA(asums2[al]), greater<ll>());
    }
    for (int a = R - 1; a <= R + C; a++)
        for (int b = R; b <= R + C; b++)
        {
            if (a > R - 1 && b > R)
                continue;
            if (dp[a][b] == 0)
                continue;
            int L = a + b;
            for (int l = 0; l <= M - L; l++)
            {
                int r = R + C - a - l;
                if (r > N - M || r < 0)
                    continue;
                vll sums1;
                recurse(L, M, a, l, req, excl, 0, sums1);
                auto &sums2 = asums2[a + l];
                sort(RA(sums1));
                int p = 0, q = 0;
                int p2 = 0, q2 = 0;
                while (p < SZ(sums1) && q < SZ(sums2))
                {
                    while (p2 < SZ(sums1) && sums1[p2] == sums1[p])
                        p2++;
                    while (q2 < SZ(sums2) && sums2[q2] == sums2[q])
                        q2++;
                    ll total = 2 * (sums1[p] + sums2[q]);
                    ll diff = llabs(total - trg);
                    if (diff < unfair)
                    {
                        unfair = diff;
                        ans = 0;
                    }
                    if (diff == unfair)
                        ans += ll(p2 - p) * ll(q2 - q) * dp[a][b];
                    if (total > trg)
                        q = q2;
                    else
                        p = p2;
                }
            }
        }
    return pll(unfair, ans);
}

int main(int argc, const char **argv)
{
    redirect(argc, argv);
    string pattern;
    cin >> R >> C >> pattern;
    int N = 2 * (R + C);
    chooset.resize(N + 1);
    for (int i = 0; i <= N; i++)
    {
        chooset[i].resize(i + 1);
        chooset[i][0] = chooset[i][i] = 1;
        for (int j = 1; j < i; j++)
            chooset[i][j] = chooset[i - 1][j - 1] + chooset[i - 1][j];
    }

    pll opt = solve(string(N, '?'));
    pll score = solve(pattern);
    // cerr << opt.first << ' ' << opt.second << ' ' << score.first << ' ' << score.second << '\n';
    if (score.first == opt.first)
        cout << score.second << '\n';
    else
        cout << "0\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 ctz __builtin_ctz
#define bcnt __builtin_popcount

template<typename T> inline bool chkmin(T &a, const T &b) { return a > b ? 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 = 70;

const int maxn = 50;

const int lim = 22;

LL C[maxN + 5][maxN + 5];

inline void prepare()
{
	REP(i, 0, maxN)
	{
		C[i][0] = 1;
		REP(j, 1, i + 1)
		{
			C[i][j] = C[i - 1][j - 1] + C[i - 1][j];
		}
	}
}

int n, m, N;

int mid;
int g[maxN + 5];

vector<pair<LL, int> > partb[maxn + 5][maxn + 5];

void dfs_partb(int x, int cnta, int cntb, LL sum = 0)
{
	if (x == mid)
	{
		partb[cnta][cntb].pb(mp(sum, 1));
		return;
	}
	REP(i, 0, 2)
	{
		if (~g[x - 1] && i != g[x - 1]) continue;
		LL tmp = 0;
		if (i == 0)
		{
			if (cnta > 0)
			{
				REP(j, 0, n) tmp += C[cnta - 1][n - 1] * C[cntb][j] * C[N - x][n - j];
				dfs_partb(x - 1, cnta - 1, cntb, sum + tmp);
			}
		}
		else
		{
			if (cntb > 0)
			{
				REP(j, 0, n) tmp -= C[cntb - 1][n - 1] * C[cnta][j] * C[N - x][n - j];
				dfs_partb(x - 1, cnta, cntb - 1, sum + tmp);
			}
		}
	}
}

map<LL, LL> parta[maxn + 5][maxn + 5];

LL ans = LLONG_MAX, ans_cnt = 0;

inline void update(const LL &val, const LL &cnt)
{
	if (chkmin(ans, val)) ans_cnt = cnt;
	else if (val == ans) ans_cnt += cnt;
}

void bfs_parta()
{
	REP(i, 0, n + m + 1) REP(j, 0, n + m + 1) parta[i][j].clear();
	parta[0][0][0] = 1;
	REP(i, 0, n + m + 1) REP(j, 0, n + m + 1)
		for (auto u : parta[i][j])
		{
			if (i + j == mid)
			{
				int p = lower_bound(ALL(partb[i][j]), mp(-u.x, -1)) - partb[i][j].begin();
				if (p < SZ(partb[i][j])) update(abs(u.x + partb[i][j][p].x), u.y * partb[i][j][p].y);
				if (p)
				{
					update(abs(u.x + partb[i][j][p - 1].x), u.y * partb[i][j][p - 1].y);
				}
			}
			else
			{
				int p = i + j;
				REP(k, 0, 2)
				{
					if (~g[p] && k != g[p]) continue;
					int cnta = i, cntb = j;
					if (k == 0) ++cnta;
					else ++cntb;
					if (cnta <= n + m && cntb <= n + m)
					{
						LL tmp = 0;
						if (k == 0)
						{
							REP(l, 0, n) tmp += C[cnta - 1][n - 1] * C[cntb][l] * C[N - p - 1][n - l];
						}
						else
						{
							REP(l, 0, n) tmp -= C[cntb - 1][n - 1] * C[cnta][l] * C[N - p - 1][n - l];
						}
						parta[cnta][cntb][u.x + tmp] += u.y;
					}
				}
			}
		}
}

inline void work()
{
	REP(i, 0, n + m + 1) REP(j, 0, n + m + 1) partb[i][j].clear();
	dfs_partb(N, n + m, n + m);
	REP(i, 0, n + m + 1) REP(j, 0, n + m + 1)
	{
		sort(ALL(partb[i][j]));
		vector<pair<LL, int> > tmp;
		int sz = SZ(partb[i][j]);
		for (int k = 0; k < sz; )
		{
			LL cur = partb[i][j][k].x;
			int cnt = 0;
			while (k < sz && partb[i][j][k].x == cur) cnt += partb[i][j][k].y, ++k;
			tmp.pb(mp(cur, cnt));
		}
		partb[i][j] = tmp;
	}
	bfs_parta();
}

int main()
{
#ifdef matthew99
	freopen("input.txt", "r", stdin);
	freopen("output.txt", "w", stdout);
#endif
	prepare();
	static char s[maxN + 5];
	scanf("%d%d%s", &n, &m, s);
	N = (n + m) << 1;
	mid = max(0, N - lim);
	memset(g, -1, sizeof g);
	work();
	ans_cnt = 0;
	REP(i, 0, N) if (s[i] == 'A') g[i] = 0; else if (s[i] == 'B') g[i] = 1;
	work();
	cout << ans_cnt << endl;
	return 0;
}


#include <bits/stdc++.h>
using namespace std;
long long C[777][777];
int r, c;
long long total;
long long best = (long long) 1e18, best_z = -1;
void dfs(long long x, long long y, int v1, int v2)
{
	long long diff = abs(x - y);
	if (best <= 1 || diff - C[v1][r] * C[v2][r] >= best)return;
	if (v1 == r - 1 && v2 == r - 1)
	{
		long long diff = abs(x - y);
		if (diff < best)
		{
			best = diff;
			best_z = x;
		}
		return;
	}
	if (v1 >= r)
	{
		long long cur1 = C[v1][r] - C[v1 - 1][r];
		long long sum2 = C[v2][r];
		dfs(x, y + cur1 * sum2, v1 - 1, v2);
	}
	if (v2 >= r)
	{
		long long sum1 = C[v1][r];
		long long cur2 = C[v2][r] - C[v2 - 1][r];
		dfs(x + sum1 * cur2, y, v1, v2 - 1);
	}
}
char s[12345];
int cntA[12345], cntB[12345];
map<long long, long long> mp;
long long solve(long long x, long long y, int v1, int v2)
{
	long long state = x * 10000 + v1 * 100 + v2;
	if(mp.find(state) != mp.end())return mp[state];
	long long &res = mp[state];
	long long diff = abs(x - y);
	if (diff - C[v1][r] * C[v2][r] > best)
	{
		return res = 0;
	}
	if (v1 < r || v2 < r)
	{
		if (v1 >= cntA[v1 + v2] && v2 >= cntB[v1 + v2])
		{
			int sum = v1 + v2;
			v1 -= cntA[sum];
			v2 -= cntB[sum];
			return res = C[v1 + v2][v1];
		}
		return res = 0;
	}
	res = 0;
	char c = s[v1 + v2 - 1];
	if (c != 'B')
	{
		long long cur1 = C[v1][r] - C[v1 - 1][r];
		long long sum2 = C[v2][r];
		res += solve(x, y + cur1 * sum2, v1 - 1, v2);
	}
	if (c != 'A')
	{
		long long sum1 = C[v1][r];
		long long cur2 = C[v2][r] - C[v2 - 1][r];
		res += solve(x + sum1 * cur2, y, v1, v2 - 1);
	}
	return res;
}
int main()
{
	scanf("%d %d", &r, &c);
	for (int i = 0; i <= 2 * (r + c); i++)
	{
		for (int j = 0; j <= 2 * (r + c); j++)
		{
			if (j == 0) C[i][j] = 1; else
			if (i == 0) C[i][j] = 0;
			else C[i][j] = (C[i - 1][j] + C[i - 1][j - 1]);
		}
	}
	total = C[r + c][r] * C[r + c][r];
	{
		long long x = 0, y = 0;
		int v1 = r + c, v2 = r + c;
		while (v1 >= r && v2 >= r)
		{
			if (x > y)
			{
				long long cur1 = C[v1][r] - C[v1 - 1][r];
				long long sum2 = C[v2][r];
				y += cur1 * sum2;
				v1--;
			}
			else
			{
				long long sum1 = C[v1][r];
				long long cur2 = C[v2][r] - C[v2 - 1][r];
				x += sum1 * cur2;
				v2--;
			}
		}
		best = abs(x - y);
	}
	dfs(0, 0, r + c, r + c);
	scanf("%s", s);
	cntA[0] = cntB[0] = 0;
	for (int i = 0; i < 2 * (r + c); i++)
	{
		cntA[i + 1] = cntA[i] + (s[i] == 'A');
		cntB[i + 1] = cntB[i] + (s[i] == 'B');
	}
	long long ans = solve(0, 0, r + c, r + c);
	cout << ans << endl;
	return 0;
}


#pragma GCC optimize ("O3")
#pragma GCC target ("sse4")

#include <bits/stdc++.h>
#include <ext/pb_ds/tree_policy.hpp>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/rope>

using namespace std;
using namespace __gnu_pbds;
using namespace __gnu_cxx;

typedef long long ll;
typedef long double ld;
typedef complex<ld> cd;

typedef pair<int, int> pi;
typedef pair<ll,ll> pl;
typedef pair<ld,ld> pd;

typedef vector<int> vi;
typedef vector<ld> vd;
typedef vector<ll> vl;
typedef vector<pi> vpi;
typedef vector<pl> vpl;
typedef vector<cd> vcd;

template <class T> using Tree = tree<T, null_type, less<T>, rb_tree_tag,tree_order_statistics_node_update>;

#define FOR(i, a, b) for (int i = (a); i < (b); i++)
#define F0R(i, a) for (int i = 0; i < (a); i++)
#define FORd(i,a,b) for (int i = (b)-1; i >= (a); i--)
#define F0Rd(i,a) for (int i = (a)-1; i >= 0; i--)
#define trav(a, x) for (auto& a : x)

#define mp make_pair
#define pb push_back
#define f first
#define s second
#define lb lower_bound
#define ub upper_bound

#define sz(x) (int)x.size()
#define all(x) begin(x), end(x)
#define rsz resize

const int MOD = 1000000007; // 998244353
const ll INF = 1e18;
const int MX = 200005;
const ld PI = 4*atan((ld)1);

template<class T> void ckmin(T &a, T b) { a = min(a, b); }
template<class T> void ckmax(T &a, T b) { a = max(a, b); }

namespace input {
    template<class T> void re(complex<T>& x);
    template<class T1, class T2> void re(pair<T1,T2>& p);
    template<class T> void re(vector<T>& a);
    template<class T, size_t SZ> void re(array<T,SZ>& a);

    template<class T> void re(T& x) { cin >> x; }
    void re(double& x) { string t; re(t); x = stod(t); }
    void re(ld& x) { string t; re(t); x = stold(t); }
    template<class Arg, class... Args> void re(Arg& first, Args&... rest) {
        re(first); re(rest...);
    }

    template<class T> void re(complex<T>& x) { T a,b; re(a,b); x = cd(a,b); }
    template<class T1, class T2> void re(pair<T1,T2>& p) { re(p.f,p.s); }
    template<class T> void re(vector<T>& a) { F0R(i,sz(a)) re(a[i]); }
    template<class T, size_t SZ> void re(array<T,SZ>& a) { F0R(i,SZ) re(a[i]); }
}

using namespace input;

namespace output {
    template<class T1, class T2> void pr(const pair<T1,T2>& x);
    template<class T, size_t SZ> void pr(const array<T,SZ>& x);
    template<class T> void pr(const vector<T>& x);
    template<class T> void pr(const set<T>& x);
    template<class T1, class T2> void pr(const map<T1,T2>& x);

    template<class T> void pr(const T& x) { cout << x; }
    template<class Arg, class... Args> void pr(const Arg& first, const Args&... rest) {
        pr(first); pr(rest...);
    }

    template<class T1, class T2> void pr(const pair<T1,T2>& x) {
        pr("{",x.f,", ",x.s,"}");
    }
    template<class T> void prContain(const T& x) {
        pr("{");
        bool fst = 1; for (const auto& a: x) pr(!fst?", ":"",a), fst = 0; // const needed for vector<bool>
        pr("}");
    }
    template<class T, size_t SZ> void pr(const array<T,SZ>& x) { prContain(x); }
    template<class T> void pr(const vector<T>& x) { prContain(x); }
    template<class T> void pr(const set<T>& x) { prContain(x); }
    template<class T1, class T2> void pr(const map<T1,T2>& x) { prContain(x); }

    void ps() { pr("\n"); }
    template<class Arg> void ps(const Arg& first) {
        pr(first); ps(); // no space at end of line
    }
    template<class Arg, class... Args> void ps(const Arg& first, const Args&... rest) {
        pr(first," "); ps(rest...); // print w/ spaces
    }
}

using namespace output;

namespace io {
    void setIn(string s) { freopen(s.c_str(),"r",stdin); }
    void setOut(string s) { freopen(s.c_str(),"w",stdout); }
    void setIO(string s = "") {
        ios_base::sync_with_stdio(0); cin.tie(0); // fast I/O
        if (sz(s)) { setIn(s+".in"), setOut(s+".out"); } // for USACO
    }
}

using namespace io;

template<class T> T invGeneral(T a, T b) {
    a %= b; if (a == 0) return b == 1 ? 0 : -1;
    T x = invGeneral(b,a);
    return x == -1 ? -1 : ((1-(ll)b*x)/a+b)%b;
}

template<class T> struct modular {
    T val;
    explicit operator T() const { return val; }
    modular() { val = 0; }
    modular(const ll& v) {
        val = (-MOD <= v && v <= MOD) ? v : v % MOD;
        if (val < 0) val += MOD;
    }

    friend ostream& operator<<(ostream& os, const modular& a) { return os << a.val; }
    friend bool operator==(const modular& a, const modular& b) { return a.val == b.val; }
    friend bool operator!=(const modular& a, const modular& b) { return !(a == b); }
    friend bool operator<(const modular& a, const modular& b) { return a.val < b.val; }

    modular operator-() const { return modular(-val); }
    modular& operator+=(const modular& m) { if ((val += m.val) >= MOD) val -= MOD; return *this; }
    modular& operator-=(const modular& m) { if ((val -= m.val) < 0) val += MOD; return *this; }
    modular& operator*=(const modular& m) { val = (ll)val*m.val%MOD; return *this; }
    friend modular pow(modular a, ll p) {
        modular ans = 1; for (; p; p /= 2, a *= a) if (p&1) ans *= a;
        return ans;
    }
    friend modular inv(const modular& a) {
        auto i = invGeneral(a.val,MOD); assert(i != -1);
        return i;
    } // equivalent to return exp(b,MOD-2) if MOD is prime
    modular& operator/=(const modular& m) { return (*this) *= inv(m); }

    friend modular operator+(modular a, const modular& b) { return a += b; }
    friend modular operator-(modular a, const modular& b) { return a -= b; }
    friend modular operator*(modular a, const modular& b) { return a *= b; }

    friend modular operator/(modular a, const modular& b) { return a /= b; }
};

typedef modular<int> mi;
typedef pair<mi,mi> pmi;
typedef vector<mi> vmi;
typedef vector<pmi> vpmi;

mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());

ll comb[61][61];
int R,C;
string S;

ll calc(string t) {
	ll ans = 0;
	int a = 0, b = 0;
	F0R(i,sz(t)) {
		if (t[i] == 'A') {
			a ++;
			ans += (comb[a][R]-comb[a-1][R])*(comb[R+C][R]-comb[b][R]);
		} else {
			b ++;
			ans -= (comb[b][R]-comb[b-1][R])*(comb[R+C][R]-comb[a][R]);
		}
	}
	if (a != b) return INF;
	return ans;
}

bool match(string t) {
	F0R(i,sz(S)) if (!(S[i] == '?' || S[i] == t[i])) return 0;
	return 1;
}

void init() {
    setIO(); re(R,C,S);
    comb[0][0] = 1;
    FOR(i,1,61) {
    	F0R(j,i+1) {
    		comb[i][j] = comb[i-1][j];
    		if (j) comb[i][j] += comb[i-1][j-1];
    	}
    }
    /*ll dif = INF;
    F0R(i,1<<sz(S)) {
    	string t;
    	F0R(j,sz(S)) {
    		if (i&(1<<j)) t += 'A';
    		else t += 'B';
    	}
    	ckmin(dif,abs(calc(t)));
    }
    ps(dif);
    ll res = 0;
    F0R(i,1<<sz(S)) {
    	string t;
    	F0R(j,sz(S)) {
    		if (i&(1<<j)) t += 'A';
    		else t += 'B';
    	}
    	if (dif == abs(calc(t)) && match(t)) res ++;
    }
    ps(res);
    exit(0);*/
}

vpl dpL[31], dpR[31];

void dfsL(int ind, int a, int b, int mask, ll p) {
	if (ind == C+1) {
		dpL[a].pb({p,mask});
		return;
	}
	dfsL(ind+1,a+1,b,mask^(1<<ind),p+(comb[a+1][R]-comb[a][R])*(comb[R+C][R]-comb[b][R]));
	dfsL(ind+1,a,b+1,mask,		   p-(comb[b+1][R]-comb[b][R])*(comb[R+C][R]-comb[a][R]));
}

void dfsR(int ind, int a, int b, int mask, ll p) {
	if (ind == C+1) {
		dpR[a].pb({p,mask});
		return;
	}
	dfsR(ind+1,a-1,b,mask^(1<<ind),p+(comb[a][R]-comb[a-1][R])*(comb[R+C][R]-comb[b][R]));
	dfsR(ind+1,a,b-1,mask,		   p-(comb[b][R]-comb[b-1][R])*(comb[R+C][R]-comb[a][R]));
}

ll ans = 0;
ll dp[31][31];

ll rev(int x, int y) {
	int z = 0;
	F0R(i,y) if (x&(1<<i)) z ^= 1<<(y-1-i);
	return z;
}

ll res = 0;

void check(ll x, int t) {
	res ++; // return;
	assert(sz(S) == 2*(R+C));
	// ps("HUH",x);
	// ps("HUH",x,S);
	/*ll tmp = 0;
	memset(dp,0,sizeof dp);
	// F0R(a,R+C+1) F0R(b,minR+C+R-a) dp[a][b] = 1;
	dp[0][0] = 1;
	F0R(a,R+C+1) F0R(b,min(R+C+1,R+C+R-a)) {
		if (a+b == R+C+R-1) {
			tmp += dp[a][b];
		} else {
			int soFar = max(a-(R-1),0)+max(b-(R-1),0);
			if (a+1 < R || (x&(1LL<<soFar))) if (S[a+b] != 'B' && a < R+C) dp[a+1][b] += dp[a][b]; //
			if (b+1 < R || !(x&(1LL<<soFar))) if (S[a+b] != 'A' && b < R+C) dp[a][b+1] += dp[a][b]; //
		}
	}
	ans += t*tmp;*/
	// ps("ZZ",__builtin_popcountll(x),C+1);
	ll tmp = 0;
	int a = 0, b = 0;
	F0R(i,2*C+2) {
		if (x&(1LL<<i)) a ++;
		else b ++;
		if (a && b) {
			// ps("??",i,a,b,x);
			FOR(j,i,2*C+2) {
				if (x == 1117763649LL) ps("HA",j,x&(1LL<<j),S[sz(S)-(2*C+2)+j]);
				if (x&(1LL<<j)) {
					if (S[sz(S)-(2*C+2)+j] == 'B') return;
				} else {
					if (S[sz(S)-(2*C+2)+j] == 'A') return;
				}
			}
			int aa = 0, bb = 0;
			F0R(j,sz(S)-(2*C+2)+i) {
				if (S[j] == 'A') aa ++;
				if (S[j] == 'B') bb ++;
			}
			ll tmp = 0;
			if (x&(1LL<<i)) {
				//ps("HUH1",aa,bb,R-1-aa,b+R-1-bb);
				tmp = comb[R-1-aa+b+R-1-bb][R-1-aa];
				// R-1 A's, b+R-1 B's
			} else {
				//ps("HUH2",a+R-1-aa,R-1-bb);
				tmp = comb[a+R-1-aa+R-1-bb][a+R-1-aa];
				// a+R-1 A's, R-1 B's
			}
			ans += t*tmp;
			return;
		}
	}
}

bool ok(ll x) {
	F0R(i,C+1) {
		if (x&(1<<i)) {
			if (S[sz(S)-C-1+i] == 'B') return 0;
		} else {
			if (S[sz(S)-C-1+i] == 'A') return 0;
		}
	}
	return 1;
}

int main() {
	init();
	dfsL(0,R-1,R-1,0,0);
	dfsR(0,R+C,R+C,0,0);
	// ps("WUT",C);
	// ps("WUT",dpR[C+1],dpL[C+1]); exit(0);
	ll dif = INF;
	F0R(i,R+C+1) {
		sort(all(dpL[i]));
		sort(all(dpR[i])); reverse(all(dpR[i]));
		int ind = 0;
		trav(t,dpL[i]) {
			while (ind+1 < sz(dpR[i]) && t.f+dpR[i][ind+1].f >= 0) ind ++;
			ckmin(dif,abs(t.f+dpR[i][ind].f));
			if (ind+1 < sz(dpR[i])) ckmin(dif,abs(t.f+dpR[i][ind+1].f));
		}
	}
	F0R(i,R+C+1) {
		vpl z;
		trav(t,dpR[i]) if (ok(rev(t.s,C+1))) z.pb(t);
		int ind = 0;
		int l = 0, r = -1;
		trav(t,dpL[i]) {
			while (l < sz(z) && t.f+z[l].f > dif) l ++;
			while (r+1 < sz(z) && t.f+z[r+1].f >= -dif) r ++;
			if (l <= r) {
				//ps("TT",__builtin_popcount(t.s),__builtin_popcount(z[l].s));
				//ps("TT",t.s<(1<<(C+1)),t.s|(rev(z[l].s,C+1)<<(C+1)),__builtin_popcountll(t.s|(rev(z[l].s,C+1)<<(C+1))));
				check(t.s|(rev(z[l].s,C+1)<<(C+1)),r-l+1);
			}
		}
	}
	// ps(res);
	// ps(res);
	ps(ans);
}

/* stuff you should look for
    * int overflow, array bounds
    * special cases (n=1?), set tle
    * do smth instead of nothing and stay organized
*/


#include<cstdio>
#include<algorithm>
#include<vector>
#define pll pair<long long, long long>
using namespace std;
long long Comb[62][62], A[32][32], B[32][32], TT;
int R, C, n;
char p[110];
long long CC[32][32], MM;
vector< pll >P[32][2], Q[32][2];
void Put(int x, int y, long long g, long long c1, long long c2, int ck){
    if(x+y == R+n){
        P[x][ck].push_back({g,c1});
        if(c2)Q[x][ck].push_back({g,c2});

        return;
    }
    Put(x+1, y, g+(!ck?A[x+1][y]:0), c1, (p[x+y] != 'B' ? c2 : 0), ck);
    Put(x, y+1, g+(ck?B[x][y+1]:0), c1, (p[x+y] != 'A' ? c2 : 0), ck);
}
void Calc1(int x, int y, long long g, int ck){
    if(x+y == R+n){
        if(P[x][ck].empty())return;
        int t = lower_bound(P[x][ck].begin(),P[x][ck].end(), pll((TT+1)/2-g,0)) - P[x][ck].begin();
        if(t != P[x][ck].size() && P[x][ck][t].second > 0){
            long long tp = (P[x][ck][t].first + g) * 2 - TT;
            if(tp<0)tp=-tp;
            if(MM > tp)MM = tp;
        }
        if(t && P[x][ck][t-1].second > 0){
            long long tp = (P[x][ck][t-1].first + g) * 2 - TT;
            if(tp<0)tp=-tp;
            if(MM > tp)MM = tp;
        }
        return;
    }
    Calc1(x-1, y, g+(!ck?A[x][y]:0), ck);
    Calc1(x, y-1, g+(ck?B[x][y]:0), ck);
}

long long Res;

void Calc2(int x, int y, long long g, int ck){
    if(x+y == R+n){
        int t = lower_bound(Q[x][ck].begin(),Q[x][ck].end(), pll((TT+1)/2-g,0)) - Q[x][ck].begin();
        if(t != Q[x][ck].size() && Q[x][ck][t].second > 0){
            long long tp = (Q[x][ck][t].first + g) * 2 - TT;
            if(tp<0)tp=-tp;
            if(MM == tp){
                Res += Q[x][ck][t].second;
            }
        }
        if(t && Q[x][ck][t-1].second > 0){
            long long tp = (Q[x][ck][t-1].first + g) * 2 - TT;
            if(tp<0)tp=-tp;
            if(MM == tp){
                Res += Q[x][ck][t-1].second;
            }
        }
        return;
    }
    if(p[x+y-1] != 'B')Calc2(x-1, y, g+(!ck?A[x][y]:0), ck);
    if(p[x+y-1] != 'A')Calc2(x, y-1, g+(ck?B[x][y]:0), ck);
}

void Make(vector< pll > &P){
    if(P.empty())return;
    sort(P.begin(),P.end());
    int i, cnt = 0;
    long long s = 0;
    for(i=0;i<P.size();i++){
        s += P[i].second;
        if(i==P.size()-1 || P[i].first != P[i+1].first){
            P[cnt++] = {P[i].first, s};
            s = 0;
        }
    }
    P.resize(cnt);
}

int main(){
    int i, j;
    scanf("%d%d",&R,&C);
    scanf("%s",p);
    for(i=0;i<=60;i++){
        Comb[i][0]=1;
        for(j=1;j<=i;j++)Comb[i][j]=Comb[i-1][j-1]+Comb[i-1][j];
    }
    n = (R+C);
    TT = Comb[n*2][R*2];
    for(i=0;i<=n;i++){
        for(j=0;j<=n;j++){
            if(i){
                if(i) A[i][j] = Comb[i-1][R-1] * (Comb[n*2-i][R] - Comb[j][R]);
            }
            if(j){
                if(j) B[i][j] = Comb[j-1][R-1] * (Comb[n*2-j][R] - Comb[i][R]);
            }
        }
    }
    CC[0][0]=1;
    for(i=0;i<=n;i++){
        for(j=0;j<=n;j++){
            if(i!=n&&p[i+j] != 'B') CC[i+1][j] += CC[i][j];
            if(j!=n&&p[i+j] != 'A') CC[i][j+1] += CC[i][j];
        }
    }
    for(i=R;i<=n;i++){
        if(p[i+R-1]!='B')Put(R,i,A[R][i],Comb[i+R-1][R-1], CC[R-1][i],0);
        if(p[i+R-1]!='A')Put(i,R,B[i][R],Comb[i+R-1][R-1], CC[i][R-1],1);
    }
    for(i=R;i<=n;i++){
        for(j=0;j<2;j++){
            Make(P[i][j]);
            Make(Q[i][j]);
        }
    }
    MM = TT+1;
    Calc1(n, n, 0, 0);
    Calc1(n, n, 0, 1);
    Calc2(n, n, 0, 0);
    Calc2(n, n, 0, 1);
    printf("%lld\n",Res);
}


//lxrtxdy!
#include <bits/stdc++.h>

using namespace std;

long long C[777][777];

int r, c;
long long total;
long long best = (long long) 1e18, best_z = -1;

void dfs(long long x, long long y, int v1, int v2) {
  long long diff = abs(x - y);
  if (best <= 1 || diff - C[v1][r] * C[v2][r] >= best) {
    return;
  }
  if (v1 == r - 1 && v2 == r - 1) {
    long long diff = abs(x - y);
    if (diff < best) {
      best = diff;
      best_z = x;
    }
    return;
  }
  if (v1 >= r) {
    long long cur1 = C[v1][r] - C[v1 - 1][r];
    long long sum2 = C[v2][r];
    dfs(x, y + cur1 * sum2, v1 - 1, v2);
  }
  if (v2 >= r) {
    long long sum1 = C[v1][r];
    long long cur2 = C[v2][r] - C[v2 - 1][r];
    dfs(x + sum1 * cur2, y, v1, v2 - 1);
  }
}

char s[12345];
int cntA[12345], cntB[12345];
map<long long, long long> mp;

long long solve(long long x, long long y, int v1, int v2) {
  long long state = x * 10000 + v1 * 100 + v2;
  if (mp.find(state) != mp.end()) {
    return mp[state];
  }
  long long &res = mp[state];
  long long diff = abs(x - y);
  if (diff - C[v1][r] * C[v2][r] > best) {
    return res = 0;
  }
  if (v1 < r || v2 < r) {
    if (v1 >= cntA[v1 + v2] && v2 >= cntB[v1 + v2]) {
      int sum = v1 + v2;
      v1 -= cntA[sum];
      v2 -= cntB[sum];
      return res = C[v1 + v2][v1];
    }
    return res = 0;
  }
  res = 0;
  char c = s[v1 + v2 - 1];
  if (c != 'B') {
    long long cur1 = C[v1][r] - C[v1 - 1][r];
    long long sum2 = C[v2][r];
    res += solve(x, y + cur1 * sum2, v1 - 1, v2);
  }
  if (c != 'A') {
    long long sum1 = C[v1][r];
    long long cur2 = C[v2][r] - C[v2 - 1][r];
    res += solve(x + sum1 * cur2, y, v1, v2 - 1);
  }
  return res;
}

int main() {
  scanf("%d %d", &r, &c);
  for (int i = 0; i <= 2 * (r + c); i++) {
    for (int j = 0; j <= 2 * (r + c); j++) {
      if (j == 0) C[i][j] = 1; else
      if (i == 0) C[i][j] = 0;
      else C[i][j] = (C[i - 1][j] + C[i - 1][j - 1]);
    }
  }
  total = C[r + c][r] * C[r + c][r];
  {
    long long x = 0, y = 0;
    int v1 = r + c, v2 = r + c;
    while (v1 >= r && v2 >= r) {
      if (x > y) {
        long long cur1 = C[v1][r] - C[v1 - 1][r];
        long long sum2 = C[v2][r];
        y += cur1 * sum2;
        v1--;
      } else {
        long long sum1 = C[v1][r];
        long long cur2 = C[v2][r] - C[v2 - 1][r];
        x += sum1 * cur2;
        v2--;
      }
    }
    best = abs(x - y);
  }
  dfs(0, 0, r + c, r + c);
  scanf("%s", s);
  cntA[0] = cntB[0] = 0;
  for (int i = 0; i < 2 * (r + c); i++) {
    cntA[i + 1] = cntA[i] + (s[i] == 'A');
    cntB[i + 1] = cntB[i] + (s[i] == 'B');
  }
  long long ans = solve(0, 0, r + c, r + c);
  cout << ans << endl;
  return 0;
}
//orzlxr!//hello


#include <iostream>
#include <iomanip>
#include <fstream>
#include <algorithm>
#include <vector>
#include <string>
#include <map>
#include <set>

using namespace std;
typedef long long ll;
const int MAXT = 62;

int R, C, T;
char c[MAXT];
ll r1score[MAXT];
ll rscore[MAXT];
ll lscore[MAXT];
ll mval;

map <pair <ll, int>, ll> mmap;
map <pair <ll, int>, ll> nmap;

ll choose (int x, int y)
{
    if (y > x || y < 0) return 0;
    ll res = 1;
    for (int i = 0; i < y; i++)
    {
        res = res * (x - i);
        res = res / (i + 1);
    }
    return res;
}

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

    cin >> R >> C;
    T = (2 * R + 2 * C);
    for (int i = 0; i < T; i++)
        cin >> c[i];

    for (int i = 0; i < MAXT; i++)
        lscore[i] = 0;
    lscore[2*R-1] = 1;
    for (int i = 2 * R; i < T; i++)
    {
       lscore[i] = lscore[i-1] * i / ((ll) i - 2 * R + 1);
    }
    for (int i = 0; i <= T; i++)
    {
        r1score[i] = choose (i, R - 1);
        rscore[i] = choose (i, R);
    }

    mval = 0;
    int acnt = 0, bcnt = 0;
    for (int i = T - 1; i >= 0; i--)
    {
        bool u = mval > 0;
        if (bcnt == T / 2)
            u = true;
        if (acnt == T / 2)
            u = false;

        if (u)
        {
            acnt++;
            mval -= r1score[T / 2 - acnt] * rscore[T / 2 - bcnt];
        }
        else
        {
            bcnt++;
            mval += r1score[T / 2 - bcnt] * rscore[T / 2 - acnt];
        }
    }
    mval = max(mval, -mval);

    ll tsum = 0;
    for (int i = 0; i < T; i++)
    {
        tsum += lscore[i];
    }

    tsum = rscore[T/2] * rscore[T/2];

    mmap[make_pair(0, 0)] = 1;
    for (int i = T - 1; i >= 2 * R - 1; i--)
    {
        nmap.clear();
        for (map<pair<ll, int>, ll>::iterator it = mmap.begin(); it != mmap.end(); it++)
        {
            ll sum = it->first.first;
            ll acnt = it->first.second;
            ll ncount = it->second;

            int aleft = T / 2 - acnt;
            int bleft = i + 1- aleft;

            ll asum = sum + r1score[aleft - 1] * rscore[bleft];
            ll bsum = sum - r1score[bleft - 1] * rscore[aleft];

            if (c[i] == 'A')
            {
                nmap[make_pair(asum, acnt + 1)] += ncount;
                nmap[make_pair(bsum, acnt)] += 0;
            }
            else if (c[i] == 'B')
            {
                nmap[make_pair(asum, acnt + 1)] += 0;
                nmap[make_pair(bsum, acnt)] += ncount;
            }
            else
            {
                nmap[make_pair(asum, acnt + 1)] += ncount;
                nmap[make_pair(bsum, acnt)] += ncount;
            }
        }
        tsum -= lscore[i];

        mmap.clear();
        for (map<pair<ll, int>, ll>::iterator it = nmap.begin(); it != nmap.end(); it++)
        {
            ll sum = it->first.first;
            int acnt = it->first.second;
            ll ncount = it->second;

            int aleft = T / 2 - acnt;
            int bleft = i - aleft;
            if (acnt > (T / 2) || (T - i - acnt) > (T / 2))
                continue;
            ll lsum = rscore[aleft] * rscore[bleft];
            if (sum < (-mval - lsum) || sum > (mval + lsum))
                continue;
            mmap[make_pair(sum, acnt)] += ncount;
        }
    }

    ll bscore = (ll) 1e18;
    for (map<pair<ll, int>, ll>::iterator it = mmap.begin(); it != mmap.end(); it++)
    {
        ll sum = it->first.first;
        bscore = min (bscore, max (sum, -sum));
    }

    ll ans = 0;
    for (map<pair<ll, int>, ll>::iterator it = mmap.begin(); it != mmap.end(); it++)
    {
        ll sum = it->first.first;
        int acnt = it->first.second;
        ll ncount = it->second;

        if (sum == bscore || sum == -bscore)
        {

            int nleft = 0;
            for (int i = 0; i < 2 * R - 1; i++)
            {
                if (c[i] == 'A')
                    acnt++;
                if (c[i] == '?')
                    nleft++;
            }

            ncount *= choose (nleft, T / 2 - acnt);
            ans += ncount;
        }
    }

    cout << ans << "\n";
    return 0;
}


#include<bits/stdc++.h>
using namespace std;
#define ll long long
ll lsc[62],rsc[62],rsc2[62];
char s[62];
map<pair<ll,int>,ll>nm,mm;
ll comb(int n,int k)
{
    if (n<k || k<0)
        return 0;
    ll rez=1,i;
    for(i=0;i<k;i++)
        rez=rez*(n-i)/(i+1);
    return rez;
}
int main()
{
    //freopen(".in","r",stdin);
    //freopen(".out","w",stdout);
    int r,c,n,i,cnta=0,cntb=0,ok,ast,bst;
    ll msum=0,nsum=0,bsum,rasp=0;
    scanf("%d%d\n",&r,&c);
    n=2*(r+c);
    scanf("%s",&s);
    lsc[2*r-1]=1;
    for(i=2*r;i<n;i++)
        lsc[i]=lsc[i-1]*i/(1ll*i-1ll*2*r+1ll);
    for(i=0;i<=n;i++)
        {
        rsc[i]=comb(i,r);
        rsc2[i]=comb(i,r-1);
        }
    nsum=rsc[n/2]*rsc[n/2];
    for(i=n-1;i>=0;i--)
        {
        if (msum>0)
            ok=1;
        else
            ok=0;
        if (cntb==n/2)
            ok=1;
        if (cnta==n/2)
            ok=0;
        if (ok)
            {
            cnta++;
            msum=msum-rsc2[n/2-cnta]*rsc[n/2-cntb];
            }
        else
            {
            cntb++;
            msum=msum+rsc2[n/2-cntb]*rsc[n/2-cnta];
            }
        }
    msum=max(msum,-msum);
    mm[make_pair(0,0)]=1;
    for(i=n-1;i>=2*r-1;i--)
        {
        nm.clear();
        for(auto it:mm)
            {
            ll sum=it.first.first,ncnt=it.second,asum,bsum;
            int cnt=it.first.second;
            ast=n/2-cnt;
            bst=i+1-ast;
            asum=sum+rsc2[ast-1]*rsc[bst];
            bsum=sum-rsc2[bst-1]*rsc[ast];
            if (s[i]=='A')
                {
                nm[make_pair(asum,cnt+1)]+=ncnt;
                nm[make_pair(bsum,cnt)]+=0;
                }
            else
                if (s[i]=='B')
                    {
                    nm[make_pair(asum,cnt+1)]+=0;
                    nm[make_pair(bsum,cnt)]+=ncnt;
                    }
                else
                    {
                    nm[make_pair(asum,cnt+1)]+=ncnt;
                    nm[make_pair(bsum,cnt)]+=ncnt;
                    }
            }
        nsum=nsum-lsc[i];
        mm.clear();
        for(auto it:nm)
            {
            ll sum=it.first.first,ncnt=it.second;
            int cnt=it.first.second;
            ast=n/2-cnt;
            bst=i-ast;
            if (cnt>n/2 || n-i-cnt>n/2)
                continue;
            if (sum<-msum-rsc[ast]*rsc[bst] || sum>msum+rsc[ast]*rsc[bst])
                continue;
            mm[make_pair(sum,cnt)]+=ncnt;
            }
        }
    bsum=1e18;
    for(auto it:mm)
        bsum=min(bsum,max(it.first.first,-it.first.first));
    for(auto it:mm)
        {
        ll sum=it.first.first,ncnt=it.second;
        int cnt=it.first.second;
        if (sum==bsum || sum==-bsum)
            {
            int sem=0;
            for(i=0;i<2*r-1;i++)
                if (s[i]=='?')
                    sem++;
                else
                    if (s[i]=='A')
                        cnt++;
            ncnt=ncnt*comb(sem,n/2-cnt);
            rasp+=ncnt;
            }
        }
    printf("%lld\n",rasp);
return 0;
}


/**
 *    author:  tourist
 *    created: 30.09.2017 21:16:15
**/
#include <bits/stdc++.h>

using namespace std;

long long C[777][777];

int r, c;
long long total;
long long best = (long long) 1e18, best_z = -1;

void dfs(long long x, long long y, int v1, int v2) {
  long long diff = abs(x - y);
  if (best <= 1 || diff - C[v1][r] * C[v2][r] >= best) {
    return;
  }
  if (v1 == r - 1 && v2 == r - 1) {
    long long diff = abs(x - y);
    if (diff < best) {
      best = diff;
      best_z = x;
    }
    return;
  }
  if (v1 >= r) {
    long long cur1 = C[v1][r] - C[v1 - 1][r];
    long long sum2 = C[v2][r];
    dfs(x, y + cur1 * sum2, v1 - 1, v2);
  }
  if (v2 >= r) {
    long long sum1 = C[v1][r];
    long long cur2 = C[v2][r] - C[v2 - 1][r];
    dfs(x + sum1 * cur2, y, v1, v2 - 1);
  }
}

char s[12345];
int cntA[12345], cntB[12345];
map<long long, long long> mp;

long long solve(long long x, long long y, int v1, int v2) {
  long long state = x * 10000 + v1 * 100 + v2;
  if (mp.find(state) != mp.end()) {
    return mp[state];
  }
  long long &res = mp[state];
  long long diff = abs(x - y);
  if (diff - C[v1][r] * C[v2][r] > best) {
    return res = 0;
  }
  if (v1 < r || v2 < r) {
    if (v1 >= cntA[v1 + v2] && v2 >= cntB[v1 + v2]) {
      int sum = v1 + v2;
      v1 -= cntA[sum];
      v2 -= cntB[sum];
      return res = C[v1 + v2][v1];
    }
    return res = 0;
  }
  res = 0;
  char c = s[v1 + v2 - 1];
  if (c != 'B') {
    long long cur1 = C[v1][r] - C[v1 - 1][r];
    long long sum2 = C[v2][r];
    res += solve(x, y + cur1 * sum2, v1 - 1, v2);
  }
  if (c != 'A') {
    long long sum1 = C[v1][r];
    long long cur2 = C[v2][r] - C[v2 - 1][r];
    res += solve(x + sum1 * cur2, y, v1, v2 - 1);
  }
  return res;
}

int main() {
  scanf("%d %d", &r, &c);
  for (int i = 0; i <= 2 * (r + c); i++) {
    for (int j = 0; j <= 2 * (r + c); j++) {
      if (j == 0) C[i][j] = 1; else
      if (i == 0) C[i][j] = 0;
      else C[i][j] = (C[i - 1][j] + C[i - 1][j - 1]);
    }
  }
  total = C[r + c][r] * C[r + c][r];
  {
    long long x = 0, y = 0;
    int v1 = r + c, v2 = r + c;
    while (v1 >= r && v2 >= r) {
      if (x > y) {
        long long cur1 = C[v1][r] - C[v1 - 1][r];
        long long sum2 = C[v2][r];
        y += cur1 * sum2;
        v1--;
      } else {
        long long sum1 = C[v1][r];
        long long cur2 = C[v2][r] - C[v2 - 1][r];
        x += sum1 * cur2;
        v2--;
      }
    }
    best = abs(x - y);
  }
  dfs(0, 0, r + c, r + c);
  scanf("%s", s);
  cntA[0] = cntB[0] = 0;
  for (int i = 0; i < 2 * (r + c); i++) {
    cntA[i + 1] = cntA[i] + (s[i] == 'A');
    cntB[i + 1] = cntB[i] + (s[i] == 'B');
  }
  long long ans = solve(0, 0, r + c, r + c);
  cout << ans << endl;
  return 0;
}


#include <iostream>
#include <cstdio>
#include <cstring>
#include <vector>
#include <algorithm>
#include <cmath>

using namespace std;

#define mp make_pair
#define pb push_back
#define ll long long

#define maxN 66

int r, c, n, i;
char s[maxN];
ll comb[maxN][maxN];

int cnt_a[maxN], cnt_b[maxN];
vector<ll> partial[maxN], partial_zero[maxN];

void compute_comb() {
    int i, j;

    for (i = 0; i <= n; i++) {
        comb[i][0] = 1;
        for (j = 1; j <= i; j++)
            comb[i][j] = comb[i - 1][j - 1] + comb[i - 1][j];
    }
}

ll get_difs(int conf, int a_bef, int b_bef) {
    int i;
    ll ans = 0;
    ll aux1, aux2;

    for (i = 0; i < c + 1; i++) {
        if (conf & (1 << i)) {
            //! here comes a B
            b_bef++;

            aux1 = comb[b_bef - 1][r - 1];
            aux2 = comb[n - b_bef][r] - comb[a_bef][r];

            ans -= aux1 * aux2;
        } else {
            //! here comes an A
            a_bef++;

            aux1 = comb[a_bef - 1][r - 1];
            aux2 = comb[n - a_bef][r] - comb[b_bef][r];

            ans += aux1 * aux2;
        }
    }

    return ans;
}

bool check(int conf) {
    int i;

    for (i = 0; i < c + 1; i++) {
        if (s[2 * r + c + i] == 'A' && ( (conf >> i) & 1 ) == 1) return false;
        if (s[2 * r + c + i] == 'B' && ( (conf >> i) & 1 ) == 0) return false;
    }

    return true;
}

void compute_second_part() {
    int i, conf;
    int limit = 1 << (c + 1);
    int a_here, b_here;

    for (conf = 0; conf < limit; conf++) {
        b_here = __builtin_popcount(conf);
        a_here = c + 1 - b_here;

        if (check(conf))
            partial[a_here].pb(get_difs(conf, r + c - a_here, r + c - b_here));
        else
            partial_zero[a_here].pb(get_difs(conf, r + c - a_here, r + c - b_here));
    }

    for (i = 0; i <= c + 1; i++) {
        sort(partial[i].begin(), partial[i].end());
        sort(partial_zero[i].begin(), partial_zero[i].end());
    }
}

ll get_coef(int conf) {
    int i, j;

    for (i = 0; i < c + 1; i++)
        if ( ((conf >> i) & 1) != (conf & 1) )
            break;

    for (j = i; j < c + 1; j++) {
        if (s[2 * r - 1 + j] == 'A' && (( (conf >> j) & 1 ) == 1)) return 0;
        if (s[2 * r - 1 + j] == 'B' && (( (conf >> j) & 1 ) == 0)) return 0;
    }

    int set_a = r - 1 + ( (conf & 1) == 0 ? i : 0 );
    int set_b = r - 1 + ( (conf & 1) == 1 ? i : 0 );

    if (set_a < cnt_a[2 * r - 2 + i]) return 0;
    if (set_b < cnt_b[2 * r - 2 + i]) return 0;
    return comb[set_a + set_b - cnt_a[2 * r - 2 + i] - cnt_b[2 * r - 2 + i]][set_a - cnt_a[2 * r - 2 + i]];
}

void upd(pair<ll, ll>& ans, pair<ll, ll> act) {
    if (act.first < 0) act.first = -act.first;

    if (ans.first < act.first) return;
    if (ans.first > act.first) {
        ans = act;
        return;
    }

    ans.second += act.second;
}

ll how_many(vector<ll>& data, ll val) {
    auto it1 = lower_bound(data.begin(), data.end(), val);
    auto it2 = upper_bound(data.begin(), data.end(), val);
    return it2 - it1;
}

ll compute_first_part() {
    int i, conf;
    int limit = 1 << (c + 1);
    int a_here, b_here;
    ll act, coef, coef2;
    pair<ll, ll> ans = mp(1LL << 60, 0);

    for (conf = 0; conf < limit; conf++) {
        b_here = __builtin_popcount(conf);
        a_here = c + 1 - b_here;
        act = get_difs(conf, r - 1, r - 1);

        //! coef may be != 0
        coef = get_coef(conf);
        auto it = lower_bound(partial[c + 1 - a_here].begin(),
                              partial[c + 1 - a_here].end(),
                              -act);

        if (it != partial[c + 1 - a_here].end()) {
            if (ans.first >= abs(*it + act)) {
                coef2 = how_many(partial[c + 1 - a_here], *it);
                upd(ans, mp(*it + act, coef * coef2));
            }
        }

        if (it != partial[c + 1 - a_here].begin()) {
            it--;
            if (ans.first >= abs(*it + act)) {
                coef2 = how_many(partial[c + 1 - a_here], *it);
                upd(ans, mp(*it + act, coef * coef2));
            }
        }

        //! coef is clearly 0
        coef = 0;
        it = lower_bound(partial_zero[c + 1 - a_here].begin(),
                         partial_zero[c + 1 - a_here].end(),
                         -act);

        if (it != partial_zero[c + 1 - a_here].end()) {
            coef2 = how_many(partial[c + 1 - a_here], *it);
            if (ans.first >= abs(*it + act)) {
                coef2 = how_many(partial_zero[c + 1 - a_here], *it);
                upd(ans, mp(*it + act, coef * coef2));
            }
        }

        if (it != partial_zero[c + 1 - a_here].begin()) {
            it--;
            if (ans.first >= abs(*it + act)) {
                coef2 = how_many(partial_zero[c + 1 - a_here], *it);
                upd(ans, mp(*it + act, coef * coef2));
            }
        }
    }

    return ans.second;
}

int main()
{
    //freopen("test.in","r",stdin);

    scanf("%d%d\n%s", &r, &c, s + 1);
    n = 2 * (r + c);

    compute_comb();

    for (i = 1; i <= n; i++) {
        cnt_a[i] = cnt_a[i - 1] + (s[i] == 'A' ? 1 : 0);
        cnt_b[i] = cnt_b[i - 1] + (s[i] == 'B' ? 1 : 0);
    }

    compute_second_part();
    ll sol = compute_first_part();

    printf("%lld", sol);

    return 0;
}


#include <bits/stdc++.h>
using namespace std;
const int N = 2e5+5;
int n,sz[N],a[N],c,ret,dp[N];
pair<int,int> m[N][2];
vector<int> adj[N];
void dfs(int x,int p){
	int f=0,u,i,d;dp[x]=0;
	if(!sz[x])f=1,++sz[x];
	d= a[x]>=c ? 1 :0;
	for(i=0;i<adj[x].size();++i){
		u= adj[x][i];
		if(u!=p){
			dfs(u,x);
			if(f)sz[x]+=sz[u];
			if(dp[u]==sz[u])dp[x]+=dp[u];
			else{
				if(m[x][0].first<dp[u])
					m[x][1]= m[x][0],m[x][0]=make_pair(dp[u],u);
				else if(m[x][1].first<dp[u])
					m[x][1]= make_pair(dp[u],u);
			}
		}
	}
	dp[x]+=d+m[x][0].first;
	if(d==0)dp[x]=0;
	ret= max(ret,dp[x]);
}
void dfs2(int x,int p,int d){
	int u,i,nd,t,v=0;
	if(d== n-sz[x])v=d,d=0;

	ret= max( ret, (t= v+ dp[x]-m[x][0].first+max(m[x][0].first,d) ) );

	for(i=0;i<adj[x].size();++i){
		u= adj[x][i];
		if(u!=p){
			nd= t;
			if(m[x][0].second==u)
				nd= dp[x]-m[x][0].first+ max(m[x][1].first,d)+v;
			else if(dp[u]==sz[u])
				nd= t-sz[x];
			if(a[x]<c)nd=0;
			dfs2(u,x,nd);
		}
	}
}
int main(){
	int i,x,y,q,l,r,k,mid;
	cin>>n>>k;
	for(i=1;i<=n;++i)scanf("%d",&a[i]);
	for(i=0;i<n-1;++i)scanf("%d%d",&x,&y),adj[x].push_back(y),adj[y].push_back(x);
	dfs(1,0);
	l=1,r= 1e6;
	while(l<r){
		mid= (l+r+1)/2;
		c= mid;
		memset(dp,0,sizeof(dp));
		memset(m,0,sizeof(m));ret=0;
		dfs(1,0);
		dfs2(1,0,0);
		if(ret>=k)l= mid;
		else
			r= mid-1;
	}
	printf("%d\n",l);
}


#include <bits/stdc++.h>
#define N 200020
#define ll long long
using namespace std;
inline int read(){
	int x=0,f=1;char ch=getchar();
	while(ch>'9'||ch<'0')ch=='-'&&(f=0)||(ch=getchar());
	while(ch<='9'&&ch>='0')x=(x<<3)+(x<<1)+ch-'0',ch=getchar();
	return f?x:-x;
}
int head[N], nxt[N<<1], to[N<<1], cnt;
void insert(int x, int y) {
	to[++cnt] = y; nxt[cnt] = head[x]; head[x] = cnt;
	to[++cnt] = x; nxt[cnt] = head[y]; head[y] = cnt;
}
int a[N], b[N], n = read(), k = read();
int f[N], sz[N], nt[N], sum, ans;
int dfs1(int x, int fa) {
	for (int i = head[x]; i; i = nxt[i]) {
		if (to[i] == fa) continue;
		dfs1(to[i], x);
		sz[x] += sz[to[i]];
		nt[x] += nt[to[i]];
	}
}
void dfs2(int x, int fa) {
	// printf("%d %d \n", x, fa);
	f[x] = 1;
	int mx = 0, sx = 0;
	for (int i = head[x]; i; i = nxt[i]) {
		if (to[i] == fa) continue;
		dfs2(to[i], x);
		if (!nt[to[i]]) f[x] += sz[to[i]];
		else if (!b[to[i]])
			if (f[to[i]] > mx) sx = mx, mx = f[to[i]];
			else if (f[to[i]] > sx) sx = f[to[i]];
	}
	f[x] += mx;
	if (!b[x]) {
		if (nt[x] == sum) ans = max(ans, f[x] + sx + n - sz[x]);
		else ans = max(ans, f[x] + sx);
	}
}
bool check(int mid) {
	// printf("%d:\n", mid);
	ans = sum = 0;
	for (int i = 1; i <= n; i++) {
		sz[i] = 1;
		sum += nt[i] = b[i] = a[i] <= mid;
	}
	dfs1(1, 0);
	dfs2(1, 0);
	// puts(ans >= k ? "Yes" : "No");
	return ans >= k;
}
int main(int argc, char const *argv[]) {
	int l = 1, r = 0, ans;
	for (int i = 1; i <= n; i++)
		r = max(r, a[i] = read());
	for (int i = 1; i < n; i++)
		insert(read(), read());
	r ++;
	while (l <= r) {
		int mid = l + r >> 1;
		if (check(mid)) l = mid + 1;
		else ans = mid, r = mid - 1;
	}
	printf("%d\n", ans);
	return 0;
}
	 	  		  	       			 	 				//hellobig_tq//hello


#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
typedef pair<int,int> PII;
#define MP make_pair
#define PB push_back
#define AA first
#define BB second
#define OP begin()
#define ED end()
#define SZ size()
#define cmin(x,y) x=min(x,y)
#define cmax(x,y) x=max(x,y)
#define NAME "535F"
#define UsingFile 0
const LL MOD = 1000000007;
const double PI = acos(-1.);
const int N = 200000+5;
int n,a[N],w[N];
int din[N],dot[N],fot[N];
vector<int>G[N];
void dfsd(int u,int f){
	int i,v;
	for(i=0;i<G[u].SZ;i++){
		v=G[u][i];
		if(v==f)continue;
		dfsd(v,u);
	}
	if(w[u]){
		din[u]=1;
		for(i=0;i<G[u].SZ;i++){
			v=G[u][i];
			if(v==f)continue;
			if(din[v])din[u]+=din[v];
			else {din[u]=0;break;}
		}
		dot[u]=1;
		int mx=0;
		for(i=0;i<G[u].SZ;i++){
			v=G[u][i];
			if(v==f)continue;
			if(din[v])dot[u]+=din[v];
			else cmax(mx,dot[v]);
		}
		dot[u]+=mx;
	}else
		din[u]=dot[u]=0;
}
void Max2(int &a,int &b,int c){
	if(c>=a){
		b=a;a=c;
	}else cmax(b,c);
}
void dfsf(int u,int f){
	int i,v;
	if(w[u]){
		int b[2];
		b[0]=fot[u];
		b[1]=0;
		int sum=0;
		for(i=0;i<G[u].SZ;i++){
			v=G[u][i];
			if(v==f)continue;
			if(din[v])sum+=din[v];
			else Max2(b[0],b[1],dot[v]);
		}
		for(i=0;i<G[u].SZ;i++){
			v=G[u][i];
			if(v==f)continue;
			if(din[v]){
				fot[v]=sum-din[v]+1+b[0];
			}else {
				if(dot[v]==b[0])
					fot[v]=sum+1+b[1];
				else fot[v]=sum+1+b[0];
			}
			if(!w[v])fot[v]=0;
		}
	}else {
		for(i=0;i<G[u].SZ;i++){
			v=G[u][i];
			if(v==f)continue;
			fot[v]=0;
		}
	}
	for(i=0;i<G[u].SZ;i++){
		v=G[u][i];
		if(v==f)continue;
		dfsf(v,u);
	}
}
int dfsdp(int u,int f){
	int ret=0;
	int i,v;
	if(w[u]){
		ret=1;
		int mx=0;
		if(~f)mx=fot[u];
		for(i=0;i<G[u].SZ;i++){
			v=G[u][i];
			if(v==f)continue;
			if(din[v])ret+=din[v];
			else cmax(mx,dot[v]);
		}
		ret+=mx;
	}
	for(i=0;i<G[u].SZ;i++){
		v=G[u][i];
		if(v==f)continue;
		int tmp=dfsdp(v,u);
		cmax(ret,tmp);
	}
	return ret;
}
int cnt(int A){
	int i;
	for(i=1;i<=n;i++)
		w[i]=a[i]>=A;
	int rt=-1;
	for(i=1;i<=n;i++)
		if(!w[i])
			rt=i;
	if(rt==-1)return n;
	dfsd(rt,-1);
	fot[rt]=0;
	dfsf(rt,-1);
	int ans=dfsdp(rt,-1);/*
	cout<<"@"<<A<<" "<<rt<<"\n";
	for(i=1;i<=n;i++)cout<<din[i]<<" ";cout<<"\n";
	for(i=1;i<=n;i++)cout<<dot[i]<<" ";cout<<"\n";
	for(i=1;i<=n;i++)cout<<fot[i]<<" ";cout<<"\n";
	cout<<ans<<"\n";*/
	return ans;
}
int main(){
    if(UsingFile)freopen(NAME".out","r",stdin);
    if(UsingFile)freopen(NAME"wa.txt","w",stdout);
    int i,j,_T;
    int k;
    while(~scanf("%d%d",&n,&k)){
    	for(i=1;i<=n;i++)
    		scanf("%d",&a[i]),G[i].clear();
    	for(i=1;i<n;i++){
    		int u,v;
    		scanf("%d%d",&u,&v);
    		G[u].PB(v),G[v].PB(u);
    	}
    	vector<int>L;
    	for(i=1;i<=n;i++)
    		L.PB(a[i]);
    	sort(L.OP,L.ED);
    	L.erase(unique(L.OP,L.ED),L.ED);
    	int le=0,re=L.SZ-1,ge=-1;
    	while(re>=le){
    		if(re-le<=1){
    			if(cnt(L[re])>=k)ge=re;
    			else ge=le;
    			break;
    		}
    		int mid=(le+re)/2;
    		if(cnt(L[mid])>=k)le=mid;
    		else re=mid;
    	}
    	printf("%d\n",L[ge]);
    }
    return 0;
}
/*
13 7
13 14 21 22 11 12 8 19 5 3 4 23 18
2 1
3 1
4 2
5 4
6 3
7 2
8 1
9 5
10 6
11 8
12 6
13 8
11
*/


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

typedef vector<int> vi;
typedef pair<int,int> pii;
typedef long long int lld;

#define sz                           size()
#define pb                           push_back
#define mp                           make_pair
#define F                            first
#define S                            second
#define fill(a,v)                    memset((a),(v),sizeof (a))
#define INF                          INT_MAX
#define mod 1000000007
#define __sync__		     std::ios::sync_with_stdio(false);
#define all(a)			     a.begin(),a.end()

#define TRACE

#ifdef TRACE
#define trace1(x)                cerr << #x << ": " << x << endl;
#define trace2(x, y)             cerr << #x << ": " << x << " | " << #y << ": " << y << endl;
#define trace3(x, y, z)          cerr << #x << ": " << x << " | " << #y << ": " << y << " | " << #z << ": " << z << endl;
#define trace4(a, b, c, d)       cerr << #a << ": " << a << " | " << #b << ": " << b << " | " << #c << ": " << c << " | " << #d << ": " << d << endl;
#define trace5(a, b, c, d, e)    cerr << #a << ": " << a << " | " << #b << ": " << b << " | " << #c << ": " << c << " | " << #d << ": " << d << " | " << #e << ": " << e << endl;
#define trace6(a, b, c, d, e, f) cerr << #a << ": " << a << " | " << #b << ": " << b << " | " << #c << ": " << c << " | " << #d << ": " << d << " | " << #e << ": " << e << " | " << #f << ": " << f << endl;

#else

#define trace1(x)
#define trace2(x, y)
#define trace3(x, y, z)
#define trace4(a, b, c, d)
#define trace5(a, b, c, d, e)
#define trace6(a, b, c, d, e, f)

#endif

const int N = 2e5 + 10;
vi adj[N];
int a[N], sub[N], n, k, v;
lld dp[N];

void dfs0(int x, int p=-1)
{
	sub[x] = 1;
	lld mx = 0;
	for(int &to : adj[x])
	{
		if(to==p) continue;
		dfs0(to, x);
		sub[x] += sub[to];
		if(sub[to] == dp[to]) dp[x] += dp[to];
		else mx = max(mx, dp[to]);
	}
	if(a[x] >= v) dp[x]+=1+mx;
	else dp[x] = 0;
}

lld ans[N];
bool ok = 0;
lld dfs(int x, int p=-1, lld out = 0, lld out_sub = 0)
{
	int idx = -1;
	lld sec = 0, mx = 0, Ans = 0;
	for(int &to : adj[x])
	{
		if(to == p) continue;
		if(dp[to] == sub[to]) Ans += dp[to];
		else
		{
			if(dp[to] >= mx) sec = mx, mx = dp[to], idx = to;
			else if(dp[to] > sec) sec = dp[to];
		}
	}
	if(out_sub != out)
	{
		if(out >= mx) sec = mx, mx = out, idx = -2;
		else if(out > sec) sec = out;
	}
	else Ans += out;
	if(a[x] >= v)
		ans[x] = Ans + mx+1;
	else ans[x] = 0;
	if(ans[x] >= k) ok = 1;
	for(int &to : adj[x])
	{
		if(to == p) continue;
		if(idx == to)
		{
			dfs(to, x, ((a[x]>=v)?(ans[x] - mx + sec):0), sub[x] + out_sub - sub[to]);
			continue;
		}
		if(sub[to] == dp[to]) dfs(to, x, ((a[x]>=v)?(ans[x] - dp[to]):0), sub[x] + out_sub - sub[to]);
		else dfs(to, x, (a[x]>=v)?ans[x]:0, sub[x] + out_sub - sub[to]);
	}
}

int main()
{
	cin>>n>>k;
	for(int i=0;i<n;i++) cin>>a[i];
	for(int i=0;i<n-1;i++)
	{
		int u, v;
		cin>>u>>v;
		u--;v--;
		adj[u].pb(v);
		adj[v].pb(u);
	}
	lld l = 0, r = 1e6+10;
	while(l<r)
	{
		lld mid = l + (r-l+1)/2;
		v = mid;
		ok = 0;
		fill(dp, 0);
		dfs0(0);
		dfs(0);
		if(ok) l = mid;
		else r = mid-1;
	}
	cout<<l<<"\n";
	return 0;
}


#include <bits/stdc++.h>

using namespace std;

#define pb push_back
#define orta (bas + son >> 1)
#define sag (k + k + 1)
#define sol (k + k)
#define endl '\n'
#define foreach(i,x) for(type(x)i=x.begin();i!=x.end();i++)
#define FOR(ii,aa,bb) for(int ii=aa;ii<=bb;ii++)
#define ROF(ii,aa,bb) for(int ii=aa;ii>=bb;ii--)
#define mp make_pair
#define nd second
#define st first
#define type(x) __typeof(x.begin())

typedef pair < int ,int > pii;

typedef long long ll;

const long long linf = 1e18+5;
const int mod = (int) 1e9 + 7;
const int logN = 17;
const int inf = 1e9;
const int N = 2e5 + 5;

int all_cnt, sum[N], cnt[N], all[N], ok[N], n, m, a[N], x, y, z;
vector< int > v[N];

int dfs(int node, int root, int big) {
	cnt[node] = a[node] < big;
	all[node] = 1;
	sum[node] = 1;
	ok[node] = 1;
	int mx = 0, mx2 = 0;
	foreach(it, v[node]) {
		if(*it == root) continue;
		if(dfs(*it, node, big)) return true;
		sum[node] += sum[*it];
		cnt[node] += cnt[*it];
		if(ok[*it] == 1) all[node] += all[*it];
		else {
			ok[node] = 0;
			if(all[*it] >= mx) {
				mx2 = mx;
				mx = all[*it];
			} else mx2 = max(mx2, all[*it]);
		}
	}
	all[node] += mx;
	if(a[node] < big) { all[node] = 0; ok[node] = 0; }
	else if(all[node] + mx2 + (cnt[node] == all_cnt ? n - sum[node] : 0) >= m) return true;
	return false;
}

int main() {

	scanf("%d %d", &n, &m);

	FOR(i, 1, n) {
		scanf("%d", &a[i]);
	}

	FOR(i, 2, n) {
		scanf("%d %d", &x, &y);
		v[x].pb(y); v[y].pb(x);
	}

	int bas = 0, son = 1000000;

	while(bas < son) {
		int ort = bas + son >> 1;
		if(bas == ort) ort++;
		all_cnt = 0;
		FOR(i, 1, n) all_cnt += a[i] < ort;
		if(dfs(1, 0, ort)) bas = ort;
		else son = ort - 1;
	}

	cout << bas << endl;

	return 0;
}


#include <iostream>
#include <stack>
#include <math.h>
#include <set>
#include <stdio.h>
#include <algorithm>
#include <assert.h>
#include <map>
#include <queue>
#include <utility>
#include <vector>
using namespace std;
#define endl "\n"
#define mp make_pair
#define int long long
#define pii pair<int , int>
inline int in(){int32_t x ; scanf("%d",&x) ; return x ;}
inline string getStr(){char ch[500001] ; scanf("%s",ch) ;return ch;}
const int MAX_N = 2e5 + 10;
inline int gcd( int a, int b ) { return b == 0 ? a : gcd( b, a%b ); }
vector<int> g[MAX_N];
bool del[MAX_N] , forb[MAX_N] , mark[MAX_N];
int a[MAX_N] , dp[MAX_N] ,  ln , vl[MAX_N] , deg[MAX_N];
queue<int> Bomb ; int  n , k;
inline void BombProcess()
{
    for (int i = 1 ; i <= n ; i ++) if (deg[i] == 1 && !forb[i]) Bomb.push(i);
    while (Bomb.size()){
        int first = Bomb.front(); Bomb.pop();
        deg[first] --;
        del[first] = true;
        int FIND = -1;
        for (auto u : g[first]){
            if (!del[u] && !forb[u]){
                FIND = u;
                break;
            }
        }
        if (FIND != -1){
            vl[FIND] += vl[first];
            deg[FIND] --;
            if (deg[FIND] == 1)
                Bomb.push(FIND);
        }
        ln = max(ln , vl[first]);
        vl[first] = 0;
    }
}
inline void dfs(int v,  int pr = -1){
    mark[v] = true;
    int f = 0 , s = 0;
    dp[v] = vl[v];
    for (auto u : g[v]){
        if (pr == u || forb[u]) continue;
        dfs(u , v);
        if (dp[u] > f) {s = f ; f = dp[u];}
        else s = max(s , dp[u]);
    }

    ln = max(ln , dp[v] + f + s);
    dp[v] += f;
}
inline bool can(int low){
    ln = 0;
    for (int i = 1 ; i <= n ; i ++){
        mark[i] = 0;
        deg[i] = g[i].size();
        dp[i] = 0;
        del[i] = 0  ;
        mark[i] = 0 ;
        vl[i] = 1;
        forb[i] = (a[i] < low);
    }
    BombProcess();
    for (int i = 1 ; i <= n ; i ++) {
        if (!mark[i] && !forb[i]) dfs(i , -1);
    }
    return ln >= k;
}
int32_t main()
{
    n = in() , k = in();
    for (int i = 0 ; i < n ;  i ++) a[i + 1] = in();
    for (int i = 0 ; i < n - 1 ; i ++){
        int v = in() , u = in();
        g[v].push_back(u);
        g[u].push_back(v);
    }
    int l = 0 , r = (1 << 20) , best = 0 , mid;
    while (l <= r){
        mid = (l + r) >> 1;
        if (can(mid)) {best = mid ; l = mid + 1 ; continue ; }
        r = mid - 1;
    }
    cout << best << "\n";
}


#include <bits/stdc++.h>
using namespace std;
const int N = 2e5+5;
int n,sz[N],a[N],c,ret,dp[N];
pair<int,int> m[N][2];
vector<int> adj[N];
void dfs(int x,int p){
	int f=0,u,i,d;dp[x]=0;
	if(!sz[x])f=1,++sz[x];
	d= a[x]>=c ? 1 :0;
	for(i=0;i<adj[x].size();++i){
		u= adj[x][i];
		if(u!=p){
			dfs(u,x);
			if(f)sz[x]+=sz[u];
			if(dp[u]==sz[u])dp[x]+=dp[u];
			else{
				if(m[x][0].first<=dp[u])
					m[x][1]= m[x][0],m[x][0]=make_pair(dp[u],u);
				else if(m[x][1].first<dp[u])
					m[x][1]= make_pair(dp[u],u);
			}
		}
	}
	dp[x]+=d+ m[x][0].first;
	if(d==0)dp[x]=0;
}
int ar[3];
void dfs2(int x,int p,int d){
	int v=0,u,i,t=d,nd;
	if(a[x]>=c){
		if(d==n-sz[x])v=d,t=0;
		ar[0]= m[x][0].first,ar[1]= m[x][1].first,ar[2]=t;
		sort(ar,ar+3);
		ret= max(ret, dp[x]+ ar[2]+v-m[x][0].first);
	}
	for(i=0;i<adj[x].size();++i){
		u= adj[x][i];
		if(u!=p){
			nd= dp[x]-m[x][0].first+ max(m[x][0].first,t)+v;
			if(u==m[x][0].second)
				nd= dp[x]-m[x][0].first+ max(m[x][1].first,t)+v;
			else if(sz[u]==dp[u])
				nd-= sz[u];
			if(a[x]<c)nd=0;
			dfs2(u,x,nd);
		}
	}
}
int main(){
	int i,x,y,q,l,r,k,mid;
	cin>>n>>k;
	for(i=1;i<=n;++i)scanf("%d",&a[i]);
	for(i=0;i<n-1;++i)scanf("%d%d",&x,&y),adj[x].push_back(y),adj[y].push_back(x);
	dfs(1,0);
	l=1,r= 1e6;
	while(l<r){
		mid= (l+r+1)/2;
		c= mid;
		memset(m,0,sizeof(m));ret=0;
		dfs(1,0);
		dfs2(1,0,0);
		if(ret>=k)l= mid;
		else
			r= mid-1;
	}
	printf("%d\n",l);
}


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

const int N = 2e5 + 5;

int n, m, a[N], b[N], dp[N], sz[N], cur[N], ans, cnt, l, r, mid, x, y;
vector < int > g[N];

void dfs1(int v, int pr = -1){
    sz[v] = 1;
    for(int to : g[v]){
        if(to != pr){
            dfs1(to, v);
            sz[v] += sz[to];
        }
    }
}

void dfs2(int v, int pr = -1){
    int all = 0, mx1 = 0, mx2 = 0;
    for(int to : g[v]){
        if(to != pr){
            dfs2(to, v);
            cur[v] += cur[to];
            if(dp[to] == sz[to]){
                all += sz[to];
            }
            else if(dp[to] > mx1){
                mx2 = mx1;
                mx1 = dp[to];
            }
            else if(dp[to] > mx2){
                mx2 = dp[to];
            }
        }
    }
    if(!b[v]){
        dp[v] = 0;
    }
    else{
        dp[v] = all + mx1 + 1;
        cur[v]++;
    }
    if(n - sz[v] == cnt - cur[v]){
        all += n - sz[v];
    }
    if(b[v]){
        ans = max(ans, all + mx1 + mx2 + 1);
    }
}

inline bool check(int x){
    ans = cnt = 0;
    for(int i = 1; i <= n; i++){
        dp[i] = sz[i] = cur[i] = 0;
        b[i] = a[i] >= x;
        cnt += b[i];
    }
    dfs1(1);
    dfs2(1);
    return ans >= m;
}

main(){
    ios_base::sync_with_stdio(0);cin.tie(0);cout.tie(0);
    cin >> n >> m;
    for(int i = 1; i <= n; i++){
        cin >> a[i];
    }
    for(int i = 1; i < n; i++){
        cin >> x >> y;
        g[x].push_back(y);
        g[y].push_back(x);
    }
    r = 1e6;
    while(r - l > 1){
        mid = (r + l) >> 1;
        if(check(mid)){
            l = mid;
        }
        else{
            r = mid;
        }
    }
    if(check(r)){
        cout << r;
    }
    else{
        cout << l;
    }
}


#include <bits/stdc++.h>

using namespace std;

#ifdef NeverBeRed
#include "debug.h"
#else
#define debug(...) 9715
#endif
typedef long long ll;
typedef long double ld;
typedef complex<ld> point;
#define F first
#define S second

int main()
{
	#ifdef TurnRed
		//freopen("a.in", "r", stdin);
		//freopen("a.out", "w", stdout);
	#endif

	ios_base::sync_with_stdio(0), cin.tie(0);

	int n, k;
	cin >> n >> k;
	vector<int> val(n);
	for (auto &i : val) cin >> i;
	vector<vector<int>> adj(n);
	for (int i = 1, u, v; i < n; ++i)
	{
		cin >> u >> v;
		--u, --v;
		adj[u].push_back(v);
		adj[v].push_back(u);
	}

	auto solve = [&](int mn)
	{
		auto w = [&](int u) { return val[u] >= mn; };

		vector<int> sz(n), dp(n), wsz(n), rdp(n);
		vector<multiset<int>> sub(n);
		for (int i = 0; i < n; ++i)
			sub[i].insert(0);

		function<void(int, int)> dfs = [&](int u, int p)
		{
			sz[u] = 1;
			wsz[u] = w(u);
			for (auto v : adj[u])
				if (v != p)
				{
					dfs(v, u);
					sz[u] += sz[v];
					wsz[u] += wsz[v];
					if (sz[v] == wsz[v])
						dp[u] += sz[v];
					else
						sub[u].insert(rdp[v]);
				}
			rdp[u] = (dp[u] + 1 + *sub[u].rbegin()) * w(u);
		};
		dfs(0, -1);

		int best = 0;
		function<void(int, int)> dfs2 = [&](int u, int p)
		{
			best = max(best, rdp[u]);
			for (auto v : adj[u])
				if (v != p)
				{
					int rdpu = rdp[u], rdpv = rdp[v];

					if (sz[v] == wsz[v])
						dp[u] -= sz[v];
					else
						sub[u].erase(sub[u].find(rdp[v]));
					sz[u] -= sz[v];
					wsz[u] -= wsz[v];
					rdp[u] = (dp[u] + 1 + *sub[u].rbegin()) * w(u);

					sz[v] += sz[u];
					wsz[v] += wsz[u];
					if (sz[u] == wsz[u])
						dp[v] += sz[u];
					else
						sub[v].insert(rdp[u]);
					rdp[v] = (dp[v] + 1 + *sub[v].rbegin()) * w(v);

					dfs2(v, u);

					rdp[v] = rdpv;
					if (sz[u] == wsz[u])
						dp[v] -= sz[u];
					else
						sub[v].erase(sub[v].find(rdp[u]));
					wsz[v] -= wsz[u];
					sz[v] -= sz[u];

					rdp[u] = rdpu;
					wsz[u] += wsz[v];
					sz[u] += sz[v];
					if (sz[v] == wsz[v])
						dp[u] += sz[v];
					else
						sub[u].insert(rdp[v]);
				}
		};
		dfs2(0, -1);

		return best;
	};

	int lo = 1, hi = 1e6;
	while (lo < hi)
	{
		int md = (lo + hi + 1) >> 1;
		if (solve(md) >= k)
			lo = md;
		else
			hi = md - 1;
	}
	cout << lo << "\n";

	return 0;
}


#include<bits/stdc++.h>
using namespace std;
int n,k,arr[1<<18];
bool vis[1<<18],big[1<<18];int failed[1<<18],failed1[1<<18];
vector<int>adj[1<<18];
pair<int,int>mx[1<<18],mx1[1<<18];
int sum[1<<18];
void dfs(int x,int p)
{
    int sz=adj[x].size(),nxt;
    bool ok=1;
    pair<int,int>pii;
    sum[x]=1;
    vis[x]=1;
    for(int i=0;i<sz;++i)
    {
        nxt=adj[x][i];
        if(nxt==p)continue;
        if(vis[nxt]){failed1[x]=failed[x];failed[x]=nxt;continue;}
        dfs(nxt,x);
        if(failed[nxt]){
            pii=make_pair(sum[nxt]+mx[nxt].first,nxt);
            if(pii>mx[x])swap(pii,mx[x]);
            if(pii>mx1[x])swap(pii,mx1[x]);
        }
        else sum[x]+=sum[nxt];
        if(failed[nxt]){failed1[x]=failed[x];failed[x]=nxt;continue;}
    }
}
void dfs1(int x,int p)
{
    //cout<<x<<" "<<sum[x]<<" "<<mx[x].first<<" "<<mx1[x].first<<" h\n";
    if(p){
        pair<int,int>pii=mx[p];
        if(mx[p].second==x)pii=mx1[p];
        if(!(!failed[p]||(failed[p]==x&&!failed1[p])))pii.first+=sum[p];
        if(!failed[x])pii.first-=sum[x];
        if(!failed[p]){
            sum[x]+=sum[p]-sum[x];
        }
        else if(failed[p]==x&&!failed1[p]){
            sum[x]+=sum[p];
        }

        //cout<<x<<" "<<p<<" "<<pii.first<<endl;
        if(pii>mx[x])swap(pii,mx[x]);
        if(pii>mx1[x])swap(pii,mx1[x]);
        //change failed
        if((failed[p]&&failed[p]!=x)||(failed1[p]&&failed1[p]!=x)){
            failed1[x]=failed[x];
            failed[x]=p;
        }
    }
    //cout<<x<<" "<<sum[x]<<" "<<mx[x].first<<" "<<mx1[x].first<<" f\n";

    int sz=adj[x].size(),nxt;
    for(int i=0;i<sz;++i){
        nxt=adj[x][i];
        if(nxt==p)continue;
        if(!big[nxt])continue;
        dfs1(nxt,x);
    }
}
bool check(int mid)
{
    //cout<<mid<<endl;
    for(int i=1;i<=n;++i){
        big[i]=(arr[i]>=mid);
        vis[i]=(arr[i]<mid);
        mx[i]=mx1[i]=make_pair(0,0);
        sum[i]=0;
        failed[i]=failed1[i]=0;
    }
    for(int i=1;i<=n;++i){
        if(!vis[i]){
            dfs(i,0);
            dfs1(i,0);
        }
    }
    //for(int i=1;i<=n;++i)cout<<i<<" "<<sum[i]<<" "<<mx[i].first<<" "<<mx1[i].first<<" "<<failed[i]<<endl;
    //cout<<"---------------------------\n";
    for(int i=1;i<=n;++i){
        if(big[i]){
            if(sum[i]+mx[i].first>=k)return 1;
        }
    }
    return 0;

}
int main()
{
    cin>>n>>k;
    for(int i=1;i<=n;++i)scanf("%d",arr+i);
    int u,v;
    for(int i=1;i<n;++i){
        scanf("%d%d",&u,&v);
        adj[u].push_back(v);
        adj[v].push_back(u);
    }
    int st=1,en=1000002,mid;
    //check(252764);return 0;
    while(st<en){
        mid=(st+en)/2;
        if(check(mid))st=mid+1;
        else en=mid;
    }
    cout<<en-1;

}


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

// total balls: 2 <= n <= 200 000
// numbers of balls to inspect: 1 <= k <= n

// n integers ai, 1 <= ai <= 1 000 000, time to build ith ball

// n-1 tines, ui vi, 1 <= ui, vi <= n, ui =/= vi, connection between balls ui and vi.

int n, k, *a, *u, *v;
int *deg, *sdeg, *adj;
int maxdfs, *vis;

pair<int,bool> dfs(int idx, int brk) {
	if (a[idx] < brk) return make_pair(0,false);
	if (vis[idx] == 1) return make_pair(0,true);
	vis[idx] = 1;
	int hi1 = 0;
	int hi2 = 0;
	int fre = 0;
	bool b = true;
	for (int i = 0; i < deg[idx]; i++) {
		int nbr = adj[sdeg[idx]+i];
		pair<int,bool> result = dfs(nbr,brk);
		if (result.second) {
			fre += result.first;
		} else {
			b = false;
			if (result.first > hi2) hi2 = result.first;
			if (hi2 > hi1) swap(hi1, hi2);
		}
	}
	if (b) {
		return make_pair(fre+1,true);
	}
	else {
		maxdfs = max(maxdfs, hi1+hi2+fre+1);
		return make_pair(hi1+fre+1,false);
	}
}

int binsearch(int lo, int hi) {
	if (lo+1 == hi) return lo;
	int mid = lo+(hi-lo)/2;
	maxdfs = 0;
	vis = (int *)calloc(n,sizeof(int));
	for (int i = 0; i < n; i++) {
		if (vis[i] == 0 && a[i] >= mid) {
			for (int j = 0; j < deg[i]; j++) {
				if (a[adj[sdeg[i]+j]] < mid) {
					dfs(i,mid);
					break;
				}
			}
		}
	}
	free(vis);
	if (maxdfs >= k) return binsearch(mid, hi);
	else return binsearch(lo, mid);
}

int main() {
	scanf("%d %d", &n, &k);
	a = (int *)malloc(n*sizeof(int));
	int mina = 1000000;
	for (int i = 0; i < n; i++) {
		scanf("%d", a+i);
		mina = min(mina, a[i]);
	}
	deg = (int *)calloc(n,sizeof(int));
	u = (int *)malloc((n-1)*sizeof(int));
	v = (int *)malloc((n-1)*sizeof(int));
	for (int i = 0; i < n-1; i++) {
		int u1, v1;
		scanf("%d %d", &u1, &v1);
		u[i] = u1-1;
		v[i] = v1-1;
		deg[u[i]]++;
		deg[v[i]]++;
	}
	sdeg = (int *)malloc(n*sizeof(int));
	sdeg[0] = 0;
	for (int i = 1; i < n; i++) sdeg[i] = sdeg[i-1]+deg[i-1];
	adj = (int *)malloc(2*(n-1)*sizeof(int));
	free(deg);
	deg = (int *)calloc(n,sizeof(int));
	for (int i = 0; i < n-1; i++) {
		adj[sdeg[u[i]]+deg[u[i]]] = v[i];
		adj[sdeg[v[i]]+deg[v[i]]] = u[i];
		deg[u[i]]++;
		deg[v[i]]++;
	}
	printf("%d\n", binsearch(mina,1000001));
	return 0;
}


#include<iostream>
#include<cstdio>
#include<string>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;

const int N = 200005;
int n,m,lim,p = 1,a[N],nex[N*2],spot[N*2],head[N],fa[N],f[N],g[N];
int maxcolor[N][2],c[N];
bool color[N],v[N];

void add(int x,int y)
{
	nex[++p] = head[x], head[x] = p, spot[p] = y;
	nex[++p] = head[y], head[y] = p, spot[p] = x;
}

void dfs1(int x)
{
	int tp,y,cnt = 0,m1 = 0,m2 = 0;
	v[x] = 1;
	for(tp = head[x]; y = spot[tp],tp; tp = nex[tp])
		if(a[y]>=lim && y!=fa[x]) {
			fa[y] = x;
			dfs1(y);
			if(!c[y]) cnt += f[y];
			else {
				c[x]++;
				if(f[y]>m2) m2 = f[y];
				if(m1<m2) swap(m1,m2);
			}
		}
	maxcolor[x][0] = m1;
	maxcolor[x][1] = m2;
	f[x] = cnt+m1+1;
	c[x] += color[x];
}

void dfs2(int x, int &ret)
{
	if(fa[x]) {//Èç¹ûx²»ÊÇµÚÒ»´ÎËÑË÷µÄ¸ù½Úµã
		if(c[fa[x]]-(c[x]!=0)>0) {
			//xÒªÔÚËüµ±³õÑ¡µÄcolor½áµãºÍËü¸¸Ç×³ýÈ¥ËüÄÇ²¿·ÖÖÐÑ¡Ôñ
			if(c[x]) {//xµ±³õ±»Ñ¡»ò²»Ñ¡
				if(f[x]<maxcolor[fa[x]][0]) {//µ±³õxÃ»ÓÐ±»Ëü¸¸Ç×Ñ¡ÖÐ
					g[x] = f[x]-maxcolor[x][0]+max(maxcolor[x][0], g[fa[x]]);
					if(g[fa[x]]>maxcolor[x][1])
						maxcolor[x][1] = g[fa[x]];
					if(maxcolor[x][0]<maxcolor[x][1])
						swap(maxcolor[x][0], maxcolor[x][1]);
				}

				else {//µ±³õËü±»Ñ¡ÖÐÁË
					g[x] = f[x]-maxcolor[x][0]+max(maxcolor[x][0],
						g[fa[x]]-maxcolor[fa[x]][0]+maxcolor[fa[x]][1]);
					//³ýÈ¥ËüËü¸¸Ç×Ö»ÄÜÍË¶øÇóÆä´ÎÁË
					if(g[fa[x]]-maxcolor[fa[x]][0]+maxcolor[fa[x]][1]>maxcolor[x][1])
						maxcolor[x][1] = g[fa[x]]-maxcolor[fa[x]][0]+maxcolor[fa[x]][1];
					if(maxcolor[x][0]<maxcolor[x][1])
						swap(maxcolor[x][0], maxcolor[x][1]);
				}
			}
			else //µ±³õx±»Ö±½Ó¼ÓÉÏ
				g[x] = f[x]-maxcolor[x][0]+max(maxcolor[x][0], g[fa[x]]-f[x]);
		}
		else {
			//xÖ±½Ó¼ÓÉÏËü¸¸Ç×
			if(c[x]) {
				if(f[x]<maxcolor[fa[x]][0])
					g[x] = f[x]+g[fa[x]];
				else
					g[x] = f[x]+g[fa[x]]-maxcolor[fa[x]][0]+maxcolor[fa[x]][1];
			}
			else
				g[x] = g[fa[x]];//f[x]+g[fa[x]]-f[x]£¬ºÍËü¸¸Ç×Ò»Ñù
		}
		c[x] += ((c[fa[x]]-(c[x]!=0))!=0);
	}
	else g[x] = f[x];
	ret = max(ret, g[x]);
	for(int tp = head[x]; tp; tp = nex[tp])
		if(a[spot[tp]]>=lim && spot[tp]!=fa[x])
			dfs2(spot[tp], ret);
}
int solve()
{
	memset(v, 0, sizeof(v));
	memset(fa, 0, sizeof(fa));
	memset(maxcolor, 0, sizeof(maxcolor));
	memset(c, 0, sizeof(c));
	int maxn = 0;
	for(int i = 1; i<=n; i++)
		if(a[i]>=lim && v[i]==0) {
			dfs1(i), dfs2(i,maxn);
		}
	return maxn>=m;
}

int main()
{
	int i,x,y,l,r,tp;
	cin >> n >> m;
	for(i = 1; i<=n; i++)
		scanf("%d", &a[i]);
	for(i = 1; i<n; i++) {
		scanf("%d%d", &x,&y);
		add(x,y);
	}
	for(l = 1,r = 1000000; l<r; )
	{
		lim = l+r+1>>1;
		memset(color, 0, sizeof(color));
		for(i = 1; i<=n; i++)
			if(a[i]<lim)
				for(tp = head[i]; tp; tp = nex[tp])
					color[spot[tp]] = 1;
		if(solve()) l = lim;
		else r = lim-1;
	}
	cout << l;
	return 0;
}


#include <bits/stdc++.h>

using namespace std;

struct DP {
  int sum;
  int mx;
};

inline DP join(DP &a, DP &b) {
  DP c;
  c.sum = a.sum + b.sum;
  c.mx = max(a.mx, b.mx);
  return c;
}

const int N = 200010;

vector <int> g[N];
int total[N];
int f[N], dp[N];
bool good[N];
int a[N];
int n;

void dfs(int v, int pr) {
  int sz = g[v].size();
  total[v] = 1;
  int sum = 0, mx = 0;
  for (int j = 0; j < sz; j++) {
    int u = g[v][j];
    if (u == pr) {
      continue;
    }
    dfs(u, v);
    total[v] += total[u];
    if (f[u] == total[u]) {
      sum += f[u];
    } else {
      mx = max(mx, f[u]);
    }
  }
  f[v] = sum + mx + 1;
  if (!good[v]) {
    f[v] = 0;
  }
}

void solve(int v, int pr, int up) {
  int sz = g[v].size();
  vector <int> children;
  for (int j = 0; j < sz; j++) {
    int u = g[v][j];
    if (u == pr) {
      continue;
    }
    children.push_back(u);
  }
  int cnt = children.size();
  int sum = 0, mx = 0;
  for (int j = 0; j < cnt; j++) {
    int u = children[j];
    if (f[u] == total[u]) {
      sum += f[u];
    } else {
      mx = max(mx, f[u]);
    }
  }
  if (up == n - total[v]) {
    sum += up;
  } else {
    mx = max(mx, up);
  }
  dp[v] = sum + mx + 1;
  if (!good[v]) {
    dp[v] = 0;
  }
  if (cnt == 0) {
    return;
  }
  vector <DP> pref(cnt + 1);
  vector <DP> suf(cnt + 1);
  pref[0] = {0, 0};
  for (int j = 0; j < cnt; j++) {
    int u = children[j];
    pref[j + 1] = pref[j];
    if (f[u] == total[u]) {
      pref[j + 1].sum += f[u];
    } else {
      pref[j + 1].mx = max(pref[j + 1].mx, f[u]);
    }
  }
  suf[cnt] = {0, 0};
  for (int j = cnt - 1; j >= 0; j--) {
    int u = children[j];
    suf[j] = suf[j + 1];
    if (f[u] == total[u]) {
      suf[j].sum += f[u];
    } else {
      suf[j].mx = max(suf[j].mx, f[u]);
    }
  }
  for (int j = 0; j < cnt; j++) {
    int u = children[j];
    DP z = join(pref[j], suf[j + 1]);
    if (up == n - total[v]) {
      z.sum += up;
    } else {
      z.mx = max(z.mx, up);
    }
    int new_up = z.sum + z.mx + 1;
    if (!good[v]) {
      new_up = 0;
    }
    solve(u, v, new_up);
  }
}

int main() {
  int k;
  scanf("%d %d", &n, &k);
  for (int i = 0; i < n; i++) {
    scanf("%d", a + i);
  }
  for (int i = 0; i < n; i++) {
    g[i].clear();
  }
  for (int i = 0; i < n - 1; i++) {
    int x, y;
    scanf("%d %d", &x, &y);
    x--; y--;
    g[x].push_back(y);
    g[y].push_back(x);
  }

  int low = 0, high = 1000010;
  while (low < high) {
    int mid = (low + high + 1) >> 1;
    for (int j = 0; j < n; j++) {
      good[j] = (a[j] >= mid);
    }
    dfs(0, -1);
    solve(0, -1, 0);
    int best = 0;
    for (int j = 0; j < n; j++) {
      best = max(best, dp[j]);
    }
    if (best >= k) {
      low = mid;
    } else {
      high = mid - 1;
    }
  }
  printf("%d\n", low);
  return 0;
}


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

using namespace std;

namespace Stand_IO_Operation
{
	#define For(i,x,y) for (int i=x,_Lim=y;i<_Lim;i++)
	#define Rep(i,x,y) for (int i=x,_Lim=y;i<=_Lim;i++)
	#define Dep(i,x,y) for (int i=x,_Lim=y;i>=_Lim;i--)

	#define mk(a,b) make_pair(a,b)

	typedef long long ll;
	typedef double ld;
	typedef pair<int,int> PII;
	typedef pair<ld,ld> PDD;
	typedef pair<ll,ll> PLL;

	inline int read(){
		int f=1,res=0,ch=getchar();
		while (ch<'0' || ch>'9'){
			if (ch=='-') f=-1;ch=getchar();
		}
		while (ch>='0' && ch<='9') res=res*10+ch-48,ch=getchar();
		return f*res;
	}
	int _sta[1<<8];
	inline void write(int val){
		if (!val){
			putchar('0');return;
		}
		if (val<0) putchar('-'),val=-val;
		*_sta=0;while (val>0) _sta[++*_sta]=val%10,val/=10;
		Dep(i,*_sta,1) putchar(_sta[i]+48);
	}
};
using namespace Stand_IO_Operation;

const int N = 200005;
int n,k,a[N],tag[N],ans,cnt;
vector<int> G[N];
int sz[N],dp[N],tag_cnt[N];

void init(int val){
	ans = cnt = 0;
	for(int i = 1;i <= n;i++){
		tag[i] = a[i] >= val ? 1 : 0;
		cnt += tag[i];
	}
	memset(tag_cnt,0,sizeof tag_cnt);
}

void dfs1(int cur,int fa){
	sz[cur] = 1;
	for(int i = 0;i < G[cur].size();i++){
		int u = G[cur][i];
		if(u == fa) continue;
		dfs1(u,cur);
		sz[cur] += sz[u];
	}
}

void dfs2(int cur,int fa){
	if(ans >= k) return;
	int all = 0,max1 = 0,max2 = 0;
	for(int i = 0;i < G[cur].size();i++){
		int u = G[cur][i];
		if(u == fa) continue;
		dfs2(u,cur);
		tag_cnt[cur] += tag_cnt[u];
		if(dp[u] == sz[u])
			all += dp[u];
		else if(dp[u] > max1){
			max2 = max1;
			max1 = dp[u];
		}
		else if(dp[u] > max2)
			max2 = dp[u];
	}
	if(!tag[cur]) dp[cur] = 0;
	else{
		dp[cur] = all+max1+1;
		tag_cnt[cur]++;
	}
	if(n-sz[cur] == cnt-tag_cnt[cur])
		all += n-sz[cur];
	if(tag[cur])
		ans = max(ans,all+max1+max2+1);
}

int main(){
	n = read(); k = read();
	for(int i = 1;i <= n;i++)
		a[i] = read();
	for(int i = 1;i < n;i++){
		int u = read(),v = read();
		G[u].push_back(v);
		G[v].push_back(u);
	}
	int l = 1,r = 1000000,mid;
	dfs1(1,0);
	while(l <= r){
		mid = (l+r)>>1;
		init(mid);
		dfs2(1,0);
		if(ans >= k) l = mid+1;
		else r = mid-1;
	}
	write(r);
	return 0;
}


#include<iostream>
#include<cstdio>
#include<string>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;

const int N = 200005;
int n,m,lim,p = 1,a[N],nex[N*2],spot[N*2],head[N],fa[N],f[N],g[N];
int maxcolor[N][2],c[N];
bool color[N],v[N];

void add(int x,int y)
{
	nex[++p] = head[x], head[x] = p, spot[p] = y;
	nex[++p] = head[y], head[y] = p, spot[p] = x;
}

void dfs0(int x)
{
	int tp,y;
	v[x] = 1;
	for(tp = head[x]; y = spot[tp],tp; tp = nex[tp])
		if(a[y]>=lim && fa[x]!=y) {
			fa[y] = x;
			dfs0(y);
			if(c[y]) c[x]++;
		}
	c[x] += color[x];
//	printf("c[%d] = %d\t", x, c[x]);
}
/*
void dfs1(int x)
{
	int tp,y,cnt = 0,m1 = 0,m2 = 0;

	for(tp = head[x]; y = spot[tp],tp; tp = nex[tp])
		if(a[y]>=lim && y!=fa[x]) {
			dfs1(y);
			if(!color[y]) cnt += f[y];
			else {
				if(m1==0) m1 = f[y];
				else {
					if(f[y]>m2) m2 = f[y];
					if(m1<m2) swap(m1,m2);
				}
			}
		}
	maxcolor[x][0] = m1;
	maxcolor[x][1] = m2;
	f[x] = cnt+m1+1;
}

void dfs2(int x, int &ret)
{
	if(fa[x]) {//Èç¹ûx²»ÊÇµÚÒ»´ÎËÑË÷µÄ¸ù½Úµã
		if(color[fa[x]]) {
			//xÒªÔÚËüµ±³õÑ¡µÄcolor½áµãºÍËü¸¸Ç×³ýÈ¥ËüÄÇ²¿·ÖÖÐÑ¡Ôñ
			if(color[x]) {//xµ±³õ±»Ñ¡»ò²»Ñ¡
				if(f[x]<maxcolor[fa[x]][0])//µ±³õxÃ»ÓÐ±»Ëü¸¸Ç×Ñ¡ÖÐ
					g[x] = f[x]-maxcolor[x][0]+max(maxcolor[x][0], g[fa[x]]);
				else //µ±³õËü±»Ñ¡ÖÐÁË
					g[x] = f[x]-maxcolor[x][0]+max(maxcolor[x][0],
						g[fa[x]]-maxcolor[fa[x]][0]+maxcolor[fa[x]][1]);
						//³ýÈ¥ËüËü¸¸Ç×Ö»ÄÜÍË¶øÇóÆä´ÎÁË
			}
			else //µ±³õx±»Ö±½Ó¼ÓÉÏ
				g[x] = f[x]-maxcolor[x][0]+max(maxcolor[x][0], g[fa[x]]-f[x]);
		}
		else {
			//xÖ±½Ó¼ÓÉÏËü¸¸Ç×
			if(color[x]) {
				if(f[x]<maxcolor[fa[x]][0])
					g[x] = f[x]+g[fa[x]];
				else
					g[x] = f[x]+g[fa[x]]-maxcolor[fa[x]][0]+maxcolor[fa[x]][1];
			}
			else
				g[x] = g[fa[x]];//f[x]+g[fa[x]]-f[x]£¬ºÍËü¸¸Ç×Ò»Ñù
		}
	}
	else g[x] = f[x];
	ret = max(ret, g[x]);
	for(int tp = head[x]; tp; tp = nex[tp])
		if(a[spot[tp]]>=lim && spot[tp]!=fa[x])
			dfs2(spot[tp], ret);
}
*/
void dfs1(int x)
{
	int tp,y,cnt = 0,m1 = 0,m2 = 0;

	for(tp = head[x]; y = spot[tp],tp; tp = nex[tp])
		if(a[y]>=lim && y!=fa[x]) {
			dfs1(y);
			if(!c[y]) cnt += f[y];
			else {
				if(f[y]>m2) m2 = f[y];
				if(m1<m2) swap(m1,m2);
			}
		}
	maxcolor[x][0] = m1;
	maxcolor[x][1] = m2;
	f[x] = cnt+m1+1;
}

void dfs2(int x, int &ret)
{
	if(fa[x]) {//Èç¹ûx²»ÊÇµÚÒ»´ÎËÑË÷µÄ¸ù½Úµã
		if(c[fa[x]]-(c[x]!=0)>0) {
			//xÒªÔÚËüµ±³õÑ¡µÄcolor½áµãºÍËü¸¸Ç×³ýÈ¥ËüÄÇ²¿·ÖÖÐÑ¡Ôñ
			if(c[x]) {//xµ±³õ±»Ñ¡»ò²»Ñ¡
				if(f[x]<maxcolor[fa[x]][0]) {//µ±³õxÃ»ÓÐ±»Ëü¸¸Ç×Ñ¡ÖÐ
					g[x] = f[x]-maxcolor[x][0]+max(maxcolor[x][0], g[fa[x]]);
					if(g[fa[x]]>maxcolor[x][1])
						maxcolor[x][1] = g[fa[x]];
					if(maxcolor[x][0]<maxcolor[x][1])
						swap(maxcolor[x][0], maxcolor[x][1]);
				}

				else {//µ±³õËü±»Ñ¡ÖÐÁË
					g[x] = f[x]-maxcolor[x][0]+max(maxcolor[x][0],
						g[fa[x]]-maxcolor[fa[x]][0]+maxcolor[fa[x]][1]);
					//³ýÈ¥ËüËü¸¸Ç×Ö»ÄÜÍË¶øÇóÆä´ÎÁË
					if(g[fa[x]]-maxcolor[fa[x]][0]+maxcolor[fa[x]][1]>maxcolor[x][1])
						maxcolor[x][1] = g[fa[x]]-maxcolor[fa[x]][0]+maxcolor[fa[x]][1];
					if(maxcolor[x][0]<maxcolor[x][1])
						swap(maxcolor[x][0], maxcolor[x][1]);
				}
			}
			else //µ±³õx±»Ö±½Ó¼ÓÉÏ
				g[x] = f[x]-maxcolor[x][0]+max(maxcolor[x][0], g[fa[x]]-f[x]);
		}
		else {
			//xÖ±½Ó¼ÓÉÏËü¸¸Ç×
			if(c[x]) {
				if(f[x]<maxcolor[fa[x]][0])
					g[x] = f[x]+g[fa[x]];
				else
					g[x] = f[x]+g[fa[x]]-maxcolor[fa[x]][0]+maxcolor[fa[x]][1];
			}
			else
				g[x] = g[fa[x]];//f[x]+g[fa[x]]-f[x]£¬ºÍËü¸¸Ç×Ò»Ñù
		}
		c[x] += ((c[fa[x]]-(c[x]!=0))!=0);
	}
	else g[x] = f[x];
//	printf("g[%d] = %d c[%d] = %d\t", x, g[x],x,c[x]);
	ret = max(ret, g[x]);
	for(int tp = head[x]; tp; tp = nex[tp])
		if(a[spot[tp]]>=lim && spot[tp]!=fa[x])
			dfs2(spot[tp], ret);
}
int solve()
{
	memset(v, 0, sizeof(v));
	memset(fa, 0, sizeof(fa));
	memset(maxcolor, 0, sizeof(maxcolor));
	memset(c, 0, sizeof(c));
	int maxn = 0;
//	cout <<"solve " <<lim<<endl;
	for(int i = 1; i<=n; i++)
		if(a[i]>=lim && v[i]==0) {
//			cout << "dfs from "<<i<<endl;
			dfs0(i), dfs1(i), dfs2(i,maxn);
		}
//	cout << maxn << endl;
//	for(int i = 1; i<=n; i++) cout << color[i]<<' ';
///	cout << endl;
	return maxn>=m;
}

int main()
{
//	freopen("shuju.in", "r", stdin);
//	freopen("out.txt", "w", stdout);
	int i,x,y,l,r,tp;
	cin >> n >> m;
	for(i = 1; i<=n; i++)
		scanf("%d", &a[i]);
	for(i = 1; i<n; i++) {
		scanf("%d%d", &x,&y);
		add(x,y);
	}
	for(l = 1,r = 1000000; l<r; )
	{
		lim = l+r+1>>1;
		memset(color, 0, sizeof(color));
		for(i = 1; i<=n; i++)
			if(a[i]<lim)
				for(tp = head[i]; tp; tp = nex[tp])
					color[spot[tp]] = 1;
		if(solve()) l = lim;
		else r = lim-1;
	}
	cout << l;
	return 0;
}


#include <bits/stdc++.h>
#define REP(i, n) for(int i = 0;i < n;++i)
#define FOR(i, a, b) for(int i = a;i < b;++i)
#define pb push_back
#define pc(x) __builtin_popcountll(x)
#define X first
#define Y second
using namespace std;
typedef long long int ll;
typedef pair<int, int> ii;
const int MAX = 201000;
int a[MAX];
int n, k;
int eu[MAX], ev[MAX];
bool cant[MAX];
int deg[MAX];
int val[MAX];
int down[MAX][2];
bool vis[MAX];
set<int> e[MAX];

void cut(int x) {
	set<ii> s;
	REP(i, n) if(a[i] >= x && e[i].size()) s.insert(ii(deg[i], i));
	while(s.size() && s.begin()->first == 1) {
		int u = s.begin()->second;
		deg[u]--;
		s.erase(s.begin());
		if(cant[u]) continue;
		int v = *e[u].begin();
		e[u].clear();
		e[v].erase(u);
		s.erase(ii(deg[v], v));
		--deg[v];
		s.insert(ii(deg[v], v));
		val[v] += val[u];
	}
}

int DFS(int u) {
	vis[u] = true;
	int res = 0;
	for(auto it : e[u]) {
		int v = it;
		if(vis[v]) continue;
		res = max(res, DFS(v));
		down[u][0] = max(down[u][0], down[v][1]);
		if(down[u][0] > down[u][1]) swap(down[u][0], down[u][1]);
	}
	down[u][0] += val[u];
	down[u][1] += val[u];
	return max(res, down[u][0] + down[u][1] - val[u]);
}

bool f(int x) {
	REP(i, n) {
		deg[i] = 0;
		if(a[i] >= x) val[i] = 1;
		else val[i] = 0;
		vis[i] = cant[i] = false;
		down[i][0] = down[i][1] = 0;
		e[i].clear();
	}
	REP(i, n - 1) {
		int u = eu[i];
		int v = ev[i];
		if(a[u] >= x && a[v] >= x) {
			e[u].insert(v);
			e[v].insert(u);
		}
		else {
			cant[u] = true;
			cant[v] = true;
		}
		++deg[u];
		++deg[v];
	}
	cut(x);
	REP(i, n) {
		if(!vis[i] && a[i] >= x) {
			if(DFS(i) >= k) return true;
		}
	}
	return false;
}

int main() {
	srand(time(NULL));
	scanf("%d %d", &n, &k);
	REP(i, n) scanf("%d", a + i);
	REP(i, n - 1) scanf("%d %d", &eu[i], &ev[i]);
	REP(i, n - 1) --eu[i], --ev[i];
	int lo = 1;
	int hi = 1000000;
	int mid = 0;
	while(lo < hi) {
		mid = (lo + hi + 1) / 2;
		if(f(mid)) lo = mid;
		else hi = mid - 1;
	}
	printf("%d\n", lo);
}