#include<bits/stdc++.h>
using namespace std;
const int mod = 1e9+7;
const int lim=1e6+10;
long long m,n;
long long l;
int f[lim];
int g[lim];
long long shengxia;
vector<long long>sum[lim],sigma[lim];
long long duan;

void jisuan()
{

}
int main()
{
    cin>>m>>l>>n;
    for(int i=1;i<=m;i++)
    {
        scanf("%d",&f[i]);
    }
    shengxia = l%m;
    for(int i=1;i<=shengxia;i++)
    g[i]=f[i];
    sort(f+1,f+m+1);
    sort(g+1,g+shengxia+1);
    long long pre = l/m;
    long long duan=min((long long)n,(long long)l/m+(l%m==0?0:1));
    for(int i=0;i<duan;i++)
    {
        int len = i+1;
        for(int j=0;j<m;j++)
        {
            if(len==1)
            {
                sum[len].push_back(1);
                if(j==0)
                    sigma[len].push_back(sum[len][j]%mod);
                else
                    sigma[len].push_back((sigma[len][j-1]+sum[len][j])%mod);
            }
            else
            {
                sum[len].push_back(sigma[len-1][j]%mod);
                if(j==0)
                    sigma[len].push_back(sum[len][j]%mod);
                else
                    sigma[len].push_back((sigma[len][j-1]+sum[len][j])%mod);
            }

        }
    }
    long long ans=0;
    if(shengxia==0)
    {
        for(int i=1;i<=duan&&i<=pre;i++)
            for(int j=0;j<m;j++)
            {
                //cout<<" A="<<pre-i+1<<" i="<<i<<" num="<<sum[i][j]<<endl;
                ans=(ans+((pre-i+1)%mod)*sum[i][j]%mod)%mod;
                //cout<<ans<<endl;
            }
    }
    else
    {
        for(int i=1;i<=duan&&i<=pre;i++)
            for(int j=0;j<m;j++)
            {
                ans=(ans+((pre-i+1)*i%mod)*sum[i][j]%mod)%mod;
            }
        //cout<<ans<<endl;
        ans=(ans+shengxia)%mod;
        //cout<<ans<<endl;
        for(int i=1;i<=duan-1 && i<=pre;i++)
        {
            // zui hou yi ge
            for(int j=1;j<=shengxia;j++)
            {
                int value=g[j];
                int pos=upper_bound(f+1,f+m+1,value)-f-1;
                //cout<<"value="<<value<<" pos="<<pos<<" sigma="<<sigma[i][pos-1]<<endl;
                ans=(ans+sigma[i][pos-1])%mod;
            }
        }
    }
    cout<<ans%mod<<endl;
}


#include <cstdio>
#include <cstring>
#include <algorithm>
#include <map>
#include <iostream>
using std::map;
const int N = 1000000 + 10;
const int mod = 1000000000 + 7;
int n, k;
long long part;
long long l;
int a[N];
int way[N], b[N];
map<int, int> rank;
int R, cnt[N];

int main()
{
	std::cin >> n >> l >> k;
	part = (l + n - 1) / n;
	k = std::min(0ll + k, part);
	for(int i = 0; i < n; i++)
	{
		scanf("%d", &a[i]);
		b[i] = a[i];
	}
	std::sort(b, b + n);
	for(int i = 0; i < n; i++) if(i == 0 || b[i] != b[i-1]) rank[b[i]] = R++;
	int res = 0;
	for(int i = 1; i <= k; i++)
	{
		if(i == 1) for(int j = 0; j < n; j++) way[j] = 1;
		else for(int j = 0; j < n; j++) way[j] = cnt[rank[a[j]]];
		int sum = 0;
		for(int j = 0; j < n; j++) (sum += way[j]) %= mod;
		(res += (1ll * sum  * ((part - i + 1 - 1) % mod) % mod)) %= mod;
		int ed = l % n; if(ed == 0) ed = n;
		for(int j = 0; j < ed; j++) (res += way[j]) %= mod;
		for(int j = 0; j < n; j++) cnt[j] = 0;
		for(int j = 0; j < n; j++) (cnt[rank[a[j]]] += way[j]) %= mod;
		for(int j = 1; j < R; j++) (cnt[j] += cnt[j-1]) %= mod;
		//printf("%d %d\n", i, res);
	}
	printf("%d\n", res);
	return 0;
}


#include <cstdio>
#include <cstring>
#include <algorithm>
#include <map>
#include <iostream>
using std::map;
const int N = 1000000 + 10;
const int mod = 1000000000 + 7;
int n, k;
long long part;
long long l;
int a[N];
int way[N], b[N];
map<int, int> rank;
int R, cnt[N];

int main()
{
	std::cin >> n >> l >> k;
	part = (l + n - 1) / n;
	k = std::min(0ll + k, part);
	for(int i = 0; i < n; i++)
	{
		scanf("%d", &a[i]);
		b[i] = a[i];
	}
	std::sort(b, b + n);
	for(int i = 0; i < n; i++)
		if(i == 0 || b[i] != b[i-1]) rank[b[i]] = R++;
	int res = 0;
	for(int i = 1; i <= k; i++)
	{
		if(i == 1) for(int j = 0; j < n; j++) way[j] = 1;
		else for(int j = 0; j < n; j++) way[j] = cnt[rank[a[j]]];
		int sum = 0;
		for(int j = 0; j < n; j++) (sum += way[j]) %= mod;
		(res += 1ll * sum * (part - i + 1 - 1) % mod) %= mod;
		int ed = l % n; if(ed == 0) ed = n;
		for(int j = 0; j < n && j < ed; j++)
			(res += way[j]) %= mod;
		memset(cnt, 0, sizeof(cnt));
		for(int j = 0; j < n; j++) (cnt[rank[a[j]]] += way[j]) %= mod;
		for(int j = 1; j < R; j++) (cnt[j] += cnt[j-1]) %= mod;
	}
	printf("%d\n", res);
	return 0;
}


#include <cstdio>
#include <cstring>
#include <algorithm>
#include <map>
using std::map;
const int N = 1000000 + 10;
const int mod = 1000000000 + 7;
int n, k;
long long l;
int a[N];
int way[N], b[N];
map<int, int> rank;
int R, cnt[N];

int main()
{
	scanf("%d%d%I64d", &n, &l, &k);
	k = std::min(k, (l + n - 1) / n);
	for(int i = 0; i < n; i++)
	{
		scanf("%d", &a[i]);
		b[i] = a[i];
	}
	std::sort(b, b + n);
	for(int i = 0; i < n; i++)
		if(i == 0 || b[i] != b[i-1]) rank[b[i]] = R++;
	int res = 0;
	for(int i = 1; i <= k; i++)
	{
		if(i == 1) for(int j = 0; j < n; j++) way[j] = 1;
		else for(int j = 0; j < n; j++) way[j] = cnt[rank[a[j]]];
		int sum = 0;
		for(int j = 0; j < n; j++) (sum += way[j]) %= mod;
		(res += 1ll * sum * (k - i + 1 - 1) % mod) %= mod;
		int ed = l % n; if(ed == 0) ed = n;
		for(int j = 0; j < n && j < ed; j++)
			(res += way[j]) %= mod;
		memset(cnt, 0, sizeof(cnt));
		for(int j = 0; j < n; j++) (cnt[rank[a[j]]] += way[j]) %= mod;
		for(int j = 1; j < R; j++) (cnt[j] += cnt[j-1]) %= mod;
	}
	printf("%d\n", res);
	return 0;
}


#include <cstdio>
#include <cstring>
#include <algorithm>
#include <map>
#include <iostream>
using std::map;
const int N = 1000000 + 10;
const int mod = 1000000000 + 7;
int n, k;
long long part;
long long l;
int a[N];
int way[N], b[N];
map<int, int> rank;
int R, cnt[N];

int multiply(int x, long long y)
{
	int res = 0;
	while(y)
	{
		if(y & 1) (res += x) %= mod;
		(x += x) %= mod; y /= 2;
	}
	return res;
}

int main()
{
	std::cin >> n >> l >> k;
	part = (l + n - 1) / n;
	k = std::min(0ll + k, part);
	for(int i = 0; i < n; i++)
	{
		scanf("%d", &a[i]);
		b[i] = a[i];
	}
	std::sort(b, b + n);
	for(int i = 0; i < n; i++) if(i == 0 || b[i] != b[i-1]) rank[b[i]] = R++;
	int res = 0;
	for(int i = 1; i <= k; i++)
	{
		if(i == 1) for(int j = 0; j < n; j++) way[j] = 1;
		else for(int j = 0; j < n; j++) way[j] = cnt[rank[a[j]]];
		int sum = 0;
		for(int j = 0; j < n; j++) (sum += way[j]) %= mod;
		(res += multiply(sum, part - i + 1 - 1) % mod) %= mod;
		int ed = l % n; if(ed == 0) ed = n;
		for(int j = 0; j < ed; j++) (res += way[j]) %= mod;
		for(int j = 0; j < n; j++) cnt[j] = 0;
		for(int j = 0; j < n; j++) (cnt[rank[a[j]]] += way[j]) %= mod;
		for(int j = 1; j < R; j++) (cnt[j] += cnt[j-1]) %= mod;
		//printf("%d %d\n", i, res);
	}
	printf("%d\n", res);
	return 0;
}


#include <cstdio>
#include <cstring>
#include <algorithm>
#include <map>
using std::map;
const int N = 1000000 + 10;
const int mod = 1000000000 + 7;
int n, l, k, a[N];
int way[N], b[N];
map<int, int> rank;
int R, cnt[N];

int main()
{
	scanf("%d%d%d", &n, &l, &k);
	k = std::min(k, (l + n - 1) / n);
	for(int i = 0; i < n; i++)
	{
		scanf("%d", &a[i]);
		b[i] = a[i];
	}
	std::sort(b, b + n);
	for(int i = 0; i < n; i++)
		if(i == 0 || b[i] != b[i-1]) rank[b[i]] = R++;
	int res = 0;
	for(int i = 1; i <= k; i++)
	{
		if(i == 1) for(int j = 0; j < n; j++) way[j] = 1;
		else for(int j = 0; j < n; j++) way[j] = cnt[rank[a[j]]];
		int sum = 0;
		for(int j = 0; j < n; j++) (sum += way[j]) %= mod;
		(res += 1ll * sum * (k - i + 1 - 1) % mod) %= mod;
		int ed = l % n; if(ed == 0) ed = n;
		for(int j = 0; j < n && j < ed; j++)
			(res += way[j]) %= mod;
		memset(cnt, 0, sizeof(cnt));
		for(int j = 0; j < n; j++) (cnt[rank[a[j]]] += way[j]) %= mod;
		for(int j = 1; j < R; j++) (cnt[j] += cnt[j-1]) %= mod;
	}
	printf("%d\n", res);
	return 0;
}


#include <cstdio>
#include <cstring>
#include <algorithm>
#include <map>
using std::map;
const int N = 1000000 + 10;
const int mod = 1000000000 + 7;
int n, k;
long long l;
int a[N];
int way[N], b[N];
map<int, int> rank;
int R, cnt[N];

int main()
{
	scanf("%d%I64d%d", &n, &l, &k);
	k = std::min(0ll + k, (l + n - 1) / n);
	for(int i = 0; i < n; i++)
	{
		scanf("%d", &a[i]);
		b[i] = a[i];
	}
	std::sort(b, b + n);
	for(int i = 0; i < n; i++)
		if(i == 0 || b[i] != b[i-1]) rank[b[i]] = R++;
	int res = 0;
	for(int i = 1; i <= k; i++)
	{
		if(i == 1) for(int j = 0; j < n; j++) way[j] = 1;
		else for(int j = 0; j < n; j++) way[j] = cnt[rank[a[j]]];
		int sum = 0;
		for(int j = 0; j < n; j++) (sum += way[j]) %= mod;
		(res += 1ll * sum * (k - i + 1 - 1) % mod) %= mod;
		int ed = l % n; if(ed == 0) ed = n;
		for(int j = 0; j < n && j < ed; j++)
			(res += way[j]) %= mod;
		memset(cnt, 0, sizeof(cnt));
		for(int j = 0; j < n; j++) (cnt[rank[a[j]]] += way[j]) %= mod;
		for(int j = 1; j < R; j++) (cnt[j] += cnt[j-1]) %= mod;
	}
	printf("%d\n", res);
	return 0;
}


#include <cstdio>
#include <cstring>
#include <algorithm>
#include <map>
using std::map;
const int N = 1000000 + 10;
const int mod = 1000000000 + 7;
int n, k;
long long l;
int a[N];
int way[N], b[N];
map<int, int> rank;
int R, cnt[N];

int main()
{
	scanf("%d%d%I64d", &n, &l, &k);
	k = std::min(0ll + k, (l + n - 1) / n);
	for(int i = 0; i < n; i++)
	{
		scanf("%d", &a[i]);
		b[i] = a[i];
	}
	std::sort(b, b + n);
	for(int i = 0; i < n; i++)
		if(i == 0 || b[i] != b[i-1]) rank[b[i]] = R++;
	int res = 0;
	for(int i = 1; i <= k; i++)
	{
		if(i == 1) for(int j = 0; j < n; j++) way[j] = 1;
		else for(int j = 0; j < n; j++) way[j] = cnt[rank[a[j]]];
		int sum = 0;
		for(int j = 0; j < n; j++) (sum += way[j]) %= mod;
		(res += 1ll * sum * (k - i + 1 - 1) % mod) %= mod;
		int ed = l % n; if(ed == 0) ed = n;
		for(int j = 0; j < n && j < ed; j++)
			(res += way[j]) %= mod;
		memset(cnt, 0, sizeof(cnt));
		for(int j = 0; j < n; j++) (cnt[rank[a[j]]] += way[j]) %= mod;
		for(int j = 1; j < R; j++) (cnt[j] += cnt[j-1]) %= mod;
	}
	printf("%d\n", res);
	return 0;
}


#include <bits/stdc++.h>
#define MOD 1000000007
#define maxint 1000005

using namespace std;

vector<int> f[maxint];
int a[maxint];

void congvao(int &a, int b)
{
	a += b;
	if (a >= MOD)
		a -= MOD;
}
int main()
{
	int n, k;
	long long l;
	cin >> n >> l >> k;
	for (int i = 0; i < n; i++)
		f[i].resize(k + 1);
	vector<int> VaL;
	for (int i = 0; i < n; i++)
	{
		cin >> a[i];
		VaL.push_back(a[i]);
	}
	sort(VaL.begin(), VaL.end());
	VaL.resize(unique(VaL.begin(), VaL.end()) - VaL.begin());
	for (int i = 0; i < n; i++)
	{
		a[i] = lower_bound(VaL.begin(), VaL.end(), a[i]) - VaL.begin();
		f[i][1] = 1;
	}
	vector<int> Counts;
	Counts.resize(VaL.size());
	for (int j = 2; j <= k; j++)
	{
		for (int i = 0; i < (int)Counts.size(); i++)
			Counts[i] = 0;
		for (int i = 0; i < n; i++)
			congvao(Counts[a[i]], f[i][j - 1]);
		for (int i = 1; i < (int)Counts.size(); i++)
			congvao(Counts[i], Counts[i - 1]);
		for (int i = 0; i < n; i++)
			f[i][j] = Counts[a[i]];
	}
	int ans = 0;
	for (int i = 0; i < n; i++)
		for (int j = 1; j <= k; j++)
		{
			long long b = l / n;
			if (i < l % n)
				b++;
			b = b - j + 1;
			if (b > 0)
				ans = (ans + (b % MOD) * f[i][j]) % MOD;
		}
	cout << ans;
	return 0;
}


#include <bits/stdc++.h>
#define MOD 1000000007
#define maxint 1000005

using namespace std;

vector<int> f[maxint];
int a[maxint];

