Jenya has recently acquired quite a useful tool — k-scissors for cutting strings. They are generally used for cutting out two non-intersecting substrings of length k from an arbitrary string s (its length should be at least 2·k in order to perform this operation) and concatenating them afterwards (preserving the initial order). For example, with the help of 2-scissors you can cut ab and de out of abcde and concatenate them into abde, but not ab and bc since they're intersecting.

It's a nice idea to test this tool before using it in practice. After looking through the papers, Jenya came up with two strings s and t. His question is whether it is possible to apply his scissors to string s such that the resulting concatenation contains t as a substring?

Input

The first line contains three integers n, m, k (2 ≤ m ≤ 2·k ≤ n ≤ 5·105) — length of s, length of t and the aforementioned scissors' parameter correspondingly.

The next two lines feature s and t consisting of lowercase latin letters.

Output

If there is no answer, print «No». 

Otherwise print «Yes» and two integers L and R denoting the indexes where cutted substrings start (1-indexed). If there are several possible answers, output any.

Examples

Input

7 4 3
baabaab
aaaa


Output

Yes
1 5


Input

6 3 2
cbcbcb
bcc


Output

Yes
2 5


Input

7 5 3
aabbaaa
aaaaa


Output

No

Note

In the first sample case you can cut out two substrings starting at 1 and 5. The resulting string baaaab contains aaaa as a substring.

