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;
const int NMAX = 500010;
int N, M, K;
int tPrefix[NMAX], tSuffix[NMAX];
int nodeValue[NMAX];
int maxLenSuff[NMAX];
char S[NMAX], T[NMAX];
vector<int> Tree[NMAX];
int kPath = 0;
int treeSize[NMAX], where[NMAX], father[NMAX], pos[NMAX];
int lazy[4 * NMAX];
int offset[NMAX];
vector<int> path[NMAX];
void DFS(int node) {
  if (Tree[node].size() == 0) return;
  for (int next : Tree[node]) {
    DFS(next);
    nodeValue[node] += nodeValue[next];
  }
}
void heavyDFS(int node) {
  if (Tree[node].size() == 0) {
    treeSize[node] = 1;
    where[node] = kPath++;
    pos[node] = path[where[node]].size();
    path[where[node]].push_back(node);
    return;
  }
  int maxSubtree = -1, maxSubtreeSize;
  treeSize[node] = 1;
  for (int next : Tree[node]) {
    heavyDFS(next);
    treeSize[node] += treeSize[next];
    if (maxSubtree == -1 || maxSubtreeSize < treeSize[next]) {
      maxSubtree = next;
      maxSubtreeSize = treeSize[next];
    }
  }
  where[node] = where[maxSubtree];
  pos[node] = path[where[node]].size();
  path[where[node]].push_back(node);
  for (int next : Tree[node]) {
    if (next == maxSubtree) continue;
    father[where[next]] = node;
  }
}
int queryLazy(int node, int left, int right, int pos, int _node, int offset) {
  if (left == right) {
    return lazy[offset + node] + nodeValue[_node];
  }
  if (lazy[offset + node]) {
    lazy[offset + node * 2] += lazy[offset + node];
    lazy[offset + node * 2 + 1] += lazy[offset + node];
    lazy[offset + node] = 0;
  }
  int mid = (left + right) / 2;
  if (pos <= mid) return queryLazy(node * 2, left, mid, pos, _node, offset);
  return queryLazy(node * 2 + 1, mid + 1, right, pos, _node, offset);
}
void updateLazy(int node, int left, int right, int qLeft, int qRight, int value,
                int offset) {
  if (left > right) return;
  if (left >= qLeft && qRight >= right) {
    lazy[offset + node] += value;
    return;
  }
  int mid = (left + right) / 2;
  if (qLeft <= mid)
    updateLazy(node * 2, left, mid, qLeft, qRight, value, offset);
  if (qRight > mid)
    updateLazy(node * 2 + 1, mid + 1, right, qLeft, qRight, value, offset);
}
int main() {
  int i;
  scanf("%d %d %d %s %s", &N, &M, &K, S, T);
  int lenT = strlen(T), currMatch = 0;
  for (i = 1; i < lenT; ++i) {
    while (currMatch != 0 && T[currMatch] != T[i]) {
      currMatch = tPrefix[currMatch];
    }
    if (T[currMatch] == T[i]) {
      ++currMatch;
    }
    tPrefix[i + 1] = currMatch;
  }
  int lenS = strlen(S);
  currMatch = 0;
  for (i = 0; i < lenS; ++i) {
    while ((currMatch != 0 && S[i] != T[currMatch]) || currMatch >= K) {
      currMatch = tPrefix[currMatch];
    }
    if (S[i] == T[currMatch]) {
      ++currMatch;
    }
    if (currMatch == lenT && i + 1 < K) {
      cout << "Yes\n" << 1 << ' ' << 1 + K << '\n';
      return 0;
    } else if (currMatch == lenT && i - K + 2 >= 1 && i + K + 1 <= lenS) {
      cout << "Yes\n" << i - K + 2 << ' ' << i + 2 << '\n';
      return 0;
    } else if (currMatch == lenT && i + 1 - lenT + 1 >= lenS - K + 1) {
      cout << "Yes\n" << lenS - 2 * K + 1 << ' ' << lenS - K + 1 << '\n';
      return 0;
    }
  }
  currMatch = 0;
  Tree[0].push_back(1);
  for (i = lenT - 2; i >= 0; --i) {
    while (currMatch != 0 && T[lenT - 1 - currMatch] != T[i]) {
      currMatch = tSuffix[currMatch];
    }
    if (T[lenT - 1 - currMatch] == T[i]) {
      ++currMatch;
    }
    tSuffix[lenT - 1 - i + 1] = currMatch;
    Tree[currMatch].push_back(lenT - 1 - i + 1);
  }
  currMatch = 0;
  for (i = lenS - 1; i >= 0; --i) {
    while ((currMatch != 0 && S[i] != T[lenT - 1 - currMatch]) ||
           currMatch >= K) {
      currMatch = tSuffix[currMatch];
    }
    if (S[i] == T[lenT - 1 - currMatch]) {
      ++currMatch;
    }
    maxLenSuff[i] = currMatch;
    if (i <= lenS - K) {
      ++nodeValue[currMatch];
    }
  }
  heavyDFS(0);
  DFS(0);
  for (i = 1; i < kPath; ++i) {
    offset[i] = offset[i - 1] + 4 * path[i - 1].size();
  }
  currMatch = 0;
  int _pos = -1;
  for (i = 0; i < lenS; ++i) {
    while ((currMatch != 0 && S[i] != T[currMatch]) || currMatch >= K) {
      currMatch = tPrefix[currMatch];
    }
    if (S[i] == T[currMatch]) {
      ++currMatch;
    }
    int currNode = maxLenSuff[i];
    while (where[currNode] != where[0]) {
      updateLazy(1, 0, path[where[currNode]].size() - 1, pos[currNode],
                 path[where[currNode]].size() - 1, -1, offset[where[currNode]]);
      currNode = father[where[currNode]];
    }
    updateLazy(1, 0, path[where[currNode]].size() - 1, pos[currNode],
               path[where[currNode]].size() - 1, -1, offset[where[currNode]]);
    if (i >= K - 1) {
      int remainder = lenT - currMatch;
      int answer =
          queryLazy(1, 0, path[where[remainder]].size() - 1, pos[remainder],
                    remainder, offset[where[remainder]]);
      if (answer > 0) {
        _pos = i;
        break;
      }
    }
  }
  if (_pos == -1) {
    cout << "No\n";
    return 0;
  }
  cout << "Yes\n";
  int last = currMatch;
  currMatch = 0;
  for (i = last + 1; i < lenT; ++i) {
    while (currMatch != 0 && T[last + currMatch] != T[i]) {
      currMatch = tPrefix[currMatch];
    }
    if (T[last + currMatch] == T[i]) {
      ++currMatch;
    }
    tPrefix[i - last + 1] = currMatch;
  }
  currMatch = 0;
  for (i = _pos + 1; i < lenS; ++i) {
    while (currMatch != 0 && S[i] != T[last + currMatch]) {
      currMatch = tPrefix[currMatch];
    }
    if (S[i] == T[last + currMatch]) {
      ++currMatch;
    }
    if (currMatch == lenT - last) {
      cout << _pos - K + 2 << ' ' << i - currMatch + 2 << '\n';
      return 0;
    }
  }
  return 0;
}