void congvao(int &a, int b)
{
	a += b;
	if (a >= MOD)
		a -= MOD;
}
int main()
{
	int n, k;
	long long l;
	cin >> n >> k >> k;
	for (int i = 0; i < n; i++)
		f[i].resize(k + 1);
	vector<int> VaL;
	for (int i = 0; i < n; i++)
	{
		cin >> a[i];
		VaL.push_back(a[i]);
	}
	sort(VaL.begin(), VaL.end());
	VaL.resize(unique(VaL.begin(), VaL.end()) - VaL.begin());
	for (int i = 0; i < n; i++)
	{
		a[i] = lower_bound(VaL.begin(), VaL.end(), a[i]) - VaL.begin();
		f[i][1] = 1;
	}
	vector<int> Counts;
	Counts.resize(VaL.size());
	for (int j = 2; j <= k; j++)
	{
		for (int i = 0; i < (int)Counts.size(); i++)
			Counts[i] = 0;
		for (int i = 0; i < n; i++)
			congvao(Counts[a[i]], f[i][j - 1]);
		for (int i = 1; i < (int)Counts.size(); i++)
			congvao(Counts[i], Counts[i - 1]);
		for (int i = 0; i < n; i++)
			f[i][j] = Counts[a[i]];
	}
	int ans = 0;
	for (int i = 0; i < n; i++)
		for (int j = 1; j <= k; j++)
		{
			long long b = l / n;
			if (i < l % n)
				b++;
			b = b - j + 1;
			if (b > 0)
				ans = (ans + (b % MOD) * f[i][j]) % MOD;
		}
	cout << ans;
	return 0;
}


#include <bits/stdc++.h>
#define MOD 1000000007
#define maxint 1000005

using namespace std;

vector<int> f[maxint];
int a[maxint];

void congvao(int &a, int b)
{
	a += b;
	if (a >= MOD)
		a -= MOD;
}
int main()
{
	ios_base::sync_with_stdio(false);
	int n, k;
	long long l;
	cin >> n >> l >> k;
	for (int i = 0; i < n; i++)
		f[i].resize(k + 1);
	vector<int> VaL;
	for (int i = 0; i < n; i++)
	{
		cin >> a[i];
		VaL.push_back(a[i]);
	}
	sort(VaL.begin(), VaL.end());
	VaL.resize(unique(VaL.begin(), VaL.end()) - VaL.begin());
	for (int i = 0; i < n; i++)
	{
		a[i] = lower_bound(VaL.begin(), VaL.end(), a[i]) - VaL.begin();
		f[i][1] = 1;
	}
	vector<int> Counts;
	Counts.resize(VaL.size());
	for (int j = 2; j <= k; j++)
	{
		for (int i = 0; i < (int)Counts.size(); i++)
			Counts[i] = 0;
		for (int i = 0; i < n; i++)
			congvao(Counts[a[i]], f[i][j - 1]);
		for (int i = 1; i < (int)Counts.size(); i++)
			congvao(Counts[i], Counts[i - 1]);
		for (int i = 0; i < n; i++)
			f[i][j] = Counts[a[i]];
	}
	int ans = 0;
	for (int i = 0; i < n; i++)
		for (int j = 1; j <= k; j++)
		{
			long long b = l / n;
			if (i < l % n)
				b++;
			b = b - j + 1;
			if (b > 0)
				ans = (ans + (b % MOD) * f[i][j]) % MOD;
		}
	cout << ans;
	return 0;
}


#include<bits/stdc++.h>
#define ll long long
#define pii pair <int,int>
using namespace std;
const int mod = 1000000007;
const int MAX= 1000000;
ll fac[MAX+10];
vector<vector<ll> > s[2];
pii a[MAX+10];
void init_fac()
{
	fac[0]=1;
	for (int i=1;i<=MAX;i++)
		fac[i] = (fac[i-1]* i)%mod;
}
ll fastpow (ll base, ll pow)
{
	if (pow==0)	return 1;
	ll x =fastpow(base,pow/2);
	ll res= (x*x)%mod;
	if (pow%2)	return (res *base)%mod;
	return res;
}
long long ncr (ll t, ll i)
{
	ll res=1;
	for (ll x =t;x>t-i;x--){
		ll y= x%mod;
		res= (res*y)% mod;
	}
	return (res *  fastpow(fac[i],mod-2) )%mod;
}
int main()
{
//	freopen("d.in","r",stdin);
	ios_base:: sync_with_stdio(0);
	cin.tie(0);
	cout.tie(0);
	long long n , l,k;
	cin>>n>>l>>k;
	for (int i=0;i<n;i++)	cin>>a[i].first  , a[i].second =i;
	for (int i=0;i<2;i++){
		for (int j=0;j<=n+1;j++){
			s[i].push_back(vector<ll>());
			for (int h=0;h<=k+1;h++)
				s[i][j].push_back(0);
		}
	}
	sort (a,a+n);
	int z = l%n;
	for (int last =0;last<n;last++){
		s[0][last][0] =1;
		if (a[last].second<z)	s[1][last][0] =1;
	}
	for (int tk=1;tk<=k;tk++){
		for (int last= n;last>=0;last--){
			s[0][last][tk] = (s[0][last][tk-1] + s[0][last+1][tk])%mod;
			s[1][last][tk] = (s[1][last][tk-1] + s[1][last+1][tk])%mod;
		}
	}
	init_fac();
	long long res=0;
	for (ll i=1;i<=min(k, l/n);i++){
		ll x = (l/n-i+1)%mod;
		res+= (x * s[0][0][i])%mod;
	}
	if (l%n!=0)
		for (ll i=1;i<=min(l/n+1,k);i++)
			res+= s[1][0][i],
			res%=mod;
	cout<<res<<endl;
}


#include<bits/stdc++.h>
using namespace std;
#define pii pair<int,int>
#define ll long long
vector< vector<ll> > dp[3];
const int mod = 1000000007;
vector<pii> arr;
struct element {
	private:
	int value;
	int position;
	int sz;
	int v;
	public:
	element (int value, int position)
	{
		this->value=value;
		this->position = position;
		sz= 1;
		v=0;
	}
	void inc (){
		sz++;
	}
	void incvalid ()
	{
		v++;
	}
	int size (){
		return sz;
	}
	int valid(){
		return v;
	}
	void print ()
	{
		cout<<value<<" "<<position<<" "<<sz<<" valid:"<<v<<endl;
	}
};
vector<element> inf;
int main ()
{
//	freopen("d.in","r",stdin);
	ll n , k,l;
	cin>>n>>l>>k;
	int a;
	for (int i=0;i<n;i++){
		cin>>a;
		arr.push_back(pii(a,i));
	}
	sort(arr.begin(),arr.end());
	inf.push_back(element (arr[0].first, 0));
	if (arr[0].second<l%n)
		inf[0].incvalid();
	for (int i=1;i<n;i++){
		if (arr[i]==arr[i-1])
			inf.back().inc();
		else
			inf.push_back(element(arr[i].first,i));
		if (arr[i].second <l%n)
			inf.back().incvalid();
	}
	for (int i=0;i<2;i++){
		dp[i].resize (inf.size()+2);
		for (int j=0;j<=n+1;j++)
			dp[i][j].resize(k+2);
	}
	ll seq = l/n;
	for (int i=0;i<inf.size();i++)
		dp[0][i][0] = 1;
	for (int i=0;i<inf.size();i++)
		if (inf[i].valid())
			dp[1][i][0] = 1;
	for (int tk=1;tk<=k;tk++){
		for (int ind =inf.size()-1;ind>=0;ind--){
			dp[0][ind][tk] = ( dp[0][ind+1][tk] + dp[0][ind][tk-1]*inf[ind].size()  )%mod;
			dp[1][ind][tk] = ( dp[1][ind+1][tk] + dp[1][ind][tk-1]*inf[ind].size()*(tk>1)+ dp[1][ind][tk-1]*inf[ind].valid()*(tk==1)  )%mod;
		}
	}
	ll res=0;
	for (int i=1;i<=min(seq,k);i++)
		res= ( res+ dp[0][0][i] *(seq-i+1)%mod )%mod;
//	cout<<res<<endl;
	if (l%n)
		for (int i=1;i<=min(seq+1, k);i++)
			res= ( res+ dp[1][0][i])%mod  ;//,cout<<"i "<<i<<": "<<dp[1][0][i]<<endl;
	cout<<res<<endl;
}


#include<bits/stdc++.h>
#define ll long long
#define pii pair <int,int>
using namespace std;
const int mod = 1000000007;
const int MAX= 1000000;
ll fac[MAX+10];
vector<vector<ll> > s[2];
bool valid_end[MAX+10];
pii a[MAX+10];
void init_fac()
{
	fac[0]=1;
	for (int i=1;i<=MAX;i++)
		fac[i] = (fac[i-1]* i)%mod;
}
ll fastpow (ll base, ll pow)
{
	if (pow==0)	return 1;
	ll x =fastpow(base,pow/2);
	ll res= (x*x)%mod;
	if (pow%2)	return (res *base)%mod;
	return res;
}
long long ncr (ll t, ll i)
{
	ll res=1;
	for (ll x =t;x>t-i;x--)
		res= (res*x)%mod;
	return (res *  fastpow(fac[i],mod-2) )%mod;
}
int main()
{
//	freopen("d.in","r",stdin);
	ios_base:: sync_with_stdio(0);
	cin.tie(0);
	cout.tie(0);
	long long n , l,k;
	cin>>n>>l>>k;
	for (int i=0;i<n;i++)	cin>>a[i].first  , a[i].second =i;
	for (int i=0;i<2;i++){
		for (int j=0;j<=n+1;j++){
			s[i].push_back(vector<ll>());
			for (int h=0;h<=k+1;h++)
				s[i][j].push_back(0);
		}
	}
	sort (a,a+n);
	int z = l%n;
	for (int last =0;last<n;last++){
		s[0][last][0] =1;
		if (a[last].second<z)	s[1][last][0] =1;
	}
	for (int tk=1;tk<=k;tk++){
		for (int last= n;last>=0;last--){
			s[0][last][tk] = (s[0][last][tk-1] + s[0][last+1][tk])%mod;
			s[1][last][tk] = (s[1][last][tk-1] + s[1][last+1][tk])%mod;
		}
	}
	init_fac();
	long long res=0;
	for (ll i=1;i<=min(k, l/n);i++){
		res+= ncr(l/n,i)* s[0][0][i];
		res%=mod;
	}
	if (l%n!=0)
		for (ll i=1;i<=min(l/n+1,k);i++)
			res+= ncr(l/n,i-1)*s[1][0][i];
			res%=mod;
	cout<<res<<endl;
}


#include<bits/stdc++.h>
#define ll long long
#define pii pair <int,int>
using namespace std;
const int mod = 1000000007;
const int MAX= 1000000;
ll fac[MAX+10];
vector<vector<ll> > s[2];
pii a[MAX+10];
void init_fac()
{
	fac[0]=1;
	for (int i=1;i<=MAX;i++)
		fac[i] = (fac[i-1]* i)%mod;
}
ll fastpow (ll base, ll pow)
{
	if (pow==0)	return 1;
	ll x =fastpow(base,pow/2);
	ll res= (x*x)%mod;
	if (pow%2)	return (res *base)%mod;
	return res;
}
long long ncr (ll t, ll i)
{
	ll res=1;
	for (ll x =t;x>t-i;x--)
		res= (res*x)% mod;
	return (res *  fastpow(fac[i],mod-2) )%mod;
}
int main()
{
//	freopen("d.in","r",stdin);
	ios_base:: sync_with_stdio(0);
	cin.tie(0);
	cout.tie(0);
	long long n , l,k;
	cin>>n>>l>>k;
	for (int i=0;i<n;i++)	cin>>a[i].first  , a[i].second =i;
	for (int i=0;i<2;i++){
		for (int j=0;j<=n+1;j++){
			s[i].push_back(vector<ll>());
			for (int h=0;h<=k+1;h++)
				s[i][j].push_back(0);
		}
	}
	sort (a,a+n);
	int z = l%n;
	for (int last =0;last<n;last++){
		s[0][last][0] =1;
		if (a[last].second<z)	s[1][last][0] =1;
	}
	for (int tk=1;tk<=k;tk++){
		for (int last= n;last>=0;last--){
			s[0][last][tk] = (s[0][last][tk-1] + s[0][last+1][tk])%mod;
			s[1][last][tk] = (s[1][last][tk-1] + s[1][last+1][tk])%mod;
		}
	}
	init_fac();
	long long res=0;
	for (ll i=1;i<=min(k, l/n);i++){
		res+= ncr(l/n,i)* s[0][0][i];
		res%=mod;
	}
	if (l%n!=0)
		for (ll i=1;i<=min(l/n+1,k);i++)
			res+= ncr(l/n,i-1)*s[1][0][i],
			res%=mod;
	cout<<res<<endl;
}


//
//  main.cpp
//  4133
//
//  Created by 苏 与轩 on 14-4-14.
//  Copyright (c) 2014年 苏与轩工作室. All rights reserved.
//

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <queue>
using namespace std;
int n,m;
int fx[4][2]={0};
char s[1505][1505];
bool visited[1505][1505]={false};
int pos[1505][1505][2]={0};
struct P{
    int x,y;
};
bool bfs(P head){
     queue<P>    q;
     //visited[head.x][head.y]=true;
     //pos[head.x][head.y][0]=head.x;
     //pos[head.x][head.y][1]=head.y;
    q.push(head);
    while (!q.empty()){
        P cur=q.front(),next;
        q.pop();
        for (int i=0;i<4;i++){
            next.x=cur.x+fx[i][0],next.y=cur.y+fx[i][1];
            int x=(next.x-1)%n+1,y=(next.y-1)%m+1;
            if (s[x][y]=='#')   continue;
            if (visited[x][y]){
                if (next.x!=pos[x][y][0]||next.y!=pos[x][y][1]){
                    return true;
                }
            }else {
                visited[x][y]=true;
                pos[x][y][0]=next.x;
                pos[x][y][1]=next.y;
                q.push(next);
            }
        }
    }
    return false;
}
int main(){
    scanf("%d%d",&n,&m);
    fx[0][0]=-1,fx[1][0]=0,fx[2][0]=0,fx[3][0]=1;
    fx[0][1]=0,fx[1][1]=1,fx[2][1]=-1,fx[3][1]=0;
    for (int i=1;i<=n;i++)
        scanf("%s",s[i]+1);
    P sta;
    for (int i=1;i<=n;i++)
        for (int j=1;j<=m;j++)
            if (s[i][j]=='S'){
                sta.x=i;
                sta.y=j;
            }
    bfs(sta)?printf("Yes\n"):printf("No\n");
    return 0;
}


#include<iostream>
#include<cstdio>
#include<cmath>
using namespace std;
int t,n;

int main()
{
	scanf("%d",&t);
	while (t--)
	{
		scanf("%d",&n);
		printf("%d\n",int(sqrt(n)));
	}
}


#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<stack>
#include<queue>
#include<vector>
#include<map>
#include<ctime>
using namespace std;
const int MAX=2500005;
int n,m,dir[4][2]={0,1,1,0,-1,0,0,-1};
int N,M,tot,sx,sy,e;
char s[4502][4502];
bool vis[4502][4502];
bool in(int i,int j)
{
    if(i<0||j<0||i>=N||j>=M)
        return false;
    return true;
}
void dfs(int i,int j)
{
    vis[i][j]=true;
    for(int k=0;k<4;k++)
    {
        int ii=i+dir[k][0],jj=j+dir[k][1];
        if(in(ii,jj)&&s[ii][jj]!='#'&&!vis[ii][jj])
            dfs(ii,jj);
    }
}
int main()
{
    int i,j,k;
    while(scanf("%d%d",&n,&m)!=EOF)
    {
        N=n*3;
        M=m*3;
        for(i=0;i<n;i++)
        {
            scanf("%s",s[i]);
            for(j=0;j<m;j++)
                if(s[i][j]=='S')
                {
                    sx=i;
                    sy=j;
                }
        }
        for(i=0;i<N;i++)
            for(j=0;j<M;j++)
                s[i][j]=s[i%n][j%m];
        memset(vis,false,sizeof(vis));
        dfs(sx+n,sy+m);
        bool flag=false;
        for(i=0;i<M;i++)
            if(vis[0][i]||vis[N-1][i])
                flag=true;
        for(i=0;i<N;i++)
            if(vis[i][0]||vis[i][M-1])
                flag=true;
        if(flag)
            puts("Yes");
        else
            puts("No");
    }
    return 0;
}
/*
5 4
##.#
##S#
#..#
#.##
#..#

5 4
##.#
##S#
#..#
..#.
#.##
*/