In the second sample case the resulting string is bccb.
#include <bits/stdc++.h>
using namespace std;
vector<int> zAlg(string s) {
  int n = s.size();
  vector<int> z(n);
  z.at(0) = n;
  int i = 1;
  int j = 0;
  while (i < n) {
    for (; i + j < n && s.at(j) == s.at(i + j); j++) {
    }
    z.at(i++) = j;
    if (j > 0) {
      for (int k = 1; i < n && z.at(k) < j - 1; k++, j--, i++)
        z.at(i) = z.at(k);
      j--;
    }
  }
  return z;
}
vector<int> matches(string p, string s, char sepChar = '\xff') {
  auto v = zAlg(p + string(1, sepChar) + s);
  int n = p.size();
  vector<int> res;
  for (size_t i = 0; i < s.size() - (n - 1); i++) {
    if (v.at(n + 1 + i) == n) res.push_back(i);
  }
  return res;
}
template <typename T>
bool updMax(T& tmax, const T& x) {
  if (x > tmax) {
    tmax = x;
    return true;
  } else {
    return false;
  }
}
template <typename T>
bool updMin(T& tmin, const T& x) {
  if (x < tmin) {
    tmin = x;
    return true;
  } else {
    return false;
  }
}
template <typename T1, typename T2>
ostream& operator<<(ostream& os, const pair<T1, T2>& p) {
  os << "(" << p.first << ", " << p.second << ")";
  return os;
}
template <typename T1, typename T2, typename T3>
ostream& operator<<(ostream& os, const tuple<T1, T2, T3>& t) {
  os << "(" << get<0>(t) << ", " << get<1>(t) << ", " << get<2>(t) << ")";
  return os;
}
template <typename T1, typename T2, typename T3, typename T4>
ostream& operator<<(ostream& os, const tuple<T1, T2, T3, T4>& t) {
  os << "(" << get<0>(t) << ", " << get<1>(t) << ", " << get<2>(t) << ", "
     << get<3>(t) << ")";
  return os;
}
template <typename T>
ostream& operator<<(ostream& os, const vector<T>& v) {
  os << '[';
  for (auto it = v.begin(); it != v.end(); it++) {
    if (it != v.begin()) os << ", ";
    os << *it;
  }
  os << ']';
  return os;
}
template <typename T, typename C>
ostream& operator<<(ostream& os, const set<T, C>& v) {
  os << '{';
  for (auto it = v.begin(); it != v.end(); it++) {
    if (it != v.begin()) os << ", ";
    os << *it;
  }
  os << '}';
  return os;
}
template <typename T, typename C>
ostream& operator<<(ostream& os, const unordered_set<T, C>& v) {
  os << '{';
  for (auto it = v.begin(); it != v.end(); it++) {
    if (it != v.begin()) os << ", ";
    os << *it;
  }
  os << '}';
  return os;
}
template <typename T, typename C>
ostream& operator<<(ostream& os, const multiset<T, C>& v) {
  os << '{';
  for (auto it = v.begin(); it != v.end(); it++) {
    if (it != v.begin()) os << ", ";
    os << *it;
  }
  os << '}';
  return os;
}
template <typename T1, typename T2, typename C>
ostream& operator<<(ostream& os, const map<T1, T2, C>& mp) {
  os << '[';
  for (auto it = mp.begin(); it != mp.end(); it++) {
    if (it != mp.begin()) os << ", ";
    os << it->first << ": " << it->second;
  }
  os << ']';
  return os;
}
template <typename T1, typename T2, typename C>
ostream& operator<<(ostream& os, const unordered_map<T1, T2, C>& mp) {
  os << '[';
  for (auto it = mp.begin(); it != mp.end(); it++) {
    if (it != mp.begin()) os << ", ";
    os << it->first << ": " << it->second;
  }
  os << ']';
  return os;
}
template <typename T, typename T2>
ostream& operator<<(ostream& os, const queue<T, T2>& orig) {
  queue<T, T2> que(orig);
  bool first = true;
  os << '[';
  while (!que.empty()) {
    T x = que.front();
    que.pop();
    if (!first) os << ", ";
    os << x;
    first = false;
  }
  return os << ']';
}
template <typename T, typename T2>
ostream& operator<<(ostream& os, const deque<T, T2>& orig) {
  deque<T, T2> que(orig);
  bool first = true;
  os << '[';
  while (!que.empty()) {
    T x = que.front();
    que.pop_front();
    if (!first) os << ", ";
    os << x;
    first = false;
  }
  return os << ']';
}
template <typename T, typename T2, typename T3>
ostream& operator<<(ostream& os, const priority_queue<T, T2, T3>& orig) {
  priority_queue<T, T2, T3> pq(orig);
  bool first = true;
  os << '[';
  while (!pq.empty()) {
    T x = pq.top();
    pq.pop();
    if (!first) os << ", ";
    os << x;
    first = false;
  }
  return os << ']';
}
template <typename T>
ostream& operator<<(ostream& os, const stack<T>& st) {
  stack<T> tmp(st);
  os << '[';
  bool first = true;
  while (!tmp.empty()) {
    T& t = tmp.top();
    if (first)
      first = false;
    else
      os << ", ";
    os << t;
    tmp.pop();
  }
  os << ']';
  return os;
}
ostream& operator<<(ostream& os, int8_t x) {
  os << (int32_t)x;
  return os;
}
template <class... Args>
string dbgFormat(const char* fmt, Args... args) {
  size_t len = snprintf(nullptr, 0, fmt, args...);
  char buf[len + 1];
  snprintf(buf, len + 1, fmt, args...);
  return string(buf);
}
template <class Head>
void dbgLog(bool with_nl, Head&& head) {
  cerr << head;
  if (with_nl) cerr << endl;
}
template <class Head, class... Tail>
void dbgLog(bool with_nl, Head&& head, Tail&&... tail) {
  cerr << head << " ";
  dbgLog(with_nl, forward<Tail>(tail)...);
}
const string end_mark("^__=end=__^");
int naive(istream& cin, ostream& cout);
int body(istream& cin, ostream& cout);
void cmpNaive() {
  while (true) {
    string s;
    getline(cin, s);
    bool run_body;
    if (s.at(0) == 'Q') {
      return;
    } else if (s.at(0) == 'B') {
      run_body = true;
    } else if (s.at(0) == 'N') {
      run_body = false;
    } else {
      cerr << "Unknown body/naive specifier.\n";
      exit(1);
    }
    string input_s;
    while (true) {
      getline(cin, s);
      if (s == end_mark) break;
      input_s += s;
      input_s += "\n";
    }
    stringstream ss_in(move(input_s));
    stringstream ss_out;
    if (run_body) {
      body(ss_in, ss_out);
    } else {
      naive(ss_in, ss_out);
    }
    cout << ss_out.str() << end_mark << endl;
  }
}
int main(int argc, char* argv[]) {
  ios_base::sync_with_stdio(false);
  cin.tie(nullptr);
  cout << setprecision(20);
  body(cin, cout);
  return 0;
}
int naive(istream& cin, ostream& cout) {
  long long int n, m, k;
  cin >> n >> m >> k;
  string s, t;
  cin >> s >> t;
  string b_ans;
  cin >> b_ans;
  auto check = [&](string u) -> bool {
    for (long long int i = 0; i < (long long int)u.size(); i++) {
      if (u.substr(i, m) == t) return true;
    }
    return false;
  };
  if (b_ans == "Yes") {
    long long int x, y;
    cin >> x >> y;
    x--;
    y--;
    if (x < 0 || x + k > y || y + k > n) {
      cout << "NG\n";
      return 0;
    }
    string con = s.substr(x, k) + s.substr(y, k);
    if (check(con)) {
      cout << "OK\n";
    } else {
      cout << "NG\n";
    }
    return 0;
  } else if (b_ans == "No") {
    for (long long int x = 0; x < n - 2 * k; x++) {
      for (long long int y = x + k; y < n - k; y++) {
        if (check(s.substr(x, k) + s.substr(y, k))) {
          cout << "NG\n";
          return 0;
        }
      }
    }
    cout << "OK\n";
    return 0;
  } else {
    cout << "NG\n";
    return 0;
  }
  return 0;
}
int body(istream& cin, ostream& cout) {
  long long int n, m, k;
  cin >> n >> m >> k;
  string s, t;
  cin >> s >> t;
  auto report = [&](long long int x, long long int y) -> void {
    cout << "Yes\n" << x + 1 << " " << y + 1 << "\n";
  };
  auto analysis = [&](string s1, string t1) -> vector<long long int> {
    auto zs = zAlg(t1 + "@" + s1);
    vector<long long int> ret(m + 1, -1);
    vector<long long int> skip(m + 1);
    iota(skip.begin(), skip.end(), 1);
    for (long long int i = 0; i < n; i++) {
      long long int len = min(k, (long long int)zs[m + 1 + i]);
      if (len == 0) continue;
      long long int start = -1;
      if (i < k) {
        if (i + len < k) continue;
        start = k - i;
      } else {
        start = 1;
      }
      long long int prev = -1;
      for (long long int j = start; j <= len;) {
        if (ret[j] < 0) {
          ret[j] = i + j;
          ;
        } else {
          if (prev >= 1) skip[prev] = skip[j];
        }
        prev = j;
        j = skip[j];
      }
      skip[start] = max(skip[start], len + 1);
    }
    return ret;
  };
  if (m <= k) {
    for (long long int i : matches(t, s)) {
      ;
      long long int i0 = max(0LL, i + m - k);
      if (i0 + k + k <= n) {
        report(i0, i0 + k);
        return 0;
      }
      long long int i1 = min(n - k, i);
      if (k <= i1) {
        report(0, i1);
        return 0;
      }
    }
  }
  auto x = analysis(s, t);
  string srev(s);
  reverse(srev.begin(), srev.end());
  string trev(t);
  reverse(trev.begin(), trev.end());
  auto y = analysis(srev, trev);
  ;
  ;
  for (long long int v = 1; v < m; v++) {
    if (x[v] < 0 || y[m - v] < 0) continue;
    if (x[v] + y[m - v] <= n) {
      report(x[v] - k, n - y[m - v]);
      return 0;
    }
  }
  cout << "No\n";
  return 0;
}
