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

using ll = long long;
using ld  = long double;
using pll = pair<ll, ll>;
using pld = pair<ld, ld>;
const int INF=1e9+7;
const ll LINF=9223372036854775807;
const ll MOD=1e9+7;
const ld PI=acos(-1);
const ld EPS = 1e-10; //微調整用（EPSより小さいと0と判定など）

int ii() { int x; if (scanf("%d", &x)==1) return x; else return 0; }
long long il() { long long x; if (scanf("%lld", &x)==1) return x; else return 0; }
string is() { string x; cin >> x; return x; }
char ic() { char x; cin >> x; return x; }
void oi(int x) { printf("%d ", x); }
void ol(long long x) { printf("%lld ", x); }
void od_nosp(double x) { printf("%.15f", x); } // 古い問題用
void od(double x) { printf("%.15f ", x); }
// long doubleで受け取り、fをLfなどに変えて出力すると、変な数値が出る
// それをなんとかするには独自の出力を作らなければならなそう
void os(const string &s) { printf("%s ", s.c_str()); }
void oc(const char &c) { printf("%c ", c); }
#define o_map(v){cerr << #v << endl; for(const auto& xxx: v){cout << xxx.first << " " << xxx.second << "\n";}} //動作未確認
void br() { putchar('\n'); }

// #define gcd __gcd //llは受け取らない C++17~のgcdと違うので注意
// int lcm(int a, int b){return a / gcd(a, b) * b;}
#define begin_end(a) a.begin(),a.end() //sort(begin_end(vec));
#define REP(i,m,n) for(ll i=(ll)(m) ; i < (ll)(n) ; i++ )
#define DREP(i,m,n) for(ll i=(ll)(m) ; i > (ll)(n) ; i-- )
#define rep(i,n) REP(i,0,n)
#define m_p(a,b) make_pair(a,b)
#define SORT_UNIQUE(c) (sort(c.begin(),c.end()), c.resize(distance(c.begin(),unique(c.begin(),c.end()))))
#define p_b push_back
#define SZ(x) ((ll)(x).size()) //size()がunsignedなのでエラー避けに
#define endk '\n'


// coutによるpairの出力（空白区切り）
template<typename T1, typename T2> ostream& operator<<(ostream& s, const pair<T1, T2>& p) {return s << "(" << p.first << " " << p.second << ")";}
// coutによるvectorの出力（空白区切り）
template<typename T> ostream& operator<<(ostream& s, const vector<T>& v) {
  int len = v.size();
  for (int i = 0; i < len; ++i) {
    s << v[i]; if (i < len - 1) s << " "; //"\t"に変えるとTabで見やすく区切る
  }
  return s;
}
// coutによる多次元vectorの出力（空白区切り）
template<typename T> ostream& operator<<(ostream& s, const vector< vector<T> >& vv) {
  int len = vv.size();
  for (int i = 0; i < len; ++i) {
    s << vv[i] << endl;
  }
  return s;
}

//最大値、最小値の更新。更新したor等しければtrueを返す
template<typename T>
bool chmax(T& a, T b){return (a = max(a, b)) == b;}
template<typename T>
bool chmin(T& a, T b){return (a = min(a, b)) == b;}

//4近傍（上下左右） rep(i, 2) にすると右・下だけに進む
vector<int> dx_4 = {1, 0, -1, 0};
vector<int> dy_4 = {0, 1, 0, -1};

// -------- template end - //


// - library ------------- //

/* 通常のSegment Tree ( ※遅延伝播なし )
  https://algo-logic.info/segment-tree/

  SegTree<X>(n,fx,ex): モノイド(集合X, 二項演算fx, 単位元ex)についてサイズnで構築
    set(int i, X x), build(): .set(i, x)でi番目(0-indexed)の要素をxにセットしてから、.build() でまとめてセグ木を構築する。O(n)
    update(i,x): i 番目(0-indexed)の要素を x に"置き換える"。O(log(n))
    query(a,b): [a,b) 全てにfxを作用させた値を取得。O(log(n))
*/
template <typename X>
struct SegTree {
  using FX = function<X(X, X)>; // X•X -> X となる関数の型
  int n;
  FX fx;
  const X ex;
  vector<X> dat;
  SegTree(int n_, FX fx_, X ex_) : n(), fx(fx_), ex(ex_), dat(n_ * 4, ex_) {
    int x = 1;
    while (n_ > x) {
      x *= 2;
    }
    n = x;
  }