#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<stack>
#include<queue>
#include<vector>
#include<map>
#include<ctime>
using namespace std;
const int MAX=2500005;
int fa[MAX],n,m,dir[2][2]={0,1,1,0};
int id[1505][1505],tot,sx,sy;
char s[1505][1505];
int find(int x)
{
    if(fa[x]!=x)
        fa[x]=find(fa[x]);
    return fa[x];
}
bool in(int i,int j)
{
    if(i<0||i>=n||j<0||j>=m)
        return false;
    return true;
}
void merge(int a,int b)
{
     int x=find(a),y=find(b);
    fa[x]=y;

}
int main()
{
    int i,j,k;
    while(scanf("%d%d",&n,&m)!=EOF)
    {
        for(i=0;i<n;i++)
            scanf("%s",s[i]);
        tot=0;
        for(i=0;i<n;i++)
        {
            for(j=0;j<m;j++)
            {
                if(s[i][j]=='.')
                    id[i][j]=++tot;
                else if(s[i][j]=='S')
                {
                    sx=i;
                    sy=j;
                    id[i][j]=++tot;
                }
                else
                    id[i][j]=-1;
            }
        }
        for(i=1;i<=tot;i++)
            fa[i]=i;
        bool flag=false;
        for(i=0;i<n&&!flag;i++)
        {
            for(j=0;j<m&&!flag;j++)
            {
                if(s[i][j]=='#')
                    continue;
                for(k=0;k<2&&!flag;k++)
                {
                    int ii=i+dir[k][0];
                    int jj=j+dir[k][1];
                    if(in(ii,jj)&&s[ii][jj]!='#')
                        merge(id[i][j],id[ii][jj]);
                }
            }
        }
        for(i=0;i<m;i++)
            if(s[0][i]!='#'&&s[n-1][i]!='#'&&find(id[0][i])==find(id[n-1][i])&&find(id[0][i])==find(id[sx][sy]))
                flag=true;
        for(i=0;i<n;i++)
            if(s[i][0]!='#'&&s[i][m-1]!='#'&&find(id[i][0])==find(id[i][m-1])&&find(id[i][0])==find(id[sx][sy]))
                flag=true;
        if(flag)
            puts("Yes");
        else
            puts("No");
    }
    return 0;
}
/*
5 4
##.#
##S#
#..#
#.##
#..#

5 4
##.#
##S#
#..#
..#.
#.##
*/


#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<stack>
#include<queue>
#include<vector>
#include<map>
#include<ctime>
using namespace std;
const int MAX=2500005;
int fa[MAX],n,m,dir[4][2]={0,1,1,0,-1,0,0,-1};
int N,M,tot,sx,sy,e,adj[MAX];
char s[4505][4505];
bool vis[4505][4505];
bool in(int i,int j)
{
    if(i<0||j<0||i>=N||j>=M)
        return false;
    return true;
}
void dfs(int i,int j)
{
    vis[i][j]=true;
    for(int k=0;k<4;k++)
    {
        int ii=i+dir[k][0],jj=j+dir[k][1];
        if(in(ii,jj)&&s[ii][jj]!='#'&&!vis[ii][jj])
            dfs(ii,jj);
    }
}
int main()
{
    int i,j,k;
    while(scanf("%d%d",&n,&m)!=EOF)
    {
        N=n*3;
        M=m*3;
        for(i=0;i<n;i++)
        {
            scanf("%s",s[i]);
            for(j=0;j<m;j++)
                if(s[i][j]=='S')
                {
                    sx=i;
                    sy=j;
                }
        }
        for(i=0;i<N;i++)
            for(j=0;j<M;j++)
                s[i][j]=s[i%n][j%m];
        memset(vis,false,sizeof(vis));
        dfs(sx+n,sy+m);
        bool flag=false;
        for(i=0;i<M;i++)
            if(vis[0][i]||vis[N-1][i])
                flag=true;
        for(i=0;i<N;i++)
            if(vis[i][0]||vis[i][M-1])
                flag=true;
        if(flag)
            puts("Yes");
        else
            puts("No");
    }
    return 0;
}
/*
5 4
##.#
##S#
#..#
#.##
#..#

5 4
##.#
##S#
#..#
..#.
#.##
*/


#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<stack>
#include<queue>
#include<vector>
#include<map>
#include<ctime>
using namespace std;
const int MAX=2500005;
int fa[100],n,m,dir[2][2]={0,1,1,0};
int id[1505][1505],tot,sx,sy;
char s[1505][1505];
int find(int x)
{
    if(fa[x]!=x)
        fa[x]=find(fa[x]);
    return fa[x];
}
bool in(int i,int j)
{
    if(i<0||i>=n||j<0||j>=m)
        return false;
    return true;
}
void merge(int a,int b)
{
     int x=find(a),y=find(b);
    fa[x]=y;

}
int main()
{
    int i,j,k;
    while(scanf("%d%d",&n,&m)!=EOF)
    {
        for(i=0;i<n;i++)
            scanf("%s",s[i]);
        tot=0;
        for(i=0;i<n;i++)
        {
            for(j=0;j<m;j++)
            {
                if(s[i][j]=='.')
                    id[i][j]=++tot;
                else if(s[i][j]=='S')
                {
                    sx=i;
                    sy=j;
                    id[i][j]=++tot;
                }
                else
                    id[i][j]=-1;
            }
        }
        for(i=1;i<=tot;i++)
            fa[i]=i;
        bool flag=false;
        for(i=0;i<n&&!flag;i++)
        {
            for(j=0;j<m&&!flag;j++)
            {
                if(s[i][j]=='#')
                    continue;
                for(k=0;k<2&&!flag;k++)
                {
                    int ii=i+dir[k][0];
                    int jj=j+dir[k][1];
                    if(in(ii,jj)&&s[ii][jj]!='#')
                        merge(id[i][j],id[ii][jj]);
                }
            }
        }
        for(i=0;i<m;i++)
            if(s[0][i]!='#'&&s[n-1][i]!='#'&&find(id[0][i])==find(id[n-1][i])&&find(id[0][i])==find(id[sx][sy]))
                flag=true;
        for(i=0;i<n;i++)
            if(s[i][0]!='#'&&s[i][m-1]!='#'&&find(id[i][0])==find(id[i][m-1])&&find(id[i][0])==find(id[sx][sy]))
                flag=true;
        if(flag)
            puts("Yes");
        else
            puts("No");
    }
    return 0;
}
/*
5 4
##.#
##S#
#..#
#.##
#..#

5 4
##.#
##S#
#..#
..#.
#.##
*/


#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<stack>
#include<queue>
#include<vector>
#include<map>
#include<ctime>
#include<set>
using namespace std;
#define MP make_pair
struct node
{
    int x,y;
};
int n,m,dir[4][2]={0,1,1,0,-1,0,0,-1};
int N,M,tot,sx,sy,e;
char s[1502][1502];
pair<int,int> pos[1502][1502];
int vx[1505][1505],vy[1505][1505];
bool vis[1502][1502];
set<pair<int,int> >ss;
bool check()
{
    queue<node>que;
    node now,next;
    vis[sx][sy]=true;
    vx[sx][sy]=sx;
    vy[sx][sy]=sy;
    //pos[sx][sy]=MP(sx,sy);
    now.x=sx; now.y=sy;
    que.push(now);
    //ss.clear();
    //ss.insert(make_pair(sx,sy));
    while(!que.empty())
    {
        now=que.front();
        que.pop();
        for(int k=0;k<4;k++)
        {
            int xx=now.x+dir[k][0],yy=now.y+dir[k][1];
            int x=(xx%n+n)%n,y=(yy%m+m)%m;
            if(s[x][y]=='#')
                continue;
            if(vis[x][y])
            {
                if(vx[x][y]!=xx||vy[x][y]!=yy)
                {
                    //cout<<x<<" "<<y<<" "<<xx<<" "<<yy<<endl;
                    return true;
                }
            }
            else
            {
                vis[x][y]=true;
                vx[x][y]=xx;
                vy[x][y]=yy;
               // pos[x][y]=MP(xx,yy);
                next.x=xx; next.y=yy;
                que.push(next);
            }
        }
    }
    return false;
}
int main()
{
    int i,j,k;
    while(scanf("%d%d",&n,&m)!=EOF)
    {
        for(i=0;i<n;i++)
        {
            scanf("%s",s[i]);
            for(j=0;j<m;j++)
                if(s[i][j]=='S')
                {
                    sx=i;
                    sy=j;
                }
        }
        memset(vis,false,sizeof(vis));
        memset(vx,-1,sizeof(vx));
        memset(vy,-1,sizeof(vy));
        if(check())
            puts("Yes");
        else
            puts("No");
    }
    return 0;
}
/*
5 4
##.#
##S#
#..#
#.##
#..#

5 4
##.#
##S#
#..#
..#.
#.##

10 10
.#########
S#........
##.#######
...#......
####.#####
.....#....
######.###
.......#..
########.#
#........#

*/


#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<stack>
#include<queue>
#include<vector>
#include<map>
#include<ctime>
using namespace std;
const int MAX=2500005;
int fa[MAX],n,m,dir[2][2]={0,1,1,0};
int id[1505][1505],tot,sx,sy;
char s[1505][1505];
int find(int x)
{
    if(fa[x]!=x)
        fa[x]=find(fa[x]);
    return fa[x];
}
bool in(int i,int j)
{
    if(i<0||i>=n||j<0||j>=m)
        return false;
    return true;
}
void merge(int a,int b)
{
     int x=find(a),y=find(b);
    fa[x]=y;

}
int main()
{
    int i,j,k;
    while(scanf("%d%d",&n,&m)!=EOF)
    {
        for(i=0;i<n;i++)
            scanf("%s",s[i]);
        tot=0;
        for(i=0;i<n;i++)
        {
            for(j=0;j<m;j++)
            {
                if(s[i][j]=='.')
                    id[i][j]=++tot;
                else if(s[i][j]=='S')
                {
                    sx=i;
                    sy=j;
                    id[i][j]=++tot;
                }
                else
                    id[i][j]=-1;
            }
        }
        for(i=1;i<=tot;i++)
            fa[i]=i;
        bool flag=false;
        for(i=0;i<n&&!flag;i++)
        {
            for(j=0;j<m&&!flag;j++)
            {
                if(s[i][j]=='#')
                    continue;
                for(k=0;k<2&&!flag;k++)
                {
                    int ii=i+dir[k][0];
                    int jj=j+dir[k][1];
                    merge(id[i][j],id[ii][jj]);
                }
            }
        }
        for(i=0;i<m;i++)
            if(s[0][i]!='#'&&s[n-1][i]!='#'&&find(id[0][i])==find(id[n-1][i]))
                flag=true;
        for(i=0;i<n;i++)
            if(s[i][0]!='#'&&s[i][m-1]!='#'&&find(id[i][0])==find(id[i][m-1]))
                flag=true;
        if(flag)
            puts("Yes");
        else
            puts("No");
    }
    return 0;
}
/*
5 4
##.#
##S#
#..#
#.##
#..#

5 4
##.#
##S#
#..#
..#.
#.##
*/


#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<stack>
#include<queue>
#include<vector>
#include<map>
#include<ctime>
using namespace std;
const int MAX=2500005;
int fa[MAX],n,m,dir[2][2]={0,1,1,0};
int id[1505][1505],tot,sx,sy;
char s[1505][1505];
int find(int x)
{
    if(fa[x]!=x)
        fa[x]=find(fa[x]);
    return fa[x];
}
bool in(int i,int j)
{
    if(i<0||i>=n||j<0||j>=m)
        return false;
    return true;
}
bool merge(int a,int b)
{
     int x=find(a),y=find(b);
    if(x==y&&find(id[sx][sy])==y)
    {
        //cout<<a<<" "<<b<<endl;
        return true;
    }
    fa[x]=y;
    return false;
}
int main()
{
    int i,j,k;
    while(scanf("%d%d",&n,&m)!=EOF)
    {
        for(i=0;i<n;i++)
            scanf("%s",s[i]);
        tot=0;
        for(i=0;i<n;i++)
        {
            for(j=0;j<m;j++)
            {
                if(s[i][j]=='.')
                    id[i][j]=++tot;
                else if(s[i][j]=='S')
                {
                    sx=i;
                    sy=j;
                    id[i][j]=++tot;
                }
                else
                    id[i][j]=-1;
            }
        }
        for(i=1;i<=tot;i++)
            fa[i]=i;
        bool flag=false;
        for(i=0;i<n&&!flag;i++)
        {
            for(j=0;j<m&&!flag;j++)
            {
                if(s[i][j]=='#')
                    continue;
                //cout<<"ca "<<i<<" "<<j<<endl;
                for(k=0;k<2&&!flag;k++)
                {
                    int ii=i+dir[k][0];
                    int jj=j+dir[k][1];
                   // cout<<i<<" "<<j<<" "<<ii<<" "<<jj<<endl;
                    if(in(ii,jj)&&s[ii][jj]!='#')
                    {
                        if(merge(id[i][j],id[ii][jj]))
                        {
                            //cout<<i<<" "<<j<<endl;
                            flag=true;
                        }
                    }
                }
                if(i==0&&s[n-1][j]!='#')
                {
                    if(merge(id[i][j],id[n-1][j]))
                    {
                        //cout<<i<<" gg "<<j<<endl;
                        flag=true;
                    }
                }
                if(j==0&&s[i][m-1]!='#')
                    if(merge(id[i][j],id[i][m-1]))
                    {
                        //cout<<i<<" ## "<<j<<endl;
                        flag=true;
                    }
            }
        }
        if(flag)
            puts("Yes");
        else
            puts("No");
    }
    return 0;
}
/*
5 4
##.#
##S#
#..#
#.##
#..#

5 4
##.#
##S#
#..#
..#.
#.##
*/


#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<stack>
#include<queue>
#include<vector>
#include<map>
#include<ctime>
using namespace std;
const int MAX=2500005;
int fa[MAX],n,m,dir[2][2]={0,1,1,0};
int id[1505][1505],tot,sx,sy;
char s[1505][1505];
int find(int x)
{
    if(fa[x]!=x)
        fa[x]=find(fa[x]);
    return fa[x];
}
bool in(int i,int j)
{
    if(i<0||i>=n||j<0||j>=m)
        return false;
    return true;
}
bool merge(int a,int b)
{
     int x=find(a),y=find(b);
    if(x==y&&find(id[sx][sy])==y)
    {
        //cout<<a<<" "<<b<<endl;
        return true;
    }
    fa[x]=y;
    return false;
}
int main()
{
    int i,j,k;
    while(scanf("%d%d",&n,&m)!=EOF)
    {
        for(i=0;i<n;i++)
            scanf("%s",s[i]);
        tot=0;
        for(i=0;i<n;i++)
        {
            for(j=0;j<m;j++)
            {
                if(s[i][j]=='.')
                    id[i][j]=++tot;
                else if(s[i][j]=='S')
                {
                    sx=i;
                    sy=j;
                    id[i][j]=++tot;
                }
                else
                    id[i][j]=-1;
            }
        }
        for(i=1;i<=tot;i++)
            fa[i]=i;
        bool flag=false;
        for(i=0;i<n&&!flag;i++)
        {
            for(j=0;j<m&&!flag;j++)
            {
                if(s[i][j]=='#')
                    continue;
                //cout<<"ca "<<i<<" "<<j<<endl;
                for(k=0;k<2&&!flag;k++)
                {
                    int ii=i+dir[k][0];
                    int jj=j+dir[k][1];
                    //cout<<i<<" "<<j<<" "<<ii<<" "<<jj<<endl;
                    if(in(ii,jj)&&s[ii][jj]!='#')
                    {
                        if(merge(id[i][j],id[ii][jj]))
                        {
                            //cout<<i<<" "<<j<<endl;
                            flag=true;
                        }
                    }
                }
                if(i==n-1&&s[0][j]!='#')
                {
                    if(merge(id[i][j],id[0][j]))
                    {
                        //cout<<i<<" gg "<<j<<endl;
                        flag=true;
                    }
                }
                if(j==m-1&&s[i][0]!='#')
                    if(merge(id[i][j],id[i][0]))
                    {
                        //cout<<i<<" ## "<<j<<endl;
                        flag=true;
                    }
            }
        }
        if(flag)
            puts("Yes");
        else
            puts("No");
    }
    return 0;
}
/*
5 4
##.#
##S#
#..#
#.##
#..#

5 4
##.#
##S#
#..#
..#.
#.##
*/


