/**
 * Calculate the number of occurances of ALL permutations of a given word in a given text.
 * INPUT: 
 *	|word| |text|
 *	word
 *	text
 * OUTPUT:
 *	The number of times "word" or any permutation of it appears in "text".
 * ALGORITHM: 
 *   - Create a multiset of letters in "word".
 *   - Go over "text", and check if any letter appears in the multiset.
 *
 * @author Erel Segal
 * @date 2010-11-04
 */

#include <iostream>
#include <string>
#include <algorithm>
using namespace std;

typedef unsigned short ushort;
typedef unsigned int uint;

// A multiset of letters - counts how many times each letter appears:
class EnglishLettersMultiset {
	ushort caps[26], noncaps[26];
	ushort myCount;
public:
	EnglishLettersMultiset() {
		fill_n(caps,26, (ushort)0);
		fill_n(noncaps,26, (ushort)0);
		myCount = 0;
	}

	EnglishLettersMultiset& operator= (const EnglishLettersMultiset& other) {
		copy(other.caps,other.caps+26, caps);
		copy(other.noncaps,other.noncaps+26, noncaps);
		myCount = other.myCount;
		return *this;
	}

	// Increase the counter for a single letter:
	void add(char c) {
		if ('A'<=c && c<='Z') {
			caps[c-'A']++;
			myCount++;
		} else if ('a'<=c && c<='z') {
			noncaps[c-'a']++;
			myCount++;
		} else throw string("tried to add an illegal char '")+c+string("'");
	}

	// Decrease the counter for a single letter; returns true iff it exists.
	bool testAndRemove(char c) {
		if ('A'<=c && c<='Z') {
			if (caps[c-'A']>0) {
				caps[c-'A']--;
				myCount--;
				return true;
			} else return false;
		}	else if ('a'<=c && c<='z') {
			if (noncaps[c-'a']>0) {
				noncaps[c-'a']--;
				myCount--;
				return true;
			} else return false;
		} else throw string("tried to remove an illegal char '")+c+string("'");
	}
	
	bool count() const { return myCount; }
	bool empty() const { return myCount==0; }
}; // class EnglishLettersMultiset



uint countPermutations(const string& word, const string& text) {
	// Initialization: create a multiset of letters in word
	EnglishLettersMultiset wordLetters;
	string::const_iterator cWord, cText;
	for (cWord=word.begin(); cWord!=word.end(); ++cWord)
		wordLetters.add(*cWord);

	uint count=0;
	EnglishLettersMultiset tempWordLetters=wordLetters;
	bool changed=true;
	for (cText=text.begin(); cText!=text.end(); ++cText) {
		//cout << *cText << ":";
		if (changed) {
			tempWordLetters = wordLetters; // restore the temporary multiset for the next iteration
			changed=false;
		}
		for (cWord=cText; cWord!=text.end(); ++cWord) {
			//cout << *cWord;
			if (!tempWordLetters.testAndRemove(*cWord)) { // no permutation starts at cText
				//cout << "-";
				break;
			} else {
				changed = true;
				if (tempWordLetters.empty()) { // found a permutation
					//cout << "+";
					count++;
					break;
				}
			}
		}
	//	cout << " ";
	}
	return count;
}



void assertCount(string word, string text, uint expected) {
	time_t before = time(NULL);
	uint a = countPermutations(word,text);
	if (a!=expected) {
		cerr << "ERROR: Count of " << word << " in " << text << " should be " << expected << " but was " << a << endl;
	} else {
		time_t after = time(NULL);
		cout << "calculated cost of " << word.length() << "x" << text.size() << " chars in " << (after-before) << " seconds" << endl;
	}
}


void testIdentical(int N) {
	string word1(1, 'a');
	string word2(2, 'a');
	string text(N, 'a');
	assertCount(word1, text, N);
	assertCount(word2, text, N-1);
	assertCount(text, word1, 0);
	assertCount(text, word2, 0);
}

void testAlmostIdentical(int N) {
	string word("ab");
	string text(N, 'a'); text += 'b';
	assertCount(word, text, 1);
}



int main() {
	try {
		/* tests:  
		assertCount("cAda","AbrAcadAbRa",2);
		testIdentical(13);
		testAlmostIdentical(13);
		*/

		uint nWord, nText;
		cin >> nWord >> nText;

		string word, text;
		cin >> word >> text;

		cout << countPermutations(word,text) << endl;
	} catch (string message) {
		cerr << "ERROR: " << message << endl;
	}
}
