#include<bits/stdc++.h>
using namespace std;
const int N=1e5+100;
int n,k,a[N],la[N],mx,mi,line[N],cnt;
struct tree{
int l,r,mx,lz;
}t[N<<4];
#define lson o<<1
#define rson o<<1|1
inline void build(int o,int l,int r){
t[o].l=l,t[o].r=r;
if(l==r) return;
int mid=(l+r)>>1;
build(lson,l,mid),build(rson,mid+1,r);
}
void pushdown(int o){
if(!t[o].lz) return;
int x=t[o].lz;t[o].lz=0;
t[lson].mx=x,t[lson].lz=x;
t[rson].mx=x,t[rson].lz=x;
}
inline void update(int o,int l,int r,int val){
if(t[o].l==l and t[o].r==r){
t[o].mx=val;
t[o].lz=val;
return;
}
pushdown(o);
int mid=(t[o].l+t[o].r)>>1;
if(r<=mid) update(lson,l,r,val);
else if(l>mid) update(rson,l,r,val);
else update(lson,l,mid,val),update(rson,mid+1,r,val);
t[o].mx=max(t[lson].mx,t[rson].mx);
}
inline int query(int o,int l,int r){
if(t[o].l==l and t[o].r==r) return t[o].mx;
pushdown(o);
int mid=(t[o].l+t[o].r)>>1;
if(r<=mid) return query(lson,l,r);
else if(l>mid) return query(rson,l,r);
else return max(query(lson,l,mid),query(rson,mid+1,r));
}
void get_last(){
vector<int>g;
for(int i=1;i<=n;i++){
while(!g.empty() and a[i]>=a[g.back()]) g.pop_back();
if(!g.empty()) la[i]=g.back();
g.push_back(i);
}
}
int dp[N];
bool check(int x){
memset(dp,0,sizeof(dp));
update(1,1,n,0);//清空线段树,用懒标记优化
if(a[1]%x==0) dp[1]=1;
else dp[1]=0;
update(1,1,1,dp[1]);
for(int i=2;i<=n;i++){
if(a[i]%x!=0){
dp[i]=dp[la[i]];
update(1,i,i,dp[i]);
continue;
}
int bb;
if(la[i]==0) bb=query(1,la[i]+1,i-1);
else bb=query(1,la[i],i-1);
bb=(!bb?0:bb+1);
dp[i]=bb;
update(1,i,i,dp[i]);
}
return dp[n]>=k;
}
int main(){
cin>>n>>k;
int num=0;
for(int i=1;i<=n;i++) scanf("%d",&a[i]),mx=max(mx,a[i]);
for(int i=1;i<=n;i++) if(a[i]==mx) num++;
if(num>=k) return printf("%d",mx),0;
get_last();
for(int i=2;i*i<=mx;i++){
if(mx%i==0){
line[++cnt]=i;
if(i*i!=mx) line[++cnt]=mx/i;
}
}
sort(line+1,line+1+cnt);
build(1,1,n);
for(int i=cnt;i>=1;i--) if(check(line[i])) return printf("%d",line[i]),0;
cout<<1;
}