#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<stack>
#include<queue>
#include<vector>
#include<map>
#include<ctime>
using namespace std;
const int MAX=2500005;
int fa[MAX],n,m,dir[2][2]={0,1,1,0};
int id[1505][1505],tot,sx,sy,e,adj[MAX];
char s[1505][1505];
int ca[MAX];
struct node
{
    int v,next;
}g[MAX*8];
void add(int u,int v)
{
    //cout<<u<<" ->"<<v<<endl;
    g[e].v=v; g[e].next=adj[u]; adj[u]=e++;
    g[e].v=u; g[e].next=adj[v]; adj[v]=e++;
}
bool dfs(int u,int fa)
{
    //cout<<"u="<<u<<endl;
    ca[u]=1;
    int i,v;
    for(i=adj[u];i!=-1;i=g[i].next)
    {
        v=g[i].v;
        if(v==fa)
            continue;
        if(ca[v]==1)
            return true;
        if(ca[v]==0)
            if(dfs(v,u))
                return true;
    }
    ca[v]=2;
    return false;
}
int find(int x)
{
    if(fa[x]!=x)
        fa[x]=find(fa[x]);
    return fa[x];
}
bool in(int i,int j)
{
    if(i<0||i>=n||j<0||j>=m)
        return false;
    return true;
}
void merge(int a,int b)
{
     int x=find(a),y=find(b);
    fa[x]=y;
}
int main()
{
    int i,j,k;
    while(scanf("%d%d",&n,&m)!=EOF)
    {
        for(i=0;i<n;i++)
            scanf("%s",s[i]);
        tot=0;
        memset(adj,-1,sizeof(adj));
        e=0;
        for(i=0;i<n;i++)
        {
            for(j=0;j<m;j++)
            {
                if(s[i][j]=='.')
                    id[i][j]=++tot;
                else if(s[i][j]=='S')
                {
                    sx=i;
                    sy=j;
                    id[i][j]=++tot;
                }
                else
                    id[i][j]=-1;
            }
        }
        for(i=1;i<=tot;i++)
            fa[i]=i;
        bool flag=false;
        for(i=0;i<n;i++)
        {
            for(j=0;j<m;j++)
            {
                if(s[i][j]=='#')
                    continue;
                for(k=0;k<2;k++)
                {
                    int ii=i+dir[k][0];
                    int jj=j+dir[k][1];
                    if(in(ii,jj)&&s[ii][jj]!='#')
                        add(id[i][j],id[ii][jj]);
                }
            }
        }
        for(i=0;i<m;i++)
            if(s[0][i]!='#'&&s[n-1][i]!='#')
                add(id[n-1][i],id[0][i]);
        for(i=0;i<n;i++)
            if(s[i][0]!='#'&&s[i][m-1]!='#')
                add(id[i][m-1],id[i][0]);
        memset(ca,0,sizeof(ca));
        if(dfs(id[sx][sy],-1))
            flag=true;
        if(flag)
            puts("Yes");
        else
            puts("No");
    }
    return 0;
}
/*
5 4
##.#
##S#
#..#
#.##
#..#

5 4
##.#
##S#
#..#
..#.
#.##
*/


#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<stack>
#include<queue>
#include<vector>
#include<map>
#include<ctime>
#include<set>
using namespace std;
struct node
{
    int x,y;
};
int n,m,dir[4][2]={0,1,1,0,-1,0,0,-1};
int N,M,tot,sx,sy,e;
char s[1502][1502];
int vis[1502][1502][2];
set<pair<int,int> >ss;
bool check()
{
    queue<node>que;
    node now,next;
    vis[sx][sy][0]=sx;
    vis[sx][sy][1]=sy;
    now.x=sx; now.y=sy;
    que.push(now);
    ss.clear();
    ss.insert(make_pair(sx,sy));
    while(!que.empty())
    {
        now=que.front();
        que.pop();
        for(int k=0;k<4;k++)
        {
            int xx=now.x+dir[k][0],yy=now.y+dir[k][1];
            int x=(xx%n+n)%n,y=(yy%m+m)%m;
            if(s[x][y]=='#')
                continue;
            if(vis[x][y][0]!=-1)
            {
                if((vis[x][y][0]!=xx||vis[x][y][1]!=yy))
                    return true;
            }
            else
            {
                vis[x][y][0]=xx;
                vis[x][y][1]=yy;
                if(ss.find(make_pair(xx,yy))!=ss.end())
                    continue;
                next.x=xx; next.y=yy;
                ss.insert(make_pair(xx,yy));
                que.push(next);
            }
        }
    }
    return false;
}
int main()
{
    int i,j,k;
    while(scanf("%d%d",&n,&m)!=EOF)
    {
        for(i=0;i<n;i++)
        {
            scanf("%s",s[i]);
            for(j=0;j<m;j++)
                if(s[i][j]=='S')
                {
                    sx=i;
                    sy=j;
                }
        }
        memset(vis,-1,sizeof(vis));
        if(check())
            puts("Yes");
        else
            puts("No");
    }
    return 0;
}
/*
5 4
##.#
##S#
#..#
#.##
#..#

5 4
##.#
##S#
#..#
..#.
#.##

10 10
.#########
S#........
##.#######
...#......
####.#####
.....#....
######.###
.......#..
########.#
#........#

*/


#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<stack>
#include<queue>
#include<vector>
#include<map>
#include<ctime>
#include<set>
using namespace std;
#define MP make_pair
struct node
{
    int x,y;
};
int n,m,dir[4][2]={0,1,1,0,-1,0,0,-1};
int N,M,tot,sx,sy,e;
char s[1502][1502];
pair<int,int> pos[1502][1502];
bool vis[1502][1502];
set<pair<int,int> >ss;
bool check()
{
    queue<node>que;
    node now,next;
    vis[sx][sy]=true;
    pos[sx][sy]=MP(sx,sy);
    now.x=sx; now.y=sy;
    que.push(now);
    //ss.clear();
    //ss.insert(make_pair(sx,sy));
    while(!que.empty())
    {
        now=que.front();
        que.pop();
        for(int k=0;k<4;k++)
        {
            int xx=now.x+dir[k][0],yy=now.y+dir[k][1];
            int x=(xx%n+n)%n,y=(yy%m+m)%m;
            if(s[x][y]=='#')
                continue;
            if(vis[x][y])
            {
                if(pos[x][y]!=MP(xx,yy))
                    return true;
            }
            else
            {
                vis[x][y]=true;
                pos[x][y]=MP(xx,yy);
                next.x=xx; next.y=yy;
                que.push(next);
            }
        }
    }
    return false;
}
int main()
{
    int i,j,k;
    while(scanf("%d%d",&n,&m)!=EOF)
    {
        for(i=0;i<n;i++)
        {
            scanf("%s",s[i]);
            for(j=0;j<m;j++)
                if(s[i][j]=='S')
                {
                    sx=i;
                    sy=j;
                }
        }
        memset(vis,false,sizeof(vis));
        if(check())
            puts("Yes");
        else
            puts("No");
    }
    return 0;
}
/*
5 4
##.#
##S#
#..#
#.##
#..#

5 4
##.#
##S#
#..#
..#.
#.##

10 10
.#########
S#........
##.#######
...#......
####.#####
.....#....
######.###
.......#..
########.#
#........#

*/


#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<stack>
#include<queue>
#include<vector>
#include<map>
#include<ctime>
using namespace std;
const int MAX=2500005;
int fa[MAX],n,m,dir[2][2]={0,1,1,0};
int id[1505][1505],tot,sx,sy;
char s[1505][1505];
int find(int x)
{
    if(fa[x]!=x)
        fa[x]=find(fa[x]);
    return fa[x];
}
bool in(int i,int j)
{
    if(i<0||i>=n||j<0||j>=m)
        return false;
    return true;
}
bool merge(int a,int b)
{
     int x=find(a),y=find(b);
    if(x==y&&find(id[sx][sy])==y)
    {
        //cout<<a<<" "<<b<<endl;
        return true;
    }
    fa[x]=y;
    return false;
}
int main()
{
    int i,j,k;
    while(scanf("%d%d",&n,&m)!=EOF)
    {
        for(i=0;i<n;i++)
            scanf("%s",s[i]);
        tot=0;
        for(i=0;i<n;i++)
        {
            for(j=0;j<m;j++)
            {
                if(s[i][j]=='.')
                    id[i][j]=++tot;
                else if(s[i][j]=='S')
                {
                    sx=i;
                    sy=j;
                    id[i][j]=++tot;
                }
                else
                    id[i][j]=-1;
            }
        }
        for(i=1;i<=tot;i++)
            fa[i]=i;
        bool flag=false;
        for(i=0;i<n&&!flag;i++)
        {
            for(j=0;j<m&&!flag;j++)
            {
                if(s[i][j]=='#')
                    continue;
                //cout<<"ca "<<i<<" "<<j<<endl;
                for(k=0;k<2&&!flag;k++)
                {
                    int ii=i+dir[k][0];
                    int jj=j+dir[k][1];
                    //cout<<i<<" "<<j<<" "<<ii<<" "<<jj<<endl;
                    if(in(ii,jj)&&s[ii][jj]!='#')
                    {
                        if(merge(id[i][j],id[ii][jj]))
                        {
                            //cout<<i<<" "<<j<<endl;
                            flag=true;
                        }
                    }
                }
            }
        }
        for(i=0;i<m;i++)
            if(s[0][i]!='#'&&s[n-1][i]!='#'&&merge(id[0][i],id[n-1][i]))
                flag=true;
        for(i=0;i<n;i++)
            if(s[i][0]!='#'&&s[i][m-1]!='#'&&merge(id[i][0],id[i][m-1]))
                flag=true;
        if(flag)
            puts("Yes");
        else
            puts("No");
    }
    return 0;
}
/*
5 4
##.#
##S#
#..#
#.##
#..#

5 4
##.#
##S#
#..#
..#.
#.##
*/


#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<stack>
#include<queue>
#include<vector>
#include<map>
#include<ctime>
using namespace std;
struct node
{
    int x,y;
};
int n,m,dir[4][2]={0,1,1,0,-1,0,0,-1};
int N,M,tot,sx,sy,e;
char s[1502][1502];
int vis[1502][1502][2];
bool check()
{
    queue<node>que;
    node now,next;
    vis[sx][sy][0]=sx;
    vis[sx][sy][1]=sy;
    now.x=sx; now.y=sy;
    que.push(now);
    while(!que.empty())
    {
        now=que.front();
        que.pop();
        for(int k=0;k<4;k++)
        {
            int xx=now.x+dir[k][0],yy=now.y+dir[k][1];
            int x=(xx%n+n)%n,y=(yy%m+m)%m;
            if(s[x][y]=='#')
                continue;
            if(vis[x][y][0]!=-1)
            {
                if((vis[x][y][0]!=xx||vis[x][y][1]!=yy))
                    return true;
            }
            else
            {
                vis[x][y][0]=xx;
                vis[x][y][1]=yy;
                next.x=xx; next.y=yy;
                que.push(next);
            }
        }
    }
    return false;
}
int main()
{
    int i,j,k;
    while(scanf("%d%d",&n,&m)!=EOF)
    {
        for(i=0;i<n;i++)
        {
            scanf("%s",s[i]);
            for(j=0;j<m;j++)
                if(s[i][j]=='S')
                {
                    sx=i;
                    sy=j;
                }
        }
        memset(vis,-1,sizeof(vis));
        if(check())
            puts("Yes");
        else
            puts("No");
    }
    return 0;
}
/*
5 4
##.#
##S#
#..#
#.##
#..#

5 4
##.#
##S#
#..#
..#.
#.##

10 10
.#########
S#........
##.#######
...#......
####.#####
.....#....
######.###
.......#..
########.#
#........#

*/


#include<iostream>
#include<stack>
#include<queue>
#include<cstdio>
#include<algorithm>
#include<vector>
#include<set>
#include<string>
#include<cstring>
#include<map>
#include<numeric>
#include<sstream>
#include<cmath>
using namespace std;
#define all(v) (v).begin(), (v).end()
#define rall(v) (v).rbegin(), (v).rend()
#define pb push_back
#define f(i,x,y) for(int i = x; i<y; i++ )
#define FORV(it,A) for(vector<int>::iterator it = A.begin(); it!= A.end(); it++)
#define FORS(it,A) for(set<int>::iterator it = A.begin(); it!= A.end(); it++)
#define quad(x) (x) * (x)
#define mp make_pair
#define clr(x, y) memset(x, y, sizeof x)
#define fst first
#define snd second
typedef pair<int, int> pii;
typedef long long ll;
typedef long double ld;
#define N 1600
#define inf 10000000
char M[N][N];
int Ch[N][N];
int Cv[N][N];
pii per[N][N];
int n, m;
int Vx[] = {0, -1, 0, 1};
int Vy[] = {-1, 0, 1, 0};
bool ans;
inline bool fora (int x, int y){
    if (min (x,y) < 0 || (x >= n) || (y >= m)) return 1;
    return 0;
}

inline pii converte (int x, int y){
    while (x < 0) x += n;
    while (y < 0) y += m;
    return mp (x%n, y%m);
}

void dfs (int x, int y){
    if (ans = 1) return;
    pii p = converte (x,y);
    if (M[p.fst][p.snd] == '#') return;
    if (per[p.fst][p.snd].fst != -inf){
        if (per[p.fst][p.snd] != mp (x,y)) ans = 1;
        return;
    }
    per[p.fst][p.snd] = mp (x,y);
    f (i, 0, 4){
        int xx = x+Vx[i], yy = y+Vy[i];
        dfs (xx,yy);
    }
}

int main (){
    ans = 0;
    scanf("%d %d", &n, &m);
    f (i, 0, n) scanf(" %s", M[i]);
    f (i, 0, n) f (j, 0, m) per[i][j] = mp (-inf,-inf);
    f (i, 0, n) f (j, 0, m) if (M[i][j] =='S'){
        dfs (i, j);
    }
    if (ans) printf("Yes\n");
    else printf("No\n");
    return 0;
}


#include<iostream>
#include<stack>
#include<queue>
#include<cstdio>
#include<algorithm>
#include<vector>
#include<set>
#include<string>
#include<cstring>
#include<map>
#include<numeric>
#include<sstream>
#include<cmath>
using namespace std;
#define all(v) (v).begin(), (v).end()
#define rall(v) (v).rbegin(), (v).rend()
#define pb push_back
#define f(i,x,y) for(int i = x; i<y; i++ )
#define FORV(it,A) for(vector<int>::iterator it = A.begin(); it!= A.end(); it++)
#define FORS(it,A) for(set<int>::iterator it = A.begin(); it!= A.end(); it++)
#define quad(x) (x) * (x)
#define mp make_pair
#define clr(x, y) memset(x, y, sizeof x)
#define fst first
#define snd second
typedef pair<int, int> pii;
typedef long long ll;
typedef long double ld;
#define N 1600
#define inf 10000000
char M[N][N];
int Ch[N][N];
int Cv[N][N];
pii per[N][N];
int n, m;
int Vx[] = {0, -1, 0, 1};
int Vy[] = {-1, 0, 1, 0};
bool ans;
inline bool fora (int x, int y){
    if (min (x,y) < 0 || (x >= n) || (y >= m)) return 1;
    return 0;
}

inline pii converte (int x, int y){
    while (x < 0) x += n;
    while (y < 0) y += m;
    return mp (x%n, y%m);
}

void dfs (int x, int y){
    if (ans == 1) return;
    pii p = converte (x,y);
    if (M[p.fst][p.snd] == '#') return;
    if (per[p.fst][p.snd].fst != -inf){
        if (per[p.fst][p.snd] != mp (x,y)) ans = 1;
        return;
    }
    per[p.fst][p.snd] = mp (x,y);
    f (i, 0, 4){
        int xx = x+Vx[i], yy = y+Vy[i];
        dfs (xx,yy);
    }
}