  void set(int i, X x) { dat[i + n - 1] = x; }
  void build() {
    for (int k = n - 2; k >= 0; k--) dat[k] = fx(dat[2 * k + 1], dat[2 * k + 2]);
  }

  void update(int i, X x) {
    i += n - 1;
    dat[i] = x;
    while (i > 0) {
      i = (i - 1) / 2;  // parent
      dat[i] = fx(dat[i * 2 + 1], dat[i * 2 + 2]);
    }
  }

  X query(int a, int b) { return query_sub(a, b, 0, 0, n); }
  X query_sub(int a, int b, int k, int l, int r) {
    if (r <= a || b <= l) {
      return ex;
    } else if (a <= l && r <= b) {
      return dat[k];
    } else {
      X vl = query_sub(a, b, k * 2 + 1, l, (l + r) / 2);
      X vr = query_sub(a, b, k * 2 + 2, (l + r) / 2, r);
      return fx(vl, vr);
    }
  }
};


// --------- library end - //


int main(){

  int N, T;
  cin >> N >> T;

  // 恐らく、N=1の入力は無い？ （制約には1<=Nとあるが、N=1だと街が1つしかないから利益の上げようがない……）
  assert(N!=1);
    
  // Range Minimum Query
  auto fx1 = [](int x1, int x2) -> int { return min(x1, x2); }; // 演算
  int ex1 = numeric_limits<int>::max(); // 単位元
  SegTree<int> segt_min(N, fx1, ex1);

  // Range Maximum Query
  auto fx2 = [](int x1, int x2) -> int { return max(x1, x2); }; // 演算
  int ex2 = 0; // 単位元
  SegTree<int> segt_max(N, fx2, ex2);

  vector<ll> as;
  rep(i, N){
    int a = ii();
    as.push_back(a);
    segt_min.set(i, a);
    segt_max.set(i, a);
  }
  segt_min.build();
  segt_max.build();

  // 差(aj-ai)が最大となるような i<j かつ ai<aj の組み合わせの数が答え
  // このようなペア(i, j)が複数(k個)あるとき、i1, j1, i2, j2, ..., ik, jk のようになっており、かつ、i1>i2>...>ik, j1>j2>...jk となっている 例えば最大の差が3のとき、3, 6, 2, 5 など
  // なぜなら、そうでなければ (i2, j1) といったペアがより大きい差を持ってしまうから

  // すると、最大差となるペアの区間は入り乱れていないから、i=0~N-2 の右側にそれぞれ仕切りを置いて、仕切りの左側の最小値 と 仕切りの右側の最大値 を比べればいい
  // その上で、それらをvectorに入れて最後に降順ソートして、最大値に等しいものがいくつあるか数えればいい

  int idx = 0; // 仕切り。この右側（つまりidx と idx+1 の間）に仕切りを入れる
  // 毎回のループで差を見つけたあと、そのときの仕切りの左側における最小値 より小さい値が出てこない限り、その差と同じか、もしくはそれ以上の差は出てこないので、それが見つかる仕切り位置までスキップする
  vector<int> diffs;
  while (idx < N-1){
    // idx : 0 ~ N-2
    int lmin = segt_min.query(0, idx+1);
    int rmax = segt_max.query(idx+1, N);
    diffs.push_back(rmax - lmin);

    // lmin未満が出てくるまでスキップ
    // idx==N-1 となったら、もう見つからないので終わり
    while(as[idx] >= lmin && idx < N-1){
      idx++;
    }
  }

  // 最大値の数を数える
  sort(begin_end(diffs));
  reverse(begin_end(diffs));
  int ans = 0;
  int maxdiff = diffs[0];
  for (int diff : diffs){
    if (diff == maxdiff) ans++;
  }

  cout << ans << endk;

}

Measured memory_bytes: 7536