int main (){
    ans = 0;
    scanf("%d %d", &n, &m);
    f (i, 0, n) scanf(" %s", M[i]);
    f (i, 0, n) f (j, 0, m) per[i][j] = mp (-inf,-inf);
    f (i, 0, n) f (j, 0, m) if (M[i][j] =='S'){
        dfs (i, j);
    }
    if (ans) printf("Yes\n");
    else printf("No\n");
    return 0;
}


#include<iostream>
#include<stack>
#include<queue>
#include<cstdio>
#include<algorithm>
#include<vector>
#include<set>
#include<string>
#include<cstring>
#include<map>
#include<numeric>
#include<sstream>
#include<cmath>
using namespace std;
#define all(v) (v).begin(), (v).end()
#define rall(v) (v).rbegin(), (v).rend()
#define pb push_back
#define f(i,x,y) for(int i = x; i<y; i++ )
#define FORV(it,A) for(vector<int>::iterator it = A.begin(); it!= A.end(); it++)
#define FORS(it,A) for(set<int>::iterator it = A.begin(); it!= A.end(); it++)
#define quad(x) (x) * (x)
#define mp make_pair
#define clr(x, y) memset(x, y, sizeof x)
#define fst first
#define snd second
typedef pair<int, int> pii;
typedef long long ll;
typedef long double ld;
#define N 1600
#define inf 10000000
char M[N][N];
int Ch[N][N];
int Cv[N][N];
pii per[N][N];
int n, m;
int Vx[] = {0, -1, 0, 1};
int Vy[] = {-1, 0, 1, 0};
bool ans;
inline bool fora (int x, int y){
    if (min (x,y) < 0 || (x >= n) || (y >= m)) return 1;
    return 0;
}

pii converte (int x, int y){
    while (x < 0) x += n;
    while (y < 0) y += m;
    return mp (x%n, y%m);
}

void dfs (int x, int y){
    pii p = converte (x,y);
    if (M[p.fst][p.snd] == '#') return;
    if (per[p.fst][p.snd].fst != -inf){
        if (per[p.fst][p.snd] != mp (x,y)) ans = 1;
        return;
    }
    per[p.fst][p.snd] = mp (x,y);
    f (i, 0, 4){
        int xx = x+Vx[i], yy = y+Vy[i];
        dfs (xx,yy);
    }
}

int main (){
    ans = 0;
    scanf("%d %d", &n, &m);
    f (i, 0, n) scanf(" %s", M[i]);
    f (i, 0, n) f (j, 0, m) per[i][j] = mp (-inf,-inf);
    f (i, 0, n) f (j, 0, m) if (M[i][j] =='S'){
        dfs (i, j);
    }
    if (ans) printf("Yes\n");
    else printf("No\n");
    return 0;
}


#include<iostream>
#include<stack>
#include<queue>
#include<cstdio>
#include<algorithm>
#include<vector>
#include<set>
#include<string>
#include<cstring>
#include<map>
#include<numeric>
#include<sstream>
#include<cmath>
using namespace std;
#define all(v) (v).begin(), (v).end()
#define rall(v) (v).rbegin(), (v).rend()
#define pb push_back
#define f(i,x,y) for(int i = x; i<y; i++ )
#define FORV(it,A) for(vector<int>::iterator it = A.begin(); it!= A.end(); it++)
#define FORS(it,A) for(set<int>::iterator it = A.begin(); it!= A.end(); it++)
#define quad(x) (x) * (x)
#define mp make_pair
#define clr(x, y) memset(x, y, sizeof x)
#define fst first
#define snd second
typedef pair<int, int> pii;
typedef long long ll;
typedef long double ld;
#define N 1600
char M[N][N];
int Ch[N][N];
int Cv[N][N];
bool per[N][N];
int n, m;
int Vx[] = {0, -1, 0, 1};
int Vy[] = {-1, 0, 1, 0};
inline bool fora (int x, int y){
    if (min (x,y) < 0 || (x >= n) || (y >= m)) return 1;
    return 0;
}

void dfs (int x, int y){
    if (per[x][y] || M[x][y] == '#') return;
    per[x][y] = 1;
    f (i, 0, 4){
        int xx = x+Vx[i], yy = y+Vy[i];
        xx = (xx+n)%n, yy = (yy+m)%m;
        dfs (xx,yy);
    }
}

void comh (int x, int y, int cor){
    if (Ch[x][y] || M[x][y] == '#') return;
    Ch[x][y] = cor;
    f (i, 0, 4){
        int xx = x+Vx[i], yy = y+Vy[i];
        if (fora(xx,0)) continue;
        yy = (yy+m)%m;
        comh (xx,yy,cor);
    }
}
void comv (int x, int y, int cor){
    if (Cv[x][y] || M[x][y] == '#') return;
    Cv[x][y] = cor;
    f (i, 0, 4){
        int xx = x+Vx[i], yy = y+Vy[i];
        if (fora(0, yy)) continue;
        xx = (xx+n)%n;
        comv (xx,yy,cor);
    }
}
bool ans;

int target;

multiset <int> E[N];
int seen[N*N];

void solve(int v){
    if (seen[v]) {
        ans = 1; return;
    }
    seen[v] = 1;
    while (E[v].size()){
        multiset <int>:: iterator it = E[v].begin();
        int u = *it;
        E[v].erase(it);
        E[u].erase(E[u].find(v));
        solve(u);
    }
}

int main (){
    scanf("%d %d", &n, &m);
    f (i, 0, n) scanf(" %s", M[i]);
    clr (per, 0); int topo = 1; clr (Cv, 0); clr (Ch, 0);
    int inix, iniy;
    f (i, 0, n) f (j, 0, m) if (M[i][j] =='S'){
        inix = i, iniy = j;
        dfs (i, j);
    }

    f (i, 0, n) f (j, 0, m) if (Ch[i][j] == 0 && M[i][j] != '#'){
        comh (i, j, topo++);
    }
    topo = 1;
    f (i, 0, n) f (j, 0, m) if (Cv[i][j] == 0 && M[i][j] != '#'){
        comv (i, j, topo++);
    }
    ans = 0;
    f (i, 0, n) f (j, 0, m) if (per[i][j]){
        f (t, 0, 2){
            int x = i+Vx[t], y = j+Vy[t];
            int xx =x, yy= y;
            if (fora(x,y)){
                x = (x+n)%n, y = (y+m)%m;
                if (M[x][y] == '#') continue;
                if (xx == x){
                    if (Cv[i][j] == Cv[x][y]) ans = 1;
                }
                else{
                    if (Ch[i][j] == Ch[x][y]) ans = 1;
                }
            }
        }
    }
    if (ans) printf("Yes\n");
    else printf("No\n");
    return 0;
}


#include<iostream>
#include<stack>
#include<queue>
#include<cstdio>
#include<algorithm>
#include<vector>
#include<set>
#include<string>
#include<cstring>
#include<map>
#include<numeric>
#include<sstream>
#include<cmath>
using namespace std;
#define all(v) (v).begin(), (v).end()
#define rall(v) (v).rbegin(), (v).rend()
#define pb push_back
#define f(i,x,y) for(int i = x; i<y; i++ )
#define FORV(it,A) for(vector<int>::iterator it = A.begin(); it!= A.end(); it++)
#define FORS(it,A) for(set<int>::iterator it = A.begin(); it!= A.end(); it++)
#define quad(x) (x) * (x)
#define mp make_pair
#define clr(x, y) memset(x, y, sizeof x)
#define fst first
#define snd second
typedef pair<int, int> pii;
typedef long long ll;
typedef long double ld;
#define N 1600
#define inf 10000000
char M[N][N];
int Ch[N][N];
int Cv[N][N];
pii per[N][N];
int n, m;
int Vx[] = {0, -1, 0, 1};
int Vy[] = {-1, 0, 1, 0};
bool ans;
inline bool fora (int x, int y){
    if (min (x,y) < 0 || (x >= n) || (y >= m)) return 1;
    return 0;
}

inline pii converte (int x, int y){
    while (x < 0) x += n;
    while (y < 0) y += m;
    return mp (x%n, y%m);
}

void dfs (int x, int y){
    pii p = converte (x,y);
    if (M[p.fst][p.snd] == '#') return;
    if (per[p.fst][p.snd].fst != -inf){
        if (per[p.fst][p.snd] != mp (x,y)) ans = 1;
        return;
    }
    per[p.fst][p.snd] = mp (x,y);
    f (i, 0, 4){
        int xx = x+Vx[i], yy = y+Vy[i];
        dfs (xx,yy);
    }
}

int main (){
    ans = 0;
    scanf("%d %d", &n, &m);
    f (i, 0, n) scanf(" %s", M[i]);
    f (i, 0, n) f (j, 0, m) per[i][j] = mp (-inf,-inf);
    f (i, 0, n) f (j, 0, m) if (M[i][j] =='S'){
        dfs (i, j);
    }
    if (ans) printf("Yes\n");
    else printf("No\n");
    return 0;
}


#include<iostream>
#include<stack>
#include<queue>
#include<cstdio>
#include<algorithm>
#include<vector>
#include<set>
#include<string>
#include<cstring>
#include<map>
#include<numeric>
#include<sstream>
#include<cmath>
using namespace std;
#define all(v) (v).begin(), (v).end()
#define rall(v) (v).rbegin(), (v).rend()
#define pb push_back
#define f(i,x,y) for(int i = x; i<y; i++ )
#define FORV(it,A) for(vector<int>::iterator it = A.begin(); it!= A.end(); it++)
#define FORS(it,A) for(set<int>::iterator it = A.begin(); it!= A.end(); it++)
#define quad(x) (x) * (x)
#define mp make_pair
#define clr(x, y) memset(x, y, sizeof x)
#define fst first
#define snd second
typedef pair<int, int> pii;
typedef long long ll;
typedef long double ld;
#define N 1600
char M[N][N];
int C[N][N];
bool per[N][N];
int n, m;
int Vx[] = {0, 0, -1, 1};
int Vy[] = {-1, 1, 0, 0};
inline bool fora (int x, int y){
    if (min (x,y) < 0 || (x >= n) || (y >= m)) return 1;
    return 0;
}

void dfs (int x, int y){
    if (per[x][y] || M[x][y] == '#') return;
    per[x][y] = 1;
    f (i, 0, 4){
        int xx = x+Vx[i], yy = y+Vy[i];
        xx = (xx+n)%n, yy = (yy+m)%m;
        dfs (xx,yy);
    }
}

void com (int x, int y, int cor){
    if (C[x][y] || M[x][y] == '#') return;
    C[x][y] = cor;
    f (i, 0, 4){
        int xx = x+Vx[i], yy = y+Vy[i];
        if (fora(xx,yy)) continue;
        com (xx,yy,cor);
    }
}

int main (){
    scanf("%d %d", &n, &m);
    f (i, 0, n) scanf(" %s", M[i]);
    clr (per, 0); int topo = 1; clr (C, 0);
    f (i, 0, n) f (j, 0, m) if (M[i][j] =='S'){
        dfs (i, j);
    }
    f (i, 0, n) f (j, 0, m) if (C[i][j] == 0 && M[i][j] != '#'){
        com (i, j, topo++);
    }
    bool ans = 0;
    f (i, 0, n) f (j, 0, m) if (per[i][j]){
        f (t, 0, 4){
            int x = i+Vx[t], y = j+Vy[t];
            if (fora(x,y)){
                x = (x+n)%n, y = (y+m)%m;
                if (C[i][j] == C[x][y]) ans = 1;
            }
        }
    }
    if (ans) printf("Yes\n");
    else printf("No\n");
    return 0;
}


#include<iostream>
#include<stack>
#include<queue>
#include<cstdio>
#include<algorithm>
#include<vector>
#include<set>
#include<string>
#include<cstring>
#include<map>
#include<numeric>
#include<sstream>
#include<cmath>
using namespace std;
#define all(v) (v).begin(), (v).end()
#define rall(v) (v).rbegin(), (v).rend()
#define pb push_back
#define f(i,x,y) for(int i = x; i<y; i++ )
#define FORV(it,A) for(vector<int>::iterator it = A.begin(); it!= A.end(); it++)
#define FORS(it,A) for(set<int>::iterator it = A.begin(); it!= A.end(); it++)
#define quad(x) (x) * (x)
#define mp make_pair
#define clr(x, y) memset(x, y, sizeof x)
#define fst first
#define snd second
typedef pair<int, int> pii;
typedef long long ll;
typedef long double ld;
#define N 1600
char M[N][N];
bool per[N][N];
int n, m;
int Vx[] = {0, 0, -1, 1};
int Vy[] = {-1, 1, 0, 0};
inline bool fora (int x, int y){
    if (min (x,y) < 0 || (x >= n) || (y >= m)) return 1;
    return 0;
}

void dfs (int x, int y){
    if (per[x][y] || M[x][y] == '#') return;
    per[x][y] = 1;
    f (i, 0, 4){
        int xx = x+Vx[i], yy = y+Vy[i];
        if (fora(xx,yy)) continue;
        dfs (xx,yy);
    }
}

int main (){
    scanf("%d %d", &n, &m);
    f (i, 0, n) scanf(" %s", M[i]);
    clr (per, 0);
    f (i, 0, n) f (j, 0, m) if (M[i][j] =='S'){
        dfs (i, j);
    }
    bool ans = 0;
    f (i, 0, n) f (j, 0, m) if (per[i][j]){
        f (t, 0, 4){
            int x = i+Vx[t], y = j+Vy[t];
            if (fora(x,y)){
                x = (x+n)%n, y = (y+m)%m;
                if (per[x][y]) {
                    ans = 1;
                }
            }
        }
    }
    if (ans) printf("Yes\n");
    else printf("No\n");
    return 0;
}


#include<iostream>
#include<stack>
#include<queue>
#include<cstdio>
#include<algorithm>
#include<vector>
#include<set>
#include<string>
#include<cstring>
#include<map>
#include<numeric>
#include<sstream>
#include<cmath>
using namespace std;
#define all(v) (v).begin(), (v).end()
#define rall(v) (v).rbegin(), (v).rend()
#define pb push_back
#define f(i,x,y) for(int i = x; i<y; i++ )
#define FORV(it,A) for(vector<int>::iterator it = A.begin(); it!= A.end(); it++)
#define FORS(it,A) for(set<int>::iterator it = A.begin(); it!= A.end(); it++)
#define quad(x) (x) * (x)
#define mp make_pair
#define clr(x, y) memset(x, y, sizeof x)
#define fst first
#define snd second
typedef pair<int, int> pii;
typedef long long ll;
typedef long double ld;
#define N 1600
char M[N][N];
int C[N][N];
bool per[N][N];
int n, m;
int Vx[] = {0, -1, 0, 1};
int Vy[] = {-1, 0, 1, 0};
inline bool fora (int x, int y){
    if (min (x,y) < 0 || (x >= n) || (y >= m)) return 1;
    return 0;
}

void dfs (int x, int y){
    if (per[x][y] || M[x][y] == '#') return;
    per[x][y] = 1;
    f (i, 0, 4){
        int xx = x+Vx[i], yy = y+Vy[i];
        xx = (xx+n)%n, yy = (yy+m)%m;
        dfs (xx,yy);
    }
}

void com (int x, int y, int cor){
    if (C[x][y] || M[x][y] == '#') return;
    C[x][y] = cor;
    f (i, 0, 4){
        int xx = x+Vx[i], yy = y+Vy[i];
        if (fora(xx,yy)) continue;
        com (xx,yy,cor);
    }
}
bool ans;

int target;

multiset <int> E[N];
int seen[N*N];

void solve(int v){
    if (seen[v]) {
        ans = 1; return;
    }
    seen[v] = 1;
    while (E[v].size()){
        multiset <int>:: iterator it = E[v].begin();
        int u = *it;
        E[v].erase(it);
        E[u].erase(E[u].find(v));
        solve(u);
    }
}

int main (){
    scanf("%d %d", &n, &m);
    f (i, 0, n) scanf(" %s", M[i]);
    clr (per, 0); int topo = 1; clr (C, 0);
    int inix, iniy;
    f (i, 0, n) f (j, 0, m) if (M[i][j] =='S'){
        inix = i, iniy = j;
        dfs (i, j);
    }

    f (i, 0, n) f (j, 0, m) if (C[i][j] == 0 && M[i][j] != '#'){
        com (i, j, topo++);
    }
    ans = 0;
    f (i, 0, n) f (j, 0, m) if (per[i][j]){
        f (t, 0, 2){
            int x = i+Vx[t], y = j+Vy[t];
            if (fora(x,y)){
                x = (x+n)%n, y = (y+m)%m;
                if (M[x][y] == '#') continue;
               // printf("%d %d\n", C[i][j], C[x][y]);
                E[C[i][j]].insert(C[x][y]);
                E[C[x][y]].insert(C[i][j]);
            }
        }
    }
    solve (C[inix][iniy]);
    if (ans) printf("Yes\n");
    else printf("No\n");
    return 0;
}


#include<iostream>
#include<stack>
#include<queue>
#include<cstdio>
#include<algorithm>
#include<vector>
#include<set>
#include<string>
#include<cstring>
#include<map>
#include<numeric>
#include<sstream>
#include<cmath>
using namespace std;
#define all(v) (v).begin(), (v).end()
#define rall(v) (v).rbegin(), (v).rend()
#define pb push_back
#define f(i,x,y) for(int i = x; i<y; i++ )
#define FORV(it,A) for(vector<int>::iterator it = A.begin(); it!= A.end(); it++)
#define FORS(it,A) for(set<int>::iterator it = A.begin(); it!= A.end(); it++)
#define quad(x) (x) * (x)
#define mp make_pair
#define clr(x, y) memset(x, y, sizeof x)
#define fst first
#define snd second
typedef pair<int, int> pii;
typedef long long ll;
typedef long double ld;
#define N 1600
#define inf 10000000
char M[N][N];
int Ch[N][N];
int Cv[N][N];
pii per[N][N];
int n, m;
int Vx[] = {0, -1, 0, 1};
int Vy[] = {-1, 0, 1, 0};
bool ans;
inline bool fora (int x, int y){
    if (min (x,y) < 0 || (x >= n) || (y >= m)) return 1;
    return 0;
}

inline pii converte (int x, int y){
    while (x < 0) x += n*n;
    while (y < 0) y += m*m;
    return mp (x%n, y%m);
}

void dfs (int x, int y){
    if (ans == 1) return;
    pii p = converte (x,y);
    if (M[p.fst][p.snd] == '#') return;
    if (per[p.fst][p.snd].fst != -inf){
        if (per[p.fst][p.snd] != mp (x,y)) ans = 1;
        return;
    }
    per[p.fst][p.snd] = mp (x,y);
    f (i, 0, 4){
        int xx = x+Vx[i], yy = y+Vy[i];
        dfs (xx,yy);
    }
}

int main (){
    ans = 0;
    scanf("%d %d", &n, &m);
    f (i, 0, n) scanf(" %s", M[i]);
    f (i, 0, n) f (j, 0, m) per[i][j] = mp (-inf,-inf);
    f (i, 0, n) f (j, 0, m) if (M[i][j] =='S'){
        dfs (i, j);
    }
    if (ans) printf("Yes\n");
    else printf("No\n");
    return 0;
}


#include <iostream>
#include <fstream>
#include <cstring>
#include <vector>
#include <stack>
#include <set>
#include <tr1/unordered_map>
#define INF 2000000000
#define MAXN 1500
#define MAXM 1500
typedef long long ULL;
using namespace std;
using namespace tr1;

int N,M;
char cosa[MAXN][MAXM];
pair <int,int> S;
int X[4]={1,-1,0,0};
int Y[4]={0,0,-1,1};
int total=0;

int mod(int a,int b){
	a=a%b;
	if(a<0)a+=b;
	return a;
}

void leggi(){
	cin >> N >> M;
	for(int i=0;i<N;i++){
		char riga[M+3];
		scanf("%s",riga);
		for(int j=0;j<M;j++){
			if(riga[j]=='S')S=make_pair(i,j);
			if(riga[j]!='#')cosa[i][j]=true;
		}
	}
}

bool dfs(){
	set <pair <int,int> > fatto;
	stack <pair <int,int> > aperti;
	aperti.push(S);
	while(!aperti.empty() and int(fatto.size())<M*N+10){
		pair <int,int> V=aperti.top();
		aperti.pop();
		int x=V.first;
		int y=V.second;

		for(int i=0;i<4;i++){
			if(cosa[mod(x+X[i],N)][mod(y+Y[i],M)] and fatto.insert(make_pair(x+X[i],y+Y[i])).second){
				aperti.push(make_pair(x+X[i],y+Y[i]));
			}
		}
	}
	if(int(fatto.size())>M*N+4)return true;
	return false;
}

int main(){
	leggi();
	bool res=dfs();
	if(res)cout << "Yes";
	else cout << "No";
}


#include <iostream>
#include <fstream>
#include <cstring>
#include <vector>
#include <stack>
#include <set>
#include <tr1/unordered_map>
#define INF 2000000000
#define MAXN 1500
#define MAXM 1500
typedef long long ULL;
using namespace std;
using namespace tr1;

int N,M;
char cosa[MAXN][MAXM];
pair <int,int> S;
int X[4]={1,-1,0,0};
int Y[4]={0,0,-1,1};
int total=0;

int mod(int a,int b){
	a=a%b;
	if(a<0)a+=b;
	return a;
}

void leggi(){
	cin >> N >> M;
	for(int i=0;i<N;i++){
		for(int j=0;j<M;j++){
			char x;
			cin >> x;
			if(x=='S')S=make_pair(i,j);
			if(x!='#')cosa[i][j]=true;
		}
	}
}

bool dfs(){
	set <pair <int,int> > fatto;
	stack <pair <int,int> > aperti;
	aperti.push(S);
	while(!aperti.empty() and int(fatto.size())<M*N+10){
		pair <int,int> V=aperti.top();
		aperti.pop();
		int x=V.first;
		int y=V.second;

		for(int i=0;i<4;i++){
			if(cosa[mod(x+X[i],N)][mod(y+Y[i],M)] and fatto.insert(make_pair(x+X[i],y+Y[i])).second){
				aperti.push(make_pair(x+X[i],y+Y[i]));
			}
		}
	}
	if(int(fatto.size())>M*N+4)return true;
	return false;
}

int main(){
	leggi();
	bool res=dfs();
	if(res)cout << "Yes";
	else cout << "No";
}


#include <iostream>
#include <fstream>
#include <cstring>
#include <vector>
#include <stack>
#include <set>
#include <tr1/unordered_map>
#define INF 2000000000
#define MAXN 5000
#define MAXM 5000
typedef unsigned long long ULL;
typedef long long LL;
using namespace std;
using namespace tr1;
ifstream in("input.txt");

int N,M;
char cosa[MAXN][MAXM];
pair <int,int> S;
int X[4]={1,-1,0,0};
int Y[4]={0,0,-1,1};
int quadri=0;

int mod(int a,int b){
	a=a%b;
	if(a<0)a+=b;
	return a;
}

void leggi(){
	cin >> N >> M;
	for(int i=0;i<N;i++){
		char riga[M+3];
		scanf("%s",riga);
		//in >> riga;
		for(int j=0;j<M;j++){
			if(riga[j]=='S')S=make_pair(i,j);
			if(riga[j]!='#'){
				quadri++;
				cosa[i][j]=true;
			}
		}
	}
}

LL hashi(LL u,LL v){
	return u*10000000+v;
}

bool dfs(){
	//set <pair <int,int> > fatto;
	unordered_map <ULL ,bool> fatto;
	stack <pair <int,int> > aperti;
	aperti.push(S);
	while(!aperti.empty() and int(fatto.size())<quadri+5){
		pair <int,int> V=aperti.top();
		aperti.pop();
		int x=V.first;
		int y=V.second;

		for(int i=0;i<4;i++){
			//if(cosa[mod(x+X[i],N)][mod(y+Y[i],M)] and fatto.insert(make_pair(x+X[i],y+Y[i])).second){
			if(cosa[mod(x+X[i],N)][mod(y+Y[i],M)] and !fatto[hashi(x+X[i],y+Y[i])]){
				fatto[hashi(x+X[i],y+Y[i])]=true;
				aperti.push(make_pair(x+X[i],y+Y[i]));
			}
		}
	}
	if(int(fatto.size())>quadri+3)return true;
	return false;
}

int main(){
	leggi();
	bool res=dfs();
	if(res)cout << "Yes\n";
	else cout << "No\n";
}


#include <iostream>
#include <fstream>
#include <cstring>
#include <vector>
#include <stack>
#include <set>
#include <tr1/unordered_map>
#define INF 2000000000
#define MAXN 5000
#define MAXM 5000
typedef unsigned long long ULL;
typedef long long LL;
using namespace std;
using namespace tr1;
ifstream in("input.txt");

int N,M;
char cosa[MAXN][MAXM];
pair <int,int> S;
int X[4]={1,-1,0,0};
int Y[4]={0,0,-1,1};
int total=0;

int mod(int a,int b){
	a=a%b;
	if(a<0)a+=b;
	return a;
}

void leggi(){
	cin >> N >> M;
	for(int i=0;i<N;i++){
		char riga[M+3];
		scanf("%s",riga);
		//in >> riga;
		for(int j=0;j<M;j++){
			if(riga[j]=='S')S=make_pair(i,j);
			if(riga[j]!='#')cosa[i][j]=true;
		}
	}
}

LL hashi(LL u,LL v){
	return u*10000000+v;
}

bool dfs(){
	//set <pair <int,int> > fatto;
	unordered_map <ULL ,bool> fatto;
	stack <pair <int,int> > aperti;
	aperti.push(S);
	while(!aperti.empty() and int(fatto.size())<M*N+10){
		pair <int,int> V=aperti.top();
		aperti.pop();
		int x=V.first;
		int y=V.second;

		for(int i=0;i<4;i++){
			//if(cosa[mod(x+X[i],N)][mod(y+Y[i],M)] and fatto.insert(make_pair(x+X[i],y+Y[i])).second){
			if(cosa[mod(x+X[i],N)][mod(y+Y[i],M)] and !fatto[hashi(x+X[i],y+Y[i])]){
				fatto[hashi(x+X[i],y+Y[i])]=true;
				aperti.push(make_pair(x+X[i],y+Y[i]));
			}
		}
	}
	if(int(fatto.size())>M*N+4)return true;
	return false;
}

int main(){
	leggi();
	bool res=dfs();
	if(res)cout << "Yes\n";
	else cout << "No\n";
}


#include <iostream>
#include <fstream>
#include <cstring>
#include <vector>
#include <stack>
#include <tr1/unordered_map>
#define INF 2000000000
#define MAXN 1500
#define MAXM 1500
typedef long long ULL;
using namespace std;
using namespace tr1;

int N,M;
char cosa[MAXN][MAXM];
pair <int,int> S;
int X[4]={1,-1,0,0};
int Y[4]={0,0,-1,1};
unordered_map <ULL,bool> fatto;
int total=0;

int mod(int a,int b){
	a=a%b;
	if(a<0)a+=b;
	return a;
}

void leggi(){
	cin >> N >> M;
	for(int i=0;i<N;i++){
		for(int j=0;j<M;j++){
			cin >> cosa[i][j];
			if(cosa[i][j]=='S'){
				S=make_pair(i,j);
				cosa[i][j]='.';
			}
		}
	}
}

ULL hashi(int x,int y){
	return ULL(x)*(1<<26)+ULL(y);
}

bool dfs(){
	stack <pair <int,int> > aperti;
	aperti.push(S);
	while(!aperti.empty() and int(fatto.size())<M*N+10){
		pair <int,int> V=aperti.top();
		aperti.pop();
		int x=V.first;
		int y=V.second;
		if(cosa[mod(x,N)][mod(y,M)]=='#' or fatto[hashi(x,y)])continue;
		fatto[hashi(x,y)]=true;
		for(int i=0;i<4;i++)aperti.push(make_pair(x+X[i],y+Y[i]));
	}
	if(int(fatto.size())>M*N+4)return true;
	return false;
}

int main(){
	leggi();
	bool res=dfs();
	if(res)cout << "Yes";
	else cout << "No";
}


#include <iostream>
#include <fstream>
#include <cstring>
#include <vector>
#include <stack>
#include <set>
#include <tr1/unordered_map>
#define INF 2000000000
#define MAXN 1500
#define MAXM 1500
typedef long long ULL;
using namespace std;
using namespace tr1;

int N,M;
char cosa[MAXN][MAXM];
pair <int,int> S;
int X[4]={1,-1,0,0};
int Y[4]={0,0,-1,1};
int total=0;

int mod(int a,int b){
	a=a%b;
	if(a<0)a+=b;
	return a;
}

void leggi(){
	cin >> N >> M;
	for(int i=0;i<N;i++){
		for(int j=0;j<M;j++){
			cin >> cosa[i][j];
			if(cosa[i][j]=='S'){
				S=make_pair(i,j);
				cosa[i][j]='.';
			}
		}
	}
}

ULL hashi(int x,int y){
	return ULL(x)*(1<<26)+ULL(y);
}

bool dfs(){
	set <pair <int,int> > fatto;
	stack <pair <int,int> > aperti;
	aperti.push(S);
	while(!aperti.empty() and int(fatto.size())<M*N+10){
		pair <int,int> V=aperti.top();
		aperti.pop();
		int x=V.first;
		int y=V.second;
		if(cosa[mod(x,N)][mod(y,M)]=='#' or !fatto.insert(V).second)continue;
		for(int i=0;i<4;i++)aperti.push(make_pair(x+X[i],y+Y[i]));
	}
	if(int(fatto.size())>M*N+4)return true;
	return false;
}

int main(){
	leggi();
	bool res=dfs();
	if(res)cout << "Yes";
	else cout << "No";
}


#include <iostream>
#include <fstream>
#include <cstring>
#include <vector>
#include <tr1/unordered_map>
#define INF 2000000000
#define MAXN 1500
#define MAXM 1500
typedef long long ULL;
using namespace std;
using namespace tr1;

int N,M;
char cosa[MAXN][MAXM];
pair <int,int> S;
int X[4]={1,-1,0,0};
int Y[4]={0,0,-1,1};
unordered_map <ULL,bool> fatto;
int total=0;

int mod(int a,int b){
	a=a%b;
	if(a<0)a+=b;
	return a;
}

void leggi(){
	cin >> N >> M;
	for(int i=0;i<N;i++){
		for(int j=0;j<M;j++){
			cin >> cosa[i][j];
			if(cosa[i][j]=='S'){
				S=make_pair(i,j);
				cosa[i][j]='.';
			}
		}
	}
}

ULL hashi(int x,int y){
	return ULL(x)*(1<<26)+ULL(y);
}

void dfs(int x,int y){
	if(cosa[mod(x,N)][mod(y,M)]=='#' or fatto[hashi(x,y)])return;
	fatto[hashi(x,y)]=true;
	total++;
	if(total>M*N+10)return;
	for(int i=0;i<4;i++)dfs(x+X[i],y+Y[i]);
}

int main(){
	leggi();
	dfs(S.first,S.second);
	if(total>M*N+4)cout << "Yes";
	else cout << "No";
}


#include<cstdio>
#include<cmath>
#include<string>
#include<cstring>
#include<cctype>
#include<cstdlib>
#include<utility>
#include<iostream>
#include<iomanip>
#include<algorithm>
#include<set>
#include<queue>
#include<vector>
#include<map>
#define inf 0x3f3f3f3f
#define SIZE 1000010
#define ll long long
#define R register
#define debug printf("OK\n")
using namespace std;
int n,m,sx,sy;
char mmp[1507][1507];
int vis[1503][1503][3];
bool flag;
const int dx[4]={-1,0,1,0},dy[4]={0,1,0,-1};
struct hxmg
{
	int x,y,b;
};
inline int read()
{
    int x=0,f=1;char ch=getchar();
    while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
    return x*f;
}
void dfs(int nx,int ny,int ox,int oy)//分别表示扩展的x,y和原迷宫的x,y 第一次走进迷宫肯定相等
{
	if(flag==true)
	return ;
	if(vis[nx][ny][0]&&(vis[nx][ny][1]!=ox||vis[nx][ny][2]!=oy))
	{
		flag=true;
		return ;
	}
	vis[nx][ny][0]=1;vis[nx][ny][1]=ox;vis[nx][ny][2]=oy;//注意用n o可能有负的
	for(R int i=0;i<4;++i)
	{
		int x=(nx+dx[i]+n-1)%n+1,y=(ny+dy[i]+m-1)%m+1;
		int mx=ox+dx[i],my=oy+dy[i];
		if(mmp[x][y]=='.')
		{
			if(!vis[x][y][0]||vis[x][y][1]!=mx||vis[x][y][2]!=my)
			dfs(x,y,mx,my);
		}
	}
}
int main()
{
    	n=read();m=read();
    	for(R int i=1;i<=n;++i)
        for(R int j=1;j<=m;++j)
        {
    	    cin>>mmp[i][j];
    	    if(mmp[i][j]=='S')
    	    {
    	    	mmp[i][j]='.';
    	        sx=i,sy=j;
    	    }
        }
        flag=false;
        dfs(sx,sy,sx,sy);
        if(flag==true)
        puts("Yes");
        else puts("No");
    return 0;
}
/*
  solution:#t25 bfs cf评测卡结构体强转 会CE 需换个方式写----->所以最终学了题解并且是dfs
           一眼bfs 找题时看到讨论版有说因为地图重复无限大 把整个矩阵复制 然后九个拼一起乱跑 觉得有理
		   但自己读题后  觉得直接判断一下如果复制接上现在的出口对应位置有没有入口就行 不用真复制乱搞
		   然后跪了 有以下情况 环和就根本不是我想的那样的情况
		   4 4
           ####
           .##S
           .##.
           ####
		   8 9
           ###.#.#.#
           #..S#.#.#
           #.###.#.#
           #.#...#.#
           #.#.###.#
           #.#.#...#
           #.#.#.###
           ..#.#.#..
		   所以怒学一波题解操作
		   如果一个点可以在原和新迷宫都被到达说明OK 但复制一定GG 太大了 可以通过新矩阵坐标取模等于原矩阵验证
		   借鉴思路 我觉得换坐标取模可以通过bfs时结构体变量除了记坐标外还记录额外的矩阵编号
		   如果在不同编号矩阵走过同一坐标说明可走无限远 只需要从中心上下左右各扩展一个就好
		   注意扩展的迷宫不能走出边界 如果走到原迷宫与扩展的交界要判扩展的接口是不是墙
		   实践表明自己的想法有锅 比如上面第二组数据就判不到
		   取模操作 如果从1开始存地图 取模要(xxxx+n-1)%n+1 这样才保证正确 %(n+1)是错的 可以手算
		   如果能原图能到达(x,y) 新图能到(x,-y) (-x,y) (x,y+n) (x+n,y) 说明 可以走无限远
*/


#include<cstdio>
#include<cmath>
#include<string>
#include<cstring>
#include<cctype>
#include<cstdlib>
#include<utility>
#include<iostream>
#include<iomanip>
#include<algorithm>
#include<set>
#include<queue>
#include<vector>
#include<map>
#define inf 0x3f3f3f3f
#define SIZE 1000010
#define ll long long
#define R register
#define debug printf("OK\n")
using namespace std;
int n,m,sx,sy;
char mmp[1507][1507];
int vis[1503][1503][3];
bool flag;
const int dx[4]={-1,0,1,0},dy[4]={0,1,0,-1};
struct hxmg
{
	int x,y,b;
};
inline int read()
{
    int x=0,f=1;char ch=getchar();
    while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
    return x*f;
}
void dfs(int nx,int ny,int ox,int oy)//分别表示扩展的x,y和原迷宫的x,y 第一次走进迷宫肯定相等
{
	if(flag==true)
	return ;
	if(vis[nx][ny][0]&&(vis[nx][ny][1]!=ox||vis[nx][ny][2]!=oy))
	{
		flag=true;
		return ;
	}
	vis[nx][ny][0]=1;vis[nx][ny][1]=ox;vis[ox][oy][2]=oy;
	for(R int i=0;i<4;++i)
	{
		int x=(nx+dx[i]+n-1)%n+1,y=(ny+dy[i]+m-1)%m+1;
		int mx=ox+dx[i],my=oy+dy[i];
		if(mmp[x][y]=='.')
		{
			if(!vis[x][y][0]||vis[x][y][1]!=mx||vis[x][y][2]!=my)
			dfs(x,y,mx,my);
		}
	}
}
int main()
{
    while(scanf("%d%d",&n,&m)!=EOF)
    {
    	memset(vis,0,sizeof(vis));
    	for(R int i=1;i<=n;++i)
        for(R int j=1;j<=m;++j)
        {
    	    cin>>mmp[i][j];
    	    if(mmp[i][j]=='S')
    	    {
    	    	mmp[i][j]='.';
    	        sx=i,sy=j;
    	    }
        }
        flag=false;
        dfs(sx,sy,sx,sy);
        if(flag==true)
        puts("Yes");
        else puts("No");
    }
    return 0;
}
/*
  solution:#t25 bfs cf评测卡结构体强转 会CE 需换个方式写----->所以最终学了题解并且是dfs
           一眼bfs 找题时看到讨论版有说因为地图重复无限大 把整个矩阵复制 然后九个拼一起乱跑 觉得有理
		   但自己读题后  觉得直接判断一下如果复制接上现在的出口对应位置有没有入口就行 不用真复制乱搞
		   然后跪了 有以下情况 环和就根本不是我想的那样的情况
		   4 4
           ####
           .##S
           .##.
           ####
		   8 9
           ###.#.#.#
           #..S#.#.#
           #.###.#.#
           #.#...#.#
           #.#.###.#
           #.#.#...#
           #.#.#.###
           ..#.#.#..
		   所以怒学一波题解操作
		   如果一个点可以在原和新迷宫都被到达说明OK 但复制一定GG 太大了 可以通过新矩阵坐标取模等于原矩阵验证
		   借鉴思路 我觉得换坐标取模可以通过bfs时结构体变量除了记坐标外还记录额外的矩阵编号
		   如果在不同编号矩阵走过同一坐标说明可走无限远 只需要从中心上下左右各扩展一个就好
		   注意扩展的迷宫不能走出边界 如果走到原迷宫与扩展的交界要判扩展的接口是不是墙
		   实践表明自己的想法有锅 比如上面第二组数据就判不到
		   取模操作 如果从1开始存地图 取模要(xxxx+n-1)%n+1 这样才保证正确 %(n+1)是错的 可以手算
		   如果能原图能到达(x,y) 新图能到(x,-y) (-x,y) (x,y+n) (x+n,y) 说明 可以走无限远
*/


/*#include<cstdio>
#include<cmath>
#include<string>
#include<cstring>
#include<cctype>
#include<cstdlib>
#include<utility>
#include<iostream>
#include<iomanip>
#include<algorithm>
#include<set>
#include<queue>
#include<vector>
#include<map>
#define inf 0x3f3f3f3f
#define SIZE 1000010
#define ll long long
#define R register
#define debug printf("OK\n")
using namespace std;
int n,m,sx,sy;
char mmp[1507][1507];
int vis[1507][1507][3];
const int dx[4]={-1,0,1,0},dy[4]={0,1,0,-1};
struct hxmg
{
    int x,y;
};
inline int read()
{
    int x=0,f=1;char ch=getchar();
    while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
    return x*f;
}
void bfs()
{
	memset(vis,0,sizeof(vis));
    queue< hxmg > q;
    hxmg bg;
    bg.x=sx;bg.y=sy;
    q.push(bg);
	vis[bg.x][bg.y][0]=1;vis[bg.x][bg.y][1]=bg.x;vis[bg.x][bg.y][2]=bg.y;
    while(q.size())
    {
        hxmg w=q.front();q.pop();
        for(R int i=0;i<=3;++i)
        {
            int cx=w.x+dx[i],cy=w.y+dy[i];
            int xx=(w.x+dx[i]+n-1)%n+1,yy=(w.y+dy[i]+m-1)%m+1;
            if(mmp[xx][yy]=='#')
            continue;
            if(vis[xx][yy][0]==1&&(vis[xx][yy][1]!=cx||vis[xx][yy][2]!=cy))
            {
            	puts("Yes");
            	exit(0);
            }
            if(!vis[xx][yy][0])
            {
                hxmg z;
                z.x=cx,z.y=cy;
                vis[xx][yy][0]=1;vis[xx][yy][1]=cx;vis[xx][yy][2]=cy;
                q.push(z);
            }
        }
    }
}
int main()
{
    n=read();m=read();
    for(R int i=1;i<=n;++i)
    for(R int j=1;j<=m;++j)
    {
    	cin>>mmp[i][j];
    	if(mmp[i][j]=='S')
    	{
    		mmp[i][j]='.';
    	    sx=i,sy=j;
    	}
    }
    for(R int i=0;i<=m+1;++i)
    mmp[0][i]='#',mmp[n+1][i]='#';
    for(R int i=0;i<=n+1;++i)
    mmp[i][0]='#',mmp[i][m+1]='#';
    bfs();
    printf("No\n");
    return 0;
}*/
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<queue>
#include<stack>
#include<math.h>
#include<vector>
#include<map>
#include<set>
#include<stdlib.h>
#include<cmath>
#include<string>
#include<algorithm>
#include<iostream>
#include<stdio.h>
using namespace std;
#define ll long long
int n,m;
struct node
{
    int x,y;
};
int dirx[4]={0,0,-1,1};
int diry[4]={-1,1,0,0};
int visx[1505][1505];
int visy[1505][1505];
char s[1505][1505];
queue<node>q;
int main()
{
    int i,j,k,stx,sty;
    node now,next;
    scanf("%d%d",&n,&m);
    for(i=0;i<n;i++)
    {
        scanf("%s",s[i]);
        for(j=0;j<m;j++)
        {
            if(s[i][j]=='S')
            {
                stx=i;
                sty=j;
            }
            visx[i][j]=10086111;
            visy[i][j]=10086111;
        }
    }
    now.x=stx;
    now.y=sty;
    int tag=0;
    visx[stx][sty]=stx;
    visy[stx][sty]=sty;
    q.push(now);
    int xx,yy;
    while(!q.empty())
    {
        now=q.front();
        q.pop();
        for(i=0;i<4;i++)
        {
            next.x=now.x+dirx[i];
            next.y=now.y+diry[i];
            xx=(next.x%n+n)%n;
            yy=(next.y%m+m)%m;
            if(s[xx][yy]!='#')
            {
                if(visx[xx][yy]==10086111)//表示之前没有经历过，随便设一个特殊值
                {
                    visx[xx][yy]=next.x;
                    visy[xx][yy]=next.y;
                    q.push(next);
                }
                else if(visx[xx][yy]!=next.x||visy[xx][yy]!=next.y)
                {
                    tag=1;
                    goto loop;
                }
            }
        }
    }
    loop:;
    if(tag)
        printf("Yes\n");
    else
        printf("No\n");
    return 0;
}

/*
  solution:cf的数据要bfs 洛谷搬过去的幻象迷宫多组数据还可以dfs
  自己写的就是bd都t飞 粘一个记录写法
*/


#include<cstdio>
#include<cmath>
#include<string>
#include<cstring>
#include<cctype>
#include<cstdlib>
#include<utility>
#include<iostream>
#include<iomanip>
#include<algorithm>
#include<set>
#include<queue>
#include<vector>
#include<map>
#define inf 0x3f3f3f3f
#define SIZE 1000010
#define ll long long
#define R register
#define debug printf("OK\n")
using namespace std;
int n,m,sx,sy;
char mmp[1507][1507];
int vis[1507][1507][3];
const int dx[4]={-1,0,1,0},dy[4]={0,1,0,-1};
struct hxmg
{
    int x,y;
};
inline int read()
{
    int x=0,f=1;char ch=getchar();
    while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
    return x*f;
}
void bfs()
{
	memset(vis,0,sizeof(vis));
    queue< hxmg > q;
    hxmg bg;
    bg.x=sx;bg.y=sy;
    q.push(bg);
	vis[bg.x][bg.y][0]=1;vis[bg.x][bg.y][1]=bg.x;vis[bg.x][bg.y][2]=bg.y;
    while(q.size())
    {
        hxmg w=q.front();q.pop();
        for(R int i=0;i<=3;++i)
        {
            int cx=w.x+dx[i],cy=w.y+dy[i];
            int xx=(w.x+dx[i]+n-1)%n+1,yy=(w.y+dy[i]+m-1)%m+1;
            if(mmp[xx][yy]=='#')
            continue;
            if(vis[xx][yy][0]==1&&(vis[xx][yy][1]!=cx||vis[xx][yy][2]!=cy))
            {
            	puts("Yes");
            	exit(0);
            }
            if(!vis[xx][yy][0])
            {
                hxmg z;
                z.x=cx,z.y=cy;
                vis[xx][yy][0]=1;vis[xx][yy][1]=cx;vis[xx][yy][2]=cy;
                q.push(z);
            }
        }
    }
}
int main()
{
    n=read();m=read();
    for(R int i=1;i<=n;++i)
    for(R int j=1;j<=m;++j)
    {
    	cin>>mmp[i][j];
    	if(mmp[i][j]=='S')
    	{
    		mmp[i][j]='.';
    	    sx=i,sy=j;
    	}
    }
    for(R int i=0;i<=m+1;++i)
    mmp[0][i]='#',mmp[n+1][i]='#';
    for(R int i=0;i<=n+1;++i)
    mmp[i][0]='#',mmp[i][m+1]='#';
    bfs();
    printf("No\n");
    return 0;
}
/*
  solution:cf的数据要bfs 洛谷搬过去的幻象迷宫多组数据还可以dfs
*/


#include<cstdio>
#include<cmath>
#include<string>
#include<cstring>
#include<cctype>
#include<cstdlib>
#include<utility>
#include<iostream>
#include<iomanip>
#include<algorithm>
#include<set>
#include<queue>
#include<vector>
#include<map>
#define inf 0x3f3f3f3f
#define SIZE 1000010
#define ll long long
#define R register
#define debug printf("OK\n")
using namespace std;
int n,m,sx,sy;
char mmp[1507][1507];
int vis[1503][1503][3];
bool flag;
const int dx[4]={-1,0,1,0},dy[4]={0,1,0,-1};
struct hxmg
{
	int x,y,b;
};
inline int read()
{
    int x=0,f=1;char ch=getchar();
    while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
    return x*f;
}
void dfs(int nx,int ny,int ox,int oy)//分别表示扩展的x,y和原迷宫的x,y 第一次走进迷宫肯定相等
{
	if(vis[nx][ny][0]&&(vis[nx][ny][1]!=ox||vis[nx][ny][2]!=oy))
	{
		puts("Yes");
		exit(0);
	}
	vis[nx][ny][0]=1;vis[nx][ny][1]=ox;vis[nx][ny][2]=oy;//注意用n o可能有负的
	for(R int i=0;i<4;++i)
	{
		int x=(nx+dx[i]+n-1)%n+1,y=(ny+dy[i]+m-1)%m+1;
		int mx=ox+dx[i],my=oy+dy[i];
		if(mmp[x][y]=='.')
		{
			if(!vis[x][y][0]||vis[x][y][1]!=mx||vis[x][y][2]!=my)
			dfs(x,y,mx,my);
		}
	}
}
int main()
{
    	n=read();m=read();
    	for(R int i=1;i<=n;++i)
        for(R int j=1;j<=m;++j)
        {
    	    cin>>mmp[i][j];
    	    if(mmp[i][j]=='S')
    	    {
    	    	mmp[i][j]='.';
    	        sx=i,sy=j;
    	    }
        }
        flag=false;
        dfs(sx,sy,sx,sy);
        puts("No");
        return 0;
}
/*
  solution:#t25 bfs cf评测卡结构体强转 会CE 需换个方式写----->所以最终学了题解并且是dfs
           一眼bfs 找题时看到讨论版有说因为地图重复无限大 把整个矩阵复制 然后九个拼一起乱跑 觉得有理
		   但自己读题后  觉得直接判断一下如果复制接上现在的出口对应位置有没有入口就行 不用真复制乱搞
		   然后跪了 有以下情况 环和就根本不是我想的那样的情况
		   4 4
           ####
           .##S
           .##.
           ####
		   8 9
           ###.#.#.#
           #..S#.#.#
           #.###.#.#
           #.#...#.#
           #.#.###.#
           #.#.#...#
           #.#.#.###
           ..#.#.#..
		   所以怒学一波题解操作
		   如果一个点可以在原和新迷宫都被到达说明OK 但复制一定GG 太大了 可以通过新矩阵坐标取模等于原矩阵验证
		   借鉴思路 我觉得换坐标取模可以通过bfs时结构体变量除了记坐标外还记录额外的矩阵编号
		   如果在不同编号矩阵走过同一坐标说明可走无限远 只需要从中心上下左右各扩展一个就好
		   注意扩展的迷宫不能走出边界 如果走到原迷宫与扩展的交界要判扩展的接口是不是墙
		   实践表明自己的想法有锅 比如上面第二组数据就判不到
		   取模操作 如果从1开始存地图 取模要(xxxx+n-1)%n+1 这样才保证正确 %(n+1)是错的 可以手算
		   如果能原图能到达(x,y) 新图能到(x,-y) (-x,y) (x,y+n) (x+n,y) 说明 可以走无限远
*/


#include<cstdio>
#include<cmath>
#include<string>
#include<cstring>
#include<cctype>
#include<cstdlib>
#include<utility>
#include<iostream>
#include<iomanip>
#include<algorithm>
#include<set>
#include<queue>
#include<vector>
#include<map>
#define inf 0x3f3f3f3f
#define SIZE 1000010
#define ll long long
#define R register
#define debug printf("OK\n")
using namespace std;
int n,m,sx,sy;
char mmp[1507][1507];
int vis[1507][1507][3];
const int dx[4]={-1,0,1,0},dy[4]={0,1,0,-1};
struct hxmg
{
    int x,y;
};
inline int read()
{
    int x=0,f=1;char ch=getchar();
    while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
    return x*f;
}
void bfs()
{
    queue< hxmg > q;
    hxmg bg;
    bg.x=sx;bg.y=sy;
    q.push(bg);
	vis[bg.x][bg.y][0]=1;vis[bg.x][bg.y][1]=bg.x;vis[bg.x][bg.y][2]=bg.y;
    while(q.size())
    {
        hxmg w=q.front();q.pop();
        for(R int i=0;i<=3;++i)
        {
            int cx=w.x+dx[i],cy=w.y+dy[i];
            int xx=(w.x+dx[i]+n-1)%n+1,yy=(w.y+dy[i]+m-1)%m+1;
            if(mmp[xx][yy]=='#')
            continue;
            if(vis[xx][yy][0]==1&&(vis[xx][yy][1]!=cx||vis[xx][yy][2]!=cy))
            {
            	puts("Yes");
            	exit(0);
            }
            if(!vis[xx][yy][0])
            {
                hxmg z;
                z.x=cx,z.y=cy;
                vis[xx][yy][0]=1;vis[xx][yy][1]=cx;vis[xx][yy][2]=cy;
                q.push(z);
            }
        }
    }
}
int main()
{
    n=read();m=read();
    for(R int i=1;i<=n;++i)
    for(R int j=1;j<=m;++j)
    {
    	cin>>mmp[i][j];
    	if(mmp[i][j]=='S')
    	{
    		mmp[i][j]='.';
    	    sx=i,sy=j;
    	}
    }
    bfs();
    printf("No\n");
    return 0;
}
/*
  solution:cf的数据要bfs 洛谷搬过去的幻象迷宫多组数据还可以dfs
*/


#include<cstdio>
#include<cmath>
#include<string>
#include<cstring>
#include<cctype>
#include<cstdlib>
#include<utility>
#include<iostream>
#include<iomanip>
#include<algorithm>
#include<set>
#include<queue>
#include<vector>
#include<map>
#define inf 0x3f3f3f3f
#define SIZE 1000010
#define ll long long
#define R register
#define debug printf("OK\n")
using namespace std;
int n,m,sx,sy;
char mmp[1507][1507];
bool vis[1507][1507],bj[1507][1507];
const int dx[4]={-1,0,1,0},dy[4]={0,1,0,-1};
struct hxmg
{
	int x,y;
};
inline int read()
{
    int x=0,f=1;char ch=getchar();
    while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
    return x*f;
}
void bfs()
{
	queue< hxmg > q;
	q.push(hxmg{sx,sy});
	while(q.size())
	{
		hxmg w=q.front();q.pop();
		if(vis[w.x][w.y]==true)
		continue;
		vis[w.x][w.y]=true;
		for(R int i=0;i<=3;++i)
		{
			int x=w.x+dx[i],y=w.y+dy[i];
			if(mmp[x][y]=='#')
			continue;
			if(mmp[x][y]=='$')
			{
				bj[w.x][w.y]=true;
				continue;
			}
			if(!vis[x][y])
			q.push(hxmg{x,y});
		}
	}
}
int main()
{
    n=read();m=read();
    for(R int i=1;i<=n;++i)
    for(R int j=1;j<=m;++j)
    {
    	cin>>mmp[i][j];
    	if(mmp[i][j]=='S')
    	mmp[i][j]='.';
    	sx=i,sy=j;
    }
    for(R int i=0;i<=m+1;++i)
    mmp[0][i]='$',mmp[n+1][i]='$';
    for(R int i=0;i<=n+1;++i)
    mmp[i][0]='$',mmp[i][m+1]='$';
    bfs();
    for(R int i=1;i<=m;++i)
    {
    	if(bj[1][i]==true&&bj[n][i]==true)
    	{
    		printf("Yes\n");
    		return 0;
    	}
    }
    for(R int i=1;i<=n;++i)
    {
    	if(bj[i][1]==true&&bj[i][m]==true)
    	{
    		printf("Yes\n");
    		return 0;
    	}
    }
    printf("No\n");
    return 0;
}
/*
  solution:#t25 bfs
           一眼bfs 找题时看到讨论版有说把整个矩阵复制 然后九个拼一起乱跑
		   觉得有理
		   但自己读题后 地图重复无限大 直接判断一下如果复制接上现在的出口对应位置有没有入口就行
		   不用真复制乱搞
*/


#include<cstdio>
#include<cmath>
#include<string>
#include<cstring>
#include<cctype>
#include<cstdlib>
#include<utility>
#include<iostream>
#include<iomanip>
#include<algorithm>
#include<set>
#include<queue>
#include<vector>
#include<map>
#define inf 0x3f3f3f3f
#define SIZE 1000010
#define ll long long
#define R register
#define debug printf("OK\n")
using namespace std;
int n,m,sx,sy;
char mmp[1507][1507];
int vis[1507][1507][3];
const int dx[4]={-1,0,1,0},dy[4]={0,1,0,-1};
struct hxmg
{
    int x,y;
};
inline int read()
{
    int x=0,f=1;char ch=getchar();
    while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
    return x*f;
}
void bfs()
{
    queue< hxmg > q;
    hxmg bg;
    bg.x=sx;bg.y=sy;
    q.push(bg);
	vis[bg.x][bg.y][0]=1;vis[bg.x][bg.y][1]=bg.x;vis[bg.x][bg.y][2]=bg.y;
    while(q.size())
    {
        hxmg w=q.front();q.pop();
        for(R int i=0;i<=3;++i)
        {
            int cx=w.x+dx[i],cy=w.y+dy[i];
            int xx=(w.x+dx[i]+n)%n,yy=(w.y+dy[i]+m)%m;
            if(mmp[xx][yy]=='#')
            continue;
            if(vis[xx][yy][0]==1&&(vis[xx][yy][1]!=cx||vis[xx][yy][2]!=cy))
            {
            	puts("Yes");
            	exit(0);
            }
            if(!vis[xx][yy][0])
            {
                hxmg z;
                z.x=cx,z.y=cy;
                vis[xx][yy][0]=1;vis[xx][yy][1]=cx;vis[xx][yy][2]=cy;
                q.push(z);
            }
        }
    }
}
int main()
{
    n=read();m=read();
    for(R int i=0;i<n;++i)
    for(R int j=0;j<m;++j)
    {
    	cin>>mmp[i][j];
    	if(mmp[i][j]=='S')
    	{
    		mmp[i][j]='.';
    	    sx=i,sy=j;
    	}
    }
    bfs();
    printf("No\n");
    return 0;
}
/*
  solution:cf的数据要bfs 洛谷搬过去的幻象迷宫多组数据还可以dfs
*/


#include<cstdio>
#include<cmath>
#include<string>
#include<cstring>
#include<cctype>
#include<cstdlib>
#include<utility>
#include<iostream>
#include<iomanip>
#include<algorithm>
#include<set>
#include<queue>
#include<vector>
#include<map>
#define inf 0x3f3f3f3f
#define SIZE 1000010
#define ll long long
#define R register
#define debug printf("OK\n")
using namespace std;
int n,m,sx,sy;
char mmp[1507][1507];
int vis[1507][1507][3];
const int dx[4]={-1,0,1,0},dy[4]={0,1,0,-1};
struct hxmg
{
    int x,y;
};
inline int read()
{
    int x=0,f=1;char ch=getchar();
    while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
    return x*f;
}
void bfs()
{
	memset(vis,0,sizeof(vis));
    queue< hxmg > q;
    hxmg bg;
    bg.x=sx;bg.y=sy;
    q.push(bg);
	vis[bg.x][bg.y][0]=1;vis[bg.x][bg.y][1]=bg.x;vis[bg.x][bg.y][2]=bg.y;
    while(q.size())
    {
        hxmg w=q.front();q.pop();
        for(R int i=0;i<=3;++i)
        {
            int cx=w.x+dx[i],cy=w.y+dy[i];
            int xx=(w.x+dx[i]+n-1)%n+1,yy=(w.y+dy[i]+m-1)%m+1;
            if(mmp[xx][yy]=='#')
            continue;
            if(vis[xx][yy][0]==1&&(vis[xx][yy][1]!=cx||vis[xx][yy][2]!=cy))
            {
            	puts("Yes");
            	exit(0);
            }
            if(!vis[xx][yy][0])
            {
                hxmg z;
                z.x=cx,z.y=cy;
                vis[xx][yy][0]=1;vis[xx][yy][1]=cx;vis[xx][yy][2]=cy;
                q.push(z);
            }
        }
    }
}
int main()
{
    n=read();m=read();
    for(R int i=1;i<=n;++i)
    for(R int j=1;j<=m;++j)
    {
    	cin>>mmp[i][j];
    	if(mmp[i][j]=='S')
    	{
    		mmp[i][j]='.';
    	    sx=i,sy=j;
    	}
    }
    bfs();
    printf("No\n");
    return 0;
}
/*
  solution:cf的数据要bfs 洛谷搬过去的幻象迷宫多组数据还可以dfs
*/


#include<cstdio>
#include<cmath>
#include<string>
#include<cstring>
#include<cctype>
#include<cstdlib>
#include<utility>
#include<iostream>
#include<iomanip>
#include<algorithm>
#include<set>
#include<queue>
#include<vector>
#include<map>
#define inf 0x3f3f3f3f
#define SIZE 1000010
#define ll long long
#define R register
#define debug printf("OK\n")
using namespace std;
int n,m,sx,sy;
char mmp[1507][1507];
int vis[1503][1503][3];
bool flag;
const int dx[4]={-1,0,1,0},dy[4]={0,1,0,-1};
struct hxmg
{
	int x,y,b;
};
inline int read()
{
    int x=0,f=1;char ch=getchar();
    while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
    return x*f;
}
void dfs(int nx,int ny,int ox,int oy)//分别表示扩展的x,y和原迷宫的x,y 第一次走进迷宫肯定相等
{
	if(vis[nx][ny][0]&&(vis[nx][ny][1]!=ox||vis[nx][ny][2]!=oy))
	{
		puts("Yes");
		exit(0);
	}
	vis[nx][ny][0]=1;vis[nx][ny][1]=ox;vis[nx][ny][2]=oy;//注意用n o可能有负的
	for(R int i=0;i<4;++i)
	{
		int x=(nx+dx[i]+n-1)%n+1,y=(ny+dy[i]+m-1)%m+1;
		int mx=ox+dx[i],my=oy+dy[i];
		if(mmp[x][y]=='.')
		{
			if(!vis[x][y][0]||vis[x][y][1]!=mx||vis[x][y][2]!=my)
			dfs(x,y,mx,my);
		}
	}
}
int main()
{
    n=read();m=read();
    for(R int i=1;i<=n;++i)
    for(R int j=1;j<=m;++j)
    {
        cin>>mmp[i][j];
        if(mmp[i][j]=='S')
        {
        	mmp[i][j]='.';
            sx=i,sy=j;
        }
    }
    flag=false;
    dfs(sx,sy,sx,sy);
    puts("No");
    return 0;
}


#include<cstdio>
#include<cmath>
#include<string>
#include<cstring>
#include<cctype>
#include<cstdlib>
#include<utility>
#include<iostream>
#include<iomanip>
#include<algorithm>
#include<set>
#include<queue>
#include<vector>
#include<map>
#define inf 0x3f3f3f3f
#define SIZE 1000010
#define ll long long
#define R register
#define debug printf("OK\n")
using namespace std;
int n,m,sx,sy;
char mmp[1507][1507];
int vis[1503][1503][3];
bool flag;
const int dx[4]={-1,0,1,0},dy[4]={0,1,0,-1};
struct hxmg
{
	int x,y,b;
};
inline int read()
{
    int x=0,f=1;char ch=getchar();
    while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
    return x*f;
}
void dfs(int nx,int ny,int ox,int oy)//分别表示扩展的x,y和原迷宫的x,y 第一次走进迷宫肯定相等
{
	if(flag==true)
	return ;
	if(vis[nx][ny][0]&&(vis[nx][ny][1]!=ox||vis[nx][ny][2]!=oy))
	{
		flag=true;
		return ;
	}
	vis[nx][ny][0]=1;vis[nx][ny][1]=ox;vis[nx][ny][2]=oy;//注意用n o可能有负的
	for(R int i=0;i<4;++i)
	{
		int x=(nx+dx[i]+n-1)%n+1,y=(ny+dy[i]+m-1)%m+1;
		int mx=ox+dx[i],my=oy+dy[i];
		if(mmp[x][y]=='.')
		{
			if(!vis[x][y][0]||vis[x][y][1]!=mx||vis[x][y][2]!=my)
			dfs(x,y,mx,my);
		}
	}
}
int main()
{
    while(scanf("%d%d",&n,&m)!=EOF)
    {
    	memset(vis,0,sizeof(vis));
    	for(R int i=1;i<=n;++i)
        for(R int j=1;j<=m;++j)
        {
    	    cin>>mmp[i][j];
    	    if(mmp[i][j]=='S')
    	    {
    	    	mmp[i][j]='.';
    	        sx=i,sy=j;
    	    }
        }
        flag=false;
        dfs(sx,sy,sx,sy);
        if(flag==true)
        puts("Yes");
        else puts("No");
    }
    return 0;
}
/*
  solution:#t25 bfs cf评测卡结构体强转 会CE 需换个方式写----->所以最终学了题解并且是dfs
           一眼bfs 找题时看到讨论版有说因为地图重复无限大 把整个矩阵复制 然后九个拼一起乱跑 觉得有理
		   但自己读题后  觉得直接判断一下如果复制接上现在的出口对应位置有没有入口就行 不用真复制乱搞
		   然后跪了 有以下情况 环和就根本不是我想的那样的情况
		   4 4
           ####
           .##S
           .##.
           ####
		   8 9
           ###.#.#.#
           #..S#.#.#
           #.###.#.#
           #.#...#.#
           #.#.###.#
           #.#.#...#
           #.#.#.###
           ..#.#.#..
		   所以怒学一波题解操作
		   如果一个点可以在原和新迷宫都被到达说明OK 但复制一定GG 太大了 可以通过新矩阵坐标取模等于原矩阵验证
		   借鉴思路 我觉得换坐标取模可以通过bfs时结构体变量除了记坐标外还记录额外的矩阵编号
		   如果在不同编号矩阵走过同一坐标说明可走无限远 只需要从中心上下左右各扩展一个就好
		   注意扩展的迷宫不能走出边界 如果走到原迷宫与扩展的交界要判扩展的接口是不是墙
		   实践表明自己的想法有锅 比如上面第二组数据就判不到
		   取模操作 如果从1开始存地图 取模要(xxxx+n-1)%n+1 这样才保证正确 %(n+1)是错的 可以手算
		   如果能原图能到达(x,y) 新图能到(x,-y) (-x,y) (x,y+n) (x+n,y) 说明 可以走无限远
*/